diff -Nru ghostscript-9.10~dfsg/arch/arch_autoconf.h.in ghostscript-9.25~dfsg+1/arch/arch_autoconf.h.in --- ghostscript-9.10~dfsg/arch/arch_autoconf.h.in 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/arch/arch_autoconf.h.in 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,97 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + + /* ---------------- Scalar alignments ---------------- */ + +#define ARCH_ALIGN_SHORT_MOD @ARCH_ALIGN_SHORT_MOD@ +#define ARCH_ALIGN_INT_MOD @ARCH_ALIGN_INT_MOD@ +#define ARCH_ALIGN_LONG_MOD @ARCH_ALIGN_LONG_MOD@ +#define ARCH_ALIGN_PTR_MOD @ARCH_ALIGN_PTR_MOD@ +#define ARCH_ALIGN_FLOAT_MOD @ARCH_ALIGN_FLOAT_MOD@ +#define ARCH_ALIGN_DOUBLE_MOD @ARCH_ALIGN_DOUBLE_MOD@ + + /* ---------------- Scalar sizes ---------------- */ + +#define ARCH_LOG2_SIZEOF_CHAR @ARCH_LOG2_SIZEOF_CHAR@ +#define ARCH_LOG2_SIZEOF_SHORT @ARCH_LOG2_SIZEOF_SHORT@ +#define ARCH_LOG2_SIZEOF_INT @ARCH_LOG2_SIZEOF_INT@ +#define ARCH_LOG2_SIZEOF_LONG @ARCH_LOG2_SIZEOF_LONG@ +#define ARCH_LOG2_SIZEOF_LONG_LONG @ARCH_LOG2_SIZEOF_LONG_LONG@ +#define ARCH_LOG2_SIZEOF_PTR @ARCH_LOG2_SIZEOF_PTR@ +#define ARCH_LOG2_SIZEOF_FLOAT @ARCH_LOG2_SIZEOF_FLOAT@ +#define ARCH_LOG2_SIZEOF_DOUBLE @ARCH_LOG2_SIZEOF_DOUBLE@ + +#define ARCH_SIZEOF_PTR @ARCH_SIZEOF_PTR@ +#define ARCH_SIZEOF_FLOAT @ARCH_SIZEOF_FLOAT@ +#define ARCH_SIZEOF_DOUBLE @ARCH_SIZEOF_DOUBLE@ + + /* ---------------- Unsigned max values ---------------- */ + +#define ARCH_MAX_UCHAR ((unsigned char)~(unsigned char)0 + (unsigned char)0) +#define ARCH_MAX_USHORT ((unsigned short)~(unsigned short)0 + (unsigned short)0) +#define ARCH_MAX_UINT ((unsigned int)~0 + (unsigned int)0) +#define ARCH_MAX_ULONG ((unsigned long)~0L + (unsigned long)0) + + /* ---------------- Floating point ---------------- */ + +#ifndef FLOATS_ARE_IEEE + +#if defined(__STDC_IEC_559__) && __STDC_IEC_559__!=0 + +# define FLOATS_ARE_IEEE 1 + +#elif (defined(FLT_RADIX) && FLT_RADIX == 2) && (defined(FLT_MANT_DIG) && FLT_MANT_DIG == 24) \ + && (defined(FLT_MIN_EXP) && FLT_MIN_EXP == -125) && (defined(FLT_MAX_EXP) && FLT_MAX_EXP == 128) + +# define FLOATS_ARE_IEEE 1 + +#elif (defined(__FLT_RADIX__) && __FLT_RADIX__ == 2) && (defined(__FLT_MANT_DIG__) && __FLT_MANT_DIG__ == 24) \ + && (defined(__FLT_MIN_EXP__) && __FLT_MIN_EXP__ == -125) && (defined(__FLT_MAX_EXP__) && __FLT_MAX_EXP__ == 128) + +# define FLOATS_ARE_IEEE 1 + +#else + +# define FLOATS_ARE_IEEE 0 + +#endif + +#endif /* FLOATS_ARE_IEEE */ + + +#if FLOATS_ARE_IEEE == 1 +# define ARCH_FLOATS_ARE_IEEE 1 +# define ARCH_FLOAT_MANTISSA_BITS 24 +# define ARCH_DOUBLE_MANTISSA_BITS 53 +#else /* FLOATS_ARE_IEEE*/ +# define ARCH_FLOATS_ARE_IEEE 0 +/* + * There isn't any general way to compute the number of mantissa + * bits accurately, especially if the machine uses hex rather + * than binary exponents. Use conservative values, assuming + * the exponent is stored in a 16-bit word of its own. + */ +# define ARCH_FLOAT_MANTISSA_BITS (sizeof(float) * 8 - 17) +# define ARCH_DOUBLE_MANTISSA_BITS (sizeof(double) * 8 - 17) +#endif /* FLOATS_ARE_IEEE*/ + + /* ---------------- Miscellaneous ---------------- */ + +#define ARCH_IS_BIG_ENDIAN @ARCH_IS_BIG_ENDIAN@ +#define ARCH_PTRS_ARE_SIGNED @ARCH_PTRS_ARE_SIGNED@ +#define ARCH_DIV_NEG_POS_TRUNCATES @ARCH_DIV_NEG_POS_TRUNCATES@ +#define ARCH_ARITH_RSHIFT @ARCH_ARITH_RSHIFT@ +#define ARCH_SIZEOF_GX_COLOR_INDEX @ARCH_SIZEOF_GX_COLOR_INDEX@ diff -Nru ghostscript-9.10~dfsg/arch/osx-x86-x86_64-ppc-gcc.h ghostscript-9.25~dfsg+1/arch/osx-x86-x86_64-ppc-gcc.h --- ghostscript-9.10~dfsg/arch/osx-x86-x86_64-ppc-gcc.h 2013-08-30 10:37:29.000000000 +0000 +++ ghostscript-9.25~dfsg+1/arch/osx-x86-x86_64-ppc-gcc.h 2018-09-13 10:02:01.000000000 +0000 @@ -18,7 +18,11 @@ #define ARCH_LOG2_SIZEOF_INT 2 #define ARCH_LOG2_SIZEOF_LONG 2 #define ARCH_LOG2_SIZEOF_LONG_LONG 3 + +#ifndef ARCH_SIZEOF_GX_COLOR_INDEX #define ARCH_SIZEOF_GX_COLOR_INDEX 8 +#endif + #define ARCH_SIZEOF_PTR 4 #define ARCH_SIZEOF_FLOAT 4 #define ARCH_SIZEOF_DOUBLE 8 @@ -60,7 +64,11 @@ #define ARCH_LOG2_SIZEOF_INT 2 #define ARCH_LOG2_SIZEOF_LONG 3 #define ARCH_LOG2_SIZEOF_LONG_LONG 3 + +#ifndef ARCH_SIZEOF_GX_COLOR_INDEX #define ARCH_SIZEOF_GX_COLOR_INDEX 8 +#endif + #define ARCH_SIZEOF_PTR 8 #define ARCH_SIZEOF_FLOAT 4 #define ARCH_SIZEOF_DOUBLE 8 @@ -99,7 +107,11 @@ #define ARCH_LOG2_SIZEOF_INT 2 #define ARCH_LOG2_SIZEOF_LONG 2 #define ARCH_LOG2_SIZEOF_LONG_LONG 3 + +#ifndef ARCH_SIZEOF_GX_COLOR_INDEX #define ARCH_SIZEOF_GX_COLOR_INDEX 8 +#endif + #define ARCH_SIZEOF_PTR 4 #define ARCH_SIZEOF_FLOAT 4 #define ARCH_SIZEOF_DOUBLE 8 diff -Nru ghostscript-9.10~dfsg/arch/windows-arm-msvc.h ghostscript-9.25~dfsg+1/arch/windows-arm-msvc.h --- ghostscript-9.10~dfsg/arch/windows-arm-msvc.h 2013-08-30 10:37:29.000000000 +0000 +++ ghostscript-9.25~dfsg+1/arch/windows-arm-msvc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Parameters derived from machine and compiler architecture. */ /* This file was generated mechanically by genarch.c, for a 32bit */ @@ -31,7 +31,11 @@ #define ARCH_LOG2_SIZEOF_SHORT 1 #define ARCH_LOG2_SIZEOF_INT 2 #define ARCH_LOG2_SIZEOF_LONG 2 + +#ifndef ARCH_SIZEOF_GX_COLOR_INDEX #define ARCH_SIZEOF_GX_COLOR_INDEX 8 +#endif + #define ARCH_SIZEOF_PTR 4 #define ARCH_SIZEOF_FLOAT 4 #define ARCH_SIZEOF_DOUBLE 8 diff -Nru ghostscript-9.10~dfsg/arch/windows-x64-msvc.h ghostscript-9.25~dfsg+1/arch/windows-x64-msvc.h --- ghostscript-9.10~dfsg/arch/windows-x64-msvc.h 2013-08-30 10:37:29.000000000 +0000 +++ ghostscript-9.25~dfsg+1/arch/windows-x64-msvc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Parameters derived from machine and compiler architecture. */ /* This file was generated mechanically by genarch.c, for a 64bit */ @@ -31,7 +31,11 @@ #define ARCH_LOG2_SIZEOF_SHORT 1 #define ARCH_LOG2_SIZEOF_INT 2 #define ARCH_LOG2_SIZEOF_LONG 2 + +#ifndef ARCH_SIZEOF_GX_COLOR_INDEX #define ARCH_SIZEOF_GX_COLOR_INDEX 8 +#endif + #define ARCH_SIZEOF_PTR 8 #define ARCH_SIZEOF_FLOAT 4 #define ARCH_SIZEOF_DOUBLE 8 diff -Nru ghostscript-9.10~dfsg/arch/windows-x86-msvc.h ghostscript-9.25~dfsg+1/arch/windows-x86-msvc.h --- ghostscript-9.10~dfsg/arch/windows-x86-msvc.h 2013-08-30 10:37:29.000000000 +0000 +++ ghostscript-9.25~dfsg+1/arch/windows-x86-msvc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Parameters derived from machine and compiler architecture. */ /* This file was generated mechanically by genarch.c, for a 32bit */ @@ -31,7 +31,11 @@ #define ARCH_LOG2_SIZEOF_SHORT 1 #define ARCH_LOG2_SIZEOF_INT 2 #define ARCH_LOG2_SIZEOF_LONG 2 + +#ifndef ARCH_SIZEOF_GX_COLOR_INDEX #define ARCH_SIZEOF_GX_COLOR_INDEX 8 +#endif + #define ARCH_SIZEOF_PTR 4 #define ARCH_SIZEOF_FLOAT 4 #define ARCH_SIZEOF_DOUBLE 8 diff -Nru ghostscript-9.10~dfsg/base/aes.c ghostscript-9.25~dfsg+1/base/aes.c --- ghostscript-9.10~dfsg/base/aes.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/aes.c 2018-09-13 10:02:01.000000000 +0000 @@ -488,7 +488,7 @@ ( FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ ( FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ ( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( RK[3] ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( RK[3] ) & 0xFF ]) << 24 ); RK[5] = RK[1] ^ RK[4]; RK[6] = RK[2] ^ RK[5]; @@ -504,7 +504,7 @@ ( FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ ( FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ ( FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( RK[5] ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( RK[5] ) & 0xFF ]) << 24 ); RK[7] = RK[1] ^ RK[6]; RK[8] = RK[2] ^ RK[7]; @@ -522,7 +522,7 @@ ( FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ ( FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ ( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( RK[7] ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( RK[7] ) & 0xFF ]) << 24 ); RK[9] = RK[1] ^ RK[8]; RK[10] = RK[2] ^ RK[9]; @@ -532,7 +532,7 @@ ( FSb[ ( RK[11] ) & 0xFF ] ) ^ ( FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ ( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( RK[11] >> 24 ) & 0xFF ]) << 24 ); RK[13] = RK[5] ^ RK[12]; RK[14] = RK[6] ^ RK[13]; @@ -662,6 +662,9 @@ } #endif + if (ctx == NULL || ctx->rk == NULL) + return; + RK = ctx->rk; GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++; @@ -682,22 +685,22 @@ X0 = *RK++ ^ ( RSb[ ( Y0 ) & 0xFF ] ) ^ ( RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ ( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)RSb[ ( Y1 >> 24 ) & 0xFF ]) << 24 ); X1 = *RK++ ^ ( RSb[ ( Y1 ) & 0xFF ] ) ^ ( RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ ( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)RSb[ ( Y2 >> 24 ) & 0xFF ]) << 24 ); X2 = *RK++ ^ ( RSb[ ( Y2 ) & 0xFF ] ) ^ ( RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ ( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)RSb[ ( Y3 >> 24 ) & 0xFF ]) << 24 ); X3 = *RK++ ^ ( RSb[ ( Y3 ) & 0xFF ] ) ^ ( RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ ( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)RSb[ ( Y0 >> 24 ) & 0xFF ]) << 24 ); } else /* AES_ENCRYPT */ { @@ -712,22 +715,22 @@ X0 = *RK++ ^ ( FSb[ ( Y0 ) & 0xFF ] ) ^ ( FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ ( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( Y3 >> 24 ) & 0xFF ]) << 24 ); X1 = *RK++ ^ ( FSb[ ( Y1 ) & 0xFF ] ) ^ ( FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ ( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( Y0 >> 24 ) & 0xFF ]) << 24 ); X2 = *RK++ ^ ( FSb[ ( Y2 ) & 0xFF ] ) ^ ( FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ ( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( Y1 >> 24 ) & 0xFF ]) << 24 ); X3 = *RK++ ^ ( FSb[ ( Y3 ) & 0xFF ] ) ^ ( FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ ( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ - ( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + ( ((unsigned int)FSb[ ( Y2 >> 24 ) & 0xFF ]) << 24 ); } PUT_ULONG_LE( X0, output, 0 ); diff -Nru ghostscript-9.10~dfsg/base/all-arch.mak ghostscript-9.25~dfsg+1/base/all-arch.mak --- ghostscript-9.10~dfsg/base/all-arch.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/all-arch.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # diff -Nru ghostscript-9.10~dfsg/base/assert_.h ghostscript-9.25~dfsg+1/base/assert_.h --- ghostscript-9.10~dfsg/base/assert_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/assert_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* A wrapper for providing assert() in ghosctscript code. Any changes diff -Nru ghostscript-9.10~dfsg/base/bench.c ghostscript-9.25~dfsg+1/base/bench.c --- ghostscript-9.10~dfsg/base/bench.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/bench.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/bobbin.c ghostscript-9.25~dfsg+1/base/bobbin.c --- ghostscript-9.10~dfsg/base/bobbin.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/bobbin.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,790 @@ +/* Copyright (C) 2016-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#ifdef BOBBIN + +#define BOBBIN_C +#include "bobbin.h" + +#include +#include +#include +#include + +#define MAX_NAME 32 + +#undef DEBUG_BOBBIN + +typedef struct +{ + void *mutex; + unsigned int flags; + char name[MAX_NAME]; +} Bobbin_mutex_data; + +enum { + BOBBIN_MUTEX_DELETED = 1 +}; + +typedef struct +{ + void *cond; + unsigned int flags; + char name[MAX_NAME]; +} Bobbin_cond_data; + +enum { + BOBBIN_COND_DELETED = 1 +}; + +typedef struct +{ + int mutex; + clock_t locktime; + unsigned char locked; +} Bobbin_thr_mut_data; + +typedef struct +{ + int cond; + clock_t waittime; + unsigned char waiting; +} Bobbin_thr_con_data; + +typedef struct +{ + void *thread; + unsigned int flags; + clock_t jointime; + int num_mutexes; + int max_mutexes; + Bobbin_thr_mut_data *mutex; + int num_conds; + int max_conds; + Bobbin_thr_con_data *cond; + char name[MAX_NAME]; +} Bobbin_thread_data; + +enum { + BOBBIN_THREAD_JOINED = 1, + BOBBIN_THREAD_FINISHED = 2 +}; + +typedef struct +{ + int inited; +#ifdef BOBBIN_PTHREADS + pthread_mutex_t lock; +#endif + int max_mutexes; + int num_mutexes; + Bobbin_mutex_data *mutex; + int max_threads; + int num_threads; + Bobbin_thread_data *thread; + int max_conds; + int num_conds; + Bobbin_cond_data *cond; +} Bobbin_globals; + +static Bobbin_globals bobbins; + +static void Bobbin_breakpoint(void) +{ +} + +static void Bobbin_fin(void) +{ + int t, i; + + fprintf(stderr, "Bobbin report:\n"); + fprintf(stderr, "%d threads, %d mutexes\n", + bobbins.num_threads, + bobbins.num_mutexes); + for (t = 0; t < bobbins.num_threads; t++) + { + Bobbin_thread_data *td = &bobbins.thread[t]; + fprintf(stderr, " Thread %d: (%s)\n", t, + td->name[0] ? td->name : "unnamed"); + for (i = 0; i < td->num_mutexes; i++) + { + int m = td->mutex[i].mutex; + fprintf(stderr, " Spent %g waiting for mutex %d (%s)%s\n", + td->mutex[i].locktime/(double)CLOCKS_PER_SEC, m, + bobbins.mutex[m].name[0] ? bobbins.mutex[m].name : "unnamed", + td->mutex[i].locked ? " LOCKED" : ""); + } + for (i = 0; i < td->num_conds; i++) + { + int c = td->cond[i].cond; + fprintf(stderr, " Spent %g waiting for cond %d (%s)%s\n", + td->cond[i].waittime/(double)CLOCKS_PER_SEC, c, + bobbins.cond[c].name[0] ? bobbins.cond[c].name : "unnamed", + td->cond[i].waiting ? " WAITING" : ""); + } + } +} + +static void grow_threads(void) +{ + int new_size = bobbins.max_threads ? bobbins.max_threads*2 : 32; + Bobbin_thread_data *new_thread; + + new_thread = realloc(bobbins.thread, + sizeof(*bobbins.thread) * new_size); + if (new_thread == NULL) + { + fprintf(stderr, "Bobbin increase thread data block\n"); + exit(1); + } + bobbins.thread = new_thread; + memset(&bobbins.thread[bobbins.max_threads], 0, + (new_size - bobbins.max_threads) * sizeof(*bobbins.thread)); + bobbins.max_threads = new_size; +} + +static void Bobbin_init(void) +{ + int t; + +#ifdef BOBBIN_PTHREADS + (void)pthread_mutex_init(&bobbins.lock, NULL); +#endif + atexit(Bobbin_fin); + bobbins.inited = 1; + + grow_threads(); + t = bobbins.num_threads++; + strcpy(bobbins.thread[t].name, "Main"); +#ifdef BOBBIN_PTHREADS + bobbins.thread[t].thread = (void *)pthread_self(); +#endif +} + +static void Bobbin_lock(void) +{ + if (bobbins.inited == 0) + Bobbin_init(); +#ifdef BOBBIN_PTHREADS + (void)pthread_mutex_lock(&bobbins.lock); +#endif +} + +static void Bobbin_unlock(void) +{ +#ifdef BOBBIN_PTHREADS + (void)pthread_mutex_unlock(&bobbins.lock); +#endif +} + +static int Bobbin_mutex(void *mutex) +{ + int i; + + for (i = 0; i < bobbins.num_mutexes; i++) + if (bobbins.mutex[i].mutex == mutex && (bobbins.mutex[i].flags & BOBBIN_MUTEX_DELETED) == 0) + break; + if (i == bobbins.num_mutexes) + { + fprintf(stderr, "Unknown mutex!\n"); + Bobbin_breakpoint(); + } + return i; +} + +static int Bobbin_mutex_idx(int thread, int mutex) +{ + Bobbin_thread_data *td = &bobbins.thread[thread]; + int i; + + for (i = 0; i < td->num_mutexes; i++) + { + if (td->mutex[i].mutex == mutex) + break; + } + if (i == td->num_mutexes) + { + if (i == td->max_mutexes) + { + int new_size = i ? i*2 : 32; + Bobbin_thr_mut_data *mutexes; + + mutexes = realloc(td->mutex, + sizeof(*mutexes) * new_size); + if (mutexes == NULL) + { + fprintf(stderr, "Bobbin failed to increase thread mutex data block\n"); + exit(1); + } + td->mutex = mutexes; + memset(&td->mutex[i], 0, + (new_size - i) * sizeof(*mutexes)); + td->max_mutexes = new_size; + } + td->mutex[i].mutex = mutex; + td->num_mutexes++; + } + return i; +} + +static int Bobbin_cond(void *cond) +{ + int i; + + for (i = 0; i < bobbins.num_conds; i++) + if (bobbins.cond[i].cond == cond && (bobbins.cond[i].flags & BOBBIN_COND_DELETED) == 0) + break; + if (i == bobbins.num_conds) + { + fprintf(stderr, "Unknown condition variable!\n"); + Bobbin_breakpoint(); + } + return i; +} + +static int Bobbin_cond_idx(int thread, int cond) +{ + Bobbin_thread_data *td = &bobbins.thread[thread]; + int i; + + for (i = 0; i < td->num_conds; i++) + { + if (td->cond[i].cond == cond) + break; + } + if (i == td->num_conds) + { + if (i == td->max_conds) + { + int new_size = i ? i*2 : 32; + Bobbin_thr_con_data *conds; + + conds = realloc(td->cond, + sizeof(*conds) * new_size); + if (conds == NULL) + { + fprintf(stderr, "Bobbin failed to increase thread cond data block\n"); + exit(1); + } + td->cond = conds; + memset(&td->cond[i], 0, + (new_size - i) * sizeof(*conds)); + td->max_conds = new_size; + } + td->cond[i].cond = cond; + td->num_conds++; + } + return i; +} + +#ifdef BOBBIN_PTHREADS +#define BOBBIN_THREAD_EQUAL(A, B) pthread_equal((pthread_t)(A), (pthread_t)(B)) +#else +#define BOBBIN_THREAD_EQUAL(A, B) (A == B) +#endif + +static int Bobbin_thread(void *thread) +{ + int i; + + for (i = 0; i < bobbins.num_threads; i++) + if (BOBBIN_THREAD_EQUAL(bobbins.thread[i].thread, thread) && + (bobbins.thread[i].flags & BOBBIN_THREAD_FINISHED) == 0) + break; + if (i == bobbins.num_threads) + { + fprintf(stderr, "Unknown thread!\n"); + Bobbin_breakpoint(); + } + return i; +} + +static int Bobbin_add_thread(void) +{ + int t; + + if (bobbins.inited == 0) + Bobbin_init(); + + Bobbin_lock(); + + t = bobbins.num_threads++; + if (t == bobbins.max_threads) + { + grow_threads(); + } + + Bobbin_unlock(); + + return t; +} + +static void Bobbin_add_mutex(void *mutex) +{ + int i; + + Bobbin_lock(); + + for (i = 0; i < bobbins.num_mutexes; i++) + if (bobbins.mutex[i].mutex == mutex && (bobbins.mutex[i].flags & BOBBIN_MUTEX_DELETED) == 0) + break; + if (i != bobbins.num_mutexes) + { + fprintf(stderr, "Reinitialising existing mutex!\n"); + Bobbin_breakpoint(); + } + else + { + if (i == bobbins.max_mutexes) + { + int new_size = i ? i * 2 : 32; + Bobbin_mutex_data *new_mutex; + + new_mutex = realloc(bobbins.mutex, + sizeof(*bobbins.mutex) * new_size); + if (new_mutex == NULL) + { + fprintf(stderr, "Bobbin failed to increase mutex data block\n"); + exit(1); + } + bobbins.mutex = new_mutex; + memset(&bobbins.mutex[i], 0, + (new_size - i) * sizeof(*bobbins.mutex)); + bobbins.max_mutexes = new_size; + } + bobbins.mutex[i].mutex = mutex; + bobbins.mutex[i].flags = 0; + bobbins.num_mutexes++; + } + + Bobbin_unlock(); +} + +static void Bobbin_del_mutex(void *mutex) +{ + int i, t; + + Bobbin_lock(); + + for (i = 0; i < bobbins.num_mutexes; i++) + if (bobbins.mutex[i].mutex == mutex && (bobbins.mutex[i].flags & BOBBIN_MUTEX_DELETED) == 0) + break; + if (i == bobbins.num_mutexes) + { + fprintf(stderr, "Deleting non-existent mutex!\n"); + Bobbin_breakpoint(); + } + else + { + int borked = 0; + bobbins.mutex[i].flags |= BOBBIN_MUTEX_DELETED; + for (t = 0; t < bobbins.num_threads; t++) + { + int mi; + Bobbin_thread_data *td = &bobbins.thread[t]; + for (mi = 0; mi < td->num_mutexes; mi++) + { + if (td->mutex[mi].mutex == i && td->mutex[mi].locked) + { + fprintf(stderr, "Thread %d has mutex %d locked at deletion time\n"); + borked = 1; + } + } + } + if (borked) + Bobbin_breakpoint(); + } + + Bobbin_unlock(); +} + +typedef struct +{ + clock_t time; + int thread; + int mutex; + int mutex_idx; +} +Bobbin_mutex_lock_data; + +static void Bobbin_prelock_mutex(void *thread, void *mutex, Bobbin_mutex_lock_data *mld) +{ + int mi; + Bobbin_lock(); + mld->thread = Bobbin_thread(thread); + mld->mutex = Bobbin_mutex(mutex); + mi = mld->mutex_idx = Bobbin_mutex_idx(mld->thread, mld->mutex); + if (bobbins.thread[mld->thread].mutex[mi].locked) + { + fprintf(stderr, "Thread %d trying to lock locked mutex %d!\n", mld->thread, mld->mutex); + Bobbin_breakpoint(); + } + bobbins.thread[mld->thread].mutex[mi].locked = 1; + Bobbin_unlock(); + mld->time = clock(); +} + +static void Bobbin_postlock_mutex(Bobbin_mutex_lock_data *mld) +{ + clock_t time = clock(); + + Bobbin_lock(); + time -= mld->time; + bobbins.thread[mld->thread].mutex[mld->mutex_idx].locktime += time; + Bobbin_unlock(); +} + +static void Bobbin_unlock_mutex(void *thread, void *mutex) +{ + int t, m, mi; + Bobbin_thread_data *td; + + Bobbin_lock(); + t = Bobbin_thread(thread); + m = Bobbin_mutex(mutex); + mi = Bobbin_mutex_idx(t, m); + td = &bobbins.thread[t]; + if (td->mutex[mi].locked == 0) + { + fprintf(stderr, "Thread %d trying to unlock unlocked mutex %d!\n", t, m); + Bobbin_breakpoint(); + } + td->mutex[mi].locked = 0; + Bobbin_unlock(); +} + +static void Bobbin_add_cond(void *cond) +{ + int i; + + Bobbin_lock(); + + for (i = 0; i < bobbins.num_conds; i++) + if (bobbins.cond[i].cond == cond && (bobbins.cond[i].flags & BOBBIN_COND_DELETED) == 0) + break; + if (i != bobbins.num_conds) + { + fprintf(stderr, "Reinitialising existing cond!\n"); + Bobbin_breakpoint(); + } + else + { + if (i == bobbins.max_conds) + { + int new_size = i ? i * 2 : 32; + Bobbin_cond_data *new_cond; + + new_cond = realloc(bobbins.cond, + sizeof(*bobbins.cond) * new_size); + if (new_cond == NULL) + { + fprintf(stderr, "Bobbin failed to increase cond data block\n"); + exit(1); + } + bobbins.cond = new_cond; + memset(&bobbins.cond[i], 0, + (new_size - i) * sizeof(*bobbins.cond)); + bobbins.max_conds = new_size; + } + bobbins.cond[i].cond = cond; + bobbins.cond[i].flags = 0; + bobbins.num_conds++; + } + + Bobbin_unlock(); +} + +static void Bobbin_del_cond(void *cond) +{ + int i, t; + + Bobbin_lock(); + + for (i = 0; i < bobbins.num_conds; i++) + if (bobbins.cond[i].cond == cond && (bobbins.cond[i].flags & BOBBIN_COND_DELETED) == 0) + break; + if (i == bobbins.num_conds) + { + fprintf(stderr, "Deleting non-existent cond!\n"); + Bobbin_breakpoint(); + } + else + { + int borked = 0; + bobbins.cond[i].flags |= BOBBIN_COND_DELETED; + for (t = 0; t < bobbins.num_threads; t++) + { + int i; + Bobbin_thread_data *td = &bobbins.thread[t]; + for (i = 0; i < td->num_conds; i++) + { + if (td->cond[i].cond == i && td->cond[i].waiting) + { + fprintf(stderr, "Thread %d has cond %d waiting at deletion time\n"); + borked = 1; + } + } + } + if (borked) + Bobbin_breakpoint(); + } + + Bobbin_unlock(); +} + +typedef struct +{ + clock_t time; + int thread; + int cond; + int cond_idx; +} +Bobbin_cond_wait_data; + +static void Bobbin_prewait_cond(void *thread, void *cond, Bobbin_cond_wait_data *cwd) +{ + int i; + Bobbin_lock(); + cwd->thread = Bobbin_thread(thread); + cwd->cond = Bobbin_cond(cond); + i = cwd->cond_idx = Bobbin_cond_idx(cwd->thread, cwd->cond); + bobbins.thread[cwd->thread].cond[i].waiting++; + Bobbin_unlock(); + cwd->time = clock(); +} + +static void Bobbin_postwait_cond(Bobbin_cond_wait_data *cwd) +{ + clock_t time = clock(); + + Bobbin_lock(); + time -= cwd->time; + bobbins.thread[cwd->thread].cond[cwd->cond_idx].waiting--; + bobbins.thread[cwd->thread].cond[cwd->cond_idx].waittime += time; + Bobbin_unlock(); +} + +static void label_thread(void *thread, const char *name) +{ + int t; + int l; + + if (thread == NULL || name == NULL) + return; + + Bobbin_lock(); + t = Bobbin_thread(thread); + + strncpy(&bobbins.thread[t].name[0], name, MAX_NAME); + bobbins.thread[t].name[MAX_NAME-1] = 0; + Bobbin_unlock(); +} + +static void label_mutex(pthread_mutex_t *mutex, const char *name) +{ + int m; + int l; + + if (mutex == NULL || name == NULL) + return; + + Bobbin_lock(); + m = Bobbin_mutex(mutex); + + strncpy(&bobbins.mutex[m].name[0], name, MAX_NAME); + bobbins.mutex[m].name[MAX_NAME-1] = 0; + Bobbin_unlock(); +} + +static void label_cond(pthread_cond_t *cond, const char *name) +{ + int c; + int l; + + if (cond == NULL || name == NULL) + return; + + Bobbin_lock(); + c = Bobbin_cond(cond); + + strncpy(&bobbins.cond[c].name[0], name, MAX_NAME); + bobbins.cond[c].name[MAX_NAME-1] = 0; + Bobbin_unlock(); +} + +#ifdef BOBBIN_WINDOWS +#endif + +#ifdef BOBBIN_PTHREADS + +#include "pthread.h" + +int Bobbin_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + Bobbin_add_mutex((void *)mutex); +#ifdef DEBUG_BOBBIN + fprintf(stderr, "mutex_init %p\n", mutex); + fflush(stderr); +#endif + return pthread_mutex_init(mutex, attr); +} + +int Bobbin_pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + Bobbin_del_mutex((void *)mutex); +#ifdef DEBUG_BOBBIN + fprintf(stderr, "mutex_destroy %p\n", mutex); + fflush(stderr); +#endif + return pthread_mutex_destroy(mutex); +} + +int Bobbin_pthread_mutex_lock(pthread_mutex_t *mutex) +{ + Bobbin_mutex_lock_data mld; + int e; + +#ifdef DEBUG_BOBBIN + fprintf(stderr, "mutex_lock %p\n", mutex); + fflush(stderr); +#endif + + Bobbin_prelock_mutex((void *)pthread_self(), mutex, &mld); + e = pthread_mutex_lock(mutex); + Bobbin_postlock_mutex(&mld); + return e; +} + +int Bobbin_pthread_mutex_unlock(pthread_mutex_t *mutex) +{ +#ifdef DEBUG_BOBBIN + fprintf(stderr, "mutex_unlock %p\n", mutex); + fflush(stderr); +#endif + + Bobbin_unlock_mutex((void *)pthread_self(), mutex); + return pthread_mutex_unlock(mutex); +} + +int Bobbin_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +{ + Bobbin_add_cond((void *)cond); +#ifdef DEBUG_BOBBIN + fprintf(stderr, "cond_init %p\n", cond); + fflush(stderr); +#endif + return pthread_cond_init(cond, attr); +} + +int Bobbin_pthread_cond_destroy(pthread_cond_t *cond) +{ + Bobbin_del_cond((void *)cond); +#ifdef DEBUG_BOBBIN + fprintf(stderr, "cond_destroy %p\n", cond); + fflush(stderr); +#endif + return pthread_cond_destroy(cond); +} + +int Bobbin_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +{ + Bobbin_cond_wait_data cwd; + int e; + +#ifdef DEBUG_BOBBIN + fprintf(stderr, "cond_wait %p\n", cond); + fflush(stderr); +#endif + + Bobbin_prewait_cond((void *)pthread_self(), cond, &cwd); + e = pthread_cond_wait(cond, mutex); + Bobbin_postwait_cond(&cwd); + return e; +} + +int Bobbin_pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*fn)(void *), void *arg) +{ + int t = Bobbin_add_thread(); + int e; + + e = pthread_create((pthread_t *)&bobbins.thread[t].thread, attr, fn, arg); + + *thread = (pthread_t)bobbins.thread[t].thread; + +#ifdef DEBUG_BOBBIN + fprintf(stderr, "pthread_create %p\n", *thread); + fflush(stderr); +#endif + + return e; +} + +int Bobbin_pthread_join(pthread_t thread, void **arg) +{ + int t; + clock_t t0, t1; + int e; + +#ifdef DEBUG_BOBBIN + fprintf(stderr, "pthread_join %p\n", thread); + fflush(stderr); +#endif + + Bobbin_lock(); + t = Bobbin_thread((void *)thread); + bobbins.thread[t].flags |= BOBBIN_THREAD_JOINED; + Bobbin_unlock(); + + t0 = clock(); + e = pthread_join(thread, arg); + t1 = clock(); + + Bobbin_lock(); + bobbins.thread[t].flags |= BOBBIN_THREAD_FINISHED; + bobbins.thread[t].jointime = t1-t0; + Bobbin_unlock(); + + return e; +} + +void Bobbin_label_thread(pthread_t thread, const char *name) +{ +#ifdef DEBUG_BOBBIN + fprintf(stderr, "label_thread %p\n", thread); + fflush(stderr); +#endif + label_thread((void *)thread, name); +} + +void Bobbin_label_mutex(pthread_mutex_t *mutex, const char *name) +{ +#ifdef DEBUG_BOBBIN + fprintf(stderr, "label_mutex %p\n", mutex); + fflush(stderr); +#endif + label_mutex((void *)mutex, name); +} + +void Bobbin_label_cond(pthread_cond_t *cond, const char *name) +{ +#ifdef DEBUG_BOBBIN + fprintf(stderr, "label_cond %p\n", cond); + fflush(stderr); +#endif + label_cond((void *)cond, name); +} + +#endif + +#endif /* BOBBIN */ diff -Nru ghostscript-9.10~dfsg/base/bobbin.h ghostscript-9.25~dfsg+1/base/bobbin.h --- ghostscript-9.10~dfsg/base/bobbin.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/bobbin.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,87 @@ +/* Copyright (C) 2016-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Bobbin: A library to aid debugging/performance tuning of threads. + * + * Usage (with C): + * First, build your project with BOBBIN defined, and include this + * header file wherever you use threading functions. + * This header file will use macros to point threading functions to + * Bobbin equivalents. + * + * Run your program, and all threading functions should be redirected + * through here. When the program exits, you will get an interesting + * list of facts. + */ + +#ifndef BOBBIN_H + +#define BOBBIN_H + +#if defined(BOBBIN) && BOBBIN + +#ifdef _WIN32 +#include + +#define BOBBIN_WINDOWS + +#error Not yet! + +#else + +#include + +#define BOBBIN_PTHREADS + +#ifndef BOBBIN_C + +#define pthread_mutex_init Bobbin_pthread_mutex_init +#define pthread_mutex_destroy Bobbin_pthread_mutex_destroy +#define pthread_mutex_lock Bobbin_pthread_mutex_lock +#define pthread_mutex_unlock Bobbin_pthread_mutex_unlock + +#define pthread_create Bobbin_pthread_create +#define pthread_join Bobbin_pthread_join + +#define pthread_cond_init Bobbin_pthread_cond_init +#define pthread_cond_destroy Bobbin_pthread_cond_destroy +#define pthread_cond_wait Bobbin_pthread_cond_wait +//#define pthread_cond_signal Bobbin_pthread_cond_signal + +#endif + +int Bobbin_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); +int Bobbin_pthread_mutex_destroy(pthread_mutex_t *mutex); +int Bobbin_pthread_mutex_lock(pthread_mutex_t *mutex); +int Bobbin_pthread_mutex_unlock(pthread_mutex_t *mutex); +int Bobbin_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); +int Bobbin_pthread_cond_destroy(pthread_cond_t *cond); +int Bobbin_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); +int Bobbin_pthread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*fn)(void *), void *arg); +int Bobbin_pthread_join(pthread_t thread, void **arg); +void Bobbin_label_thread(pthread_t thread, const char *name); +void Bobbin_label_mutex(pthread_mutex_t *mutex, const char *name); +void Bobbin_label_cond(pthread_cond_t *cond, const char *name); + +#endif + +#else + +#define Bobbin_label_thread(A,B) do { } while (0) +#define Bobbin_label_mutex(A,B) do { } while (0) +#define Bobbin_label_cond(A,B) do { } while (0) + +#endif + +#endif /* BOBBIN_H */ diff -Nru ghostscript-9.10~dfsg/base/claptrap.c ghostscript-9.25~dfsg+1/base/claptrap.c --- ghostscript-9.10~dfsg/base/claptrap.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/claptrap.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,289 @@ +/* Copyright (C) 2015-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#include +#include +#include + +#include "claptrap.h" +#include "claptrap-impl.h" + +/* This is the actual guts of the per-pixel processing. + * We use a static inline, so the compiler can optimise + * out as many of the tests as possible. */ +inline static void process_at_pixel(ClapTrap * gs_restrict ct, + unsigned char * gs_restrict buffer, + int x, + int clips_on_x, + int clips_on_y, + int first_comp, + int last_comp, + int prev_comp, + int comp, + int line_offset, + unsigned char *process) +{ + /* We look at the pixel values on comp. + * We look at the process values passed into us from prev_comp, and pass out + * into comp. + */ + + /* Use local vars to avoid pointer aliasing */ + int width = ct->width; + int height = ct->height; + int num_comps = ct->num_comps; + int max_x_offset = ct->max_x_offset; + int max_y_offset = ct->max_y_offset; + int span = ct->span; + int lines_in_buf = ct->lines_in_buf; + unsigned char *linebuf = ct->linebuf; + int y = ct->y; + /* Some offsets we will use repeatedly */ + int o = x * num_comps; + int oc = o + comp; + /* p != 0 if we need to be processed because a previous component shadows us. + * If we're the first component then no one can shadow us. */ + int p = (first_comp ? 0 : *process); + int sx, sy, ex, ey, lo, v; + unsigned char *pc; + unsigned char *ppc; + + assert((first_comp != 1) ^ (prev_comp == -1)); + assert((last_comp != 1) ^ (comp == ct->comp_order[num_comps-1])); + + /* Work out the search region bounds */ + sy = y - max_y_offset; + if (clips_on_y && sy < 0) + sy = 0; + ey = y + max_y_offset; + if (clips_on_y && ey >= height) + ey = height-1; + sx = x - max_x_offset; + if (clips_on_x && sx < 0) + sx = 0; + ex = x + max_x_offset; + if (clips_on_x && ex >= width) + ex = width-1; + + /* We only need to check for shadowing lower components if we're + * not the last last component (!last_comp). We can only need to process + * here if we are not the first component (!first_comp) and + * if (p != 0) then we need to search for the maximum local value + * of this component. */ + v = linebuf[line_offset + oc]; + if (!last_comp || (!first_comp && p)) + { + int min_v, max_v; + + lo = sy % lines_in_buf; + if (!first_comp) + max_v = v; + if (!last_comp) + min_v = v; + pc = &linebuf[lo * span + sx * num_comps + comp]; + ex -= sx; + for (sy = ey-sy; sy >= 0; sy--) + { + ppc = pc; + for (sx = ex; sx >= 0; sx--) + { + int cv = *ppc; + ppc += num_comps; + if (!first_comp && cv > max_v) + max_v = cv; + else if (!last_comp && cv < min_v) + min_v = cv; + } + pc += span; + lo++; + if (lo == lines_in_buf) + { + pc -= span * lines_in_buf; + } + } + /* If we're not the last component, and we meet the criteria + * the next component needs processing. */ + if (!last_comp) + { + /* Process flag for next component inherits from this one */ + int np = p; + if (v > np && shadow_here(v, min_v, comp)) + np = v; + + *process = np; +#ifdef SAVE_PROCESS_BUFFER + buffer[oc] = np; + return; +#endif + } + + if (!first_comp && p > v && trap_here(v, max_v, comp)) + { + if (max_v < p) + p = max_v; + v = p; + } + } + buffer[oc] = v; +} + +int ClapTrap_GetLine(ClapTrap * gs_restrict ct, + unsigned char * gs_restrict buffer) +{ + int max_y; + int l_margin; + int r_margin; + int comp_idx; + int prev_comp; + int comp; + int x; + int line_offset; + unsigned char *process; + + /* Read in as many lines as we need */ + max_y = ct->y + ct->max_y_offset; + if (max_y > ct->height-1) + max_y = ct->height-1; + while (ct->lines_read <= max_y) + { + int bufpos = ct->span * (ct->lines_read % ct->lines_in_buf); + int code = ct->get_line(ct->get_line_arg, &ct->linebuf[bufpos]); + if (code < 0) + return code; + ct->lines_read++; + } + + /* Now we have enough information to calculate the process map for the next line of data */ + l_margin = ct->max_x_offset; + r_margin = ct->width - ct->max_x_offset; + if (r_margin < 0) + { + r_margin = 0; + l_margin = 0; + } + x = (ct->y % ct->lines_in_buf); + process = &ct->process[x * ct->width]; + line_offset = x * ct->span; + if (ct->y < ct->max_y_offset || ct->y >= ct->height - ct->max_y_offset) + { + unsigned char *p = process; + /* Some of our search area is off the end of the bitmap. We must be careful. */ + comp = ct->comp_order[0]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer, x, 1, 1, 1, 0, -1, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer, x, 0, 1, 1, 0, -1, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer, x, 1, 1, 1, 0, -1, comp, line_offset, p++); + } + for (comp_idx = 1; comp_idx < ct->num_comps-1; comp_idx++) + { + p = process; + prev_comp = comp; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer, x, 1, 1, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer, x, 0, 1, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer, x, 1, 1, 0, 0, prev_comp, comp, line_offset, p++); + } + } + p = process; + prev_comp = comp; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer, x, 1, 1, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer, x, 0, 1, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer, x, 1, 1, 0, 1, prev_comp, comp, line_offset, p++); + } + } + else + { + unsigned char *p = process; + /* Our search area never clips on y at least. */ + comp = ct->comp_order[0]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer, x, 1, 0, 1, 0, -1, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer, x, 0, 0, 1, 0, -1, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer, x, 1, 0, 1, 0, -1, comp, line_offset, p++); + } + for (comp_idx = 1; comp_idx < ct->num_comps-1; comp_idx++) + { + p = process; + prev_comp = comp; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer, x, 1, 0, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer, x, 0, 0, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer, x, 1, 0, 0, 0, prev_comp, comp, line_offset, p++); + } + } + p = process; + prev_comp = comp; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer, x, 1, 0, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer, x, 0, 0, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer, x, 1, 0, 0, 1, prev_comp, comp, line_offset, p++); + } + } + ct->y++; + if (ct->y == ct->height) + { + ct->y = 0; + ct->lines_read = 0; + } + + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/claptrap.h ghostscript-9.25~dfsg+1/base/claptrap.h --- ghostscript-9.10~dfsg/base/claptrap.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/claptrap.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,50 @@ +#ifndef CLAPTRAP_H +#define CLAPTRAP_H + +/* Copyright (C) 2015-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#include "std.h" +#include "stdpre.h" +#include "gsmemory.h" + +#ifndef inline +#define inline __inline +#endif /* inline */ + +typedef struct ClapTrap ClapTrap; + +typedef int (ClapTrap_LineFn)(void *arg, unsigned char *buf); + +ClapTrap *ClapTrap_Init(gs_memory_t *mem, + int width, + int height, + int num_comps, + const int *comp_order, + int max_x_offset, + int max_y_offset, + ClapTrap_LineFn *get_line, + void *get_line_arg); + +void ClapTrap_Fin(gs_memory_t *mem, + ClapTrap *trapper); + +int ClapTrap_GetLine(ClapTrap * gs_restrict trapper, + unsigned char * gs_restrict buffer); + +int ClapTrap_GetLinePlanar(ClapTrap * gs_restrict trapper, + unsigned char ** gs_restrict buffer); + +#endif /* CLAPTRAP_H */ diff -Nru ghostscript-9.10~dfsg/base/claptrap-impl.h ghostscript-9.25~dfsg+1/base/claptrap-impl.h --- ghostscript-9.10~dfsg/base/claptrap-impl.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/claptrap-impl.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,53 @@ +#ifndef CLAPTRAP_IMPL_H + +/* The API for this is that the caller requests trapped scanlines. + * We rely on being able to request untrapped scanlines from a source. + * Because we need to look ahead (and behind) of the current position + * to calculate whether trapping is needed at a given point, we use a + * rolling buffer to hold several scanlines. + * + * First we examine the buffered data to calculate a 'process map'. + * The process map says whether we need to consider 'smearing' + * component i at position(x, y). If we ever consider trapping + * component i, we will also consider trapping component i+1. + * + * We need to have processed line y+max_y_offset in order to be + * sure that the process map for line y is complete. + */ + +struct ClapTrap +{ + ClapTrap_LineFn *get_line; + void *get_line_arg; + int width; + int height; + int num_comps; + const int *comp_order; + int max_x_offset; + int max_y_offset; + int lines_in_buf; /* How many lines we can store in linebuf (2*max_y_offset+1) */ + unsigned char *linebuf; + int lines_read; /* How many lines we have read into linebuf so far */ + int y; /* Which output line we are on */ + int span; + unsigned char *process; +}; + +/* Evaluate whether a given component should 'shadow' components + * under it (i.e. if the component plane 'comp' was printed + * offset, would it noticably change the amount of the colours + * under it that could be seen) */ +inline static int shadow_here(int v, int min_v, int comp) +{ + return (min_v < 0.8 * v && min_v < v - 16); +} + +/* Given that component comp might be exposed by a higher + * plane being offset, would the value exposed here be + * noticably different from the values around it? */ +inline static int trap_here(int v, int max_v, int comp) +{ + return (v < 0.8 * max_v); +} + +#endif /* CLAPTRAP_IMPL_H */ diff -Nru ghostscript-9.10~dfsg/base/claptrap-init.c ghostscript-9.25~dfsg+1/base/claptrap-init.c --- ghostscript-9.10~dfsg/base/claptrap-init.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/claptrap-init.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,69 @@ +/* Copyright (C) 2015-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#include "claptrap.h" +#include "claptrap-impl.h" + +ClapTrap *ClapTrap_Init(gs_memory_t *mem, + int width, + int height, + int num_comps, + const int *comp_order, + int max_x_offset, + int max_y_offset, + ClapTrap_LineFn *get_line, + void *get_line_arg) +{ + ClapTrap *ct; + + ct = (ClapTrap *)gs_alloc_bytes(mem, sizeof(*ct), "ClapTrap"); + if (ct == NULL) + return NULL; + + ct->width = width; + ct->height = height; + ct->num_comps = num_comps; + ct->comp_order = comp_order; + ct->max_x_offset = max_x_offset; + ct->max_y_offset = max_y_offset; + ct->get_line = get_line; + ct->get_line_arg = get_line_arg; + ct->lines_in_buf = max_y_offset * 2 + 1; + ct->lines_read = 0; + ct->y = 0; + ct->span = width * num_comps; + + ct->linebuf = gs_alloc_bytes(mem, ct->span * ct->lines_in_buf, "ClapTrap linebuf"); + ct->process = gs_alloc_bytes(mem, ct->width * ct->lines_in_buf, "ClapTrap process"); + if (ct->linebuf == NULL || ct->process == NULL) + { + gs_free_object(mem, ct->linebuf, "ClapTrap linebuf"); + gs_free_object(mem, ct->process, "ClapTrap process"); + gs_free_object(mem, ct, "ClapTrap"); + return NULL; + } + + return ct; +} + +void ClapTrap_Fin(gs_memory_t *mem, ClapTrap *ct) +{ + if (ct) + { + gs_free_object(mem, ct->linebuf, "ClapTrap linebuf"); + gs_free_object(mem, ct->process, "ClapTrap process"); + } + gs_free_object(mem, ct, "ClapTrap"); +} diff -Nru ghostscript-9.10~dfsg/base/claptrap-planar.c ghostscript-9.25~dfsg+1/base/claptrap-planar.c --- ghostscript-9.10~dfsg/base/claptrap-planar.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/claptrap-planar.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,288 @@ +/* Copyright (C) 2015-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#include +#include +#include + +#include "claptrap.h" +#include "claptrap-impl.h" + +/* This is the actual guts of the per-pixel processing. + * We use a static inline, so the compiler can optimise + * out as many of the tests as possible. */ +inline static void process_at_pixel(ClapTrap * gs_restrict ct, + unsigned char * gs_restrict buffer, + int x, + int clips_on_x, + int clips_on_y, + int first_comp, + int last_comp, + int prev_comp, + int comp, + int line_offset, + unsigned char *process) +{ + /* We look at the pixel values on comp. + * We look at the process values passed into us from prev_comp, and pass out + * into comp. + */ + + /* Use local vars to avoid pointer aliasing */ + int width = ct->width; + int height = ct->height; + int num_comps = ct->num_comps; + int max_x_offset = ct->max_x_offset; + int max_y_offset = ct->max_y_offset; + int span = ct->span; + int lines_in_buf = ct->lines_in_buf; + unsigned char *linebuf = ct->linebuf; + int y = ct->y; + /* Some offsets we will use repeatedly */ + int oc = x + comp * width; + /* p != 0 if we need to be processed because a previous component shadows us. + * If we're the first component then no one can shadow us. */ + int p = (first_comp ? 0 : *process); + int sx, sy, ex, ey, lo, v; + unsigned char *pc; + unsigned char *ppc; + + assert((first_comp != 1) ^ (prev_comp == -1)); + assert((last_comp != 1) ^ (comp == ct->comp_order[num_comps-1])); + + /* Work out the search region bounds */ + sy = y - max_y_offset; + if (clips_on_y && sy < 0) + sy = 0; + ey = y + max_y_offset; + if (clips_on_y && ey >= height) + ey = height-1; + sx = x - max_x_offset; + if (clips_on_x && sx < 0) + sx = 0; + ex = x + max_x_offset; + if (clips_on_x && ex >= width) + ex = width-1; + + /* We only need to check for shadowing lower components if we're + * not the last last component (!last_comp). We can only need to process + * here if we are not the first component (!first_comp) and + * if (p != 0) then we need to search for the maximum local value + * of this component. */ + v = linebuf[line_offset + oc]; + if (!last_comp || (!first_comp && p)) + { + int min_v, max_v; + + lo = sy % lines_in_buf; + if (!first_comp) + max_v = v; + if (!last_comp) + min_v = v; + pc = &linebuf[lo * span + comp * width + sx]; + ex -= sx; + for (sy = ey-sy; sy >= 0; sy--) + { + ppc = pc; + for (sx = ex; sx >= 0; sx--) + { + int cv = *ppc++; + if (!first_comp && cv > max_v) + max_v = cv; + else if (!last_comp && cv < min_v) + min_v = cv; + } + pc += span; + lo++; + if (lo == lines_in_buf) + { + pc -= span * lines_in_buf; + } + } + /* If we're not the last component, and we meet the criteria + * the next component needs processing. */ + if (!last_comp) + { + /* Process flag for next component inherits from this one */ + int np = p; + if (v > np && shadow_here(v, min_v, comp)) + np = v; + + /* Update the next components process flag if required */ + *process = np; +#ifdef SAVE_PROCESS_BUFFER + buffer[x] = np; + return; +#endif + } + + if (!first_comp && p > v && trap_here(v, max_v, comp)) + { + if (max_v < p) + p = max_v; + v = p; + } + } + buffer[x] = v; +} + +int ClapTrap_GetLinePlanar(ClapTrap * gs_restrict ct, + unsigned char ** gs_restrict buffer) +{ + int max_y; + int l_margin; + int r_margin; + int comp_idx; + int prev_comp; + int comp; + int x; + int line_offset; + unsigned char *process; + + /* Read in as many lines as we need */ + max_y = ct->y + ct->max_y_offset; + if (max_y > ct->height-1) + max_y = ct->height-1; + while (ct->lines_read <= max_y) + { + int bufpos = ct->span * (ct->lines_read % ct->lines_in_buf); + int code = ct->get_line(ct->get_line_arg, &ct->linebuf[bufpos]); + if (code < 0) + return code; + ct->lines_read++; + } + + /* Now we have enough information to calculate the process map for the next line of data */ + l_margin = ct->max_x_offset; + r_margin = ct->width - ct->max_x_offset; + if (r_margin < 0) + { + r_margin = 0; + l_margin = 0; + } + x = (ct->y % ct->lines_in_buf); + process = &ct->process[x * ct->width]; + line_offset = x * ct->span; + if (ct->y < ct->max_y_offset || ct->y >= ct->height - ct->max_y_offset) + { + unsigned char *p = process; + /* Some of our search area is off the end of the bitmap. We must be careful. */ + comp = ct->comp_order[0]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 1, 1, 0, -1, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 0, 1, 1, 0, -1, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 1, 1, 0, -1, comp, line_offset, p++); + } + for (comp_idx = 1; comp_idx < ct->num_comps-1; comp_idx++) + { + prev_comp = comp; + p = process; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 1, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 0, 1, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 1, 0, 0, prev_comp, comp, line_offset, p++); + } + } + prev_comp = comp; + p = process; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 1, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 0, 1, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 1, 0, 1, prev_comp, comp, line_offset, p++); + } + } + else + { + /* Our search area never clips on y at least. */ + unsigned char *p = process; + comp = ct->comp_order[0]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 0, 1, 0, -1, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 0, 0, 1, 0, -1, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 0, 1, 0, -1, comp, line_offset, p++); + } + for (comp_idx = 1; comp_idx < ct->num_comps-1; comp_idx++) + { + prev_comp = comp; + p = process; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 0, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 0, 0, 0, 0, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 0, 0, 0, prev_comp, comp, line_offset, p++); + } + } + prev_comp = comp; + p = process; + comp = ct->comp_order[comp_idx]; + for (x = 0; x < l_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 0, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < r_margin; x++) + { + process_at_pixel(ct, buffer[comp], x, 0, 0, 0, 1, prev_comp, comp, line_offset, p++); + } + for (; x < ct->width; x++) + { + process_at_pixel(ct, buffer[comp], x, 1, 0, 0, 1, prev_comp, comp, line_offset, p++); + } + } + ct->y++; + if (ct->y == ct->height) + { + ct->y = 0; + ct->lines_read = 0; + } + + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/ConvertUTF.c ghostscript-9.25~dfsg+1/base/ConvertUTF.c --- ghostscript-9.10~dfsg/base/ConvertUTF.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ConvertUTF.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,539 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - - See the header file "ConvertUTF.h" for complete documentation. - ------------------------------------------------------------------------- */ - -#include "ConvertUTF.h" -#ifdef CVTUTF_DEBUG -#include -#endif - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF -#define false 0 -#define true 1 - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - if (target >= targetEnd) { - result = targetExhausted; break; - } - ch = *source++; - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_LEGAL_UTF32) { - if (flags == strictConversion) { - result = sourceIllegal; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - --source; /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF32* target = *targetStart; - UTF32 ch, ch2; - while (source < sourceEnd) { - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if (target >= targetEnd) { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; -#ifdef CVTUTF_DEBUG -if (result == sourceIllegal) { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); -} -#endif - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) { - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return false; - /* Everything else falls through when "true"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) > 0xBF) return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { - int length = trailingBytesForUTF8[*source]+1; - if (source+length > sourceEnd) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (! isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead+1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if (flags == strictConversion ) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if (target > targetEnd) { - --source; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF32* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (source + extraBytesToRead >= sourceEnd) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (! isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up the source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- - - Note A. - The fall-through switches in UTF-8 reading code save a - temp variable, some decrements & conditionals. The switches - are equivalent to the following loop: - { - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); - } - In UTF-8 writing code, the switches on "bytesToWrite" are - similarly unrolled loops. - - --------------------------------------------------------------------- */ diff -Nru ghostscript-9.10~dfsg/base/ConvertUTF.h ghostscript-9.25~dfsg+1/base/ConvertUTF.h --- ghostscript-9.10~dfsg/base/ConvertUTF.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ConvertUTF.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - - -#ifndef ConvertUTF_INCLUDED -#define ConvertUTF_INCLUDED - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Header file. - - Several funtions are included here, forming a complete set of - conversions between the three formats. UTF-7 is not included - here, but is handled in a separate source file. - - Each of these routines takes pointers to input buffers and output - buffers. The input buffers are const. - - Each routine converts the text between *sourceStart and sourceEnd, - putting the result into the buffer between *targetStart and - targetEnd. Note: the end pointers are *after* the last item: e.g. - *(sourceEnd - 1) is the last item. - - The return result indicates whether the conversion was successful, - and if not, whether the problem was in the source or target buffers. - (Only the first encountered problem is indicated.) - - After the conversion, *sourceStart and *targetStart are both - updated to point to the end of last text successfully converted in - the respective buffers. - - Input parameters: - sourceStart - pointer to a pointer to the source buffer. - The contents of this are modified on return so that - it points at the next thing to be converted. - targetStart - similarly, pointer to pointer to the target buffer. - sourceEnd, targetEnd - respectively pointers to the ends of the - two buffers, for overflow checking only. - - These conversion functions take a ConversionFlags argument. When this - flag is set to strict, both irregular sequences and isolated surrogates - will cause an error. When the flag is set to lenient, both irregular - sequences and isolated surrogates are converted. - - Whether the flag is strict or lenient, all illegal sequences will cause - an error return. This includes sequences such as: , , - or in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code - must check for illegal sequences. - - When the flag is set to lenient, characters over 0x10FFFF are converted - to the replacement character; otherwise (when the flag is set to strict) - they constitute an error. - - Output parameters: - The value "sourceIllegal" is returned from some routines if the input - sequence is malformed. When "sourceIllegal" is returned, the source - value will point to the illegal value that caused the problem. E.g., - in UTF-8 when a sequence is malformed, it points to the start of the - malformed sequence. - - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Fixes & updates, Sept 2001. - ------------------------------------------------------------------------- */ - -/* --------------------------------------------------------------------- - The following 4 definitions are compiler-specific. - The C standard does not guarantee that wchar_t has at least - 16 bits, so wchar_t is no less portable than unsigned short! - All should be unsigned values to avoid sign extension during - bit mask & shift operations. ------------------------------------------------------------------------- */ - -typedef unsigned long UTF32; /* at least 32 bits */ -typedef unsigned short UTF16; /* at least 16 bits */ -typedef unsigned char UTF8; /* typically 8 bits */ -typedef unsigned char Boolean; /* 0 or 1 */ - -/* Some fundamental constants */ -#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD -#define UNI_MAX_BMP (UTF32)0x0000FFFF -#define UNI_MAX_UTF16 (UTF32)0x0010FFFF -#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF -#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF - -typedef enum { - conversionOK, /* conversion successful */ - sourceExhausted, /* partial character in source, but hit end */ - targetExhausted, /* insuff. room in target for conversion */ - sourceIllegal /* source sequence is illegal/malformed */ -} ConversionResult; - -typedef enum { - strictConversion = 0, - lenientConversion -} ConversionFlags; - -/* This is for C++ and does no harm in C */ -#ifdef __cplusplus -extern "C" { -#endif - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags); - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags); - -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd); - -#ifdef __cplusplus -} -#endif - -/* --------------------------------------------------------------------- */ - -#endif /* ConvertUTF_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/ctype_.h ghostscript-9.25~dfsg+1/base/ctype_.h --- ghostscript-9.10~dfsg/base/ctype_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ctype_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Wrapper for ctype.h */ diff -Nru ghostscript-9.10~dfsg/base/dirent_.h ghostscript-9.25~dfsg+1/base/dirent_.h --- ghostscript-9.10~dfsg/base/dirent_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/dirent_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/dos_.h ghostscript-9.25~dfsg+1/base/dos_.h --- ghostscript-9.10~dfsg/base/dos_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/dos_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/echogs.c ghostscript-9.25~dfsg+1/base/echogs.c --- ghostscript-9.10~dfsg/base/echogs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/echogs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 'echo'-like utility */ @@ -92,7 +92,7 @@ */ FILE *in = 0; const char *extn = ""; - char fmode[4]; + char fmode[5] = {0}; #define FNSIZE 4096 char *fnparam = NULL; /* Initialisation to shut up compilers */ char fname[FNSIZE]; @@ -149,8 +149,10 @@ argp[i] = argp[i - 1]; argp += 2, nargs -= 2; } - } else + } else { strcpy(fname, ""); + fnparam = fname; /* quieten static analysis */ + } if (nargs > 0 && !strcmp(*argp, "-h")) { eputc = hputc, eputs = hputs; argp++, nargs--; @@ -235,7 +237,7 @@ char str[26]; time(&t); - strcpy(str, ctime(&t)); + strncpy(str, ctime(&t), 25); str[24] = 0; /* remove \n */ (*eputs) (str, out); } break; diff -Nru ghostscript-9.10~dfsg/base/errno_.h ghostscript-9.25~dfsg+1/base/errno_.h --- ghostscript-9.10~dfsg/base/errno_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/errno_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Generic substitute for Unix errno.h */ diff -Nru ghostscript-9.10~dfsg/base/ets.c ghostscript-9.25~dfsg+1/base/ets.c --- ghostscript-9.10~dfsg/base/ets.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ets.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,973 @@ + /* + * Testbed implementation of Even Better Screening. Please see + * http://www.artofcode.com/eventone/ for more details. + * + * Copyright 2001-2004 Raph Levien + * + * Code in this module is covered by US Patents 5,055,942 and + * 5,917,614, and corresponding international patents. This version + * of ETS is for commercial licensees and is governed by the licensing + * agreement between artofcode LLC and the licensee. Please see + * http://www.artofcode.com/eventone/ for information on licensing. +*/ + +#include +#include +#include +#include "ets.h" + +/* source for threshold matrix - need to improve build process */ +#include "ets_tm.h" + +#define ETS_VERSION 150 + +#define ETS_SHIFT 16 +#define IMO_SHIFT 14 + +#define FANCY_COUPLING + +typedef struct { + int err; /* Total error carried out of pixel in the line above */ + int r; /* expected distance value (see paper for details) */ + int a; /* expected distance intermediate value (see paper) */ + int b; /* expected distance intermediate value (see paper) */ +} ETS_PixelData; + +typedef struct { + int *dst_line; /* Output pointer */ + ETS_PixelData *line; /* Internal data for each pixel on the line */ + int *lut; /* Table to map from input source value to internal + * intensity level. Internal intensity level is 0 to + * 1<line[0].err; + } + + coupling = 0; + + for (i = 0; i < xd; i++) + { + if (fancy_coupling) + coupling += c_line[i]; + else + coupling = 0; + /* Lookup image data and compute R for all planes. */ + pii = pi; + for (plane_idx = 0; plane_idx < n_planes; plane_idx++, pii++) + { + ETS_PlaneCtx *ctx = planes[plane_idx]; + ETS_SrcPixel src_pixel = src[plane_idx][i * in_plane_step]; + int new_r; + int c1 = ctx->c1; + int rlimit = 1 << (30 - ETS_SHIFT + c1); + unsigned char *dst_ptr = dest[plane_idx]; + int new_e_1_0; + int achieved_error; + int err; + int imo; + int expected_r; + ETS_PixelData * gs_restrict pd = &ctx->line[i]; + + im = ctx->lut[src_pixel]; /* image pixel (ink level) */ + expected_r = ctx->dist_lut[src_pixel]; /* expected distance */ + if (r_style != ETS_RSTYLE_NONE) + rand_shift = ctx->rs_lut[src_pixel]; /* random noise shift */ + + /* Forward pass distance computation; equation 2 from paper */ + if (pii->r + pii->a < pd->r) + { + pii->r += pii->a; + pii->a += 2*aspect_y2; + } + else + { + pii->a = pd->a; + pii->b = pd->b; + pii->r = pd->r; + } + + /* Shuffle all the errors and read the next one. */ + pii->e_1_1 = pii->e_0_1; + pii->e_0_1 = pii->e_m1_1; + pii->e_m1_1 = i == xd - 1 ? 0 : pd[1].err; + /* Reuse of variables here; new_e_1_0 is the total error passed + * into this pixel, with the traditional fs weights. */ + new_e_1_0 = ((pii->e_1_0 * 7 + pii->e_m1_1 * 3 + + pii->e_0_1 * 5 + pii->e_1_1 * 1) >> 4); + + /* White pixels stay white */ + if (im == 0) + { + dst_ptr[i * out_plane_step] = 0; + /* If we are forcing white pixels to stay white, we should + * not propagate errors through them. Or at the very least + * we should attenuate such errors. */ + new_e_1_0 = 0; + } + else + { + /* The guts of ets (Equation 5) */ + int ets_bias; + + if (expected_r == 0) + { + ets_bias = 0; + } + else + { + /* Read the current distance, and clamp to avoid overflow + * in subsequent calculations. */ + new_r = pii->r; + if (new_r > rlimit) + new_r = rlimit; + /* Should we store back with the limit? */ + + /* Change the units on the distance to match our lut + * and subtract our actual distance (rg) from the expected + * distance (expected_r). */ + rg = new_r << (ETS_SHIFT - c1); + ets_bias = rg - expected_r; + + /* So ets_bias is the difference that we want to base our + * threshold modulation on (section 2.1 of the paper). + * Exactly how do we do that? We present various options + * here. + * 0 no modulation + * 1 what the code did when it came to me. No reference + * to this in the paper. + * 2 use it unchanged. + * 3 like 1, but same shift either side of 0. + * 4+ scale the modulation down. + */ + switch (ets_bias) + { + case ETS_BIAS_ZERO: + ets_bias = 0; + break; + case ETS_BIAS_REDUCE_POSITIVE: + if (ets_bias > 0) ets_bias >>= 3; + break; + case ETS_BIAS_NONE: + break; + case ETS_BIAS_REDUCE: + ets_bias >>= 3; + break; + default: + ets_bias /= ets_bias-3; + } + } + + /* Non white pixels get biased, and have the error + * applied. The error starts from the total error passed + * in. */ + err = new_e_1_0; + + /* Plus any ETS bias (calculated above) */ + err += ets_bias; + + /* Plus any random noise. Again various options here: + * 0 No random noise + * 1 The code as it came to me, using lookup table + * 2 commented out when it came to me; using pseudo + * random numbers generated from seed. + */ + switch(r_style) + { + default: + case ETS_RSTYLE_NONE: + break; + case ETS_RSTYLE_PSEUDO: + /* Add the two seeds together */ + sum = seed1 + seed2; + + /* If the add generated a carry, increment + * the result of the addition. + */ + if (sum < seed1 || sum < seed2) sum++; + + /* Seed2 becomes old seed1, seed1 becomes result */ + seed2 = seed1; + seed1 = sum; + + err -= (sum >> rand_shift) - (0x80000000 >> rand_shift); + break; + case ETS_RSTYLE_THRESHOLD: + err += tmline[((unsigned int)(i+ctx->tm_offset)) % tmwidth] << (24 - rand_shift); + break; + } + + /* Clamp the error; this is explained in the paper in + * section 6 just after equation 7. */ + /* FIXME: Understand this better */ + if (err < elo) + err = elo; + else if (err > ehi) + err = ehi; + + /* Add the coupling to our combined 'error + bias' value */ + /* FIXME: Are we sure this shouldn't be clamped? */ + err += coupling; + + /* Calculate imo = the quantised image value (Equation 7) */ + imo = ((err + im) * dith_mul + (old_quant ? 0 : (1 << (ETS_SHIFT + 7)))) >> (ETS_SHIFT + 8); + + /* Clamp to allow for over/underflow due to large errors */ + if (imo < 0) imo = 0; + else if (imo > levels - 1) imo = levels - 1; + + /* Store final output pixel */ + dst_ptr[i * out_plane_step] = imo; + + /* Calculate the error between the desired and the obtained + * pixel values. */ + achieved_error = im - ((imo * imo_mul) >> IMO_SHIFT); + + /* And the error passed in is updated with the error for + * this pixel. */ + new_e_1_0 += achieved_error; + + /* Do the magic coupling here; strengths is 0 when + * multiplane optimisation is turned off, hence coupling + * remains 0 always. Equation 6. */ + coupling += (achieved_error * ctx->strength) >> 8; + + /* If we output a set pixel, then reset our distances. */ + if (imo != 0) + { + pii->a = aspect_y2; + pii->b = aspect_x2; + pii->r = 0; + } + } + + /* Store the values back for the next pass (Equation 3) */ + pd->a = pii->a; + pd->b = pii->b; + pd->r = pii->r; + pd->err = new_e_1_0; + pii->e_1_0 = new_e_1_0; + } + if (fancy_coupling) + { + coupling = coupling >> 1; + c_line[i] = coupling; + } + } + + /* Note: this isn't white optimized, but the payoff is probably not + that important. */ + if (fancy_coupling) + { + coupling = 0; + for (i = xd - 1; i >= 0; i--) + { + coupling = (coupling + c_line[i]) >> 1; + c_line[i] = (coupling - (coupling >> 4)); + } + } + + /* Update distances. Reverse scanline pass. */ + for (plane_idx = 0; plane_idx < n_planes; plane_idx++) + { + ETS_PlaneCtx *ctx = planes[plane_idx]; + int av = aspect_y2; + int bv = aspect_x2; + int rv = 0; + int c1 = ctx->c1; + int rlimit = 1 << (30 - ETS_SHIFT + c1); + ETS_PixelData * gs_restrict pd = &ctx->line[xd]; + + for (i = xd; i > 0; i--) + { + pd--; + /* Equation 4 from the paper */ + if (rv + bv + av < pd->r + pd->b) + { + rv += av; + av += (aspect_y2<<1); + } + else + { + rv = pd->r; + av = pd->a; + bv = pd->b; + } + if (rv > rlimit) rv = rlimit; + pd->a = av; + pd->b = bv + (aspect_x2 << 1); + pd->r = rv + bv; + } + } + + if (r_style == 2) + { + seeds[0] = seed1; + seeds[1] = seed2; + } +} + +/** + * ets_line: Screen a line using EvenTonedFS screening. + * @ctx: An #EBPlaneCtx context. + * @dest: Array of destination buffers, 8 bpp pixels each. + * @src: Array of source buffer, ET_SrcPixel pixels each. + * + * Screens a single line using Even ToneFS screening. + **/ +#ifdef OLD_QUANT +#define OLD_QUANT_VAL 1 +#else +#define OLD_QUANT_VAL 0 +#endif +#ifdef FANCY_COUPLING +#define FANCY_COUPLING_VAL 1 +#else +#define FANCY_COUPLING_VAL 0 +#endif + +static void +ets_line_none(ETS_Ctx *etc, unsigned char **dest, const ETS_SrcPixel * const *src) +{ + ets_line_template(dest, src, etc->n_planes, etc->levels, etc->aspect_x, etc->aspect_y, etc->elo, etc->ehi, etc->ets_bias, ETS_RSTYLE_NONE, + OLD_QUANT_VAL, FANCY_COUPLING_VAL, + etc->c_line, NULL, 0, 0, etc->y, etc->width, etc->plane_ctx, etc->seeds, etc->n_planes, etc->n_planes); +} + +static void +ets_line_threshold(ETS_Ctx *etc, unsigned char **dest, const ETS_SrcPixel * const * src) +{ + ets_line_template(dest, src, etc->n_planes, etc->levels, etc->aspect_x, etc->aspect_y, etc->elo, etc->ehi, etc->ets_bias, ETS_RSTYLE_THRESHOLD, + OLD_QUANT_VAL, FANCY_COUPLING_VAL, + etc->c_line, etc->tmmat, etc->tmwidth, etc->tmheight, etc->y, etc->width, etc->plane_ctx, etc->seeds, etc->n_planes, etc->n_planes); +} + +static void +ets_line_pseudo(ETS_Ctx *etc, unsigned char **dest, const ETS_SrcPixel * const * src) +{ + ets_line_template(dest, src, etc->n_planes, etc->levels, etc->aspect_x, etc->aspect_y, etc->elo, etc->ehi, etc->ets_bias, ETS_RSTYLE_PSEUDO, + OLD_QUANT_VAL, FANCY_COUPLING_VAL, + etc->c_line, NULL, 0, 0, etc->y, etc->width, etc->plane_ctx, etc->seeds, etc->n_planes, etc->n_planes); +} + +#ifdef UNUSED +static void +ets_line_default(ETS_Ctx *etc, unsigned char **dest, const ETS_SrcPixel * const * src) +{ + ets_line_template(dest, src, etc->n_planes, etc->levels, etc->aspect_x, etc->aspect_y, etc->elo, etc->ehi, etc->ets_bias, etc->r_style, + OLD_QUANT_VAL, FANCY_COUPLING_VAL, + etc->c_line, etc->tmmat, etc->tmwidth, etc->tmheight, etc->y, etc->width, etc->plane_ctx, etc->seeds, etc->n_planes, etc->n_planes); +} +#endif + +void +ets_line(ETS_Ctx *etc, unsigned char **dest, const ETS_SrcPixel * const * gs_restrict src) +{ + etc->line_fn(etc, dest, src); + etc->y++; +} + +/** + * ets_plane_free: Free an #EBPlaneCtx context. + * @ctx: The #EBPlaneCtx context to free. + * + * Frees @ctx. + **/ +static void +ets_plane_free(void *malloc_arg, ETS_PlaneCtx *ctx) +{ + if (!ctx) + return; + + ets_free(malloc_arg, ctx->line); + ets_free(malloc_arg, ctx->lut); + ets_free(malloc_arg, ctx->dist_lut); + ets_free(malloc_arg, ctx->rs_lut); + ets_free(malloc_arg, ctx); +} + +static double +compute_distscale(const ETS_Params *params) +{ + double distscale = params->distscale; + + if (distscale == 0.0) + { + distscale = -1; + switch(params->aspect_x) + { + case 1: + switch(params->aspect_y) + { + case 1: + distscale = 0.95; + break; + case 2: + distscale = 1.8; + break; + case 3: + distscale = 2.4; /* FIXME */ + break; + case 4: + distscale = 3.6; + break; + } + break; + case 2: + switch(params->aspect_y) + { + case 1: + distscale = 1.8; + break; + case 2: + break; + case 3: + distscale = 1.35; /* FIXME */ + break; + case 4: + break; + } + break; + case 3: + switch(params->aspect_y) + { + case 1: + distscale = 2.4; /* FIXME */ + break; + case 2: + distscale = 1.35; /* FIXME */ + break; + case 3: + break; + case 4: + distscale = 0.675; /* FIXME */ + break; + } + break; + case 4: + switch(params->aspect_y) + { + case 1: + distscale = 3.6; + break; + case 2: + break; + case 3: + distscale = 0.675; /* FIXME */ + break; + case 4: + break; + } + break; + } + if (distscale == -1) + { + fprintf(stderr, "aspect ratio of %d:%d not supported\n", + params->aspect_x, params->aspect_y); + exit(1); + } + } + return distscale; +} + +static unsigned int +ets_log2(unsigned int x) +{ + unsigned int y = 0; + unsigned int z; + + for (z = x; z > 1; z = z >> 1) + y++; + return y; +} + +static unsigned int +ets_log2up(unsigned int x) +{ + return ets_log2(x-1)+1; +} + +static int +compute_randshift(int nl, int rs_base, int levels) +{ + int rs = rs_base; + + if ((nl > (90 << (ETS_SHIFT - 10)) && + nl < (129 << (ETS_SHIFT - 10))) || + (nl > (162 << (ETS_SHIFT - 10)) && + nl < (180 << (ETS_SHIFT - 10)))) + rs--; + else if (nl > (321 << (ETS_SHIFT - 10)) && + nl < (361 << (ETS_SHIFT - 10))) + { + rs--; + if (nl > (331 << (ETS_SHIFT - 10)) && + nl < (351 << (ETS_SHIFT - 10))) + rs--; + } + else if ((nl == (levels - 1) << ETS_SHIFT) && + nl > (((levels - 1) << ETS_SHIFT) - + (1 << (ETS_SHIFT - 2)))) + { + /* don't add randomness in extreme shadows */ + } + else if ((nl > (3 << (ETS_SHIFT - 2)))) + { + nl -= (nl + (1 << (ETS_SHIFT - 2))) & -(1 << (ETS_SHIFT - 1)); + if (nl < 0) nl = -nl; + if (nl < (1 << (ETS_SHIFT - 4))) rs--; + if (nl < (1 << (ETS_SHIFT - 5))) rs--; + if (nl < (1 << (ETS_SHIFT - 6))) rs--; + } + else + { + if (nl < (3 << (ETS_SHIFT - 3))) nl += 1 << (ETS_SHIFT - 2); + nl = nl - (1 << (ETS_SHIFT - 1)); + if (nl < 0) nl = -nl; + if (nl < (1 << (ETS_SHIFT - 4))) rs--; + if (nl < (1 << (ETS_SHIFT - 5))) rs--; + if (nl < (1 << (ETS_SHIFT - 6))) rs--; + } + return rs; +} + +/** + * ets_new: Create new Even ToneFS screening context. + * @source_width: Width of source buffer. + * @dest_width: Width of destination buffer, in pixels. + * @lut: Lookup table for gray values. + * + * Creates a new context for Even ToneFS screening. + * + * If @dest_width is larger than @source_width, then input lines will + * be expanded using nearest-neighbor sampling. + * + * @lut should be an array of 256 values, one for each possible input + * gray value. @lut is a lookup table for gray values. Output is from + * 0 for white (no ink) to .... + * + * + * Return value: The new #EBPlaneCtx context. + **/ +static ETS_PlaneCtx * +ets_plane_new(void *malloc_arg, const ETS_Params *params, ETS_Ctx *etc, int plane_idx, int strength) +{ + int width = params->width; + int *lut = params->luts[plane_idx]; + ETS_PlaneCtx *result; + int i; + int *new_lut = NULL; + int *dist_lut = NULL; + char *rs_lut = NULL; + double distscale = compute_distscale(params); + int c1; + int rlimit; + int log2_levels, log2_aspect; + int rs_base; + + result = (ETS_PlaneCtx *)ets_malloc(malloc_arg, sizeof(ETS_PlaneCtx)); + if (result == NULL) + goto fail; + + log2_levels = ets_log2(params->levels); + log2_aspect = ets_log2(params->aspect_x) + ets_log2(params->aspect_y); /* FIXME */ + c1 = 6 + log2_aspect + log2_levels; + if (params->c1_scale) + c1 -= params->c1_scale[plane_idx]; + result->c1 = c1; + rlimit = 1 << (30 - ETS_SHIFT + c1); + result->tm_offset = TM_WIDTH/ets_log2up(params->n_planes); + result->strength = strength; + + /* Set up a lut to map input values from the source domain to the + * amount of ink. Callers can provide a lut of their own, which can be + * used for gamma correction etc. In the absence of this, a linear + * distribution is assumed. The user supplied lut should map from + * 'amount of light' to 'gamma adjusted amount of light', as the code + * subtracts the final value from (1<> 7)) >> (24 - ETS_SHIFT); +#else + nli = (i * ((double) (1 << ETS_SHIFT)) / ETS_SRC_MAX) + 0.5; +#endif + } + else + nli = lut[i] >> (24 - ETS_SHIFT); + if (params->polarity == ETS_BLACK_IS_ZERO) + new_lut[i] = (1 << ETS_SHIFT) - nli; + else + new_lut[i] = nli; + } + + /* Here we calculate 2 more lookup tables. These could be separated out + * into 2 different loops, but are done in 1 to avoid a small amount of + * recalculation. + * dist_lut[i] = expected distance between dots for a greyscale of level i + * rs_lut[i] = whacky random noise scale factor. + */ + dist_lut = (int *)ets_malloc(malloc_arg, (ETS_SRC_MAX + 1) * sizeof(int)); + if (dist_lut == NULL) + goto fail; + rs_lut = (char *)ets_malloc(malloc_arg, (ETS_SRC_MAX + 1) * sizeof(int)); + if (rs_lut == NULL) + goto fail; + + rs_base = 35 - ETS_SHIFT + log2_levels - params->rand_scale; + + /* The paper says that the expected 'value' for a grayshade g is: + * d_avg = 0.95 / 0.95/(g^2) + * This seems wrong to me. Let's consider some common cases; for a given + * greyscale, lay out the 'ideal' dithering, then consider removing each + * set pixel in turn and measuring the distance between that pixel and + * the closest set pixel. + * + * g = 1/2 #.#.#.#. visibly, expected distance = SQR(2) + * .#.#.#.# + * #.#.#.#. + * .#.#.#.# + * + * g = 1/4 #.#.#.#. expected distance = 2 + * ........ + * #.#.#.#. + * ........ + * + * g = 1/16 #...#... expected distance = 4 + * ........ + * ........ + * ........ + * #...#... + * ........ + * ........ + * ........ + * + * This rough approach leads us to suspect that we should be finding + * values roughly proportional to 1/SQR(g). Given the algorithm works in + * terms of square distance, this means 1/g. This is at odds with the + * value given in the paper. Being charitable and assuming that the paper + * means 'squared distance' when it says 'value', we are still a square + * off. + * + * Nonetheless, the code as supplied uses 0.95/g for the squared distance + * (i.e. it appears to agree with our logic here). + */ + for (i = 0; i <= ETS_SRC_MAX; i++) + { + double dist; + int nl = new_lut[i] * (params->levels - 1); + int rs; + + /* This is (or is supposed to be) equation 5 from the paper. If nl + * is g, why aren't we dividing by nl*nl ? */ + if (nl == 0) + { + /* The expected distance for an ink level of 0 is infinite. Just + * put 0! */ + dist = 0; + } + else if (nl >= ((1<levels-1))) + { + /* New from RJW: Our distance measurements are only meaningful + * within the bottom 'level band' of the output. Do not apply + * ETS to higher ink levels. */ + dist = 0; + } + else + { + dist = (distscale * (1 << (2 * ETS_SHIFT - c1))) / nl; + if (dist > rlimit << (ETS_SHIFT - c1)) + dist = rlimit << (ETS_SHIFT - c1); + } + + if (params->rand_scale_luts == NULL) + { + rs = compute_randshift(nl, rs_base, params->levels); + rs_lut[i] = rs; + } + else + { + int val = params->rand_scale_luts[plane_idx][i]; + + rs_lut[i] = rs_base + 16 - ets_log2(val + (val >> 1)); + } + dist_lut[i] = (int)dist; + } + + result->lut = new_lut; + result->dist_lut = dist_lut; + result->rs_lut = rs_lut; + + result->line = (ETS_PixelData *)ets_calloc(malloc_arg, width, sizeof(ETS_PixelData)); + if (result->line == NULL) + goto fail; + for (i = 0; i < width; i++) + { + result->line[i].a = 1; + result->line[i].b = 1; + /* Initialize error with a non zero random value to ensure dots don't + land on dots when we have same planes with same gray level and + the plane interaction option is turned off. Ideally the level + of this error should be based upon the values of the first line + to ensure that things get primed properly */ + result->line[i].err = -((rand () & 0x7fff) << 6) >> (24 - ETS_SHIFT); + } + + return result; +fail: + if (result) + { + ets_free(malloc_arg, new_lut); + ets_free(malloc_arg, dist_lut); + ets_free(malloc_arg, rs_lut); + ets_free(malloc_arg, result->line); + } + ets_free(malloc_arg, result); + return NULL; +} + + +/** + * ets_destroy: Destroy an #EvenBetterCtx context. + * @ctx: The #EvenBetterCtx context to destroy. + * + * Frees @ctx. + **/ +void +ets_destroy(void *malloc_arg, ETS_Ctx *ctx) +{ + int i; + int n_planes; + + if (ctx == NULL) + return; + + if (ctx->dump_file) + fclose(ctx->dump_file); + + n_planes = ctx->n_planes; + for (i = 0; i < n_planes; i++) + ets_plane_free(malloc_arg, ctx->plane_ctx[i]); + ets_free(malloc_arg,ctx->plane_ctx); + ets_free(malloc_arg, ctx->c_line); + + ets_free(malloc_arg, ctx); +} + +ETS_Ctx * +ets_create(void *malloc_arg, const ETS_Params *params) +{ + ETS_Ctx *result = (ETS_Ctx *)ets_malloc(malloc_arg, sizeof(ETS_Ctx)); + int n_planes = params->n_planes; + int i; + + if (result == NULL) + return NULL; + + if (params->dump_file) + { + int header[5]; + + header[0] = 0x70644245; + header[1] = 'M' * 0x1010000 + 'I' * 0x101; + header[2] = ETS_VERSION; + header[3] = ETS_SRC_MAX; + header[4] = sizeof(ETS_SrcPixel); + fwrite(header, sizeof(int), sizeof(header) / sizeof(header[0]), + params->dump_file); + if (params->dump_level >= ETS_DUMP_PARAMS) + { + fwrite(params, 1, sizeof(ETS_Params), params->dump_file); + } + if (params->dump_level >= ETS_DUMP_LUTS) + { + for (i = 0; i < params->n_planes; i++) + fwrite(params->luts[i], sizeof(int), ETS_SRC_MAX + 1, + params->dump_file); + } + } + + result->width = params->width; + result->n_planes = n_planes; + result->levels = params->levels; + + result->aspect_x = params->aspect_x; + result->aspect_y = params->aspect_y; + + result->ehi = (int)(0.6 * (1 << ETS_SHIFT) / (params->levels - 1)); + result->elo = -result->ehi; + + result->ets_bias = params->ets_bias; + result->r_style = params->r_style; + + result->c_line = (int *)ets_calloc(malloc_arg, params->width, sizeof(int)); + + result->seeds[0] = 0x5324879f; + result->seeds[1] = 0xb78d0945; + + result->dump_file = params->dump_file; + result->dump_level = params->dump_level; + + result->plane_ctx = (ETS_PlaneCtx **)ets_calloc(malloc_arg, n_planes, sizeof(ETS_PlaneCtx *)); + if (result->plane_ctx == NULL) + goto fail; + for (i = 0; i < n_planes; i++) + { + result->plane_ctx[i] = ets_plane_new(malloc_arg, params, result, i, params->strengths[i]); + if (result->plane_ctx[i] == NULL) + goto fail; + } + result->y = 0; + result->tmmat = tmmat; + result->tmwidth = TM_WIDTH; + result->tmheight = TM_HEIGHT; + + /* Can replace this with optimised versions - for now, just the random ones. */ + switch (result->r_style) + { + default: + case ETS_RSTYLE_NONE: + result->line_fn = ets_line_none; + break; + case ETS_RSTYLE_THRESHOLD: + result->line_fn = ets_line_threshold; + break; + case ETS_RSTYLE_PSEUDO: + result->line_fn = ets_line_pseudo; + break; + } + + return result; + +fail: + ets_destroy(malloc_arg, result); + return NULL; +} diff -Nru ghostscript-9.10~dfsg/base/ets.h ghostscript-9.25~dfsg+1/base/ets.h --- ghostscript-9.10~dfsg/base/ets.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ets.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,116 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include /* For FILE */ +#include "stdpre.h" /* for gs_restrict */ + +#ifndef inline +#define inline __inline +#endif + + +/* Definitions for source pixel format. + * Reasonable settings are as follows: + * 8-bit: unsigned char ETS_SrcPixel; ETS_SRC_MAX = 255 + * 12-bit 0..4095: unsigned short (or int) ETS_SrcPixel; ETS_SRC_MAX = 4095 + * 12-bit 0..4096: unsigned short (or int) ETS_SrcPixel; ETS_SRC_MAX = 4096 + * 16-bit 0..65535: unsigned short (or int) ETS_SrcPixel; ETS_SRC_MAX = 65535 + * 16-bit 0..65536: unsigned int ETS_SrcPixel; ETS_SRC_MAX = 65536 + */ + +/* A quick and dirty switch for 8 or 16 bit data */ +#define CHAR_SOURCE + +#ifdef CHAR_SOURCE + typedef unsigned char ETS_SrcPixel; + #define ETS_SRC_MAX 255 +#else + typedef unsigned short ETS_SrcPixel; + #define ETS_SRC_MAX 65535 +#endif + +/* Photoshop (and possibly other image formats define white in a CMYK image with a + value of 255 (65535). This is opposite of the PAM files that Robin has created. + The ETS code expects white to be at 0. Adjustments to the values in gray level + will be baked into the LUT if needed */ +typedef enum { + ETS_BLACK_IS_ZERO = 0, + ETS_BLACK_IS_ONE +} ETS_POLARITY; + +/* To use the file dump capability: + + Open a file as with: fopen ("dumpfile", "wb"); + Put the resulting FILE * pointer in params->dump_file. + Set params->dump_level to the desired level. ET_DUMP_ALL dumps all + inputs and outputs. Other values will lead to much smaller files, + but may not be as insightful. + + If no dump file is desired, set params->dump_file to NULL. +*/ + +typedef enum { + ETS_DUMP_MINIMAL, + ETS_DUMP_PARAMS, + ETS_DUMP_LUTS, + ETS_DUMP_INPUT, + ETS_DUMP_ALL +} ETS_DumpLevel; + +typedef enum { + ETS_RSTYLE_NONE = 0, + ETS_RSTYLE_THRESHOLD = 1, + ETS_RSTYLE_PSEUDO = 2 +} ETS_RStyle; + +typedef enum { + ETS_BIAS_ZERO = 0, + ETS_BIAS_REDUCE_POSITIVE = 1, + ETS_BIAS_NONE = 2, + ETS_BIAS_REDUCE = 3, + ETS_BIAS_DIVIDE_BY_N_LESS_3 = 4, +} ETS_Bias; + +typedef struct { + int width; + int n_planes; + int levels; /* Number of levels on output, <= 256 */ + int **luts; + double distscale; /* 0 to autoselect based on aspect */ + int aspect_x; + int aspect_y; + int *strengths; + int rand_scale; /* 0 is default. Larger means more random. */ + int *c1_scale; /* now an array, one per channel; 0 is default */ + ETS_Bias ets_bias; + ETS_RStyle r_style; + FILE *dump_file; + ETS_DumpLevel dump_level; + int **rand_scale_luts; + ETS_POLARITY polarity; +} ETS_Params; + +typedef struct _ETS_Ctx ETS_Ctx; + +ETS_Ctx * +ets_create(void *malloc_arg, const ETS_Params *params); + +void +ets_line(ETS_Ctx *ctx, unsigned char **dest, const ETS_SrcPixel * const * gs_restrict src); + +void +ets_destroy(void *malloc_arg, ETS_Ctx *ctx); + +void * +ets_malloc(void *malloc_arg, int size); + +void * +ets_calloc(void *malloc_arg, int count, int size); + +void +ets_free(void *malloc_arg, void *p); + +#ifdef __cplusplus +} +#endif diff -Nru ghostscript-9.10~dfsg/base/ets_tm.h ghostscript-9.25~dfsg+1/base/ets_tm.h --- ghostscript-9.10~dfsg/base/ets_tm.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ets_tm.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,4099 @@ +#define TM_WIDTH 256 +#define TM_HEIGHT 256 +const signed char tmmat[] = { + 51, -28, 14, 31, 43, -58, -27, 45, -45, 38, 1, 2, -30, -1, 62, 42, + 10, 35, -60, 36, -80, -8, -55, 84, -59, 15, -43, -42, 84, -47, 0, 3, + 9, -50, 44, -2, -22, 48, -68, 42, -20, 37, -33, 55, -41, -24, 10, 30, + -100, 70, 0, -35, -35, 21, 36, -33, -22, -33, 46, -43, -55, 75, 33, 54, + -40, 26, -15, 36, -31, 20, 43, -22, -3, 41, 14, 13, -53, 14, 16, -16, + 56, -34, 6, 41, 44, -7, -16, 46, -27, 39, 68, 21, 12, 43, -29, 71, + -44, 17, 10, 63, -31, -47, 49, 49, -68, 68, -4, -28, 22, -50, 45, -24, + 12, -20, -46, -18, 21, 8, -59, 62, -33, -17, -23, 7, 50, 54, -11, -23, + 60, -8, -23, -35, 35, 1, -45, 66, -61, 95, -31, 74, -68, 84, -104, 38, + -36, -36, 21, -6, -10, 61, -1, 18, -61, -13, 33, -44, -28, -13, -8, 33, + 10, 56, -60, -51, 87, -43, 88, -75, 110, -84, 88, -58, -59, 88, 15, -33, + -47, -21, 63, 47, -13, 3, 9, -21, 45, -46, 3, 50, -31, 63, -17, 48, + 27, 51, -67, 48, 26, 37, 38, 8, 49, -3, 16, 14, -18, 0, -41, 30, + 41, -47, 65, -44, 50, -33, 43, -7, 10, -24, -62, 43, -22, 55, -11, 66, + -34, 19, 44, -66, 24, 28, 71, 4, -41, 41, 20, -51, -20, 0, 47, -42, + 24, -2, 17, -38, 37, -54, 24, -56, -4, 18, -12, -8, -24, -56, 36, -26, + 3, -51, 38, -83, 28, -3, 20, -49, 31, -64, -44, 40, 14, -48, -50, -39, + -12, -17, 47, -43, 68, -9, 9, -82, 88, -89, 85, -24, -41, -11, 45, 34, + 5, 55, -68, 36, -43, 13, 53, 12, 41, -49, 32, -3, -30, 50, 27, 34, + 7, 11, -23, -16, 55, -29, -28, 48, 2, -11, -25, 52, 41, -72, 19, -21, + 36, 6, -44, -27, 22, -55, -54, -7, -45, 15, 19, -14, 43, 19, -26, -14, + -36, 8, 21, -31, -45, -33, -45, 31, -25, -44, -18, -47, -17, 30, -1, -39, + 25, 20, -13, -84, 69, 3, -10, -44, 42, -29, 39, -22, -23, -18, 40, -7, + 67, -33, 106, -41, 36, -78, 47, 4, -20, -54, 62, 20, -78, -41, 40, 5, + -32, 1, 52, -35, -45, -3, -8, 8, 36, -44, -36, -52, 1, 5, 41, 13, + -18, 43, -7, 5, 22, -17, -48, 63, 26, -16, 26, 6, 14, 36, -47, 61, + -48, -55, 92, -40, 19, -61, 37, -14, -22, 66, -61, 43, 39, -79, -14, 50, + 19, 46, -55, -24, -48, 27, -56, 43, 1, 30, -46, -12, -32, -4, -41, -19, + -6, -46, 46, -53, 6, -7, -36, 41, -61, 31, -44, 16, 6, 17, 28, -35, + 30, -47, 0, 37, -15, 3, -9, -5, -23, 46, 46, 17, -32, -17, -62, 35, + -35, 14, 8, 37, -51, -55, -19, -20, 14, 41, -34, 0, 27, 20, 18, -46, + 47, -49, -22, -1, 27, -7, 65, -23, 16, 4, 20, -13, 21, 58, -79, 39, + -14, 63, -2, 29, 52, 7, 28, -3, -9, 50, 62, -40, 56, 9, 13, 45, + 34, 43, -55, 21, 6, -58, 32, 42, 13, 11, -35, 35, 14, 2, -12, -80, + 43, -88, 39, -13, 54, 0, -70, 7, 0, -54, 63, -45, 17, -2, -71, -15, + -31, 13, -50, 47, -26, 45, -2, 0, -4, 85, -32, -48, 22, 14, -32, -18, + -7, 33, 35, -13, -25, 60, 65, 40, 37, 30, -36, 28, -41, -13, 72, -21, + 52, 55, -41, -2, 35, 16, 47, -61, 45, 76, -15, 20, 0, 1, 26, -34, + 0, -35, 15, 71, -73, -3, 39, -38, -3, -37, 21, 17, 18, 26, -70, 0, + -18, -25, -76, 13, -68, 79, -21, 14, 23, 80, -74, 0, 20, 60, -19, 48, + -51, -32, 54, -33, 70, 30, -2, -36, 72, -54, 87, 19, 6, 28, -50, -7, + -30, -51, 41, -33, -24, -44, 72, -78, -16, -37, -8, -18, 46, -59, 54, -66, + 8, 4, -8, 7, -46, 74, 9, -10, -33, -10, 27, 29, -48, 92, -74, 33, + -64, 2, 41, -18, 67, 17, 9, -53, 20, 9, 12, 2, 65, -41, 70, -33, + 78, -45, 45, -23, -19, -21, 6, -40, 40, -63, 57, 55, -73, 42, -11, -35, + 21, -37, 36, -15, 11, 29, 1, -5, 43, -60, -42, 6, 32, -68, 74, -32, + -14, 22, -17, -20, 36, 40, 14, -28, 29, -28, -37, 53, -55, 56, -72, 64, + 7, 29, -9, 26, -17, 46, -54, 1, -40, 10, 39, -14, -32, -8, 45, 12, + -4, -10, -42, -47, -73, 0, -38, 31, 31, -13, -15, -54, -23, -30, 66, -82, + -37, -35, 39, 18, -72, 52, 13, -54, 13, 25, 36, -88, 29, 16, 19, 79, + -76, 46, 64, -52, -8, -39, 77, -85, 53, -5, -60, 45, 38, -77, 77, 40, + -21, 18, -12, -7, 10, -56, 33, -42, -53, 6, -50, 48, -67, 69, 28, -22, + 23, -5, -55, 65, 26, -52, -77, 0, -27, -50, 2, -41, -4, 17, -71, 30, + -73, -4, -39, 52, -4, -1, 27, 43, -53, -49, 25, -72, 86, -75, 3, 9, + 25, 9, -12, -51, 63, -20, 66, -58, 72, -4, 9, -78, 42, -35, 26, 20, + 20, 21, 44, 33, 14, 0, -21, -12, 19, -92, 54, 19, -46, -42, -23, 18, + 29, 31, -60, 22, -23, -71, 70, -61, 0, -5, -29, -26, -2, 58, -24, 31, + 44, 70, -40, 4, 18, 21, 57, -20, 40, 8, 38, 15, 43, -61, 6, 0, + 33, 30, -17, -53, 93, -60, -38, -11, 10, -13, 34, -46, -7, 24, 36, -57, + 46, 15, -38, -20, -22, -61, 28, -57, 62, -44, 36, -12, -33, 3, -27, -7, + -51, 25, -12, -26, 53, -7, 8, -40, 56, -29, -25, -22, -50, 78, -62, 54, + -4, 28, -22, -44, 35, 4, -73, 75, -68, 96, 6, 33, -30, 40, 22, 9, + -8, -62, 57, -61, 37, -42, 0, 30, -20, 4, 37, -17, 20, -53, 6, -49, + 11, -30, -39, 23, -48, -4, 35, 16, 21, -17, -44, 52, 15, 42, -31, -30, + -23, 11, 9, 66, 32, 40, -8, -57, 2, -60, 23, 96, -50, 92, -81, 91, + 5, 21, -22, -17, 35, 7, 51, -36, -36, -60, 31, 63, -77, 14, -24, -34, + 41, 8, -75, 8, -8, 4, -16, 61, 3, -50, 55, 17, -65, 72, -42, -4, + -10, 41, 63, -62, 58, 55, -70, 39, 64, -60, 54, 31, 6, -63, -26, -23, + 20, -40, 72, -98, 33, -15, 82, -27, 41, 28, 48, 21, 2, 20, -44, 98, + -36, 90, -44, -41, 36, -22, -56, 33, 5, -23, 17, 71, -95, 98, -47, 58, + -86, 58, -12, 49, -62, 28, -90, 63, -49, -35, -7, 63, 6, -14, 19, 28, + -41, 53, -59, -29, -3, -4, 40, 0, -6, 39, -4, -11, 27, 66, -67, 12, + -31, 18, -18, 59, -42, 28, -1, 1, 54, -41, 14, -9, 32, -64, 9, -35, + -50, -6, -26, -24, 41, -55, -43, -38, 37, -31, -17, -24, -29, 16, 49, 41, + -54, -28, 31, 18, -62, 6, 52, 14, 29, -1, -20, -2, -10, -9, -33, 3, + 15, -36, 62, 7, 24, 68, 43, -5, 19, -14, 8, 7, 45, -20, 39, -55, + 98, -38, 42, -50, 39, -27, 75, -39, 50, -59, 77, -32, 39, -95, 78, -41, + -3, 35, -28, -14, 14, 32, 5, -33, -5, -21, -30, -30, 31, -6, -49, 22, + 28, 35, 11, 31, -40, 51, -28, -61, 26, 27, -27, -31, 65, -46, 60, -36, + 26, 53, 16, 2, 52, -44, -35, -22, -3, -37, 14, -67, 28, -46, 18, 31, + -3, -2, -47, 0, -60, -2, -5, 76, -31, 100, -60, -36, -16, -56, 51, -53, + -39, -33, 17, 49, -81, 49, -54, 13, 48, -7, 22, -24, 68, -28, -15, -37, + 26, -26, 40, 37, 30, -24, 49, -70, -17, 58, -55, 9, -65, 43, 14, -21, + -22, 8, -46, 26, -39, -34, 42, 31, -19, -4, -15, -13, 32, -4, 56, -3, + 32, -27, -19, 23, 59, -79, 22, -42, -36, -61, 39, -86, 89, -48, -6, -61, + 22, -59, 7, 51, 9, -17, 65, -50, 50, -61, 38, -26, 1, -18, -17, -61, + 63, -47, -8, 15, 14, -35, 86, -2, 9, 31, 9, -7, -80, 40, -46, 28, + -85, 33, -21, 61, -49, -50, 24, 24, -82, 9, -25, 24, -74, -12, 20, 27, + 45, -35, 52, -49, 9, 0, 47, -58, 9, 22, -1, -4, -34, 91, -40, -9, + 59, -31, 30, 40, -17, 36, 8, 31, -38, 49, 47, -46, 14, 1, -59, -44, + 23, 24, -1, -25, 40, 11, -24, 66, -58, -48, 38, -26, 74, -13, 24, 4, + 53, -15, -16, -9, -48, -44, -47, 0, -16, -24, 20, -16, -15, 13, 5, -29, + -16, -65, 46, -74, 56, -6, -55, 50, -23, 39, -38, -10, 52, 41, -98, 82, + -45, 17, 6, -25, 2, -30, 9, 14, 1, -33, 15, -41, 8, 10, 4, -67, + 48, -56, -38, 6, 3, -40, 0, 48, -8, 0, -27, 52, -25, -31, 41, -5, + 47, -46, -55, 21, 20, 17, 16, 1, 43, 21, 24, 26, -58, 50, 15, -34, + -49, 46, 29, 49, -21, 10, 54, -60, 2, -65, 63, 14, 5, 38, -20, -12, + 96, -45, 41, -19, 64, -39, -39, 33, -2, -3, -32, -47, -10, 45, -29, 53, + 32, -60, 33, -94, 37, -6, -55, 82, -46, 42, -11, 68, 1, 38, -55, 41, + -20, -30, 25, -20, 17, -29, 46, -102, 42, 40, -53, 6, 24, -36, -36, -3, + -31, 65, 5, -50, -4, 8, 23, 19, 20, -23, 47, -1, -48, 54, 30, -41, + 50, 52, -35, -41, 1, -26, -7, -30, 63, -49, 19, 27, -13, 82, -67, 56, + 7, 0, 64, -45, -25, 41, -68, -29, -46, 42, -43, 14, 37, 21, 15, -3, + 40, 39, 15, -91, 78, 35, -42, 49, 49, 28, 7, -18, 67, 40, -64, 44, + -38, -37, -61, 33, 47, -67, 38, -21, -11, -38, 11, 50, -44, 5, -32, 59, + -61, 58, 32, -75, 33, -56, 66, -16, -57, -15, -11, 69, -80, 62, 29, -3, + 45, 23, -37, 73, -80, 7, -13, -18, -3, 101, -76, 17, -35, 6, -21, 0, + -33, -13, -1, 31, -3, 46, -9, 32, -35, -21, 7, -60, 73, -62, 32, 25, + 32, 52, 7, 40, -45, -3, -48, 52, -39, -16, 6, -4, -20, 18, 25, 14, + -28, 7, 6, 31, 34, 28, -63, 58, 31, 43, -65, 49, 34, -5, 7, 33, + 11, 20, 10, 31, 2, 35, 12, 4, 1, 54, -33, 0, 2, 65, -96, 41, + -72, 44, 10, -27, -33, 34, -39, 5, 5, -42, -46, -10, 41, 27, -77, 44, + 2, 28, -11, -49, 23, -20, -47, 4, 1, -11, -23, 32, -57, 23, 7, 9, + -73, 46, -26, -3, -6, -4, 61, -49, 31, 46, 3, 11, 6, 20, -22, -11, + -17, 35, -38, 85, -79, 53, -18, -43, 47, 6, -50, -51, -14, 1, -24, -4, + -22, 45, -49, -4, -22, 85, -65, 72, -7, 1, -22, 15, -10, 28, 25, 36, + -2, -43, 34, 20, -52, 65, -8, 30, 0, 83, -52, -26, 15, -46, -6, 68, + -89, -19, 54, -14, 9, -11, 0, -32, 22, -10, 17, -32, -33, -32, 64, -43, + 23, 23, -92, 58, -4, 38, 32, -18, 55, 4, 2, -12, -81, 71, -45, -31, + 18, -43, -20, 97, -59, 27, -33, -26, -68, 46, -33, -4, -13, -60, 52, -76, + 74, 20, 55, -6, 3, 3, 40, -20, 20, 11, 29, -31, 19, -66, 27, 37, + -14, -91, 43, -14, 44, -50, -8, 0, 63, -15, 37, -73, 64, -21, -62, 23, + -30, -29, -30, 19, 33, -28, 16, -46, 37, -82, 19, 83, -50, -50, 66, -14, + -38, 44, -2, -13, 58, -48, -8, 18, 33, -38, 91, -8, 36, -32, -62, 60, + -76, -31, -6, 18, 40, -43, 97, -52, -2, 19, -25, -5, 30, -50, 2, 15, + -38, -25, 5, -40, -34, 19, 48, -56, -76, 38, -7, 23, -89, 40, 15, -32, + -26, 29, -46, 38, 6, -31, -46, 33, -22, -11, -31, -50, -4, -30, 30, -8, + 56, -68, 48, -56, 66, -6, -12, -41, 17, 42, 41, -13, -14, -25, 39, 11, + -33, -47, 21, 49, -68, 49, 14, 49, -60, 50, 27, 10, -7, -1, -8, -43, + 21, 45, -68, 22, 12, -24, 33, -39, -46, -21, 2, -5, 52, -47, -6, -30, + -10, 42, 38, -46, 23, -1, -37, 72, -55, 66, -2, 52, -15, 39, 15, 48, + 6, 49, 1, -10, -12, -58, 5, -22, -8, 6, 36, -17, -40, -30, 0, 8, + -47, 67, -61, 76, -50, -31, 5, 2, -36, -50, -20, 16, 36, 62, -38, -19, + 45, 15, 34, -64, 93, -67, 24, -23, 53, -45, 71, -62, 40, 10, -19, 46, + -55, 11, 36, -38, 35, -86, 12, 24, -81, 68, -54, 60, 21, -26, 4, 9, + -9, -20, 43, -62, 19, -32, 61, -37, 22, -1, -6, -4, -13, 34, 29, -18, + -18, -44, 0, -74, 15, -45, 16, 20, -33, -59, 15, 20, -39, 93, -72, 47, + -64, 83, 15, -23, -52, 44, 0, 33, -49, 26, 16, -6, -37, 29, 34, 47, + -28, -26, 24, 12, -11, 19, -25, 17, -14, 54, -27, -76, 55, 0, 34, -72, + 50, 15, -26, 28, -28, -47, 39, 13, 35, -12, -56, 5, -34, 32, 77, -69, + 71, -15, 59, -31, -29, -1, -75, 84, -35, -1, 63, -38, -17, 70, -76, 60, + -2, 19, 36, -65, 39, -32, 15, -34, 33, 19, -35, 54, -7, -11, -24, 39, + -37, 4, -28, -1, -2, -34, -6, 29, 25, -29, 54, 32, 38, 33, 3, -6, + -10, 0, 36, -48, 43, -19, 14, 31, -28, -46, 17, 26, -34, 67, -39, 30, + -40, 39, -38, 32, 23, -9, -5, -49, 42, -12, -83, 50, -51, 55, -50, 78, + -45, 11, 45, -22, -7, 10, -51, 34, 25, 36, 3, -34, -1, 29, 15, 23, + 4, -39, -37, 60, -34, 67, -54, -5, -19, -27, -35, 34, -50, -7, -26, -25, + -33, -31, 5, 0, 40, 56, -25, 5, -12, 44, -41, 53, 42, -17, 54, -44, + 34, -61, -20, -62, 103, -38, 36, -39, -9, 33, 29, -36, -32, -54, 41, 3, + 13, -6, -24, 21, -46, 36, 23, -3, -7, -19, 27, -12, 26, -30, 21, -36, + -5, 16, -37, -29, 7, 59, -32, 61, 0, -32, -38, 33, -39, 85, -71, 83, + -32, 5, -23, 59, -52, 10, -46, 35, 13, 53, -68, 25, -42, 14, 10, 21, + -49, 85, 17, 12, 43, -21, 49, -17, -6, 70, -78, 63, 47, -88, 86, -36, + 49, -73, 47, 25, 40, -22, 3, -7, -37, -35, 44, -49, 81, -11, -58, -40, + 6, 48, 34, -39, 0, 16, 0, 51, -2, 8, 60, -19, 18, 0, 3, 36, + -53, 54, -35, 17, 49, 24, -61, -11, -71, 72, 1, -52, 0, 7, -73, 55, + -47, 63, -91, 57, -19, 39, 41, -57, 20, -1, 15, -2, -21, -50, 65, -60, + 67, -106, 62, 35, 29, -74, 80, 5, 40, -29, 62, -81, 39, 45, -61, -29, + 76, -20, 0, 1, 48, 28, 5, -33, 1, -41, 24, -33, -25, -36, 15, -24, + 2, 29, -28, -21, 28, -24, -21, 30, 47, -27, -39, 24, 70, -71, -32, 73, + 9, 0, 3, -17, -72, 34, 8, -2, 61, -57, 102, -56, 38, 8, 14, -35, + -8, 50, 11, -7, -42, 88, -82, 96, -80, -27, 53, -56, -4, 23, 33, 16, + -35, -22, 60, -82, 80, -71, 9, 40, -7, 18, -10, 10, -34, 63, 4, 18, + 54, -3, 38, 24, -16, -77, 65, 1, -34, -4, -2, -18, -13, 11, -61, 9, + -18, 61, 35, 36, -43, -27, -23, 17, 24, -8, 15, 49, -1, 21, 0, -22, + -52, 4, -18, 23, 30, -51, 57, -17, 16, -6, -14, -31, 78, -63, 23, -49, + 58, -49, 59, 35, 1, -35, 25, -83, 54, -22, 67, -45, -25, -30, 30, -56, + 43, 2, 29, -62, 51, -17, 54, -3, -82, 54, -3, 15, 49, -43, -51, 38, + -14, -95, 20, 42, -33, 19, -62, -34, 60, 31, -19, -57, -24, 68, -57, -37, + -18, 63, -35, -58, 15, -54, -2, -26, 62, 63, -75, 88, -88, 2, 40, 2, + -6, 0, -56, 52, -63, -23, 43, -66, -12, -38, -59, 22, 40, -53, 52, -49, + -16, -48, -13, -1, -68, 17, 64, -64, 92, -75, 56, 59, -4, 37, -38, 45, + -58, 7, 9, -61, 74, -44, 4, 6, -14, 4, -52, -1, 53, 17, 27, -57, + 44, 37, -18, -62, 48, 3, -60, -10, 1, -38, -37, 47, -8, -8, 34, 65, + -44, -20, 0, -21, -34, 2, -25, 62, -53, 26, -43, 73, -50, 43, 41, -47, + 53, -18, -5, 39, 23, -15, -27, -12, -32, 24, 7, -22, -81, 109, -38, -21, + -55, -6, -18, -8, 60, 29, -14, -47, -17, 31, -81, 22, 17, -65, 43, 10, + 14, -71, -6, 0, 11, -41, 90, -105, 90, -25, -38, 94, -48, -9, -47, -57, + 41, -4, -8, 14, -61, 74, -6, 21, 16, 8, -22, -28, 39, -79, 50, -53, + -17, -63, -14, 17, 2, -11, 10, -44, -12, 70, -32, 42, -36, -20, 10, 32, + 44, -67, -25, -24, -38, 73, 31, -5, -10, -55, 69, -68, -4, 53, -48, 14, + 29, 34, -26, -32, -17, -36, -8, -33, 19, 11, -55, -14, -70, 11, 21, 36, + 18, -19, -48, 59, -50, -37, 38, 38, -27, 14, -5, 30, -20, 73, -59, -11, + 10, -25, -14, 33, -39, 68, -63, 0, 55, -46, -16, 13, 27, -27, 31, 20, + 19, 47, 21, -63, -22, 1, 63, 0, -44, -36, 50, 25, 16, -63, 44, 44, + -19, -35, 14, 34, -56, 59, 58, 18, -87, -18, 37, -91, 88, -66, 24, 26, + -41, 22, 75, -50, 85, -2, 31, -39, 77, 2, 64, -57, 6, 25, -59, 75, + 18, 51, 15, 52, 10, 13, 3, 41, -36, -24, 17, -89, -27, -25, 51, -41, + 58, -5, -2, 70, -57, 23, -18, -28, 58, 25, 6, 0, -46, 30, -22, -27, + -13, 4, 49, -68, -5, -19, 41, 19, 0, -11, 36, -2, -2, -2, -85, 21, + -39, 54, 0, -37, 69, 9, -10, 33, -37, 64, -42, 16, -3, -2, 15, -44, + 24, 27, -20, -91, 48, 6, 35, -8, 101, -27, -35, 28, 24, -52, -11, 37, + 28, 32, 33, 37, -28, -35, 1, 40, -42, 73, -15, 25, 4, -63, 71, -79, + 0, 82, -64, 23, 20, 24, -83, 55, 15, -32, 30, -13, -19, 20, 25, 68, + -41, 32, 18, -14, 55, -45, -9, -51, -37, 6, 38, -1, 3, 9, 17, -26, + 43, 12, 60, -23, -22, 24, 32, 27, 32, -46, -16, -60, 42, 32, 46, -72, + 12, 2, 64, -1, 52, -93, -16, 38, 19, -11, 8, -9, -23, -36, 25, 0, + 30, -47, 31, 72, -39, 30, 3, 49, 23, 15, 58, 34, 61, 12, 22, -33, + -24, 43, -26, -22, 50, 43, -58, 5, -67, 12, 24, -94, 66, -50, 42, 0, + 4, 10, -16, 45, -16, -47, 69, -34, -34, 21, 59, -75, 13, 41, 15, -75, + -2, 8, -14, 30, -9, 23, -72, 29, -23, 52, -4, -22, -22, -26, 15, 0, + 10, -28, -3, 52, 7, -33, -77, 42, 17, 50, -64, 39, 29, 11, -9, -1, + 31, -71, -35, -40, 26, -86, 32, -74, 38, -50, -50, 69, -25, -61, 54, -88, + 3, -23, -53, -46, 9, -35, -59, 0, -7, -31, 47, 49, 56, -3, -6, -18, + -3, 7, 22, -46, 31, -55, -14, 5, -66, -2, -6, 2, 35, -76, 49, -25, + 9, 24, -35, 51, 52, 0, 4, -63, 34, 11, -38, -12, 44, -22, 75, 21, + -36, -12, 35, 15, -2, -32, -29, 32, -12, -2, 11, -27, 45, -69, 46, -14, + -49, -16, -13, 102, -19, 17, -64, -22, -66, -45, -3, 42, -10, 10, 3, 9, + 26, -64, 4, -37, -29, 9, 26, 20, -33, -14, -48, 50, -38, 69, -49, 18, + 47, -43, 16, 31, -47, 16, 48, -47, 40, -25, -24, -39, 15, -3, 45, -56, + 35, -53, -24, 24, 12, -43, 20, 57, -13, 12, -37, 16, -15, 50, -30, 40, + -69, 43, -70, -10, -39, 46, -64, -12, 19, -27, 61, -21, 38, -40, -7, 8, + 11, 8, -65, -40, 35, 19, 53, -46, -4, 23, -54, 76, -32, 11, -22, 9, + -38, 23, 14, -41, -33, 49, 38, -69, -34, 24, -37, -32, -68, 11, -32, 45, + -26, 37, -57, 6, -11, -64, 59, 26, 18, 39, 4, 56, -17, -1, -2, 0, + 52, -76, 83, -71, -51, 96, -85, 12, 43, -16, -23, 69, -32, -44, 23, 4, + 18, 2, -52, -19, 22, 40, -18, -12, 68, -49, 14, -4, 14, 32, 35, -63, + 61, 45, -13, -85, 62, -1, 25, -17, 31, 51, -4, -26, -52, 39, 36, -57, + 18, 75, 18, -17, 24, 12, 37, -7, 76, -54, 100, -63, 45, 15, 8, 36, + 24, -49, 82, -20, 45, -32, 88, 14, -8, -19, 13, -16, -65, 16, -7, 42, + 8, -29, -30, -9, 46, 28, 54, 17, 65, 54, -71, 45, 1, 58, 13, 25, + -58, 71, -65, 48, -41, -34, -2, 44, -27, -21, -15, 2, -8, 25, -52, -75, + 59, -19, -48, 43, -21, -26, 35, -50, 76, -5, -77, 51, -46, 68, -56, 26, + 70, -23, 7, -68, -34, 32, 23, 6, 56, 33, 42, -32, 44, -44, 2, -9, + -21, 45, -34, 11, 39, -6, -24, 36, -47, 37, -15, 14, -3, 21, -28, -33, + 24, 5, -21, -40, 15, -68, 21, -40, -56, 33, 3, 37, 34, -68, -13, -63, + 46, 11, 9, 5, -55, 74, -41, -39, 7, 22, 28, 44, -27, -64, -15, -23, + 37, 1, 7, 51, 29, -88, 74, 2, 16, 3, -23, -33, -20, 25, -26, -9, + -22, 51, 64, -20, 36, -80, 32, 17, -47, 34, -9, -9, 32, 9, 61, -17, + 8, -1, -32, 66, 2, -50, 42, -54, 63, -45, 26, -30, 49, 18, 31, -42, + 34, -14, 32, 8, 38, 9, -78, 77, -68, 17, -39, 35, -43, 4, -15, -6, + -10, 13, -31, 49, 56, -83, 96, -22, -40, -25, 41, -58, 2, 8, -42, 35, + 10, 26, 11, 61, -45, -1, 24, -3, -22, -20, -2, -5, -2, -20, -16, 53, + -68, -66, 44, 53, -99, 43, -41, -15, -33, -47, -24, 4, 9, -25, -29, -6, + -10, -42, -12, 17, 9, 62, -91, 90, -97, 4, -47, 12, 18, 44, -56, 8, + 30, -30, -1, 60, -79, 69, -57, -50, 80, -44, 24, -31, 67, -78, 66, -81, + -15, -43, 66, -33, -40, 33, -76, -3, -54, -43, 24, 37, -57, -60, 55, -59, + 0, -2, -32, -13, 8, -18, 32, -12, 49, -17, 55, -23, 9, 25, 8, 54, + 51, -63, 85, -49, -44, 72, -33, -31, -66, 29, 70, -61, 35, -6, 8, -21, + -38, 5, 0, 35, 63, -72, 83, -39, -23, -7, 7, -44, 37, -62, 69, -13, + -36, 26, 23, -11, 4, 34, -15, 3, 29, -39, 57, -26, -32, -17, 49, -7, + 63, -58, 89, 9, -20, 75, 18, 40, 53, -41, 51, -46, -9, 34, 49, 57, + -38, 8, -57, 63, -65, 42, -2, 79, -67, 9, -23, -36, 46, 70, 11, 41, + -54, 64, -53, -11, -3, 61, -34, -5, -20, -35, 55, 37, 29, -3, 63, -6, + -21, -56, -23, -24, 14, 47, -35, -50, 19, 0, 0, -18, 0, -21, -85, 50, + -56, 12, -30, 51, -73, 34, -44, 0, 20, -61, 14, 11, 31, -19, -23, -49, + 29, -9, -15, -22, -20, 1, 23, -54, 18, -30, 10, 25, -31, -2, 4, -9, + 26, 44, -56, 59, -57, -1, -66, 70, -33, 59, 21, -22, -31, 72, -59, 44, + -38, 0, -25, -42, -24, 79, -53, 35, -61, 64, -21, 17, -32, 66, -9, 36, + 3, 32, -14, -12, 47, 29, 33, -10, 50, 0, 20, 56, -31, 39, 27, 69, + -3, -3, -53, 39, -47, -24, 1, -65, 89, -10, 44, -39, -16, -72, 54, -14, + 17, -20, -33, 12, -68, 64, -74, 96, -52, 17, 14, 17, -20, 48, -10, 38, + 60, 28, 14, -4, -34, 53, 13, -26, 4, 80, -45, -17, 64, -43, -32, 53, + -7, 29, 0, 33, 11, -7, 23, -61, -54, 1, 11, -17, -34, 4, -21, -46, + -35, 62, -56, -1, 12, -5, -16, 92, 12, 7, -31, 15, 17, 29, -26, -14, + 22, -2, 37, -66, -35, 27, -50, -31, 43, 25, 18, -57, -1, 64, -75, 44, + 27, -21, -46, 32, -72, 9, -20, 45, -59, 91, -77, 70, 5, -9, -25, -31, + -41, -14, -22, -14, 12, -54, -21, -1, -58, 57, -30, 12, 33, -17, -65, -33, + 53, -36, 38, 12, 61, -79, 22, -91, 64, 6, -50, 57, -69, -57, 48, -50, + 2, -23, 0, 22, -12, 49, -83, 34, 48, 7, -59, -21, 20, -20, -73, 18, + -7, 59, 22, -3, 3, 27, -35, 45, 3, 11, 0, -1, 21, -1, 48, 12, + 27, -50, 35, -76, 98, -19, 22, 24, 23, 54, -20, 49, -72, 12, 6, 54, + -82, 91, -56, 64, 16, 11, 29, 33, -24, 9, -36, 32, -3, 45, 15, -5, + -34, -13, 10, -61, 30, 49, 27, -17, 33, -63, -28, 63, -7, 11, 7, -10, + -2, 28, 8, 26, -12, -14, -17, 7, 12, -14, 1, -18, -9, -78, 2, -44, + -32, 56, -44, 32, 11, -56, -22, -2, -36, 43, -77, 30, -55, 5, -32, -74, + -13, 51, -1, 34, -31, 60, -46, 94, -67, 32, -66, 4, 18, 23, -24, 23, + -48, 66, -11, 39, 26, 42, -8, -54, 46, -44, -7, 30, -67, -54, 44, -13, + -61, 22, -55, 9, 8, 8, -40, 55, -31, 15, -47, 35, 17, -6, 30, -29, + -5, -16, -25, -4, -4, 1, -28, 67, 51, -53, 46, 40, -56, 41, -25, 28, + 7, -16, 23, 18, 17, 24, 6, -66, -35, -8, 58, -38, -65, 19, -6, 24, + -53, 44, 15, 10, 18, -7, 17, 3, 18, -31, -50, 101, -65, 19, -14, -5, + -77, 77, -6, -66, 58, 41, -47, -31, 32, -49, -11, -38, 30, 62, -70, 77, + 43, -52, 23, -39, 1, 64, 27, -32, -30, 74, -68, -1, -8, -10, 80, 0, + -2, -24, 6, -33, -45, 61, -28, 28, 7, 20, -42, 13, 18, -11, 37, -5, + 18, -36, 15, 36, -69, -39, 94, -45, -30, -28, 30, 29, -14, 6, -6, 41, + 43, -71, -22, -35, 31, -28, 56, 6, -9, -43, -3, 40, -13, -21, -27, 46, + -39, 66, -7, 19, -46, -6, -6, -57, -1, -47, -25, -39, 56, -8, -67, 45, + 21, -22, -15, -39, 65, -51, -20, -3, -1, 37, -49, 22, 0, -49, 1, -29, + 26, -40, 20, 5, 28, -78, 46, -35, -16, 55, -19, -48, -15, 24, -63, 45, + 10, -44, -24, 31, -5, 27, -33, 26, 46, -52, 16, 34, 0, 82, 2, 89, + -53, -36, -11, 27, -50, -15, 58, -13, -18, -13, 35, -24, 61, 39, -14, 99, + -41, 31, -21, 20, -59, 57, 6, -23, -59, 63, 36, -5, 38, -23, 18, 46, + -5, -55, 14, -1, -49, 17, -50, 41, -68, 61, 25, 30, 59, -12, 58, -50, + -17, 14, 62, -18, 9, -12, 13, 0, -22, -9, -37, 47, -11, 11, 36, -48, + 64, -16, 48, -12, -57, 57, 20, -61, 51, 10, -61, 24, 60, 14, 24, -67, + -4, 1, -22, 31, -25, 21, -53, 52, 43, -55, 43, -35, 53, 12, 10, 40, + -26, -44, 57, -35, -10, 12, 0, -20, -24, 0, 60, -65, 19, 41, -43, 88, + -34, 9, 10, 51, -37, 23, 31, 21, -32, 24, 34, 84, -67, -21, 56, -36, + -4, 23, -3, 76, -23, -29, -27, 35, 30, -97, 101, -43, 70, -30, -74, 63, + -85, 52, 22, -17, 41, -41, 15, -7, 13, -11, 18, 38, 26, -21, -30, 31, + -53, 62, -20, -4, 62, 8, -64, 26, 44, -65, 40, -28, -24, 70, -18, -51, + 32, -25, 63, -2, 4, 10, -59, 17, -61, 91, -60, 37, -30, 14, -42, -16, + -31, -29, 22, -25, -37, 62, 41, 34, 27, 58, 9, -27, 26, 23, 11, 31, + -74, 45, -34, 58, -80, 39, -29, -8, -8, -25, 43, -29, 24, 40, 45, -66, + 16, 43, -29, -6, 4, -16, -3, 36, -32, 33, 23, 67, -16, -26, 19, -16, + 40, 62, -65, 55, -48, 6, -26, 23, -28, 86, -38, -39, 58, -65, -7, -55, + 46, -12, 53, -45, 68, -25, 23, 58, -47, 22, 10, -2, -72, 14, -29, -64, + 1, -57, 59, -6, 41, -63, -8, -48, 85, -56, -55, 58, -50, -3, -16, -67, + 79, -24, -9, 15, 19, -14, 39, 24, -33, 6, -42, -5, -47, -8, -40, 22, + 38, -16, -40, -13, -14, -29, -1, -7, 9, 47, -46, 62, -53, -30, 55, -74, + 9, -32, 47, -81, 91, -46, 10, -43, -61, 60, -19, -45, -72, 8, 10, 47, + 26, 25, -27, -39, 66, -30, 10, -24, 32, -14, -52, 37, 12, -30, -52, -4, + 4, 54, -52, 34, -45, 51, -18, -8, 20, 21, -35, 55, -39, -58, 59, -52, + 14, 28, -55, 33, -42, 50, -53, -34, -5, -13, -53, -77, 54, -37, -9, -71, + 53, -15, 23, -63, 49, -59, 19, -58, 19, 80, -65, -8, -77, 67, -16, 37, + 14, -5, -44, 46, -25, 10, 48, -26, 36, -64, 30, -47, -70, 78, -21, -53, + 2, 23, -19, -67, 19, 24, -23, 18, 15, 0, 22, 39, -28, -33, 5, 14, + 27, -73, 42, -37, 7, -17, 41, -35, 15, -28, 20, 13, -46, 65, 16, 39, + 34, 31, 23, 27, 20, -74, -20, -61, 18, -34, -46, 50, -32, -16, 2, -36, + 49, -49, 25, -47, 77, -42, 26, -41, 70, -47, 36, 45, -81, -7, 9, 45, + -41, 7, -24, 55, -3, 30, -41, -1, -40, -13, -49, -34, 33, 35, 24, -12, + -76, -43, 34, 32, 20, -21, -9, -7, 11, -61, 6, -2, 25, -35, -43, 80, + -3, -15, 33, -5, -6, -41, 22, -49, -27, 37, -13, 40, 6, -11, -5, 31, + 5, 66, -43, -5, -24, 47, 13, 18, -16, 13, 50, -84, 30, 57, -34, 3, + 17, -72, 55, 38, -78, 49, -42, 2, -12, 42, -33, -22, 0, 26, 65, -68, + 30, -17, -5, 28, 23, 68, -10, -28, 41, -60, 1, -17, -27, 0, 7, 19, + -3, 5, -5, 40, -72, 21, 33, 17, 39, -58, 16, 58, 64, -17, -69, -14, + -17, -14, -5, -23, -46, 0, 12, -56, 21, 49, -7, 49, -8, -32, 77, -86, + 69, -73, 64, -73, 55, -43, 46, -44, 24, -1, -4, -13, 78, 19, -42, 40, + 56, -27, 43, -35, -10, 0, -38, 108, -16, 22, 49, 74, -82, 24, 12, 46, + -8, 9, -47, 54, -69, 66, 33, 26, 5, -36, 12, 22, 43, 0, -56, 24, + -60, 63, 39, -33, 0, -28, -22, -1, 18, -37, -13, 26, 56, -72, 50, 26, + 28, 40, -53, 58, 45, -77, 50, -24, 16, -79, 58, -86, 66, -54, 45, -3, + 38, 11, -48, -37, 58, -24, 41, 7, 46, -13, -23, -3, 42, -41, -47, 0, + -73, -9, 4, -51, 4, 94, -13, 90, -71, 56, -53, 52, -19, 57, 24, -2, + 0, 28, 20, -3, -29, 32, 22, 71, -75, 3, -23, 28, -5, 36, -29, -15, + 44, 13, -8, -38, -9, 36, -51, 57, 7, 1, 3, 61, -63, -41, -44, 37, + 43, 51, -70, -37, -38, 51, -38, 30, -44, 51, -20, 15, -21, 17, 57, -69, + 2, -13, 24, -69, 34, -58, 56, 38, 0, 0, 1, -2, 11, 54, -24, 26, + -1, -67, 59, -56, -4, -72, 31, -55, 5, 17, -17, 54, -23, 25, -60, 78, + -84, 104, -84, -22, 66, -58, 15, -32, -3, 38, 64, -45, 64, -31, -72, 35, + 39, -74, 43, 61, -87, -12, -33, 58, -57, 69, 0, 61, -16, 21, 32, 0, + -15, 74, -51, -6, 78, -47, 23, -25, -35, 23, 27, -28, -69, 55, 42, 13, + 40, -3, 5, 54, 46, 45, 20, -43, 37, -43, -62, 3, -58, 100, -96, 57, + 49, -18, -40, 66, -47, 50, -48, 50, 5, -12, -40, 38, -65, -38, 49, -69, + 26, -56, 67, 0, -33, 16, 43, -61, -57, 48, -2, -54, 70, 2, 42, -19, + 43, -35, 25, 4, -19, 39, -85, 55, -82, 19, 22, -40, -38, 74, -66, 66, + -43, -28, -2, -19, 43, -42, -8, 20, 16, 15, 31, 12, -41, 78, -35, -31, + -60, 22, 19, -41, -18, 43, -81, 43, -33, 49, 34, 4, 23, -34, -3, 7, + -61, 60, 13, 78, -73, -35, 33, -72, -73, 29, 19, -25, 17, -40, 48, 24, + 74, -17, -46, 32, -41, -41, -24, -55, 63, -91, 41, -11, -21, -21, -69, 15, + -56, 40, -40, -1, -9, -35, 1, -68, 71, -54, 19, -12, -35, -12, 23, -16, + 34, -38, 14, 31, 1, 24, 31, 0, -52, 18, 48, -70, 78, 56, 10, -37, + 30, -6, -13, 67, 28, 58, -67, 79, -71, 48, -13, 11, -58, 44, -30, 45, + -21, 3, -4, 71, -15, 11, -31, -8, -31, -36, 23, -19, -3, -45, 31, -58, + 59, 15, 21, 25, 30, 56, -32, 68, -3, 34, -30, -2, 5, -41, 11, 19, + 4, -82, 54, 24, -12, 2, 0, 53, 22, -35, -61, 69, -48, 10, 78, -55, + -9, 64, -64, -39, 53, 41, -5, -2, -4, 17, -32, -50, 30, 5, -59, -19, + 53, -66, -16, 14, -41, 42, -51, 54, 34, -25, 28, -38, -7, 8, -51, 0, + -17, -39, 52, -62, -35, -52, -1, -13, 43, 0, 42, 12, 12, -90, 93, -40, + -50, -27, 47, -42, 23, 42, -46, 16, 0, -47, 39, -28, 69, -29, -6, -24, + 21, -15, -42, 16, -7, 46, -49, 18, 49, -41, -1, -2, -39, -50, -6, -37, + 1, -25, 18, -47, -37, 35, 6, -34, 81, -22, -54, 49, 20, -33, 23, 28, + 6, -42, 59, -89, 70, 28, -12, -16, 21, -33, 47, -78, 52, -54, -21, 89, + -42, 68, -55, 27, 45, 12, 38, 23, -42, -51, -20, -11, -18, -21, 8, 42, + -29, -65, 55, -103, 103, -26, 34, 53, 60, -28, 34, -27, 57, -55, 26, -29, + -49, 31, 20, 52, -19, 39, 22, 9, 23, 59, 69, -31, -12, 15, 77, -57, + 41, 40, -27, 41, -20, -6, 39, -31, 67, 1, 12, 14, 57, 5, -39, -31, + -53, 41, 19, -55, -17, -27, 52, -29, 3, 57, -35, 6, -31, -68, 31, -43, + -52, 69, 17, -48, -37, -38, 10, -65, 88, -35, -41, 46, 20, -44, 50, 28, + -72, 49, -55, 12, -47, 64, 4, 2, 34, 28, 20, -28, -30, 37, -9, -27, + -31, 43, -47, 12, -52, 26, 30, -37, -52, 60, -55, 48, 68, -60, 6, 26, + 7, 60, -23, 28, 25, -45, -13, 15, -45, -20, 62, -48, 12, 40, -95, 54, + -4, -10, -3, 85, -49, -34, -29, -26, 50, -15, -44, 65, -54, 23, 66, -49, + 22, -30, 76, -57, 27, -37, 32, -39, -28, 5, 4, 49, -58, 55, 2, 55, + -59, 57, -5, 34, -59, 75, -5, 58, -81, 45, -14, -16, 41, 18, 4, -38, + 64, -21, 8, -17, 20, -59, 81, -73, 43, -18, 38, 49, -61, 0, 33, -30, + -21, -25, 57, 1, -18, 29, -8, -17, 5, -17, -18, -13, 36, 18, 20, 26, + -23, -41, 70, 51, -30, 28, -2, 59, -82, 49, 44, -20, -47, -12, 15, -5, + 20, 22, -49, 97, -86, 11, -10, 34, 11, 13, -43, 52, -39, 72, -19, -42, + 43, -38, -20, -29, -46, -84, 71, -62, 66, 29, -8, 46, 47, -32, 10, 0, + 19, 21, -20, 61, -31, -35, 28, -89, -3, 12, 3, 25, -51, 78, -41, 16, + -15, -6, -12, -36, 11, -5, -8, -30, -33, -62, -38, -22, -22, -9, -24, 54, + -42, -42, 25, -11, 28, -11, 33, -42, -44, -38, 48, -16, -41, -56, 96, -1, + 41, -14, 1, 48, 61, -36, -35, -10, 5, -47, -26, 16, 16, 57, -46, 71, + -21, -40, -9, 41, -16, 66, 22, 27, -38, 49, -50, 19, 52, -46, -42, 5, + 0, 45, -18, 33, -52, 11, 12, -52, -17, -18, 37, -23, 44, -48, -53, 84, + -27, 8, -16, 10, -8, -4, -69, 58, -26, -18, 9, -64, -46, 25, 1, 22, + -18, -44, -16, -36, -7, 24, 12, -40, 23, 4, -7, -39, 2, -27, 89, -40, + 35, 13, -20, -72, 64, -23, 58, 25, -7, -31, 63, -35, 34, -32, -8, -15, + 3, 30, -23, 51, 6, -40, 42, 50, 4, -22, -48, 31, 38, -58, -1, -23, + 17, 14, 9, -56, 80, -75, 44, -66, 33, -23, 33, 0, -37, -10, 21, -22, + 21, 44, -19, -40, 69, -52, -11, 5, -7, 0, -13, -67, 13, 57, -34, 59, + -23, 73, -58, 22, -30, -42, 22, 35, 26, 32, -29, 47, 10, 7, -69, 47, + -2, 30, -45, -27, 6, -36, 59, -94, 75, -62, -33, -12, 93, -1, -20, 0, + -37, 16, -38, 11, 0, 27, -32, -30, -10, 2, -25, 15, -54, -2, -26, 18, + 33, -46, 90, -12, 62, 49, -46, 20, -67, -8, 68, -110, 71, -55, 36, -33, + 7, -14, 46, -68, 24, -17, 1, 45, 21, 8, -67, 26, 42, -40, -15, 0, + 9, -31, 55, -9, -26, -30, 82, -42, 47, 56, -38, 40, 42, 10, 48, -16, + -21, 59, -19, 16, -60, -10, -3, 23, 23, 27, -4, 4, 43, 33, -56, 17, + -23, -28, 43, -71, -34, 24, 24, -24, -10, 28, 46, -32, -24, 19, 1, -25, + 8, -5, -33, 17, -38, -8, -22, -35, -11, 32, 25, -60, 1, 28, -8, 0, + 34, -65, 74, -64, 58, -39, -47, 79, 24, 54, -55, -35, 9, 44, 41, -37, + -20, -51, 86, -21, 42, -28, 7, 52, -27, -26, 50, 6, 70, -21, -16, 1, + 4, -36, 34, 59, -45, 39, 43, -64, 97, -49, 16, 43, 58, -52, -80, 99, + -48, -54, 14, 57, -20, -46, 17, -20, -48, 49, -78, 48, 13, -26, 29, -40, + -18, -4, -34, 18, -18, -29, 24, -14, -53, 96, -63, 79, -69, -4, 78, -43, + -39, -4, -50, 37, -17, 5, 11, 36, -46, 66, 12, -54, 1, -18, -37, 20, + 5, -6, -47, 89, -46, 78, -18, 4, 27, -21, -17, 68, -18, -30, -44, 32, + 19, -66, -1, -25, 74, -59, 72, -81, -15, 20, -37, -18, 38, -45, 73, -56, + 37, -41, -26, 54, 33, 6, -35, 1, 2, 35, 10, 4, -71, 29, -42, 61, + 29, 22, -34, 9, -27, 36, -11, 37, -40, 47, -9, -35, 99, -32, 2, 0, + -44, 30, -9, -46, -69, 16, -13, 45, 24, -19, -5, 22, -2, 5, -10, -12, + 57, -61, 28, 9, -16, 23, -22, 24, -60, -4, 63, -59, 23, -31, 23, 21, + 46, -55, 92, -91, 68, 0, -55, 14, 9, -56, 76, -67, 32, -51, 1, -21, + -1, -47, 32, 4, 80, -56, -16, 42, -4, -55, -36, -9, -25, 40, -37, -3, + -37, -12, -32, 61, 31, -33, -9, 1, 52, -35, 16, -24, 32, -46, 32, 53, + 14, 29, 33, 1, 32, 44, -16, 13, -44, 7, -16, 2, -2, 9, 22, -17, + 58, -73, -14, 14, -38, 31, 53, -93, -57, 9, -6, 34, 64, -81, 26, 2, + 42, -10, -61, 6, -35, 17, 36, -44, 2, 1, 13, 15, -54, 10, -59, 79, + -37, 28, -6, 15, -35, -5, -13, 3, -21, -24, -29, -31, -34, 59, 40, -85, + -2, 76, -16, -15, 2, -3, 6, -5, 61, -42, -12, 45, -5, -43, 27, 13, + 54, -5, 12, -49, 93, -77, 25, -30, -26, 20, -34, -30, 63, -49, -26, 48, + 24, 60, -18, -1, -36, 37, 49, -65, 0, -22, -49, 63, -9, 45, 16, -20, + 6, -40, 20, -40, -14, -59, -5, -50, 40, 3, 15, -28, 19, 55, -37, -14, + 38, 7, 73, -61, -14, 57, -64, 86, -58, -13, 11, 0, -35, -32, 33, -3, + -7, -29, 57, -36, -23, -37, 20, 41, 36, -28, -11, 22, -32, 48, -28, -51, + -23, -45, -19, 37, 54, -17, -4, 16, 58, -53, 21, -16, -20, -41, 50, 28, + -8, 17, -30, 43, 45, 20, 9, 13, -19, -30, -28, -27, 52, -58, 22, -26, + -26, 29, 46, -49, -14, 0, -25, -7, 48, -12, 7, -44, 65, -56, 57, -58, + 62, -54, -38, 36, 26, 26, -4, -46, 71, -41, 0, 16, 4, -42, 38, 12, + 31, 8, 30, -55, -52, 99, -46, 30, -29, 53, 45, -3, -51, 33, -8, 36, + 8, 19, 10, 8, -49, 28, 26, -14, -41, -13, 36, 4, -21, 28, -36, -35, + -30, -42, -30, -16, -36, -10, 33, -10, -15, 28, 50, -16, -9, 15, -16, -21, + -22, 59, 19, 19, 28, -26, 41, 45, 32, 11, -18, -32, -55, 40, -25, -15, + 34, 7, 1, 74, -28, -15, -3, 47, -64, 54, -67, 33, -19, 22, 26, -21, + -18, -17, 5, -50, 84, -47, 56, 11, -31, 8, 86, 4, -31, -12, 8, 93, + -66, -51, 64, -37, 29, 1, 38, 29, -74, 105, -45, -22, -11, 57, 7, 30, + -48, -54, 80, -64, -34, 61, 20, 14, -10, 43, 42, 10, -41, 29, 11, -43, + 39, -64, 8, -30, 38, -9, -89, 65, -15, 7, -39, 50, -81, 39, -20, 6, + -36, 42, -1, 18, 25, -1, 59, 68, -70, 37, -22, 27, -34, 19, 6, 55, + -42, -15, -39, 67, 9, -42, 71, -67, 51, 31, 11, 4, 35, 9, -55, 63, + -52, 41, -58, 70, -29, 19, 35, -44, -37, -37, 42, -43, 43, -16, -23, 43, + 36, 30, 41, -26, -85, 23, -30, 24, -42, -12, 36, -60, 52, 36, -58, -26, + 12, 26, -63, 46, -110, 82, -62, 1, -49, 91, -22, 65, -63, 45, 37, -53, + 8, -22, -18, -9, 37, 50, -14, -29, -38, 47, -25, -18, -1, 3, -10, -11, + -27, 58, -23, -28, 10, -51, 18, 30, -102, 61, -8, -34, 50, -42, 8, -44, + 19, -90, 58, 20, -21, -61, 59, -70, 63, -70, 14, -16, 43, -56, 50, 9, + -2, 41, -44, -44, 56, -36, 45, -80, 52, -5, 0, -6, 39, -72, 71, -13, + -7, 58, 43, -14, -21, 43, -24, 65, 36, -75, -8, 16, 0, 11, 40, -33, + -10, 11, -29, -17, 0, -12, -23, -63, 23, 17, 23, -3, 64, -21, 45, -62, + -17, 21, -23, -16, -39, 44, -9, -58, 107, -91, 69, -35, 15, -29, -5, 41, + 24, 35, -38, 28, -39, -7, -37, 47, -15, -19, -21, -61, 59, -39, -12, -65, + 84, -12, 0, -18, 14, -60, -6, -12, -10, -66, 46, -2, 6, -50, 16, -37, + 56, -4, -5, 29, 60, -78, 61, -61, 5, -32, -15, -31, 40, -9, -29, 25, + -73, 67, 45, -2, 44, -55, 48, 18, -25, 36, -8, 11, 17, 7, 35, 2, + -29, 18, 16, -43, 37, -36, -26, -51, 51, 17, -17, -4, -13, -7, 5, -65, + -17, -5, 22, -97, 29, 9, -62, 11, -44, -10, 10, 38, -34, 57, -26, 34, + -16, 27, 51, -29, 0, -42, -19, 47, 7, -13, 44, -18, 8, -5, 7, 62, + -79, 9, -58, 52, 91, -93, 93, -48, 26, 45, -81, 78, 3, -10, 51, -7, + -14, -1, 24, 17, 66, -61, 39, -10, 16, -65, 39, -72, 71, -7, -61, 46, + 63, -16, 18, 54, -64, 15, -62, 91, 5, -44, 78, -22, 44, -7, 38, -7, + -29, 27, -66, 60, -16, 48, -78, 43, 37, 37, -61, 59, -10, 3, 47, -7, + 42, 30, -12, -24, 9, 55, -61, 44, 26, -42, 7, 35, 37, -28, -67, 30, + -6, -55, 25, 45, 4, 11, 29, 17, 40, -42, 16, -42, 33, -13, 15, 24, + -39, -41, 30, -1, -17, -28, 19, -84, -10, 47, 57, -37, -42, -18, -68, 44, + -10, 27, 34, -37, 3, -21, 55, -27, 24, -47, 0, -35, 9, -58, 41, 27, + 8, 18, -55, 25, 57, -10, 31, -22, -23, 51, -28, -3, 42, -1, -12, -67, + 38, 0, -39, 19, -68, 71, -7, 13, -5, -31, 55, 35, -27, 31, 34, -14, + -13, 24, 24, -24, -1, 30, 12, 38, -58, 90, -66, 87, -53, 13, -42, -30, + 42, -54, -3, 37, -46, -12, -3, 9, 8, 19, 20, -23, -54, 84, -44, 33, + 54, -62, -24, -50, 0, 15, 21, 3, 10, -41, 29, 15, -27, 4, 20, -48, + 89, -25, -22, -21, 33, 22, 23, -31, -25, -25, 1, -8, -37, -13, 51, 57, + -33, 58, 32, 52, -13, 15, 24, -50, 79, -53, 41, -24, -63, -9, 28, -72, + 28, -12, -68, -4, -40, 49, -4, -34, 53, -1, -40, 12, 52, -25, 33, -51, + 6, 33, -9, -39, -45, 67, -54, 5, -52, 46, 43, -46, 10, -19, -22, -25, + 73, -30, 10, -47, -38, -33, 29, -44, 43, 48, 10, 20, -42, -28, 55, 24, + -52, -57, 40, -68, 48, 18, 34, -96, 60, -21, -38, -29, 24, -40, -12, -10, + 30, -67, 56, 21, -37, -37, 35, 27, -65, 18, -21, -5, -43, 8, -11, -33, + 20, -67, 32, 9, -39, 0, 10, 22, 8, 34, -70, 10, -63, 18, 72, 4, + -27, 36, -14, 0, -64, 3, -12, -38, 0, -51, 64, -22, 0, -52, 57, -77, + 26, 24, 0, 13, -6, 17, -28, 105, -72, -3, -18, -52, 84, -7, 80, -16, + -37, 2, -45, -11, 83, 1, -4, -28, 24, -17, 69, -47, 52, 46, -28, -25, + -19, 21, 10, -1, -61, -41, 49, -46, 60, -70, 7, 0, -14, -14, -37, 43, + 38, -51, 68, 10, 53, -41, 43, -19, -45, 51, -55, 29, -24, 7, -25, -41, + 41, -68, 35, 40, -50, 18, -67, 66, 15, -32, 5, -59, 29, -7, 87, -42, + 14, 14, 24, -40, -8, 43, -3, -31, 43, -61, 5, -3, 57, -35, -13, -37, + -13, 2, -12, 34, 23, -59, 12, -35, 17, -55, 18, -66, 18, 1, -1, -19, + -31, -14, 5, 34, -53, -65, 73, 46, -17, 25, -43, 57, 17, 9, -39, -34, + 18, -29, -75, -11, 8, -6, 67, -38, 44, 12, -27, -13, 88, -17, 5, -12, + 40, 37, 40, 44, 30, 8, 33, -22, -56, 12, 28, 17, -69, 0, -59, 58, + -6, -38, 29, -57, 50, -35, -31, 64, -36, 27, -57, -8, -21, 11, 5, -48, + 24, -71, 64, -12, 84, -9, 30, -52, -21, -52, 25, -25, 25, 69, -30, -39, + -34, 106, -71, 85, -27, -6, 6, 41, -43, 29, 15, 6, -50, 48, -15, 38, + 38, 15, -45, 58, -58, 54, 24, -6, -11, 38, 19, 39, 34, 9, -45, 64, + -22, 18, 6, 43, -59, 34, -21, -5, -41, 31, 41, -19, 39, -35, -61, -10, + 33, 2, -18, 46, -19, 25, 0, 67, -15, -3, -6, 46, -3, 43, -20, 61, + -43, -7, 10, -14, -5, -34, 42, -66, 58, -41, 52, 0, 18, -55, -28, 23, + 21, 14, 42, -34, -32, -59, 67, -26, 8, 24, -8, -38, 3, -27, -31, 23, + -3, 13, 38, 20, 46, 22, -78, 69, -93, 102, -51, 26, 43, -10, 19, 27, + -68, -43, 33, -48, -60, 40, -1, 7, -31, 50, 1, -21, 47, 34, -32, 50, + 8, -25, -1, -49, 50, 17, 2, -61, 11, -19, 62, -4, 19, -21, -63, 43, + -54, 34, 41, -15, 16, -26, 39, 10, -34, 48, -10, -24, -23, 24, 63, 19, + 61, -10, -22, 4, 34, -33, 55, -18, 46, 1, 55, -9, 62, -89, 21, -38, + 58, -46, 47, -29, 61, 23, -71, -18, -22, -3, -5, -17, 43, -12, -14, 41, + 16, 16, 26, 53, -47, 11, -29, -45, -7, -49, 48, -12, -67, 55, 20, -43, + -9, -40, -9, -86, 59, -30, -26, -28, 42, -11, 0, -10, 79, -59, 43, 17, + 22, -33, 16, 60, 12, 41, 50, -63, -39, 38, 18, -3, 2, 68, -52, 61, + -53, 37, 33, -27, -60, 70, -59, 57, 0, 86, -18, 18, -54, -46, -21, 69, + 9, -76, 61, -40, -62, 58, -16, -35, -3, 32, -54, 33, 24, -3, 21, -84, + -1, 2, -22, 17, 7, -16, 1, -52, 28, -80, 19, -27, -33, -31, 15, 11, + -40, -48, 75, -81, 77, -42, -20, 16, -36, 30, -53, 64, -40, 54, 35, 33, + -13, -44, -15, 29, 28, -45, -22, -32, -34, 28, 17, -66, 35, -65, 53, 11, + -35, 28, 32, -20, -2, -52, 22, -6, 13, 35, -10, -60, 62, 25, -43, -14, + -3, -13, -13, 4, 45, -2, -29, 37, -64, -9, -52, 59, -6, -53, 21, 12, + 26, -36, -32, -38, -33, 12, 57, -41, 70, -60, -1, 25, 2, -3, -39, -25, + 96, 5, 18, 0, 70, -54, -53, 60, -4, -36, -2, 49, -41, -67, 65, -72, + -10, 61, -35, 60, 18, -49, -24, 29, -8, -2, -33, -45, 75, -18, 6, 28, + 45, -58, -33, 9, -52, 12, -8, 7, 30, -67, -1, 87, -38, -26, -87, 38, + -90, 11, 0, 34, -10, 43, -33, -22, -5, 16, -27, -27, 27, 60, -15, 42, + 27, 8, 0, -22, -38, 38, 58, -71, 87, -50, 93, -61, 42, -60, 49, -10, + 33, -12, 1, -24, -24, 33, -22, 48, -18, 52, -53, -13, 38, -1, -43, 40, + -22, 29, 19, 3, -17, 3, 28, -5, 56, -21, 10, -12, 18, 18, -27, -35, + 40, 0, 5, -81, 8, -84, 30, 15, 68, -48, -22, 5, 10, -64, 41, -24, + 18, -4, -49, 11, -26, 9, -9, 56, -59, -61, -18, 29, -5, 26, 52, -65, + -4, 37, -42, 29, 18, -40, 20, -4, -26, 30, 23, 54, -64, 55, -13, 61, + -26, 51, -45, 20, -30, 30, 6, 0, -9, 66, -68, 82, 13, 2, -23, 35, + 19, 29, -25, -22, 21, 46, 31, -32, 43, 2, -53, 45, -61, 5, -8, -11, + -17, 27, 16, -15, -44, 40, -52, 79, -2, -24, 22, 36, 1, -27, 16, -43, + 34, 35, -32, -2, 51, 52, 21, 7, -51, 24, -10, 24, -1, -77, 62, 1, + 22, 29, -5, -22, -24, -3, 57, -35, 31, 52, 11, -29, 45, 43, -21, -4, + 14, 38, -44, 52, 28, 36, -47, -52, -3, 29, 8, -70, 31, -32, 33, 5, + -58, -56, 30, -34, -10, 17, 75, -46, 14, -17, 17, -2, -34, 95, -106, 82, + 21, -50, 18, -8, -80, 79, 3, 11, -23, 67, 5, -20, -24, -36, 20, -20, + -8, -6, 60, 36, 44, 24, -32, -14, 42, 1, 49, -91, 30, 37, 92, -66, + 84, -24, 57, -73, 30, -45, 41, -27, 1, -26, -13, -1, 12, -60, -15, -32, + -34, 57, -51, 16, 33, -62, 38, -1, 36, -18, -24, -6, -31, -10, 29, -42, + -54, 20, -32, 9, 1, 46, -4, 40, -55, 60, -38, 100, -74, 29, -32, 35, + -14, -57, 34, 12, -30, 23, -16, -20, -57, 28, -28, 2, -32, -65, 36, -20, + -8, 3, 2, 61, 22, -13, 33, 22, -32, -27, 60, -35, -10, 23, 34, 8, + 23, 16, 22, -33, 0, 47, -60, 15, 19, 18, 39, -20, 5, -50, 11, 61, + -67, -12, 50, 4, -2, 24, -27, 25, 15, -25, -32, -29, -49, -17, -61, 83, + -79, 35, -53, 36, 8, -7, -55, 56, -20, 14, -1, -32, -30, -14, 2, -29, + 45, -76, 77, -55, 16, -24, -42, -7, 11, -45, 24, 10, -4, 6, -7, -9, + -27, 3, 55, 14, 60, -65, 68, 8, -38, -18, 51, -50, 38, -54, 27, -23, + -57, 5, -45, 46, -78, 14, -86, 12, 27, 17, -20, -34, -15, 67, -12, 21, + -24, 5, 5, -31, 38, -57, 13, 24, -5, -5, -50, -32, 12, 10, -25, 32, + -46, 37, 5, -18, -50, -41, 52, 7, 76, -77, 56, -52, 75, -40, 76, -59, + 90, 6, -11, 10, 28, -48, -19, -22, 22, -16, -17, 15, -29, -13, 61, -41, + 2, -19, 36, -15, 30, -12, -65, 29, 53, -106, 75, 15, 2, 53, 31, -29, + 6, 0, -51, -39, -6, -16, 18, -39, 6, 14, -34, 48, -17, -32, -63, 44, + -31, 34, -66, 6, 7, -43, 66, -40, -18, 54, 14, -1, 12, 42, -25, -13, + 83, -48, 12, -20, -6, 14, -31, -28, -13, -2, 54, 1, 24, 52, -49, 26, + 39, -28, 7, 58, -43, -14, -49, 38, -66, 39, -8, -69, 39, -2, -37, -4, + 3, 17, 2, 74, -70, 75, -56, 18, 4, 26, 35, -54, 21, 80, 1, -9, + -51, 83, -47, 10, -47, 11, -60, 2, -18, 12, -23, 24, 32, 12, -76, 15, + -41, 52, -9, -2, 29, -35, 31, -24, -38, 3, -27, 48, -37, 87, -63, 11, + 55, -8, -4, -37, 30, -34, 23, 5, 39, -63, 3, 51, 51, 12, 1, -48, + 0, 54, 0, -30, -7, -26, 5, -5, 17, 44, 9, -9, 53, 42, -73, 50, + -69, -18, 36, -13, 8, 0, -4, 22, -2, 55, 2, -13, -35, 69, -12, 28, + 58, -39, -66, -12, -37, 31, -45, -39, 8, 15, -34, 8, 7, -15, 89, -9, + 36, 27, 76, -22, 24, -23, 50, 37, -71, 0, -15, 28, 36, -55, -13, -4, + -23, -15, 24, -29, 44, 39, -10, -43, -40, 47, 20, 66, -71, 53, -51, 21, + 0, -21, -71, 56, -23, 53, -4, -3, -11, -37, 52, 37, -58, 9, -9, -35, + 20, -66, 44, -37, 53, -71, 76, -55, 80, -43, 74, -66, -19, 61, -25, 16, + -69, 44, -34, 2, -3, 30, 62, -40, -73, 81, -60, -3, -41, -12, -41, 50, + -1, -24, 40, -12, 0, -2, -3, -39, 59, -16, -35, 60, -67, 51, -17, -31, + -1, 11, 38, -32, 10, 30, -40, 23, 19, -49, 10, -18, 43, -56, 46, -30, + -18, -50, 21, 11, -13, 53, 40, -5, -35, 60, -86, -2, 12, -39, 28, -71, + 36, -27, -15, -15, 31, 31, -8, -1, 39, 32, -83, 67, -55, 26, 69, -3, + 35, -4, -28, -33, -12, 42, -25, 22, 9, -37, 15, 49, -24, -18, -52, 27, + 40, -43, -59, -7, 78, -70, 72, 39, -76, 53, 0, -34, 12, -24, 51, -6, + -15, -39, 12, -43, 34, 13, 51, -51, 73, 3, -23, -13, 38, -59, -16, 6, + -12, -20, -39, 10, -66, 63, -53, -42, 21, 43, 17, -30, -48, 4, 59, -8, + 41, -57, 50, -30, 64, -1, 11, 26, -61, -47, 20, -46, -7, -1, 16, 29, + 14, 49, -58, 50, 11, 20, -22, 10, -7, -58, -43, 41, 13, -72, 9, -14, + -2, -34, 100, -33, 25, 9, -36, 24, 0, 14, 44, -71, -13, -2, -76, -25, + -18, -11, -71, -23, -13, 11, 17, 22, -17, 40, 34, -39, -36, -11, 54, 25, + -20, 19, 9, 25, -27, -54, -3, 69, 62, -22, -28, -51, 73, -62, -9, 68, + -14, -43, 76, 1, -11, -1, -4, -64, 45, -36, -31, 36, 12, -40, 6, 17, + 45, -6, -12, 72, -66, 38, 32, -39, -76, 67, -68, 110, -66, -6, 44, -7, + 37, 29, -32, 0, 2, 14, -33, -15, 48, 22, -29, -32, 75, -32, 53, -20, + 14, -26, -15, 57, -34, 2, 86, -15, -14, -12, -6, -14, 49, 27, 31, -9, + 69, -102, 48, -38, 52, -54, 17, 37, -50, 57, 34, 57, -87, 56, -30, 17, + 32, 60, -47, 49, -41, -18, -72, 0, 29, -39, 84, -9, -34, 18, 36, 39, + -11, 18, -3, -34, 63, -55, -20, -47, 21, 8, 32, -3, 27, -20, -52, 17, + -53, 29, -17, -27, 33, -62, 32, -63, -6, -15, -4, -18, 72, -25, 6, 14, + -73, 80, 38, 61, -116, 121, -98, 17, 16, 13, -29, 33, -39, 18, 44, -41, + -8, 0, 0, 59, -28, -29, -62, 48, -50, -5, 7, 0, 20, 89, -78, 35, + 58, -50, 72, 35, 55, 11, 23, 54, 19, -62, -13, 38, 57, -25, -27, -20, + -8, 30, -51, 59, -10, -46, 21, 41, 39, -22, 11, 28, -42, 34, -31, 33, + -15, -50, 68, -9, -46, 37, -32, 36, 27, 20, 13, 19, 10, 41, -55, 18, + 3, -18, -62, 55, -39, 41, 32, 31, 24, -41, -3, 79, 11, 31, 78, -22, + -19, 58, 50, -5, 21, -49, -38, -40, 22, 31, -86, 57, 43, -24, -30, -53, + 23, -25, 34, 21, -46, 49, 14, -65, -71, 17, -52, 79, -91, 91, -62, -41, + 47, 22, 0, -45, 43, -5, 3, 55, -2, 38, 4, -16, -49, 71, -51, 10, + -52, -17, -25, -41, 30, 23, -30, 31, 72, -17, 44, -81, 39, 18, -34, -4, + -54, 27, 5, -35, 32, -63, 86, -70, 72, -38, -32, 94, -61, 12, -17, -14, + 5, -14, 43, -21, -24, -28, -27, -59, 14, 48, -34, -9, -35, -7, -17, 12, + -69, 82, -13, 52, -61, 36, 42, -57, -7, -56, -60, -41, 32, -16, 47, -60, + 30, -46, -17, 41, -37, -1, 54, 45, -25, -8, -66, 6, 6, 19, -66, 31, + -4, 40, -4, 31, -14, -16, 38, 0, -31, 9, -14, 30, -26, -30, 72, -55, + 30, -51, 49, 11, 11, 47, 6, 49, 34, 35, -7, -19, -46, -17, 40, 32, + -33, -23, -43, 10, 48, -55, -14, 53, 5, 6, 44, -44, -22, 50, -69, 31, + 65, -56, -14, -38, 49, -45, 30, 24, 18, 41, -29, -21, -4, -84, 64, -6, + -8, -45, -30, -20, -39, -12, -34, -49, -45, 78, -64, -7, -9, -13, -38, 36, + -6, 10, -26, -41, -10, 28, -54, -19, 0, -19, -20, 34, -9, -39, -36, 61, + -47, 45, -59, 15, -43, -14, 22, -15, -28, 15, 35, -89, 48, 20, 0, -16, + -27, 44, 0, 36, -67, 12, -64, -16, 15, -7, -13, -76, -2, 22, -82, 81, + -37, -25, -3, -35, 16, 68, 7, 50, -4, -43, 76, -31, -48, 17, 51, 24, + -29, 22, -7, -69, 57, -51, 18, 23, 92, -65, 79, -43, 17, 43, -24, 89, + -93, 46, -52, 31, -24, 20, 4, -64, -55, 24, 7, -8, -6, -6, 71, -48, + 95, 0, -13, 50, 17, -75, 16, 25, -85, 0, -72, 70, -61, -2, 30, -49, + 79, -30, 37, -11, -6, 22, -11, -8, -71, 64, 4, -58, 0, 12, -7, -5, + 37, 21, -50, 1, 39, 38, -17, 67, 59, -72, 39, -28, 71, -39, -1, 8, + 63, -76, 61, -87, 46, -53, -28, 69, -37, 82, 43, 25, -8, -2, -39, -32, + 92, -58, 36, 4, 30, 32, -37, 23, -28, -23, 70, 30, -32, -5, 10, -66, + -5, -22, -29, -27, 24, -30, 34, 43, -46, 54, -25, 8, -49, 23, 34, -63, + 60, -21, 39, -3, -19, -24, -37, -27, -21, -29, -19, 47, 32, -6, 33, -82, + 57, 38, -10, -1, -27, 34, -26, -4, -53, 52, -67, 25, 15, -85, 62, -56, + -11, 0, 56, 33, 54, -18, -16, -35, -17, 27, -14, -12, -9, 86, -37, -45, + 62, 48, 49, -19, -14, 47, -2, 0, 44, -10, 46, -29, 44, 6, 49, -3, + -50, 40, -36, 66, 8, 14, 1, 5, -19, 17, 12, 5, -2, 45, 44, -41, + 18, -8, -4, 73, -18, 81, -39, -34, 41, -58, 35, -20, 12, -49, 45, -12, + 78, -82, 12, 2, 20, 64, -59, 78, -38, 22, 0, 70, -8, -11, -7, -40, + 29, 12, -76, 83, -51, -21, -56, 63, -58, 47, -51, 56, 56, -59, 7, 31, + -49, -36, 11, 35, 48, 16, 14, -30, -38, 13, -55, 52, -7, -38, -29, -28, + 59, -31, -33, 48, -33, -51, 54, 11, 54, -57, 2, 30, -27, -21, 18, -30, + -25, -80, 83, -85, 47, 24, 4, -55, 89, -2, 63, -60, 97, -61, 18, 21, + -70, 45, -19, 26, -37, 4, -60, 81, -24, -2, -7, 16, 73, -51, 52, -54, + -18, 47, -41, 90, -65, 18, -50, -42, -50, 79, -1, -18, -43, -9, 34, -58, + -15, -12, 42, -16, 26, 75, 3, -65, 64, -106, 32, 12, -19, 0, 19, 21, + -87, 38, -25, -16, -35, 0, 11, 17, 21, -22, 22, -36, 9, -3, 13, 54, + 32, -7, -2, 14, 2, 18, 16, -53, 44, -45, 20, 23, 50, -17, -13, 93, + -77, 56, -58, -5, -6, 24, 31, 21, 27, 29, -19, 4, -82, 60, -78, 87, + -51, 14, -14, 48, -26, -52, 46, 18, -6, 9, 44, -42, 45, 86, -81, 76, + 44, -9, -40, -32, -53, -46, 54, 32, 12, -53, -34, 68, -65, -18, 16, 22, + -66, -57, -33, -1, -46, 57, 10, -23, 6, -37, 25, -15, 16, -57, -3, -9, + -1, 14, 0, -32, 38, -11, -27, 23, 16, 9, -44, 29, -72, 65, -77, -24, + 84, -41, -5, -60, -19, -52, 18, 19, 4, 19, -83, 78, -13, 16, -59, 56, + -76, 82, -46, 76, -82, 2, -24, 23, -58, 49, -24, -55, 53, 1, -25, 45, + -12, 9, 56, -24, 25, 19, -2, -63, 59, -33, -11, -51, 2, -14, -49, 1, + 54, 0, 41, -52, -27, -77, 64, -52, 85, -54, 27, 4, -23, 64, 34, -30, + 7, -9, -6, 26, 28, 57, -69, -14, 55, -59, 50, 0, 26, -40, 13, 14, + 1, 80, -36, 27, -45, -39, 64, -71, 7, -42, 5, 70, -66, -30, 71, -31, + 26, 4, -3, -8, 0, 19, 75, -73, 19, 32, 55, -58, -61, 2, 20, 17, + -13, -39, -23, -28, -19, 60, -36, 99, -10, -59, 67, -18, -18, 43, 8, 58, + -11, 15, -58, 42, -76, -30, -72, 88, -66, 101, -67, -22, -8, 19, 14, -17, + 41, 0, 49, -37, 60, -22, -11, -56, 17, -38, 1, 13, 42, -29, 20, -43, + 4, 21, -54, 67, -74, -15, 18, -38, -20, 51, -38, 3, -35, -13, -46, -19, + -49, 70, -37, 50, -51, -10, 9, -38, 9, -17, -12, 29, 20, 4, 45, -75, + 27, -22, -26, 15, -17, 28, 0, -2, 13, -22, -63, 36, -47, -71, 79, -72, + -29, -47, 79, -46, 53, 29, 10, -77, 55, 24, 44, -29, 32, 35, 32, -76, + 72, 37, 15, -9, 35, -84, 13, 40, -83, 48, -11, -8, -44, 10, 25, -22, + 34, 2, -3, 10, -18, -29, 58, -35, -26, 13, 31, 29, -16, 11, 47, -61, + -17, -14, 6, 77, 4, -4, 48, -2, -45, 7, 53, -33, -42, 22, -2, 24, + -41, -23, -7, -22, 3, 69, 0, 8, 1, 11, -32, 51, -46, -49, 55, -7, + 0, -39, -34, 18, -28, -13, 0, 14, 24, 1, -47, 86, 14, 20, 43, 6, + 45, -52, -16, 31, -44, 121, -63, 23, -15, 30, -32, 14, 39, -72, -32, -20, + -15, 1, 30, 28, -67, -20, 11, 64, -30, -13, 47, -46, -25, 65, -34, -30, + 33, -59, 25, 27, -36, 63, -50, 84, -31, 18, -3, -51, 41, 29, -77, 53, + -30, -58, 47, -30, 1, -32, -29, 38, 16, -39, -66, 60, 46, -41, -29, 33, + -7, 61, -37, 59, 7, -22, 34, -62, -9, 12, -42, 24, 29, -29, 24, -54, + 30, -21, 17, 44, 6, 58, 40, -1, -61, 41, -51, 92, -70, 22, -11, 29, + -30, 46, -19, -38, 25, -34, 3, 48, -30, 11, 15, -61, 75, -63, -12, 14, + 0, 53, -1, -38, 80, -46, 20, 75, -33, -57, 70, -49, 67, -37, 71, -21, + 19, -6, -9, 41, -23, 29, -1, 48, -23, -13, -19, -6, -23, -35, 36, 69, + -39, 6, -12, -17, 8, 63, -65, 40, -57, -52, 76, 42, -28, 64, -82, 98, + -43, 45, 0, 18, -32, -30, 8, 43, -60, 19, -62, 60, -48, -48, 22, 10, + -14, -4, 11, -60, 13, 39, 13, -7, 49, 26, 11, -3, 51, 47, -5, -26, + 38, -77, 66, -60, 29, 40, -73, 95, -38, -39, 20, -26, 4, -54, 22, 55, + 27, 6, -65, -6, -18, -61, 9, -29, 67, -57, 29, 20, 2, -35, 49, 41, + -28, 64, -59, 72, -11, -65, 28, 22, -6, -31, 57, -8, -18, 56, -14, -33, + 3, 28, 39, 24, 37, 13, -33, 32, 45, -68, 58, -53, -15, 23, -54, 27, + -17, -1, -5, 38, -27, -65, -5, 6, -8, 10, -27, 30, -68, 67, 55, 0, + 26, 62, -46, -1, -2, 19, -34, -47, 11, 60, -72, 63, -9, -29, -19, 36, + -13, 52, -52, 3, 1, 6, -18, -68, 69, -53, 60, -46, -22, 27, 5, 42, + -17, 56, -64, 85, -34, 45, -68, 43, -33, -6, 3, 19, -17, 54, -6, -51, + 0, 0, 36, -47, -10, 50, -50, 43, 9, -55, 16, -15, 35, -45, 26, -3, + -57, 92, -61, -22, 22, -30, -9, -21, 25, -8, 61, -51, 45, -1, -8, -44, + 11, -26, -5, 58, -75, 42, -38, 0, 8, 48, -47, 29, -54, 73, 42, -43, + 71, -77, 18, 3, -41, 22, 13, -81, 21, 15, -1, 13, -52, 78, -10, 15, + -17, -31, 17, -19, 31, 52, -91, -7, 25, -4, -49, 74, -63, 96, -50, -84, + 72, -3, 23, 3, 4, -22, -19, 25, 48, 72, -23, -67, 58, 19, 17, -95, + 88, -75, -2, 27, 49, -5, -29, 15, 53, -19, 30, -78, 6, 46, -62, 16, + -15, 25, 27, 13, 58, -56, 9, 33, -39, -76, 53, -50, -40, 0, -37, -50, + 6, 4, 18, 11, -30, -18, 5, -71, 57, 59, -48, 8, 54, -25, 61, -113, + 57, -20, 47, 23, 61, 13, 30, -53, 35, 21, -62, 58, -46, 31, -96, 30, + -72, 69, -29, -18, -14, 23, -5, -47, -19, 1, -14, 29, 2, -53, 54, 39, + -66, 20, -18, -76, 3, -23, -2, -9, -57, 61, -24, 9, -50, -6, -32, -13, + -13, -25, 17, -21, 25, 57, -13, 39, -18, -51, -8, 49, -12, -17, -9, 6, + -52, -52, -1, 25, -3, -3, 37, 4, -36, -47, 67, -58, -29, 70, -4, 27, + -13, -77, 68, 1, 34, -8, 20, -2, 0, 74, -88, 82, -36, 2, -41, -20, + 12, -5, 60, -77, -2, 33, 18, -13, 60, -15, 63, -27, 2, -44, 62, 11, + -15, 66, -44, 14, -10, 26, 30, -73, 38, 3, 32, 32, -62, 16, -22, 47, + -27, -46, 54, 7, -37, 14, -37, -44, 29, 38, -43, 0, 10, -46, 32, 45, + -43, -1, 0, 14, 53, 27, 30, 6, -2, 13, -1, 27, -40, -50, 15, -62, + -20, -16, 19, -12, 32, 12, -19, 37, -3, 47, -68, -22, 7, -56, -35, 29, + -8, 24, -24, -19, -10, -84, 77, 18, 18, 16, 12, 33, 23, -56, -32, 100, + -57, 14, -13, -28, -1, -66, 64, 52, -81, -30, -24, 25, -52, -36, 63, 0, + 33, -31, 53, -59, -14, -10, 57, -67, -46, 5, 31, 49, 11, 16, 44, -38, + 38, -38, -38, 28, -46, -28, 58, -55, -22, 59, 1, 16, -30, 5, 46, 44, + 9, -8, 61, -40, 7, 82, -45, 17, -4, -45, 26, -22, -53, -30, 2, 62, + -31, 26, -44, 9, -64, -5, 48, 0, -29, -12, 32, -6, -39, 63, -1, 77, + -16, 2, -51, 60, -27, -20, -36, 83, -37, 34, -38, -22, 23, 34, -67, -34, + 22, 4, 39, 40, -32, 102, -70, 26, 14, -50, -20, 15, 66, 13, 12, 39, + -21, 74, -39, 55, -87, 18, -3, -20, -7, 60, 55, -44, 36, -44, 25, -69, + 88, -2, 59, -54, -2, 21, 0, 8, 73, -51, 3, 39, 56, -56, 7, -38, + -39, 58, 8, -63, 32, -22, 4, -54, -16, -3, -25, 18, -23, 30, 44, 0, + -39, 4, -23, 16, 0, -22, -1, 3, -11, -35, -15, -32, -14, 53, -69, -6, + 26, -91, 35, -8, 30, -50, -18, 39, -23, 20, -37, 56, 8, -16, -21, 43, + -83, 98, -51, 16, -31, 52, 45, -17, 57, -60, 52, 4, -59, 71, 9, -4, + 47, -17, -41, -22, -54, 9, -79, 55, -72, -14, 13, -22, 51, -23, -11, 59, + -57, 65, -7, -5, 17, -65, 40, -26, -25, 2, 83, 6, 6, 61, -33, 29, + -17, -8, 64, 1, 27, 58, -70, 45, -27, -42, 30, -33, -46, 81, -70, -24, + 49, -42, 41, -19, 25, 51, -65, -38, 60, -47, 67, -74, 118, -78, 28, -57, + -5, -17, 25, -15, -6, 14, 34, -7, 77, -33, 21, -74, -8, 16, 4, -18, + -20, 27, -5, 35, -18, 61, -76, 67, -7, 54, -69, 17, 35, -23, 9, -74, + 72, -37, -19, -15, -43, -21, 10, 22, 16, 5, -72, 68, 44, 32, -43, -45, + -14, 13, 44, 4, 8, -59, 31, -62, 62, -10, 28, 43, -58, 33, -30, -82, + 55, 23, -25, 51, 24, 19, 52, -51, 28, 7, -15, 62, -25, -29, 71, 38, + -53, 58, -47, 7, -38, -65, 43, 25, 13, 19, 26, 18, -85, 36, 26, -84, + 26, -107, 64, -74, 51, 21, 4, 15, 33, -82, 8, -57, 19, -17, 36, 21, + -18, -40, -26, 26, -43, 54, -55, 35, -33, -15, 26, 1, -70, 34, 25, 24, + 25, -6, 47, -28, -5, -16, 55, 56, 6, -28, 24, 8, 19, -39, 8, -28, + 28, 15, -8, 10, 38, -59, 55, -63, -2, -19, 60, -18, 48, -56, 110, -56, + 49, 42, 10, -38, -30, -8, 54, -13, -8, 12, -31, -20, -53, 79, -22, 5, + 25, -63, 22, 5, 10, -49, 12, 18, -30, -1, -20, -26, 46, -50, -20, -43, + 21, 11, -6, 57, 72, -51, 20, 1, 55, 20, 4, 25, 6, -12, 33, -9, + 40, -33, -50, -3, 23, 27, 27, 6, 59, -62, -52, 8, -15, -12, 59, -50, + -27, -11, -21, -21, 0, -17, 39, -32, 11, 7, -38, -11, 55, -5, 52, 62, + -64, 32, 36, 9, -40, 27, 12, 31, -59, 24, 26, -11, -68, 64, 10, -27, + 57, 5, -26, -1, -35, 42, -50, 4, -50, 11, -17, 72, -56, -19, 25, -31, + -24, -2, -5, -3, -4, -40, -4, 10, 43, -62, -23, 45, 27, -22, 42, 23, + -63, -27, 93, -50, 92, -55, -3, 23, -18, -47, 74, -24, -10, -1, 7, 62, + -23, -12, -10, 7, -1, 48, 0, -5, 5, -11, -55, -34, 55, -38, -32, 86, + -36, -45, -32, -11, -48, 23, -88, 36, 10, 58, -56, -22, -19, 63, -78, 27, + -63, 35, -31, 60, -27, 78, -98, 78, -75, -9, -21, 64, 0, -16, 10, 28, + 0, 60, 36, 10, -11, -45, 14, 3, -53, 30, 38, 5, -12, 71, -69, 30, + 0, 43, -24, 32, -32, -8, 53, -39, 42, -32, -1, -18, 78, -62, -34, 4, + -36, -19, -48, 52, -40, 37, -75, -35, -43, 38, -3, 21, -19, 58, -17, -10, + -3, -10, 45, 3, -55, 78, -69, 80, 40, -14, -48, 19, -17, -11, -69, 6, + -41, -16, -21, 14, 89, -65, 20, -78, 79, -51, 74, 26, -13, -48, 43, 5, + 37, 38, 11, -44, 10, 26, -55, -4, 44, -18, 6, -4, 0, -35, 48, 26, + -15, 55, -60, 10, -75, 53, 21, -54, -56, 0, 32, -39, 18, 4, -59, 54, + 0, 1, 81, -39, -31, -57, -10, 40, -75, 94, -22, 31, -20, -28, -11, 29, + 74, -4, -24, -17, -49, 68, -54, -31, -26, 47, 12, -30, -7, 9, -77, -51, + -53, 66, -58, -42, 47, 36, -32, -22, 56, -30, 38, 30, 3, -46, 1, -26, + 11, 13, -12, 31, -20, -25, 19, 28, -5, -54, 57, 13, -16, 19, -8, -3, + 30, 39, 12, 27, 8, 72, -71, 6, -62, 98, -70, 7, -73, 0, 10, -40, + 75, -32, -26, -12, -32, 16, 18, -6, 26, 6, -18, -19, 12, -50, 65, -27, + -43, 52, -67, 59, -8, -38, -36, -11, 58, -68, 72, 46, -10, 12, 12, -35, + 9, 19, 58, -47, 16, 15, 79, -27, -37, -37, 14, 37, 7, -8, -17, 31, + 66, -61, 19, -35, -18, -28, 61, -39, 27, 28, -32, -39, -31, 51, -14, 43, + -37, -20, -61, 40, 54, -43, -11, -7, 3, 63, -83, 73, -45, -38, 42, -35, + 16, -62, 31, 40, 12, -6, -37, -24, 50, -16, -3, -36, -62, 114, -46, 47, + -8, -6, 53, -14, -35, 41, 6, 50, 45, -20, 24, -91, 64, -35, 5, -7, + -33, 68, -103, 78, -41, -12, -7, -46, 0, 15, -7, 52, 0, 12, 35, 62, + 25, -6, 16, -38, -35, 44, -2, 65, -39, 19, -56, -35, 49, -20, 16, -38, + -23, 1, -58, 3, 60, -40, 32, -34, 44, -50, -9, 7, -4, 72, -29, -13, + -30, 18, -28, 6, 35, -52, 1, 60, -7, 13, -36, -51, 50, 41, -25, -39, + 35, -34, 4, -15, 77, -22, 27, -17, 18, -48, -47, 78, -70, 37, -40, 0, + -45, 3, 56, 23, 38, -23, 17, 57, 4, 12, -61, 64, -9, -21, 69, 47, + 13, 12, 5, -18, 34, -76, -32, 25, -26, -10, -20, -37, 20, 11, -6, 49, + -58, -8, -3, 12, 15, 55, 0, -29, 22, 37, -57, -48, 46, 24, 58, -4, + 2, -12, -53, 3, -22, -60, 73, 11, 6, -41, 43, 17, 26, -23, 9, 28, + 31, -57, 23, -13, 63, 7, 20, -9, -6, 48, 3, -25, 42, 15, -51, -15, + 66, -83, 90, -52, -41, 33, 31, -20, 29, 5, -68, 19, -76, 75, -47, 28, + 37, -1, -57, 73, 10, -72, -6, -57, 73, 26, -26, 16, -57, 46, -28, -44, + -16, 70, -63, 52, 12, 70, -80, 11, 11, -38, 62, 2, 5, -15, -9, -39, + 75, 0, -28, -5, -16, -6, 29, -6, -11, -20, -8, 2, 49, -30, 12, 12, + -22, 43, -46, -77, 41, -27, 43, -35, 34, 0, 34, 61, 51, -73, -13, 32, + 13, -19, 0, -22, 42, 22, -6, -66, -59, 55, -34, 58, -38, -8, -28, -7, + 56, -46, 24, -21, 55, -43, 45, -13, 25, 9, -20, -30, -5, -7, -35, -84, + 36, -4, -50, 26, -33, 14, -12, -21, 42, -32, 4, 61, -59, 29, -4, -13, + -42, 85, 14, 43, -58, 0, 53, -18, 50, -60, 91, -33, 33, -71, 25, -15, + -4, 0, 33, 19, -51, 8, -34, 24, -17, 7, 21, 57, -27, -78, 91, -20, + -58, 18, 58, -28, -82, 37, -22, 62, -77, 86, -33, -5, 26, -12, 66, -27, + -42, 48, -83, 3, -55, -8, -38, 4, 12, 21, 8, -73, 68, -26, -57, 25, + 11, -55, -46, 33, 19, 36, 73, -58, 52, -63, 64, -11, 19, -4, 8, 5, + -12, 76, -58, 43, -50, -18, -53, 77, -68, -16, 70, -57, 25, -53, -74, 9, + -13, -29, 36, -26, 76, -32, -20, 11, -24, -56, 36, 13, 12, 15, 25, -68, + -8, 28, -7, 13, -90, 44, -37, -24, -34, -30, -55, 56, -17, -27, -17, 63, + -34, 46, -53, 10, 76, -24, 59, -52, -6, 20, 71, -30, 17, -7, -44, 67, + -78, 60, -14, -61, -1, 58, -27, 71, -72, 9, 7, 11, 74, -74, 50, -20, + 31, -18, 9, 3, -70, -25, 46, 21, -58, 14, -1, 14, -21, -20, 22, -2, + -69, 72, -16, 37, 3, 22, -25, 58, -25, -13, 32, -42, -38, 73, -6, -61, + 27, 32, 7, 69, -18, -6, -29, 9, -54, -8, -43, -50, -15, 21, -25, -16, + -40, 60, -42, -34, -7, -13, 28, 28, 34, -65, 34, 18, -21, -31, 51, 42, + -54, 36, 2, 10, -32, -42, 79, -64, 15, -53, -3, 44, -13, 44, -27, 88, + -23, -15, 79, 0, 27, 15, -11, -3, -63, 2, -13, -17, 33, -5, -42, 61, + -42, -55, 2, -44, -4, 3, -37, 8, -25, 11, -17, -24, -3, 44, -70, 25, + 77, -47, 2, 23, 16, 56, -56, 61, -45, 11, -4, -28, -33, 95, -63, -18, + 40, -17, -21, -37, 90, 7, 34, -31, 21, -51, 3, 15, 27, -5, -49, 50, + -3, 19, 39, 1, 41, 51, 13, -21, -4, 43, -35, 27, 11, -33, 52, -11, + 22, 56, 0, 7, 23, -37, -55, -9, 12, 46, -59, 15, -24, 32, -33, 50, + -34, -57, 31, -12, -32, 87, -26, -6, 66, -24, 45, -25, 43, -6, 63, -11, + 26, 21, -32, -27, 20, -38, 45, -56, 53, -1, 25, -65, -32, -8, -46, 41, + 3, -7, 47, -5, 57, -70, 85, -15, 39, 62, 34, -30, 2, 14, 49, -44, + -42, 35, 0, -57, -9, -34, -8, -57, 75, -60, -19, -31, 8, -8, 43, -50, + 0, -4, -4, 44, 16, -16, -9, -14, 23, -41, 44, -49, -48, 66, -34, -6, + 23, 34, -57, 56, 29, 30, -63, 6, 33, -13, 55, -18, -52, 23, -19, 4, + -1, -41, 19, -52, 5, 1, 0, -76, 55, -17, -59, 77, -38, 12, -61, 89, + -56, -15, 29, -56, -57, 70, 20, 42, -14, 49, -10, 41, -16, 28, 40, 8, + 86, -72, 52, 14, 35, -49, 14, -10, -3, 56, -27, 38, -1, 54, -20, 1, + -36, -9, 37, -25, 2, 31, -52, 58, -21, 72, -50, 16, 31, -61, -22, 17, + -17, -16, -56, 47, -83, 40, -25, 62, 28, 48, 20, -37, 30, -60, 61, 30, + -7, 46, -30, 98, -32, 15, 6, 25, -19, 68, 4, -7, -68, 53, 40, -13, + -28, -28, -37, -47, 23, 3, -17, 36, -18, 64, -66, 26, -9, -38, -12, 52, + 51, -19, 56, -23, -44, -5, -69, 41, 3, 37, 21, -7, -5, 2, 38, -2, + -6, 37, -84, 7, -36, -36, 7, -36, -9, 6, -16, -11, 0, 31, -55, 0, + -87, 27, 3, -18, -27, 11, 37, 33, -58, 29, -34, 66, -36, -51, 22, -7, + 39, 52, -25, 17, -62, 16, 1, 5, -72, 17, -12, 23, -40, 26, 19, -36, + 1, -33, 11, 36, 46, -11, -19, 43, 9, 6, 16, 39, 48, -12, 30, 20, + -77, 68, -61, -27, -14, 8, -32, 6, -32, -84, 64, -50, 26, 21, -6, -36, + 61, 19, 26, 42, -21, 8, 22, 71, -47, 8, 90, -69, 85, -22, 51, -50, + -11, 56, -55, 44, -36, 42, -31, -2, 24, -27, 50, -12, -18, -2, 43, -24, + -7, -30, 40, -49, 34, -6, -21, 49, 24, -46, -84, 49, 38, 31, 66, -62, + 82, -30, -36, -12, 49, -54, 61, 13, 21, 8, 56, 17, -56, 8, 55, -78, + 43, -7, 17, -12, 94, -81, -30, 52, -28, -20, 42, -55, -16, 43, -58, -32, + -38, -6, 29, -55, 47, -16, 21, 0, -39, 15, -16, -37, -50, -56, -15, 33, + 40, -23, -12, 37, -59, 57, -5, -19, -30, -20, 16, 29, -68, 32, 58, -3, + -35, 26, -4, 12, 34, 42, -31, -62, -13, -9, -38, 20, 0, 36, -46, -57, + 28, 35, -49, -51, 29, 15, -10, 38, -70, -50, 27, -45, 79, -40, -2, -50, + -41, 50, 20, 57, 40, -35, -36, -6, 15, -53, 75, -22, 6, 2, 55, -61, + -56, 36, -61, 40, -42, 73, 9, -23, -48, -32, 26, -59, 69, -35, -53, 59, + -82, 33, 9, 20, 17, 42, -50, 34, -1, -36, 43, -15, -5, -26, 21, 1, + 75, 22, -60, -7, 23, 4, 0, 5, 53, -35, 38, -11, -11, 57, -17, 11, + 12, -73, -6, 0, 64, -1, -52, -5, 21, 14, 12, -51, 4, -40, 14, -28, + 58, 3, -2, -29, -46, -67, 44, -3, -69, 33, -45, 13, -48, 37, -78, 75, + 25, -15, 16, -5, 41, -19, 29, -3, 16, 13, 12, 4, 5, -82, 45, -49, + 25, -55, -1, -1, -23, 23, -35, 4, -39, 26, -83, 44, -36, -19, -13, 52, + -17, 36, -21, -2, 26, -49, 49, 31, -14, -1, -54, 37, 1, -39, -30, -34, + 2, 3, 1, 18, -25, -53, 77, -81, 5, 72, 35, 28, -59, -46, -21, 20, + -67, 64, 45, -21, 40, 34, -53, -10, -34, 15, -60, 17, 36, -50, 5, 41, + 13, -12, -3, 29, -42, -22, 96, -74, -9, 23, 20, -40, 49, -64, 49, 70, + -57, 29, -15, -53, -31, 19, -31, 35, -21, 17, -51, 91, 25, 61, 29, -31, + -34, -11, -48, 17, 34, -74, 36, 23, 38, 37, -51, -3, 29, 23, -35, -59, + 21, 50, -92, 63, -31, -10, 4, 29, 20, -18, 15, -27, 5, -17, 48, 37, + 40, -100, 31, 46, -58, -21, -34, 12, 34, 19, -16, 36, -59, 46, 4, 42, + 26, 13, 1, -62, -31, -61, 98, -77, 27, 9, 1, -9, -38, 6, -37, -5, + -16, -4, 21, -25, 58, -82, -2, 38, 68, -45, 50, -29, -68, 57, -53, 22, + -20, 24, 22, -16, 19, -5, 31, 6, -23, -30, 38, -29, 13, 25, 6, -51, + -2, -36, 67, 4, 17, -31, -7, -25, -15, -28, 17, -26, 25, -14, -37, -48, + -12, 52, 27, -27, 18, -15, 91, -70, 63, 17, 2, 3, 30, -58, 63, -45, + -27, -13, 4, 45, 7, 49, 23, 7, 51, -22, -14, -12, 34, -60, 34, -51, + -38, -10, -9, 36, 19, -21, 28, 13, -37, -2, -43, 22, -34, 55, 13, 27, + -45, 21, -20, 49, -31, -25, 54, -38, 4, 30, 9, -19, -22, -25, 22, -30, + -41, 42, -22, -14, -12, -58, 27, -53, -22, 17, 34, 9, 12, 59, -25, 97, + -59, 46, 3, -31, -19, 29, -42, 56, 0, -69, -72, 36, -21, 32, 37, -6, + 9, -81, 7, 20, -66, -47, 65, 4, -55, 85, -66, 16, -5, 6, 15, 7, + -26, -3, -51, -1, 58, 0, -46, 25, 34, -56, 66, -4, 5, 68, -55, -54, + 77, -18, 2, 69, 37, 7, 8, -55, 24, -6, 48, -45, -63, -38, 35, -21, + 43, 47, 26, 32, -54, 79, -75, 47, -48, -36, 15, 20, 16, -45, 31, 72, + -56, -9, 82, -54, 6, -4, -61, 15, 18, 27, 11, 56, -62, 47, -36, -63, + 29, 57, 27, -81, 75, 13, 31, 24, 37, -51, 13, 0, 28, -21, 9, 22, + -64, 2, 31, -25, 63, 61, -74, 43, 31, -72, 44, -61, 80, 33, -30, 51, + 28, 27, 16, 9, 16, 55, 0, 12, -66, 4, -10, 51, 52, -55, 53, 46, + -5, -10, -48, -6, -8, 0, -19, 3, 29, 44, -39, 13, 17, 24, 0, 21, + 18, -14, -45, -11, -55, 8, 40, -59, 55, -34, -29, 39, -37, 65, -13, 68, + -52, 27, -6, -56, 46, -60, 0, -1, -66, -32, -37, 36, 15, 10, -24, -4, + 74, -18, 32, -93, 58, -40, -50, 24, -4, -19, 3, 22, 27, 24, 22, -18, + 66, -12, -4, -34, -3, -70, 42, -14, -41, 75, -68, 81, -8, -7, -19, -2, + 79, -57, 8, 8, -24, 10, 8, -55, 60, 6, -3, 21, 34, 28, -25, 6, + 42, 29, -49, 7, 29, 54, -5, 51, 0, 14, 27, -42, -20, -58, 48, -75, + 18, -32, 36, 60, -32, 14, 61, -87, 9, 29, 74, -25, -5, -64, 72, -61, + 41, 49, -20, 1, 9, 55, -42, -20, 37, -74, 32, 59, -32, 33, -89, 61, + -63, 85, 9, -40, -2, -26, 7, -27, -24, 11, -19, -37, -8, -50, -3, -1, + -52, 25, 62, -113, 26, -53, 7, 0, 11, -27, 42, -53, 84, -25, 34, -63, + -3, -40, 5, -55, 44, 7, -60, 58, -79, 59, -49, -17, 46, -18, 37, -44, + -15, 73, -59, -15, -35, 42, 18, 42, -67, -44, 43, -97, 59, 10, -47, 39, + -46, -22, -33, 65, -82, 13, 9, -54, -63, 39, -24, 44, -52, 34, -67, 39, + 7, -16, 12, 32, -74, 2, 50, -51, 27, 37, -19, 23, -59, 26, -35, 18, + -54, -1, 3, -43, -51, -43, 0, -51, 98, -45, -2, -20, 5, -14, -40, -41, + 34, 34, 28, 56, -19, 49, -28, -27, -20, 13, 33, 27, -26, -64, -3, -26, + -3, 38, 3, 17, 34, 27, -4, 30, 8, 48, -45, 27, -25, -56, 12, -3, + 42, -18, 32, 9, -1, -31, 56, 4, 48, 13, 9, -41, 18, 28, 4, -21, + 18, -74, 65, -23, 34, 28, -10, 5, -24, 5, -31, 19, -27, 12, -5, 14, + -4, -46, 55, 26, -4, 48, -2, 10, -1, 30, 18, -81, 33, -41, 34, -21, + -49, -3, -1, 36, 16, 39, 18, -4, -51, 14, 11, 17, -3, -27, -24, 55, + -16, -63, 64, -63, 46, -86, 46, -89, 85, -67, -27, 59, -6, 26, 40, 6, + -37, 38, 3, -96, 38, -45, -23, 53, 34, -59, 16, -27, 13, 52, -21, -31, + 14, 22, -25, 11, 42, 7, -11, 33, 9, 45, 1, -74, 5, 10, 27, -8, + -15, -33, -10, 66, -35, 62, 20, -7, 12, -23, 27, 13, 31, 34, 51, 14, + 63, -41, -30, 45, 35, 41, -7, 33, 24, -14, -55, -13, 29, -19, 55, -42, + 94, 16, -37, 8, -28, 15, 27, -14, 82, -39, -1, 46, -77, -17, 42, -78, + 74, -101, 67, 1, 73, -21, -15, -7, 31, -16, 53, 35, -50, 31, 45, -35, + -10, 76, -24, 22, 54, -52, 9, 54, -5, 43, 5, 16, -1, -14, 57, -58, + 16, -24, 18, -45, 63, -34, -42, 20, 9, -60, -2, 44, 74, -45, -26, 2, + -25, 56, -76, 78, 46, -1, 30, -20, 2, -4, 1, -50, 50, 44, -18, 1, + -29, -77, 51, -77, -7, -87, 44, 56, -35, -52, 32, -69, 0, 81, -7, 15, + 0, -28, 21, -53, 59, -78, 30, -4, -8, 15, 31, -16, 7, 42, -19, 6, + -1, -39, 63, -71, 12, 44, -75, -6, 21, 20, 23, -48, 49, -92, 62, -58, + 18, -13, 4, 3, -25, -37, -56, 64, 10, 14, -27, -3, -16, 54, -72, -3, + -44, 96, -54, -5, 1, -32, -42, 13, -74, 12, -6, 42, 20, 0, -38, 6, + 59, -23, 46, -68, 49, -72, -30, 22, 42, -57, 48, -64, -36, 78, -45, -51, + 80, -32, -2, -4, 0, 60, -76, 53, -64, 43, -2, -42, -27, 20, -48, 59, + -60, 7, -32, 100, 1, 2, 26, -66, 36, 17, -67, 53, -8, -23, -27, 21, + 2, 8, -43, -32, -5, -60, 57, -8, 17, -77, 21, 52, 21, -58, 22, 16, + 18, -34, 88, -94, 20, -22, -26, 30, -34, 32, -32, 29, 5, -40, -50, 8, + -63, 0, 13, -44, -24, -63, 53, -84, 4, -4, 80, -50, 16, 30, -51, 14, + -66, -35, 26, 28, 14, 37, -74, 75, -69, 28, 10, 49, 42, 38, -46, 78, + -100, 108, -65, 0, -23, -29, -18, 17, 26, -2, -59, 8, -30, -24, 36, -32, + 11, -70, 48, -36, -66, 107, -61, -26, -7, 14, -58, -7, 7, 4, -34, 40, + -13, 9, 39, -5, 7, -9, 20, -19, 14, 46, -34, -39, -84, 100, -20, 38, + 7, -49, 44, -28, -37, 51, -31, 28, -31, 53, -86, 71, -78, -9, 18, 0, + 61, 0, -29, 40, 19, 73, -40, 2, 7, -6, 31, 33, -14, -50, -36, 55, + -47, 83, -65, 26, 0, 8, -13, -15, -9, 4, -38, -24, 18, -24, 39, -49, + 79, -25, -34, 59, -61, 23, 0, 53, -57, 0, -8, 29, -16, 55, -34, 63, + 39, -7, -10, -24, 63, 4, 60, -81, 36, 8, -3, 27, 2, -66, 108, -20, + 0, -31, -22, 9, 52, 20, -41, 56, 37, 17, -6, -12, -35, 42, -11, -24, + -32, 40, 15, -28, -15, 4, 20, -4, -47, 39, 11, 20, -53, 30, 11, 12, + -59, 25, 37, 52, -23, -71, 78, -48, 80, -32, 39, 9, 31, -37, 46, -3, + 59, 33, -36, -24, -73, 12, 31, -13, -9, -12, 60, 5, -10, 57, -55, 25, + -53, 48, -24, 63, -46, 32, -53, -75, 37, 36, 0, -73, 67, -60, 64, -8, + 28, -43, -46, 60, 1, 54, -20, -35, 41, -64, 57, -102, 25, 26, 35, -53, + 88, -54, 64, 25, -18, 32, 17, -16, 56, -27, -19, 37, -12, 2, 18, -12, + 30, 59, -54, -36, 4, -45, 22, -39, 26, -20, -53, -47, -56, 36, -43, 36, + 46, -79, 69, -2, -32, 51, 30, 36, -64, -10, 13, -19, 86, -68, 33, -26, + 25, 30, 15, 4, 0, -29, 20, 14, -12, 12, 27, 9, -52, 39, 13, -66, + 55, -56, -6, 2, 29, -39, 13, 14, 14, -32, -1, 42, 31, -39, -13, 13, + -63, 59, 13, -14, -22, -51, 27, -10, 54, -74, 90, 29, 32, 0, -62, 23, + -29, 9, 16, -34, 38, -42, -10, 28, 30, 10, -33, -36, 75, -12, 49, -54, + 25, 5, -13, -4, 8, 43, -54, 36, -35, -16, -2, 63, -28, 5, -34, 71, + -86, -15, -23, 54, -23, -1, 13, -24, 23, -41, 36, -49, 2, -19, -8, -34, + -72, 7, 20, 45, -46, 31, -57, 28, 10, 6, -12, -12, -60, 87, -69, -49, + 60, 13, -22, 14, -96, 18, 49, -41, 10, -42, 7, -44, 45, 32, -49, 72, + 14, -86, 12, 32, 7, 56, -43, -8, 5, 18, 0, 11, 4, 0, 16, 20, + -54, 67, -70, -44, 23, 58, -6, -26, -14, -31, 24, -36, -27, -16, -19, 11, + -50, -56, 12, 34, 64, 13, -53, 39, 2, 38, -53, -53, 36, -63, 30, 3, + 40, -7, 44, -35, 15, -22, 45, 67, -16, 9, -19, 27, -15, 28, -65, 8, + -3, 22, -4, 0, -40, 5, -56, 64, -21, 0, 40, 56, 4, 3, -13, 4, + -36, 9, -84, 49, 17, 20, 31, -35, 3, -63, 95, -82, 48, -77, 59, -68, + 42, -75, 43, 38, 3, 14, 35, -49, -21, 19, 66, 47, -29, 36, -18, -38, + 28, 0, -56, 22, -23, -17, -68, 52, -56, 62, 29, 47, -77, 36, 20, 0, + 27, -6, -20, -15, -21, -13, 3, -14, 30, -28, -66, 25, 56, -9, -46, 37, + 10, 2, -27, 63, -25, 5, 25, 18, -38, 32, 0, -21, -9, 35, -24, -3, + 80, -20, 24, -20, 30, 45, -6, -34, -49, 54, -64, -83, 76, -48, 57, -10, + 52, -41, 29, -46, 24, 18, -13, -13, -55, 21, 26, 15, -80, 31, 33, -50, + -18, -6, -46, 78, -60, 54, -19, 29, 15, -15, 36, -36, 31, -42, 53, -55, + 61, 10, 32, -56, 54, 5, 4, -30, 1, -49, 57, -16, 68, -8, 34, -44, + 81, 42, -63, -47, 40, -52, 85, -82, 27, -12, 24, -40, 80, -65, 37, 8, + 47, -36, -44, 48, 68, 22, -44, -23, 6, 37, 28, 34, 0, -43, 44, -19, + -59, 84, -1, 10, -41, -9, 27, 16, 30, -45, -56, 28, -19, 33, -26, -28, + 43, -37, -18, 70, -68, 5, -55, 75, 11, -17, 9, 66, -7, -1, -19, 35, + -27, 85, -32, 4, -80, 61, -12, -20, -59, -4, 72, 20, -20, 6, 59, -70, + 62, -25, -55, 68, 38, -21, 44, -53, 9, -6, -46, 28, 9, -23, -2, 58, + -57, 37, -13, 16, -2, 50, 2, 8, -22, 42, -74, 2, -48, -32, 35, 55, + -32, 37, 54, -54, -51, 9, -52, -3, 67, -5, -30, 13, -12, 27, -26, 69, + -67, 68, -66, 30, -33, 49, -59, 81, -2, -4, -45, -17, 6, -61, 12, 35, + 42, -56, 79, 16, 52, -34, 13, 27, 13, 6, -57, -14, 8, -28, 37, -44, + -17, -77, 57, 4, 69, -40, 33, -31, -8, 54, 14, 40, -73, -25, 44, 21, + -51, 18, 41, -104, 75, -78, 13, -42, 35, 17, -35, 66, -32, -20, 0, -20, + -64, -6, -22, -36, -19, 41, -32, 77, 73, -74, 48, 57, -80, -5, 10, -10, + -40, 2, -22, 62, -4, -42, -12, -31, 69, -6, -75, 66, 29, -35, -30, 55, + 18, 13, 51, -65, 33, -17, -31, 9, -47, 50, -37, 13, -44, 51, 20, -19, + -43, 1, -21, 51, -2, -34, 40, -24, 56, 61, -55, 13, -82, 39, -51, 55, + -41, -55, 55, 61, -56, 65, -73, 43, 13, 3, -88, 74, -59, 82, -52, 8, + -58, 43, -19, 41, -78, -24, -19, 55, 27, -46, -26, -45, -31, 22, 11, -34, + 21, -23, -80, 65, -22, -11, -32, 27, 9, -9, 37, 47, -40, -25, 28, 5, + 33, 60, -31, 69, -41, 23, 46, -69, -34, -29, -14, -35, -5, 53, -8, -35, + 5, 8, -71, 24, 55, -34, -8, -6, 84, -39, -15, -34, 32, -61, 39, -13, + -49, 9, -2, -44, -33, -12, -17, -25, -1, 35, -36, 63, -45, 56, -89, 42, + -4, -54, 24, -44, 36, -82, 55, -15, -17, -17, 31, 43, -2, 33, -64, -40, + 39, -36, -18, 47, -9, 3, 44, 8, -66, -19, 13, -11, 64, -13, 0, -29, + 18, 16, 32, -67, 72, -49, 15, -55, 32, -53, 62, 22, -17, 87, -51, 2, + -55, 34, -93, 29, -108, 84, -30, -37, -65, 44, 4, -52, -33, 75, -51, 66, + 1, 34, 20, 10, -38, 2, 26, 19, -20, 23, -28, 24, 4, 29, -74, 17, + 46, -55, -17, 86, -63, 24, 70, -25, -27, -10, -24, 16, -44, 23, -29, 60, + 4, 8, 42, 14, 34, -24, -32, -51, -77, 9, 33, -36, 69, 66, -48, 67, + -67, 36, 42, -66, -41, 68, -2, 33, -57, 44, -16, 14, -75, 62, 6, -17, + -33, -51, 64, -69, 21, -28, -8, 12, 9, 60, -55, 22, 46, -42, -9, 41, + 48, -18, -22, -26, -24, 8, 37, -20, -39, -74, 92, -45, 96, -32, 36, -48, + 23, 23, -43, -59, 67, -61, 51, -16, -37, 21, 28, 49, -53, -33, 15, 36, + -7, 39, -66, 50, -25, 90, -47, -34, 0, 48, -16, 65, 18, -52, 48, 30, + -25, 39, 40, -15, -23, 24, 33, -27, -46, 35, -16, -37, 92, -51, -41, 29, + -91, -39, 1, -39, -28, 32, -26, 58, 13, 45, 17, -62, 61, -39, 33, -6, + -28, 6, 41, 5, -32, 9, 36, 8, -40, -13, 83, -45, 38, -34, 67, -1, + 0, 1, 21, 34, -20, 3, 19, 40, -45, -62, 68, -82, 35, 15, 7, 35, + -19, 28, 7, 49, -63, 44, -32, -23, 69, -60, -2, -34, -30, -8, 47, -2, + 25, 7, -59, 27, -6, -10, -25, 16, 23, -39, 48, -37, -58, 33, -39, 33, + -42, 67, -55, 22, -10, 4, 37, -8, 20, -38, -7, 7, -14, -28, 10, -47, + 80, -63, 86, -15, 64, -3, 7, 19, 91, -32, 47, 54, 66, -98, 26, -81, + 61, -9, -23, -18, -19, -24, 4, 13, -28, -26, -30, 21, 7, -24, 40, -6, + 12, 50, -52, 5, -23, 41, -43, -24, 68, 59, -65, 39, 53, -9, 56, 18, + -41, 1, -29, -38, 4, 16, 10, 19, 54, 35, -60, 30, -54, -56, -42, 30, + 44, -54, -29, 66, 8, -15, -65, 51, 20, -27, 19, -14, 48, -11, -56, 34, + 58, -56, 37, -4, 65, 2, -54, 76, -54, -20, 8, 0, -23, 13, 2, -53, + 5, 30, -25, 37, -13, -17, -46, 45, -26, 48, -45, -39, -36, -39, 62, -36, + 11, 29, 24, 10, -64, 67, -49, 25, -17, 43, 5, -1, -50, 88, -10, 0, + 5, 43, -75, 75, -63, -51, 44, -7, 25, 1, -19, -45, -26, 20, -46, -23, + 47, -37, 38, -74, 41, -34, -26, 8, 68, -75, 9, -9, -57, 61, 14, 26, + 42, 50, -5, 56, -44, 25, -59, 39, -42, -6, 64, -41, 52, -83, 43, 24, + 30, 13, 17, -34, 0, -42, 77, -73, 20, -17, -54, 8, -3, -41, -17, -70, + 109, -97, 84, -69, 54, -7, -47, 48, 15, 85, -52, 68, -63, -36, -6, 57, + -51, 21, -39, -35, 79, -22, 34, -1, 3, 3, 26, 20, 45, -66, 41, 9, + -55, 33, 10, -7, 29, 0, 12, 21, 7, 58, -6, 49, -14, 0, 38, -20, + -32, -57, 51, -64, 24, -60, 15, -59, 53, -39, 75, -39, -3, 62, -52, 57, + -32, 51, -48, -6, -15, -68, 18, -37, -55, -22, -46, -46, -24, 64, -20, 43, + -50, -29, 46, 26, 9, -36, 72, -68, 32, 43, 22, -42, 20, -13, 41, -51, + -9, -38, 9, 38, -9, -27, -15, 6, -53, -28, 28, 28, -36, -45, -36, -18, + -44, 91, -64, 58, -55, 42, -26, 27, -8, -66, 94, -54, 25, 74, -43, 69, + -93, 67, 33, -62, 32, 50, 45, -47, -14, -28, 46, -21, -43, 44, 21, -40, + 30, 10, 48, -92, 2, -16, 83, -68, 19, 74, -23, -22, 50, -6, -65, 60, + -72, 72, -41, -32, 42, 35, -55, 38, 20, 31, -46, 93, 5, 35, -46, 3, + -13, -66, -17, 41, 23, -63, 72, -60, -16, -53, -54, 64, -4, -53, -9, 30, + -74, 20, 12, 17, -16, 67, 14, -45, -1, -10, 72, -27, 34, -42, 8, 49, + -76, 61, 2, 39, -39, 17, 44, -19, -6, 76, -14, 5, -29, 32, 20, -46, + -11, -27, 20, 2, -18, 9, 15, 43, -61, 60, -85, 30, 18, 12, 21, -64, + 3, -41, 31, 34, -59, 53, -88, 65, 29, -6, 69, 32, -32, 28, 40, 22, + -88, 67, -35, -7, -19, -11, -3, -21, 35, -60, -16, 30, 17, 27, 31, -39, + -37, 32, 52, -36, 19, -44, -35, -11, -18, 17, 10, 3, -45, 62, -25, 3, + 0, 0, 12, 20, -26, 41, -74, 34, -55, -23, -43, 52, -27, -32, 75, -32, + 63, 22, -3, 21, 52, -15, 46, 3, -12, 57, -88, 67, -11, -26, 4, -70, + 70, -86, 54, -16, 26, 73, -81, 105, -3, 17, 63, 7, 6, 3, 18, -34, + 34, 16, -49, 32, -69, 97, -68, 17, 20, -63, -7, -10, -21, 17, -6, -22, + 47, -32, 61, -9, -13, -15, 29, -4, 19, 5, -46, -34, -20, 46, -12, 65, + -35, 13, 10, -30, 44, -19, 21, -30, 35, -63, 27, -73, 63, -57, 11, 6, + 16, -16, -24, 23, -8, -90, -10, -22, 21, 14, -64, 63, -61, 19, -12, -2, + 10, -52, -2, 74, 6, -27, -9, -11, 18, -52, -17, -16, -38, -3, 58, -19, + 67, -59, 6, 36, -46, 30, 4, 43, -83, 13, -8, -46, -43, 58, -25, 4, + 36, 65, -16, 12, -56, 69, -7, -7, 51, 41, 42, -47, 15, 4, 58, -53, + 41, -32, 9, 19, -33, -14, -4, -54, 35, 22, -33, -40, 27, 22, -4, 0, + 24, -47, -58, 62, -46, 59, -39, -35, 47, -66, 14, -51, 37, -30, 4, -55, + 51, -47, 38, -4, 15, -36, 52, -62, 93, -56, 14, -15, 32, -68, -1, 32, + -16, 10, 2, -5, -26, 26, 53, -42, -26, 4, -70, 4, 5, 1, -16, 43, + 18, -35, -14, 47, -12, 4, 0, 24, -23, 41, -21, -51, 30, -33, 50, -83, + 84, -57, 10, -16, -3, 35, 19, -11, 46, -24, 69, -72, 74, -23, -58, -12, + 38, -19, -16, -65, 51, -16, 52, -36, -7, 66, 7, -32, 12, -19, -26, -40, + 0, 39, 14, -73, -8, 50, -26, -35, 1, -24, 23, -51, 58, -42, 41, -6, + 47, -48, 36, -15, 31, -49, 80, -78, -20, -18, -28, -13, 0, -8, -14, 73, + -32, 16, -37, 59, -41, 9, -43, 29, 39, -21, 47, -4, 26, 16, -25, 24, + 28, -30, -29, 26, 20, -52, 46, 40, -36, 91, -29, 76, -26, 60, -2, 6, + -36, 41, -8, -6, -24, -23, 55, -57, 17, 24, 56, 7, 21, -10, -15, 19, + -21, 9, -46, 68, -17, 68, 60, -83, 96, -84, 89, -66, 78, -43, 75, -62, + 0, 2, -4, -41, 9, -14, 19, -14, -40, 1, 60, 10, 13, 77, -109, 55, + -16, -20, 65, -66, -21, 50, -57, -51, 37, 27, -22, 56, -3, -40, 51, -15, + 22, -83, 81, -66, 11, -40, -3, -10, 25, -42, -30, 5, -26, -19, -23, 54, + -3, -19, 51, 1, -20, -24, 47, 32, 34, -78, 45, -14, 15, -12, 53, -63, + 49, 30, 5, -9, 9, -74, 88, -32, -4, -47, 46, 19, 4, -35, 21, 50, + -37, 0, -1, 0, 5, -28, -18, -1, -5, -46, 21, 26, 9, 53, -33, 27, + 2, 29, -81, 91, -25, 67, -42, -23, 14, -49, 63, 20, -31, -16, -16, -8, + -22, 10, 19, 15, 43, -27, -12, -24, -25, 50, -64, 93, -3, -28, -12, 65, + -13, -1, 72, -35, 28, -39, -36, 36, -29, -39, -34, 0, -31, 17, 56, 54, + -75, 59, 0, 98, -110, 60, -66, 9, 34, -68, -11, -18, -47, 76, -42, 76, + -32, -28, -27, 73, -47, -21, 14, 35, -11, 52, -76, 67, -75, 52, -20, -18, + 9, -14, -16, 32, -52, 52, -99, 62, 38, 12, -51, 102, -53, -35, 35, -60, + -18, -46, -20, 6, -20, 38, -1, -43, 23, -41, 13, 38, -42, -4, 29, -64, + 89, -92, 67, -62, 24, 60, -67, 5, -34, -33, 3, -35, -10, -73, 5, 17, + -70, 29, -53, 32, 0, -14, 21, -40, 55, -5, -67, -22, -32, 20, -28, -38, + 1, 68, -13, -58, 63, -55, -38, 57, -56, 74, -67, 36, -8, 13, -50, 70, + -26, 3, 8, 9, 55, -74, 21, 42, 18, 48, -81, 47, -58, -60, 61, 18, + -24, -41, 6, 65, 3, -44, 72, 13, 11, 38, -22, 19, -25, 32, -17, 22, + -70, 96, -78, 79, 8, 43, 25, -25, -10, 45, -39, 34, 73, -32, 25, -61, + -11, -2, -44, 10, 9, -39, -2, -46, 35, 0, 38, -30, 8, -39, 14, -14, + -64, 57, -25, -52, 72, -38, 13, -37, 40, 62, -62, 81, -68, 53, -69, -14, + 84, -9, -25, 1, -18, 0, 58, -20, -20, 37, -16, 37, -59, -30, -42, 5, + -22, 2, 38, -80, 29, -75, 17, 39, -35, 45, -15, -42, 6, 19, 7, -26, + 48, -27, 36, -36, -52, 31, 2, 21, -24, 55, -53, -15, -39, -18, 45, -66, + 46, -45, -43, 5, -8, 30, 52, -21, 21, 24, 2, 50, -16, -23, -15, -74, + 80, -76, 16, -66, 64, 11, 17, -55, 41, 35, 3, 31, 68, -43, -37, 24, + 5, 20, -63, 18, 30, 57, -66, -5, -3, 36, -15, 19, 42, -22, 38, -8, + 36, -38, 24, -1, -15, -18, 39, 47, -60, -32, 39, -82, 14, 41, 9, 58, + 61, 43, 13, 36, 18, 15, -8, -4, -14, 0, 39, -34, -19, 79, -41, -15, + -54, 48, 5, -6, -41, -16, 13, -35, 52, -32, 11, -16, 37, 80, -62, 54, + 19, 44, 36, -26, -4, 47, -2, -60, -12, 4, 7, 38, -9, 1, 44, 32, + -24, -4, -49, 39, -84, 14, 29, 6, 30, -51, -9, -22, 44, -45, -22, 35, + -76, 81, -98, 16, -4, 0, 27, -37, -31, 9, -24, 32, 25, 49, -8, -44, + 9, 21, 22, -10, -41, 21, -77, 23, -8, -43, -31, -12, -9, -11, -46, 28, + -5, -42, 23, -63, 48, -52, -33, 50, -6, 0, 51, -44, -16, -23, 7, 54, + 34, -8, -12, 57, 8, -26, 57, -23, -8, 16, 28, -39, -17, 42, 25, 6, + 66, -87, 42, 10, -4, -19, 17, 37, 9, -33, 7, -32, 10, 33, 78, -18, + -44, -5, -23, 63, -33, 53, -57, -31, 40, 22, -49, -29, 8, 62, 31, 9, + -61, 43, -40, 30, 15, 41, -29, 29, -64, 37, 27, 18, 16, 12, 23, -3, + -3, 24, -30, -25, 54, -1, -36, 35, -39, -17, 28, 41, -27, 40, -25, 10, + -11, 1, 65, -26, -20, -32, 30, -25, -46, -10, 4, 29, -33, 21, -5, 79, + -61, 94, -14, -23, -17, 14, 3, 44, -72, 3, -33, -5, -58, 54, -66, 36, + -47, -57, 101, -26, -25, 12, 4, 24, -17, -35, -21, -13, -39, 10, -33, 42, + -32, 11, 1, 46, -42, 13, -18, -14, -36, 73, 37, -17, 62, -57, -13, -54, + -57, -45, -22, 21, -88, 52, -53, -3, 74, -40, 17, 7, -29, -15, -17, 37, + 21, 19, -51, 84, -29, 78, -34, 24, 47, 4, -25, 41, -21, -51, 22, -2, + 9, -48, -46, 11, 35, -67, 51, 50, 32, 34, -43, 22, 32, -21, -44, 34, + -29, 49, 16, 40, 15, 47, -45, 8, -23, 34, -23, 35, 0, 76, -3, -43, + 85, -53, 66, 37, 11, 10, 18, 2, 46, -50, -13, -6, -17, 19, -69, 57, + -45, 5, -18, -48, 21, 44, 13, 47, -58, 61, 0, 54, -3, 64, -41, 35, + 2, -28, 24, -17, -38, 22, 41, -8, -6, -29, -72, 42, 24, -46, 40, -96, + 55, -39, -8, -49, 34, 26, -31, -17, 18, 31, -69, -6, 57, -48, -46, -25, + -17, 46, -11, 29, -26, -6, -38, 24, -34, -19, 14, -53, 33, -48, -40, -1, + 26, -19, 19, -71, 40, 8, -19, -4, 21, -33, 59, -20, 55, -96, 62, -34, + 60, 6, -12, -44, 75, -72, 58, -31, 55, -29, -16, -53, -15, -37, -43, 39, + -9, 1, 36, -11, 18, -54, 86, -59, 47, 7, 12, -33, 42, 16, -55, 70, + -1, -53, 64, -29, 18, 24, 15, -59, 61, 54, -36, -1, -13, 12, -69, 33, + -24, -58, -37, 48, -8, -80, 60, -73, 68, 19, 38, 52, 2, 45, 25, 30, + 53, 35, -66, -2, -1, 34, -30, 0, 19, -9, 28, 14, 30, 19, -13, -95, + 57, -29, 32, -46, 30, 25, -6, 28, 9, -49, -23, 55, -65, -20, 66, -42, + 87, 56, -10, -11, 28, 11, 48, -48, -25, 0, 28, -34, 37, -19, 7, -34, + -17, 34, 11, -78, 27, -79, 51, -64, -18, -9, -47, 7, -22, 47, 20, -32, + 26, -60, 82, -38, 53, -12, -18, -57, -65, -30, 18, 5, -13, 19, 69, -86, + 16, -26, -43, -40, -37, 38, -73, 57, -30, -13, -13, 17, -41, -37, -64, 97, + -85, 80, -41, -56, -31, 44, -52, 10, -45, 39, 42, 2, -41, 17, 3, 7, + 59, -2, 74, 6, 34, -35, -44, 37, -31, 23, -14, -38, -1, 3, -8, 25, + -23, 27, 23, 18, 2, -54, -28, 14, 50, -46, 85, -4, -4, -13, 15, 63, + -43, 49, -33, 58, 8, -38, 24, -11, -47, 55, 4, 31, -52, 77, -4, 31, + 1, -21, 17, -57, 0, 48, 26, -77, 70, 3, 46, 29, -57, 59, -4, -22, + -23, -14, 30, 12, 18, -38, 59, 30, -50, 8, -4, 15, -9, -12, 24, -55, + 38, -30, -14, 6, -67, 64, -14, -34, 8, -36, 36, 12, 69, 55, 25, -60, + -19, -17, 42, -29, -47, 78, -60, 21, -41, 70, -54, 84, -77, 61, -40, -16, + -8, 10, -20, 16, -48, 24, -24, -7, 47, -60, -62, 81, -72, 24, 43, -15, + -23, 74, 13, -15, 27, 40, 42, -44, 51, -63, -35, -17, -30, -44, -14, -37, + -40, -5, 19, 16, 0, -68, 67, -48, -20, 35, 24, -72, 3, 18, 6, 84, + 28, -11, 2, 11, -29, -33, 25, -46, -16, 59, -18, -6, 52, -11, 22, -22, + -38, -36, 26, -16, -3, 6, -35, 25, 26, -35, 52, -38, -18, 26, -56, 65, + 10, -23, -9, 41, 50, -40, 75, -42, 96, -28, 51, -1, 29, -1, -75, 50, + 15, 38, -53, 5, -40, 2, 41, 44, 39, 64, -60, -16, -7, -19, -79, 68, + 21, 9, 53, 3, 30, 24, 50, 19, -43, 46, -25, 56, -55, 3, 74, -77, + 20, -36, -1, 2, 33, -30, 11, 35, -36, -26, 3, -9, 25, 27, -35, 12, + -31, -17, -61, -44, -14, -32, 79, -59, 69, -35, -32, 82, 20, -41, -61, 71, + -29, 1, -35, 35, 21, 43, 12, -37, -8, -13, -22, 13, 12, 44, -39, -19, + -29, 1, 3, -50, -36, 79, -19, 8, -21, 11, -47, 32, 18, -70, -6, 13, + 22, -56, 69, -25, 45, -62, 0, 52, -8, -81, 50, -66, 65, -59, 24, 69, + -19, 31, 16, 0, 20, 6, -78, 23, 68, -56, 29, -2, -2, -9, 38, -24, + 7, -7, 56, -55, 72, -42, -16, 2, -15, 53, -5, -53, -65, -86, 47, -22, + 56, 38, -48, 39, -21, -14, 6, -12, 19, -34, -38, -51, 24, 18, -14, -42, + 27, -21, 4, 1, 5, -22, 33, 14, -23, 11, 65, -32, 28, 16, 40, -24, + 66, -91, 80, -65, 14, -25, -1, -44, 22, 19, 14, -15, -18, 62, -28, 40, + 49, -37, 60, -55, -54, 32, 30, 8, -54, 0, 33, 39, -43, 39, -58, -56, + -41, -31, -16, 35, -5, 7, 76, -59, 97, -65, 17, -65, 32, -26, 4, 10, + -44, 40, 24, -48, 15, -3, 14, 24, -40, 25, -37, 47, 5, -19, 57, 4, + -56, 82, -60, 21, -12, -64, 27, -26, -46, -24, -13, 43, -8, -30, 44, -5, + 53, -69, 55, -57, 75, -77, 45, -85, 53, -108, 82, -12, 9, 6, 55, -26, + -11, -34, -28, 60, -62, -25, -40, -12, -17, 44, -55, 42, 37, 43, -32, 74, + -49, -41, 46, 36, -58, 62, -56, -32, 56, 51, 27, -31, -4, -31, 76, -81, + 49, -49, 99, 39, -14, 19, -71, 54, -60, 3, 28, -78, -54, 65, 13, -39, + -49, 51, -26, 0, -16, -28, 15, -23, 2, -25, 10, -6, 13, -52, 47, -4, + -4, 42, -58, 46, 66, -70, 13, -20, -10, 70, -67, 2, 5, 20, 26, 29, + -3, -28, -44, 72, -56, 85, -42, 52, -41, 62, -54, 29, 37, -36, -35, -71, + 59, -77, 40, -2, -44, -42, 34, 11, -72, 61, -59, 34, 10, -59, 22, -21, + -29, 78, -70, 39, 15, -8, -16, 72, -90, 31, 9, 22, 57, 48, 18, 12, + -96, 28, -9, -52, 82, -68, 89, -96, 101, -68, 75, 9, -27, 2, 59, 29, + 20, -48, 12, -19, -2, 63, -45, -24, 57, -63, -43, 51, -54, -22, -23, -21, + -52, 59, -3, -35, 55, -15, -22, 56, 4, -52, -1, 33, 10, -38, 33, -60, + -57, 74, -47, 51, 48, 31, -75, 11, 62, -18, 8, -83, 46, 50, -39, 106, + 10, 48, -29, -29, 41, -35, -66, 13, -56, 35, -33, 61, -1, 1, 28, 37, + 13, -22, 19, 32, -51, 69, -19, -42, 11, 50, -42, -25, 25, -28, -22, -56, + 43, -65, 16, 3, 8, 14, 59, -21, 81, -45, 18, -30, 22, -34, -17, -48, + -22, 28, -1, 16, -27, 41, 5, -35, 17, 46, -34, 11, -32, 36, -13, 5, + 45, -58, 17, -18, 25, -33, 65, -10, -7, -32, 64, -97, 8, -59, 16, -73, + 73, 27, -10, -14, 61, -52, 44, 31, -60, -29, -47, -33, 48, 36, -80, 54, + 0, 14, -57, -46, 86, -59, 61, -20, 20, 16, -50, 59, 32, -43, 48, 51, + -1, -3, -4, -47, 47, -51, 57, 46, -47, 105, -84, 61, 8, -33, 29, -24, + 11, -2, 7, -43, 4, -45, 47, -88, 82, -107, 73, 8, -15, 21, -12, -56, + 2, 46, -2, -51, 55, -59, -33, -57, -13, -51, 72, 24, -53, 0, 68, 53, + -52, 59, -46, 43, 6, 28, 18, 29, -77, 77, -28, 1, 4, 26, 40, -24, + 48, -72, 20, 14, -19, 13, 20, 0, 24, 10, -44, 59, -64, -35, 11, -15, + 49, 24, -38, 31, 11, -38, -12, 66, -97, 59, -39, 32, 17, -22, -57, -26, + -5, 29, 16, 36, -53, -8, -6, 75, -78, 62, 33, -36, -4, 19, 35, -24, + 43, -37, -22, -1, -16, 27, -37, -17, -13, 41, -44, 40, -1, 2, -39, 55, + 60, -87, 68, -102, 17, -61, 76, 41, -72, 50, -62, 54, 0, -56, -6, -51, + -9, -33, -19, 15, 35, -52, 100, -42, 84, -49, 3, -25, -22, 15, -21, -62, + 31, -25, -20, -11, 10, -37, -34, 74, -53, 8, 24, 22, 7, 30, 7, 42, + 28, 54, -45, 38, -46, -6, -76, 62, -36, 0, -22, 12, 12, -9, 58, -6, + 35, 15, 16, -51, 85, -35, 65, -81, 76, -49, 14, 9, -41, -23, -31, 44, + 18, 6, 58, -87, 64, -3, 51, -67, 111, -72, 55, 24, 22, 38, -49, 11, + -2, 13, -14, 7, -35, 9, 5, -38, 71, -51, 55, 34, -46, -56, 68, -66, + 60, -7, -8, 53, -54, -46, 51, -56, -51, 45, 31, 15, -46, 70, -71, -79, + 21, 14, 7, 53, 51, -30, -38, 15, -26, -49, 31, -9, -4, -33, 21, -42, + 30, -6, 16, 33, 30, 15, 39, 58, -28, 36, 20, -67, 43, 10, -40, 52, + -41, 13, 6, -13, 22, 34, 40, 59, 49, -26, -18, -54, 13, 64, -39, -57, + 30, -61, -22, -4, 17, 38, -38, -9, 84, -88, 13, 5, 13, -6, -39, -21, + -13, 65, -7, -61, 28, 0, -31, -13, 26, -23, 21, -42, -9, 47, -1, -77, + 51, 2, -21, 13, -14, 31, -26, -16, 28, 20, -41, 22, -16, -15, 28, 37, + -17, -40, 29, 12, -15, 63, -40, -1, 4, 12, -3, 32, 32, -56, 39, 59, + -55, 4, 6, 26, -78, 85, -60, 66, -3, -35, -25, 50, 0, -52, 27, 39, + -69, 37, -9, 55, 6, 57, -60, -46, 42, 10, 62, -16, -44, 90, -22, 2, + -6, 58, 40, -53, 7, 44, -64, 15, -63, 16, -23, 46, 20, -48, 33, 9, + 9, -7, 36, -59, 72, 0, -12, 18, -27, -3, -37, 18, -48, -19, 0, -32, + -35, -38, 1, 42, -59, 53, -12, 0, -42, 39, -29, 46, 4, 25, -52, -32, + -84, 48, -20, -23, -47, -1, -8, -9, -4, -13, 13, -1, 66, -41, 65, -95, + 18, 7, -81, 90, -35, 9, -49, 45, -89, 21, -43, 9, -54, -21, 56, -21, + -29, -19, 25, -19, 54, -89, 46, -31, 11, -21, 43, -24, 48, 17, 4, -2, + -65, 15, -45, -12, 59, -29, 49, 23, 63, -67, 18, -48, 46, -16, 34, 73, + 32, -51, -14, -25, -32, -29, 52, 3, 12, 38, -22, -1, -41, 52, 23, -16, + -23, 38, -3, -37, -55, 0, -34, -53, 34, 12, -44, 17, -30, 70, -15, -63, + 85, -30, 15, -51, 37, -75, 49, -87, -1, 58, -11, 50, 12, -56, -28, 62, + 3, 71, 1, -36, -23, -5, 0, -15, -51, 51, 1, 10, -4, 21, 10, 22, + -10, -75, 6, 86, -46, 5, -61, 51, -32, 25, -3, 54, -16, -3, 45, 0, + 5, -51, 15, 43, -37, 56, -73, 52, -33, 26, -7, -21, -24, 61, -16, 26, + -41, 10, 18, -50, 25, 29, -38, -17, -21, 68, -73, 37, -51, 65, -35, -36, + -23, 41, 25, 9, 76, -65, 25, -49, 20, 46, 28, -65, 90, -52, 54, -80, + 56, -23, -5, -15, -59, -23, -2, 3, -60, 17, -67, 29, -23, -36, 11, 18, + -56, 15, -66, 88, -27, 26, -18, 1, 47, 35, -20, 38, -41, -21, 12, 7, + 23, -52, -28, 66, -42, 36, -59, -2, 75, -28, 0, 6, -6, 9, 17, 16, + -33, 64, -42, 47, 7, 38, -32, 3, 27, 22, -31, -27, -62, 61, 45, 27, + 55, -70, 44, -9, 34, -28, 57, -23, 9, 41, 47, -63, 31, -4, 11, 51, + -3, -29, 66, -62, -19, -62, 73, -74, 56, 38, -70, 66, 33, 37, -17, 3, + 81, -32, -36, 7, -6, 42, 52, -61, 35, 26, -60, -1, -37, 33, -40, 30, + 39, 15, 73, -78, 50, 7, -90, 34, -14, -44, 37, -15, -45, -7, -43, -63, + 10, -5, 16, 77, -64, 41, -88, 64, -25, -19, -32, 16, 34, -48, -51, 49, + -20, -38, 71, -26, 72, 71, -51, 38, -75, 13, 47, -23, -24, -44, 15, 25, + -67, 67, -4, 8, 9, 20, -54, 58, -10, -36, -28, -30, 6, 30, -41, 9, + 41, -71, -50, 49, 66, -46, 28, -43, 95, -66, -1, -27, -6, 5, -16, -7, + 12, 53, 19, -68, 0, 53, 12, 47, -46, -30, -16, -7, -13, -17, -20, -30, + 1, 27, -25, 1, 39, -11, 24, -1, 64, -82, 75, -45, 63, -37, 45, -16, + 15, 0, -25, 41, -6, -67, 55, 5, -43, -43, -32, 14, -2, 23, -43, 11, + 18, -10, 37, -38, -55, -5, 27, 38, -55, 40, -44, -14, -54, 60, -11, 31, + -34, 55, -57, 33, 48, 44, 25, -13, 64, -59, 15, -6, 61, -10, 36, -51, + 82, -26, 23, -83, 73, -51, 55, -14, -73, 42, -3, -48, 12, 48, -2, 15, + -32, 70, 6, -46, 44, -69, 71, 7, -28, 13, -21, -34, 39, 43, -24, 53, + -52, 18, 35, -65, -29, 32, -21, 5, 18, 4, 8, 2, 22, -60, -89, 38, + 55, 3, -60, 17, -39, 75, -100, 69, -36, -22, -36, 15, -53, 42, -60, -5, + 40, -42, -12, 44, 21, 61, -53, 11, -1, 17, 24, -35, -85, 49, -53, 66, + -80, -8, 19, 35, -32, -3, -3, -2, -1, 0, 8, 51, -50, 57, -59, 18, + -8, 1, -11, 23, -26, -3, 65, -53, 30, 37, -4, 48, -2, 39, 14, 52, + -31, -19, 2, -37, 36, 37, 20, -28, 7, -32, 76, -55, 50, 26, 59, -22, + -10, 9, -59, -43, -23, -57, -9, 31, 12, 23, -13, -22, 54, 6, -78, 46, + 7, -30, -23, -7, -36, 20, -9, -34, 52, -14, 41, 43, -28, 38, -19, 64, + -71, 30, 80, -65, -5, -15, -22, 9, -54, 60, 46, -52, -24, 35, 18, 20, + -62, 24, 30, -28, 35, -38, 0, -6, 38, -13, 4, 45, 9, 22, 10, 68, + -20, 29, -38, -10, -44, 8, -9, -7, -21, 16, -7, 6, -44, -8, -42, -9, + -48, 65, -56, 59, -75, 80, -47, 29, 48, 28, 41, 28, -25, -18, 63, -48, + 13, -41, -26, 25, 14, 26, 17, -24, 71, -46, -38, 86, -38, -16, -48, 9, + -49, -31, 92, -71, -45, -53, 29, 34, 6, 4, 39, -21, -45, 36, 3, -4, + -1, -10, 51, -21, -25, -1, 14, -52, 47, 34, -90, 34, 35, -71, -47, 53, + -10, -37, -47, 15, -27, 86, -17, -47, 28, -37, 24, 3, 25, -75, -18, 7, + 16, 36, -29, 52, 9, -38, 81, -51, -62, 20, 46, -86, 49, 31, 80, -42, + -18, -33, 95, -30, 89, -53, 55, -23, 4, 13, 0, 3, 39, -34, 74, -42, + -33, -27, 46, -14, -33, 3, 38, -5, 3, -3, 7, 31, 30, 19, -65, 28, + 0, 66, -81, 28, -69, 40, -56, 6, 42, -65, 40, -56, -6, -15, 2, -6, + 26, -49, -3, -65, 45, 21, -11, 10, -15, -42, 10, -83, 34, -29, 34, -20, + -36, 54, -51, 2, -11, -82, 71, -19, -11, 24, -13, 48, -90, 48, -88, 42, + 68, -27, 68, 52, -28, 38, 3, 17, -11, 5, -3, -1, -11, 3, 70, 26, + -46, 89, -80, 58, -60, 73, 19, -29, 24, -13, -60, 39, -32, -39, 38, -45, + 11, 13, -56, 38, 48, 6, -14, 41, 15, -50, -22, 64, 2, -33, 13, 31, + -50, 46, -9, -20, 42, -51, 12, -27, -10, 7, -50, -2, -11, -8, 7, -63, + -42, 17, 66, -59, 28, -51, 73, -57, 0, -18, -46, 63, -29, 36, 0, 24, + -14, 11, 35, -92, 95, -59, 8, -12, 16, -24, -63, -17, 50, 3, -12, -31, + 35, 23, 11, -45, 30, -54, -56, 57, -63, -13, 35, -34, 84, -56, 90, -58, + 83, -11, -56, 85, 3, 41, -16, -79, 50, -58, -33, 67, -37, -38, -60, 16, + 13, -19, 45, -48, -7, 9, 46, 14, -67, 25, 49, 18, -4, 77, -40, 56, + -45, 7, 34, 55, -37, -33, -54, 84, -37, 9, 53, -10, 1, 100, -54, -21, + -31, 19, -44, -2, -8, -19, -44, 36, 28, 30, -37, 27, 33, -23, -29, -35, + -47, -15, -56, -28, -31, -33, -42, 30, 30, -43, -11, -3, -46, -1, -27, -10, + 96, -18, 20, -4, -1, 28, -66, -2, 21, -7, -82, 24, -68, -3, 51, -44, + 5, 4, -15, 53, 33, 14, 20, -22, 25, 12, 5, 48, 8, 74, -62, 44, + -44, 92, -70, 55, 18, -34, -6, 21, 47, 11, -34, 47, 30, -43, -31, -16, + 57, 15, -32, 72, -4, 84, -55, -12, -14, 40, -63, -29, 89, -58, 70, -58, + -37, -32, -62, 75, -48, -14, 36, -91, 25, 30, 14, 22, -42, -17, -31, -14, + -30, 5, 72, -7, 20, -68, 0, 41, -90, 74, -87, 69, -69, 86, -57, -32, + 68, -50, -13, -33, -34, 50, -29, -34, 52, -1, -69, 40, 1, -24, -30, 1, + 32, -47, -30, -2, -13, 29, 41, -10, 8, 64, -20, 16, 51, -39, 33, 69, + -40, 47, -92, 60, 33, 17, -28, 31, 39, -13, 47, -18, 22, 9, 46, -73, + 20, 43, -79, 58, -26, -29, 22, -8, -26, 24, 64, -83, 40, -44, 87, -36, + 14, -52, 3, -15, 46, -5, 54, -28, 52, -38, 47, -29, -46, 30, -46, 33, + -16, 0, 41, -99, 58, -70, -4, 65, -10, 50, 42, -29, -23, 66, 29, 55, + -47, -20, -60, 57, -8, 55, -59, 16, 33, -44, 7, -33, 24, -67, 12, -45, + 34, 44, -62, 19, -51, 39, -25, 5, 14, -1, -27, -33, -6, -97, 78, 22, + -49, 93, -56, 14, 47, 9, -37, -20, -10, 5, 7, -3, -86, 61, 1, 49, + 43, 86, -19, 70, -14, 20, 37, -20, -49, 71, -28, -19, 84, -80, 95, -49, + -41, -34, 76, -64, 19, 55, -14, -14, 3, 26, 44, 21, 58, -11, 4, 37, + -30, 48, 39, -79, 23, -17, -48, 47, -36, -11, -30, -23, 2, -64, 7, 15, + -28, -18, 22, 40, -22, -20, -2, -25, -30, -58, 50, 16, -13, 6, 36, 42, + -51, -20, 52, -85, -30, -52, 68, -1, 14, 28, 46, -14, -64, -21, 40, -29, + 41, 28, -10, -78, 68, 15, -34, 73, 22, -83, 72, -58, 50, 40, -31, 0, + 19, -37, -23, -4, -55, 82, -9, 16, 45, -21, 49, 52, -77, 76, -50, 60, + 12, -2, 69, -10, 78, -72, 39, 26, -56, 12, 27, 51, -76, 81, -47, 15, + 34, -39, 72, -57, -18, -13, 20, -35, -37, 11, -29, -40, -13, -11, -39, -25, + 45, 25, 21, 30, -80, -6, -7, -56, 36, -41, 3, -30, -51, -18, -20, 48, + 13, -39, 64, 18, 54, 16, -45, -18, 5, -8, -25, 60, 21, 2, -62, 43, + -39, 94, -23, 4, -46, 22, 15, -55, 21, 53, -62, 72, -61, 45, -8, 48, + -62, 33, -3, 85, -78, 91, -72, 20, -48, 3, -47, 36, 30, -17, -19, -34, + 14, 25, 24, 30, -6, -47, 59, -52, -24, -35, 96, -55, 39, 53, -72, 71, + -52, 34, 47, -27, 14, 39, 37, 6, -15, -35, 43, -42, 50, 55, -22, -43, + 41, -91, 57, 28, -77, 27, 77, -39, 30, 36, -7, 7, 27, 18, -30, 19, + -21, -39, -43, 21, 24, 40, -18, -2, -26, 60, -31, 49, -25, 77, -41, -3, + 85, -56, -28, -36, 43, -84, 22, 1, 17, 35, -90, 10, -23, -16, -43, 27, + -2, -52, -20, 14, -32, 68, 23, -30, 27, 58, -51, 17, 49, -41, 38, 30, + 9, -57, 59, -52, -2, -15, 51, -19, 7, 57, -16, 27, -54, 35, -56, -20, + 52, -3, 14, 73, 5, 10, -33, -12, -27, -29, 36, -51, 76, 8, 49, -72, + 17, 44, -24, 72, -34, 0, -51, 30, -74, 66, -41, -3, -28, -9, 31, -9, + -4, 22, -33, 18, 24, -77, 74, -98, 27, 17, -51, -3, 35, -62, 44, -41, + -20, -31, -29, 5, -32, 17, -44, -18, 80, -63, 18, -42, 73, -41, 52, -68, + 54, 2, 17, 9, 71, -1, -17, 35, -10, 69, -31, 64, 18, 52, -39, -22, + -45, -6, 7, -44, 41, 0, 41, 27, 32, -8, -41, 32, 47, 9, 29, -3, + -49, 15, -58, -16, -88, 18, 50, 0, 20, -13, -5, -1, -62, 5, 40, -82, + 59, -85, 0, 2, 57, -23, -18, 6, -8, -47, -7, -29, 92, -82, 73, -67, + 36, -50, -10, -35, 42, -72, 73, -40, 16, -32, 37, -30, 10, -25, -3, 7, + -42, 49, -47, -11, -37, -7, 29, 17, 45, -44, -71, 33, -26, -54, 62, -1, + -43, -38, -61, 55, -20, -29, -46, 35, -48, 95, -94, 96, -76, 0, 6, 34, + -8, 28, 1, -45, 79, -29, -61, 27, -17, -28, -27, 19, -37, -47, -13, -11, + -35, 14, -11, -1, -45, -14, -33, 39, -31, -27, 8, -28, 70, -81, -29, -11, + 6, 26, 55, -8, 32, 45, -54, -18, 49, -62, 74, -36, -6, 57, -26, -8, + -33, 41, 40, -20, -52, -26, -38, -10, -20, 0, 58, -47, -10, 44, 17, -70, + 21, -7, 29, 16, -46, 21, 22, -30, -39, 31, -45, -18, -5, 0, 29, 27, + -70, 40, -47, -58, 41, -56, 45, -34, 58, -35, 22, 1, -45, -35, 11, 41, + 0, -26, -34, 37, -25, -31, 73, -69, 73, -71, 44, -34, 68, -28, 62, -35, + -45, 70, -27, 39, 14, 50, -61, 82, -59, 55, -46, 38, -84, 70, -30, 60, + -30, 38, -2, -27, 34, -32, 27, 10, -30, 56, 9, -33, -37, -1, -42, 14, + -52, -7, -10, -30, -28, -18, 41, 2, -28, -65, -25, -48, 21, -51, 29, 56, + -39, 6, -39, 59, -6, 13, -37, -53, 5, 65, -32, 77, -65, -9, -35, -13, + 45, -23, 58, -40, 105, -42, 29, -71, 32, -64, 31, -9, 27, 3, -9, 41, + 37, 20, 38, 2, -35, -62, 16, 39, 43, 18, 58, -48, -21, -43, 39, -44, + 42, -14, 23, 2, 50, -21, 45, 0, 32, -35, 66, -86, 76, -53, 60, 5, + 36, -4, -13, -27, 29, 58, -83, 11, 0, 40, 21, 50, -73, 29, -58, 38, + 33, 63, -17, 61, -27, -8, -3, 25, 12, -61, 65, -37, 17, 40, -65, -15, + -8, -9, -15, 64, -83, 34, 5, 26, -1, -29, 39, -32, 16, 84, -32, 48, + 38, 2, -20, 39, 15, 15, 2, -30, 83, -25, 29, -3, -85, 58, 49, 4, + -32, -2, -33, -34, 35, -41, 56, -62, 31, -8, -2, -21, -23, 0, 27, 53, + -28, -49, 21, 50, 68, 7, 0, 43, 30, -35, -41, 23, 52, -54, -61, 104, + -18, -7, -23, -10, 46, 22, -4, 17, 27, -60, 59, 5, 29, -4, 25, -68, + 87, -11, -41, 57, 45, -25, 6, 8, -42, 50, -18, -18, 94, -23, -11, -35, + 1, -9, 24, -44, 15, -21, 33, 31, -54, 31, 9, -35, 0, -34, -33, -16, + 49, -19, -48, 1, -27, 13, -17, -55, 37, -5, -16, 8, 25, 3, -56, -1, + -45, 33, 8, -25, 47, 21, -20, -8, -36, 19, -38, 25, 64, -8, 49, -14, + 29, 59, -68, 6, 27, -24, 18, -27, 33, 35, 37, 4, -11, 45, 23, 1, + 9, 48, -22, 4, -27, 0, 53, -1, -8, -8, -12, -45, 37, 36, 3, 3, + 33, 31, -55, 57, -97, 31, 28, 36, 1, 60, -28, -22, 39, -11, -48, 27, + -63, -10, -35, -21, 51, 50, 26, -57, -61, 44, -86, 48, 21, 14, -22, 30, + -29, 17, -43, 7, -15, -14, -19, -12, -49, 38, -41, 90, -62, 43, -2, -66, + 27, -5, 9, 44, -15, -50, 45, 0, -64, 60, -66, 57, 11, 48, 17, -70, + 39, -94, 22, -72, -40, 71, -19, -10, 9, 43, -57, 52, -51, 5, 4, 85, + -34, -35, 21, -19, -7, 20, -56, 24, -13, 22, -26, 64, -5, -36, -38, -25, + -42, 33, -20, 2, 9, -15, 50, -41, -26, -50, 44, -18, 68, -19, 3, -76, + 39, -37, 52, -65, 21, 19, -12, 62, -15, -26, 39, 43, -6, 46, -72, 28, + -2, 46, 3, -49, -44, -23, -21, -15, 12, -79, 72, -30, -17, 0, 38, -89, + 28, -15, -13, -10, -56, 72, -80, 26, -66, 59, -38, 0, -9, -4, -1, 9, + -70, 59, -18, -11, -48, 28, 4, -3, 17, 16, -31, 3, -54, 40, -14, 54, + 23, -37, 29, 36, 6, -31, -1, -21, 46, 22, -51, 54, -9, 13, 57, 13, + 12, -46, 61, -7, 51, 12, -12, 37, -10, -12, 34, -24, 18, 47, -33, 61, + 11, -30, 30, 43, -37, -45, 33, -24, 47, -30, 57, -35, -51, 8, 10, -18, + 34, -56, 79, 7, 45, -43, -3, -26, 7, 10, 13, -36, 29, -60, 0, -17, + 35, -38, -39, 61, -61, 31, -72, 87, -72, -32, -5, -19, 8, 3, -13, 13, + -80, -8, -5, -57, 50, -25, -28, -41, 6, -52, 61, -38, 8, -7, 47, -52, + 17, 50, -62, 59, -32, -34, 25, 12, -6, 59, -23, 43, -49, 70, -13, 13, + 0, 50, 39, -41, 34, -49, 45, -61, 43, 4, 3, -24, -22, -52, -17, 20, + 28, -27, -14, -30, 3, 36, -32, 21, 27, -75, 65, -44, -42, -16, 54, 14, + -19, 43, 42, 69, 55, -12, -67, 35, -33, -6, 39, -60, -22, 55, 13, -56, + -6, 73, -26, 63, 49, -80, 52, 9, -70, 12, 34, -50, -19, 40, 21, 19, + -1, -3, -2, 6, -46, 0, 34, -61, 69, 13, -18, -37, 33, -68, 14, 54, + 75, -82, 59, 53, -74, 54, 3, -53, 9, -18, -54, 54, -90, 39, -40, 32, + -2, -63, -36, 19, 7, 66, -12, 4, -11, 49, 34, -73, 55, 1, -36, 95, + 16, -34, 44, 29, -45, -34, 31, -4, 0, 47, -42, 19, 22, 10, -19, -37, + 51, -30, 34, -6, 9, -35, 47, 48, -84, 64, -28, -20, 32, -5, -40, -45, + 18, 44, 7, 1, -38, 16, -44, 37, -37, 14, 8, -35, -17, 16, -26, -49, + -71, 78, -35, -4, -59, -6, -21, -7, -7, 15, -38, 18, 16, -50, 30, -38, + -37, 46, -65, -40, 63, -9, -28, -7, 32, -20, 25, -28, -18, 73, -54, -34, + 30, -35, -7, -87, 35, 33, -64, 84, -72, 0, -23, 33, 38, -7, 0, -24, + -57, 31, -4, 35, 14, 6, 6, -40, 70, 61, 14, -45, 40, -20, -14, 10, + 49, 47, 16, 20, 7, 55, 14, 35, -16, -6, 44, -16, 43, -67, 0, 34, + -36, 19, 34, -49, 35, -49, -6, -7, -19, -51, 8, 12, 22, -89, 14, 11, + -59, -15, -44, 56, -63, 70, -9, 43, -43, 31, -25, -33, 34, 32, 65, -71, + 31, 9, 16, -32, 26, 32, 4, 2, 46, -46, 23, 2, -11, 21, -43, -10, + 30, -32, -54, -69, -51, 7, 43, 2, -21, -36, 0, 37, 45, -28, -59, 65, + -55, 12, -42, -49, -18, 10, 51, -30, 74, 11, 28, -35, -32, 41, -60, 53, + -10, -5, 63, -20, -27, 14, 44, -27, 30, -26, -17, 97, -72, 49, 23, -32, + -74, 46, -53, 4, 2, -25, -26, -14, 40, 32, 8, -72, 56, 9, 78, -79, + -20, 88, -6, 1, 35, -68, 44, -22, 43, -70, -4, 43, 9, -16, -6, -70, + -27, -4, 4, -24, 35, 8, 20, 14, 19, -39, 27, 2, -52, 47, -12, 10, + 35, -50, -5, 12, 0, -23, -27, -12, -2, 20, -31, 16, -29, 34, 12, 18, + -65, -9, -75, 78, -65, 95, -13, 29, -25, 2, -10, 61, -50, 88, -30, 56, + 49, -5, -20, 0, 66, -26, 41, -36, -3, -44, 48, -36, 20, -35, 51, 16, + 28, -58, 69, -10, 52, -47, 21, 3, -17, 34, -72, 19, 7, -41, 13, 12, + 47, 11, 46, 42, -74, 16, 71, -52, 37, -5, 38, -4, -73, 56, -21, 14, + 61, -47, -30, 58, -76, 17, -43, 51, -52, -41, -29, 42, -26, 52, -12, -2, + -11, -30, -36, 48, -47, -15, -73, 43, 67, -94, 17, -71, 34, 51, -17, 0, + 34, 9, 30, -22, -36, 54, 53, 24, -19, 7, -6, 62, -85, 93, -19, 19, + -11, 52, -6, -22, 49, -44, -32, 56, 5, -81, 95, -34, 38, -3, -57, 83, + -51, 61, -78, 37, 18, -53, -40, 63, -63, 21, 28, -20, 47, -26, 0, -57, + 52, -9, 30, 55, 9, 12, 15, -53, 57, 12, -26, 31, -39, 44, 13, 0, + 2, 39, -20, -21, 74, 6, -27, -24, -32, -66, 28, 47, -23, 23, 58, -31, + -26, 20, -86, 75, -38, 66, -51, 2, 19, 54, -23, -61, 57, -82, 40, -62, + 63, 43, -34, 50, -21, 39, -41, 53, -13, 14, -25, 58, -36, 10, -68, 39, + 56, -96, 40, 2, -53, 65, -9, 18, -13, 25, 20, -48, 51, -11, -13, 87, + -21, 48, -7, 60, -53, 40, 25, -92, 35, -39, 74, -69, 77, -101, 64, 26, + -58, 50, -37, -17, 16, 51, -62, 11, 13, 20, 23, 31, -19, -25, 15, 3, + 83, -11, 38, -10, -11, -43, -45, 18, 15, 0, -42, -5, -18, -68, 0, -12, + 5, -40, 28, -30, -50, 28, 6, 64, 13, 1, 0, 14, 40, -37, -9, 9, + 1, 0, -53, 24, -7, 3, 18, -56, 36, 9, 11, 65, 3, 47, -11, -17, + -26, -40, 11, -52, 91, -40, -42, 7, 14, 20, -50, 36, -53, 48, -22, -11, + 26, -6, -14, -30, 61, 38, -3, 6, -21, 76, -33, 40, 11, -58, -14, 50, + -73, 75, -31, -37, -5, -3, 52, -33, -48, 68, 52, -34, 54, -72, 45, -12, + 22, -35, -42, 12, 55, -19, -75, -26, 18, 17, -23, -52, 37, 0, -76, 65, + -31, 2, -36, 38, 17, 12, 58, -92, 15, 32, -33, -35, 35, -22, -34, -16, + 3, -51, 106, -68, 62, -29, 44, -47, 54, 9, -13, 6, -46, 41, -16, 21, + 37, -32, -44, -11, 36, 15, -8, 0, -11, 15, 30, -5, -34, -69, 71, 0, + -58, 59, -12, 51, -76, -26, -21, 52, 8, 37, -81, 53, -61, -1, -25, -27, + 58, -31, 13, 11, -13, -32, 19, -27, -45, -58, 23, -15, -17, 44, 13, 8, + 2, -27, 0, 0, 0, 8, 10, -17, -14, 2, 63, -50, 69, -48, 7, -7, + -27, 76, -14, -34, -24, 24, -28, -32, 45, 18, 11, -42, 15, -24, 41, -93, + 50, -96, 48, -84, 55, -65, -37, 52, 8, -11, -48, 31, 0, 41, -21, -14, + 18, 24, 7, 28, -40, 0, 48, -30, 5, -47, -3, -54, 43, -33, 3, -6, + -25, -62, 47, -27, -13, 80, 30, 46, -27, -12, 16, 40, 22, 66, -43, -14, + 26, 34, 27, 45, -26, 24, -27, -49, -50, 74, -74, 64, -97, 19, 0, -9, + 21, -44, 12, 29, -67, 7, 19, -3, 18, -32, -33, -30, -68, -14, 3, 22, + -40, 19, 3, 25, -91, 71, 0, -34, 16, 24, -38, 63, -40, 34, -55, 24, + 3, 26, -15, 36, -73, -21, -30, 52, -24, -28, 55, -57, 20, 9, -62, 44, + 11, -1, -37, 62, -31, 56, -51, -27, 35, -18, -77, 66, -61, 14, -8, 40, + -61, -34, 49, -25, -34, 24, 45, 19, -77, 83, -75, 88, -12, -39, 93, -53, + 43, -43, -32, -17, -42, -18, -18, 26, 31, -20, 9, 30, 18, -54, 49, 52, + -34, 9, -54, 26, -35, -30, -34, 19, -49, -5, 5, 0, 9, -31, 34, -49, + -9, 41, 4, 23, -102, 59, -57, 62, -32, 9, -1, -43, 83, -10, -20, -52, + 54, -49, -26, 55, -13, 48, -24, -39, 30, -24, 71, -51, 55, 0, 12, -1, + -32, 57, 23, -57, 63, -33, -17, -1, 51, 46, 24, 24, 3, -77, 71, -72, + 11, 26, -46, 59, -63, 33, -11, -25, -15, -45, 17, -59, -9, 44, -53, 46, + 58, -63, -39, 92, -31, 3, -2, -19, -26, -8, -48, 59, -9, -43, 24, 26, + -18, 74, -15, 48, -28, 36, 58, -17, 19, -22, 57, -18, 3, -32, 0, -6, + -31, 11, -41, 1, 42, -11, 50, -50, 55, 25, 55, -61, 44, 30, -64, 21, + 22, 36, -19, -44, 6, -82, 1, -71, 33, -41, 1, 27, -75, -9, 51, -6, + -55, -44, -63, 54, -33, 53, -18, 26, 42, -73, 18, -6, 63, 19, -49, 15, + -11, 21, 6, 23, 53, -54, 49, -55, 17, -10, 57, 4, 54, 52, -58, 56, + 28, -71, 53, -68, 89, -72, 31, 21, -40, -11, -12, -11, -23, 4, 21, 34, + -35, 11, -6, 43, 51, 20, -30, -44, 71, -81, 25, 22, 7, 15, 25, -37, + 16, -13, 33, -2, 9, 10, -31, 96, -70, 62, -20, 19, 24, -16, -14, 25, + 13, 37, -9, -3, -35, 28, -19, 29, 38, -44, 17, -29, -31, 19, -56, -45, + 41, 41, 58, 25, 21, -5, 20, 46, -89, 61, -40, -1, 29, 6, -50, 14, + -53, 83, -46, 15, 4, 43, 13, 23, -9, 9, -35, 23, 26, -52, 45, 45, + -43, 41, -41, 4, 47, 11, -16, -59, 41, 14, -2, 44, -82, 41, -31, 6, + 33, -12, 72, -54, -6, -16, 64, 17, 0, 54, -53, -16, 65, -82, 91, -78, + 39, -69, 22, 10, 74, -70, 55, 6, 0, -57, -41, 55, -72, 71, -42, 60, + -54, 8, -33, -28, 77, -64, -34, 44, 50, 2, -52, 85, -44, 33, 63, -59, + -63, 46, 53, -99, 48, -28, 49, -14, 58, -55, 54, -91, 78, -56, 40, 8, + 13, -59, 0, 1, -25, 13, -50, -63, 79, -41, -42, -3, -7, -40, 10, -21, + 70, -27, 18, -11, 37, -36, -45, 56, -63, -13, -25, 40, 6, -15, 68, -44, + 21, -41, 26, 17, 24, 49, 20, 45, -60, 105, -47, -30, 89, -1, -22, 33, + 26, 56, -38, -27, 42, -38, -22, -46, 54, 11, 64, 0, -68, 28, 13, 51, + -28, 5, 10, -44, -10, -6, 69, -12, 12, -52, 42, -45, 34, -49, -24, -33, + 73, -42, 52, 39, -3, -56, 74, -56, 31, 27, 46, -76, 71, -9, 72, -61, + -19, 14, -43, -2, -52, -37, 79, -10, -13, 27, 57, -82, 17, 7, -5, 28, + 42, -40, 23, -5, -22, -10, 31, -69, -1, 11, -23, -35, -17, -15, -33, -42, + 30, -41, 30, 53, -19, 16, -57, 59, -85, 60, 7, 43, 43, -32, 38, 39, + -3, -57, -22, -72, 67, -54, -6, -60, 41, -3, 7, -61, 57, -5, 5, 29, + 49, -76, 46, -30, 29, 9, -36, -51, 71, -23, -15, 19, -32, 35, -37, -37, + -45, 14, -45, 36, -4, -16, 68, -21, -47, -27, 6, -53, 72, -1, 26, 25, + -82, 18, -65, 75, -54, 27, -71, -48, 32, -96, 82, -68, 52, -56, -19, 57, + 7, -19, 9, -46, -62, 43, -4, -55, 59, 67, -39, 36, 51, -77, 30, 9, + -4, 38, 18, 48, -29, 46, 58, -93, 47, 3, -27, 3, 10, -35, -15, -20, + 84, -74, -2, 48, -31, 51, -76, 2, 41, -30, 9, 45, -16, -18, -7, 46, + -44, 1, 13, 15, -55, 30, 16, 61, -104, 52, -7, 49, -42, 71, 40, -19, + -26, 11, -49, 40, -37, -19, 16, -44, 14, 64, -7, 16, -55, -38, 30, -49, + 24, -1, 34, -14, 44, -52, -19, 61, -29, -78, 35, 15, -66, -12, 28, -63, + 27, -26, 45, 25, 22, -29, 72, -40, -32, 27, -79, -37, 37, 20, -23, -16, + -7, -53, 68, -30, 30, -13, -62, 21, -32, 49, -48, 45, -53, 46, -3, 36, + -46, -21, -1, -63, 22, 6, -25, 3, 45, -78, 34, 48, -56, -15, -63, 27, + -42, 73, -18, 22, -9, 28, -68, 29, -33, -23, -59, 8, 53, 6, -46, -61, + 17, 2, -45, -33, 56, -54, 48, 37, -8, 21, 28, 28, 36, 26, 50, 47, + 14, -33, -1, -105, 55, -12, 37, -69, 43, -7, -39, -14, -60, 3, 32, -100, + 47, 45, -26, 69, -36, -11, 50, 9, 23, -14, 1, 17, -47, -15, 5, -77, + 21, 66, -74, 49, -30, 16, 45, -15, -14, 3, -47, 26, 7, 22, 21, 42, + -2, 57, -2, 22, -68, -3, -45, 23, 33, 34, -14, -10, -49, 64, -70, 49, + 64, -41, 34, -29, 61, -30, 63, -16, 17, 64, -60, 29, -13, 48, -35, -41, + 47, 30, 4, 41, 1, -37, 35, 1, -33, -44, 1, -11, -43, 83, -75, 92, + -75, 61, -10, -67, 0, -13, -31, 83, -73, 17, 1, 16, -29, 40, 26, -59, + 3, 30, -81, 35, 12, 31, -34, 89, -87, 84, -37, -30, 28, -1, -45, 28, + -49, 8, 19, -10, 57, -72, -34, 42, 2, 47, 24, -62, 48, -14, -24, 2, + -52, 23, -29, 67, -23, 11, 40, -17, -9, -79, 9, 63, -24, 32, -6, 29, + -28, -28, -42, -30, -34, 26, -12, -51, 5, 80, -24, 11, 1, 16, 0, 17, + -57, 74, -60, -22, 23, -68, 22, 77, -47, -20, 85, -13, 22, -26, -7, -27, + 40, -27, 4, -16, -68, 59, -13, 18, 1, 25, -52, -49, -1, 11, -14, 12, + 33, -3, 60, -40, 17, 9, -54, 29, -16, 55, -81, 12, 0, -29, 87, -53, + 34, -32, -6, 40, -43, 56, -19, 37, 14, 3, 78, -50, -46, -39, 31, 12, + 32, -17, 66, -15, 25, 27, -78, 15, 24, -69, 8, -46, -5, -39, 5, -65, + -5, 27, 22, 48, 29, -36, 22, -1, 26, 5, 31, 46, 67, -43, -6, 20, + 32, -16, -29, 64, -46, -16, -19, 42, -57, 61, -55, 38, 51, -19, 41, 16, + -46, 13, 7, -66, 84, -76, 3, -3, 29, -8, 16, -17, 37, -63, -27, 0, + -22, -19, -20, 12, 24, 45, -9, 40, -10, -3, 6, 56, -56, -8, 2, -11, + -66, 36, 13, -71, 64, -51, 26, 9, 6, -21, 17, -15, 11, -15, 89, -75, + -65, -19, -3, 21, -17, -3, 55, -50, -31, 9, 71, -35, -33, -21, 34, -28, + -9, -34, -46, 88, -27, -33, 7, 8, -43, 61, -74, 40, 3, -73, 34, 43, + -27, 12, 29, 50, -98, 39, -41, -31, 8, -54, 15, 8, -48, 44, 4, -42, + 71, 28, -27, -49, 44, 40, 70, -55, 67, -78, -40, 50, -20, -35, 1, 2, + 67, -24, 47, -52, -25, 46, -28, 23, 50, 52, -63, -50, 30, 3, -17, 13, + 7, 55, 29, 24, 38, 50, -60, 49, 32, -58, 2, -50, 0, 23, 14, -21, + 0, 7, 17, 20, -45, 78, -57, -52, 58, -33, -18, -31, 38, 39, -47, 49, + 24, 46, -27, 39, 63, -28, 14, 11, -26, 23, 16, 47, 17, 16, -15, -34, + -53, 25, -35, 0, 20, 9, 41, -38, 3, 24, 24, 17, 25, 39, -43, 35, + 14, 23, -30, 29, -82, 57, -36, -5, 33, -74, 1, 30, 40, 52, -8, 3, + -11, -32, -15, -52, 36, 24, -1, -20, -20, 80, -73, 23, 25, -24, -30, -15, + 64, -47, 34, -95, 22, -62, 42, -8, -25, -30, -39, -65, -71, 51, 9, 16, + -38, 3, -28, -69, 87, 0, 7, 15, -15, 18, -22, -58, 58, -39, -4, 15, + 51, -65, 40, 0, -25, -17, 43, -7, 24, -61, 34, 50, -63, 58, 46, -3, + 51, 18, -28, 51, -98, 38, -46, -8, -5, 2, -8, -40, 20, 79, -80, 58, + -26, 67, -76, 45, -18, -35, 21, -21, 0, -6, -49, 36, -62, 76, -124, 109, + 44, -8, 15, 17, -6, -14, -20, 54, 4, 57, -85, 5, 76, -27, -8, -2, + 1, -12, 67, -27, 8, -11, 18, 13, 5, 42, -29, 19, 51, -17, 23, -42, + 29, -2, -9, -34, 74, 32, -48, 29, 25, -3, -26, 46, 28, 4, 37, 49, + -118, 46, -2, 24, -19, -21, -41, -13, -25, 22, 66, -50, -52, 55, 11, 29, + -41, -23, -34, 44, -22, 5, -27, -20, -65, 10, 50, 27, -54, 40, 14, -37, + 52, -93, 71, -69, -4, -31, -12, -14, 29, -28, 40, 67, -64, 29, 5, 17, + -24, -16, -38, -19, 40, -23, -10, 48, -45, 21, 4, 40, -81, 76, -44, -7, + -86, 61, -58, 20, -71, 38, -90, 37, -13, 21, -1, 17, -27, -16, 4, 18, + 24, 4, 64, -24, -25, -11, -47, 0, 27, -10, -36, -35, 31, -43, -15, 15, + -41, -3, 63, -71, 55, 40, -73, 30, 21, 30, 15, -29, -19, -47, 23, 31, + 17, 23, -56, 87, -90, -4, -11, 47, 46, -40, 75, -17, 7, 50, 28, 19, + -45, 32, 49, -5, 41, 63, -80, 28, -3, 27, 43, 43, 46, -6, 8, -5, + 17, -50, 57, 15, -23, -56, 3, -45, 32, -52, 33, 11, -57, 33, -55, 23, + -28, 49, 32, -46, 61, 3, 6, -9, 6, 47, -37, -17, 36, -60, -28, -44, + -46, 24, 6, -28, 45, 14, 19, 23, -34, -12, 66, -42, 63, -93, 76, -5, + -40, 14, 2, 41, -9, 18, -5, -34, -32, 60, 8, 45, -62, 21, 59, -74, + 4, -30, 15, 4, -11, 6, -40, -22, 54, -64, 72, 48, -72, 46, -13, 17, + -43, 55, -73, 57, -21, 30, 2, -20, -5, -4, -6, 26, -54, -13, 22, 27, + 2, 5, 1, -8, -52, 15, 27, 32, 9, -3, 59, -69, -15, -60, -17, -19, + 67, 11, -32, -22, 12, -56, 106, -66, 38, -14, 3, 37, 49, -17, 3, -11, + 58, 23, 40, -60, 19, 3, 69, -8, -14, 34, -47, 2, 37, -1, -89, 42, + -27, 20, -63, 44, -4, -26, 45, 18, -8, -24, 22, -67, 61, -74, 18, 43, + -72, 21, 48, 8, -37, 29, 17, -2, 32, -25, -26, -29, 69, -46, -12, -16, + 68, -44, 88, -74, 25, 10, 33, 1, 47, -29, -57, 26, -18, 63, -26, 4, + 7, 5, -97, 77, -63, 69, -26, 66, -60, 53, 3, -12, -60, 60, -50, 64, + -46, -46, 14, -3, 19, -10, 0, 53, -82, 6, 4, -7, 8, -74, 62, -79, + -6, 29, 28, -11, 68, -16, 20, -62, -67, 53, -90, -26, 26, -69, 33, 6, + -11, 15, -61, -25, -24, -35, 67, -45, 79, -61, 7, -23, -36, 10, -30, 19, + 12, 2, -16, 5, 15, 64, -13, 12, 33, -9, 46, -46, 56, -18, 51, -51, + -33, 25, -54, 11, -76, 49, 17, -43, -10, -29, 19, 30, -86, 97, -25, 69, + -40, 65, -63, 42, -21, 16, -23, -11, 9, -38, 40, -72, 39, -4, -27, -21, + 4, -10, 12, 1, 4, -23, 48, 27, 42, -26, -51, 50, -31, 29, -24, 22, + 0, 49, -1, -49, -3, 43, -8, 44, -62, 4, -61, -51, 73, -55, -5, -16, + 28, 5, 44, -60, -15, -13, 33, 17, 26, -88, 43, -79, 84, -49, 25, -84, + 69, -85, 7, 30, -28, -24, 13, -38, -15, 10, -17, -5, 65, 36, 13, -15, + 5, -49, 25, 19, 37, -18, -17, 15, 0, -47, 18, -68, 8, -31, -1, -24, + -49, -6, 44, -63, 39, -45, 4, -49, 40, 9, -26, 3, -52, 43, 51, 62, + -45, 12, 15, 16, 16, -30, -52, 51, -50, 67, -62, 31, 32, -36, 80, -82, + 88, 29, -51, 33, -33, 11, 43, -50, 26, -14, 14, 71, -67, 33, 68, -18, + -57, 28, -61, 65, -12, -44, 18, 45, -84, 58, -26, 73, -48, -42, 76, -48, + -3, -34, 83, -53, 31, -6, 14, 2, -41, -3, 12, -27, 93, -47, 65, -55, + 50, 19, 44, -25, -45, 66, -47, -40, 26, 31, -61, 50, 43, 34, 30, -22, + -16, 8, 8, -50, 8, -39, 19, 36, 1, 31, 72, -4, -42, 33, 0, -62, + -6, 14, 7, 7, -6, 20, -11, -49, -38, -13, 65, -55, 2, 30, -21, 5, + 15, -81, 53, -34, -8, -30, 19, 12, -67, 36, -59, 28, -32, 43, -22, 46, + -15, 69, -56, 87, 11, 13, -73, 78, -79, 108, -90, 24, 29, -15, -6, -13, + 27, -72, 15, 17, -4, -8, 4, 35, -50, 76, -47, 35, 22, 33, 7, -10, + 20, 4, -27, -21, -23, 1, -56, -12, -20, -43, 90, -80, 34, -46, 42, -33, + 0, -39, -40, 67, 2, 4, -12, 29, 12, 49, 25, 12, -21, 49, 19, -49, + -12, 26, -52, 44, -35, 37, -93, 8, 16, 62, 26, 19, -45, -4, 26, 26, + -3, 48, -7, -32, 48, -53, 5, -34, 64, -79, 47, -26, -60, -32, -20, 36, + -59, 66, -58, -2, 0, -56, 73, -40, -17, 60, 12, 30, -28, 38, -48, 97, + -40, 41, -36, 79, -16, 58, -41, 13, 3, -5, 30, 15, 62, -51, -16, -38, + -7, 27, -9, -5, 41, 3, 14, 48, -31, -5, 1, -33, 22, -25, -36, -5, + -50, 16, -63, 41, -29, -10, -5, -21, -5, -17, 60, -86, 38, -12, -61, 21, + 44, -3, -44, -8, 21, 25, -22, -32, -10, 41, -13, -38, -6, 48, -57, 13, + -6, 15, -51, 38, 33, 14, -36, -43, 89, -69, 3, 29, -21, -3, -40, -40, + 53, -64, 20, 41, -55, -39, 77, -43, 65, -31, 8, -35, -46, 19, 2, 17, + -64, 57, -4, -15, 41, 17, -38, 0, -8, -5, -66, 40, 52, -66, 72, 16, + 1, 22, 1, -2, 49, -22, 28, 54, 9, 61, -80, 98, -19, 26, -22, 17, + -10, 64, 26, -45, 22, -43, 26, 24, 8, 33, 25, 0, -38, 51, -55, 28, + -41, 17, -51, -4, -89, 83, -52, 31, 36, -71, 67, -35, 44, -15, -45, 36, + -42, 70, -15, 44, -74, 17, -13, -6, 9, 8, -43, 34, -60, -27, -11, -20, + 41, -11, -1, 63, -27, 37, 76, -38, 65, -3, -22, 8, 48, -7, -15, 10, + -3, 104, -47, -8, -29, 50, -88, 90, -63, -56, 47, -36, -30, 62, -42, 81, + -20, 35, 7, 13, 1, -19, 60, 3, -43, -32, -17, -29, 62, -11, 15, -44, + -3, -6, 3, 67, -46, 49, 64, -46, 19, 30, -58, 45, 31, 5, 59, -57, + 32, -4, 57, -29, -1, 50, -1, -1, 0, -56, 42, -79, 43, -16, 18, -103, + 82, -41, -13, -74, 69, -85, 22, 24, 15, 13, -25, -33, -14, 1, 19, -9, + -27, 1, -15, -10, -36, -53, 48, -38, -33, 37, -15, 11, 27, 38, 4, 46, + -61, 57, 37, 4, 27, -4, 2, 37, -15, -56, 39, -3, 5, -39, 54, -19, + -11, 31, 29, -14, 46, -41, 69, -42, 4, -42, 53, -36, 0, -4, 65, -30, + 20, 46, -25, 21, -67, 34, -36, 26, -4, 62, -46, -10, -38, 38, 31, 20, + 9, 4, -23, -7, 89, -54, 42, -46, 7, 2, -45, 71, -27, -36, -34, 25, + 57, -26, -23, -25, -34, -24, 18, 50, -55, 57, -32, 11, -48, 61, -110, 65, + -43, -2, 0, -45, 7, -25, -12, -60, 44, -2, -12, -77, 18, -55, 54, -15, + 17, -69, 5, 41, 10, 0, -9, 12, -85, 59, -48, 18, 9, -57, -20, 14, + -4, 10, 68, -59, 125, -74, -20, 33, -3, -15, 33, -60, 4, 5, 40, -57, + 50, -67, 58, -80, 44, -12, 36, 22, -18, -42, -34, 68, -39, 23, 15, 17, + -36, -11, 47, -48, 38, -37, -46, -37, -22, 58, -51, 80, -66, 46, -43, -12, + -9, -47, -32, 23, 38, -51, 42, -29, -7, 54, -63, 14, -45, 20, -71, 25, + -66, 18, 1, -16, 12, 30, 2, -33, 23, 50, -13, -31, 27, 2, -46, 49, + -12, -12, 14, -35, 20, -72, -3, 9, 12, -39, 51, 42, -92, 50, -29, -19, + 41, -52, 17, 17, -52, -39, 16, 30, -7, -28, 30, 38, 1, -51, 37, 83, + -42, -10, -15, 79, -50, 39, -10, -69, -26, -13, 76, -20, 25, -20, 18, -45, + 64, -52, 41, 4, 12, 32, -16, 19, 23, -23, -5, 46, -55, -59, 65, -1, + 18, -44, -16, -6, 61, -83, 62, -66, 34, 40, -23, 85, -73, 102, -100, 61, + -61, 55, -40, 50, -49, 48, -43, 72, -86, 65, 16, 0, -39, 71, -76, 45, + -79, 39, -31, -31, 51, 41, -45, -5, 13, 34, -19, 42, 24, -8, -51, 33, + -64, 21, 4, -8, -46, 69, -31, 12, 0, 52, -13, -8, 17, 58, -29, 49, + -43, -10, 30, 85, -47, 95, -58, 28, 10, -13, -8, -39, 33, -19, 49, -2, + -23, -33, 75, -47, 76, -62, 31, 34, -63, -9, -2, 49, 42, -6, 6, -67, + 76, -67, 82, -80, -1, -43, 47, 15, 37, -44, -29, -30, 28, 58, 26, 34, + -44, 75, -72, 28, -84, 12, 64, -94, 41, -46, 32, -1, 67, -45, 9, 29, + -6, -8, 26, 17, 5, 0, -2, -52, 51, 34, 19, -16, 15, 13, -55, 45, + -5, 4, -55, 41, -47, -14, 50, 53, -25, -29, -11, -57, 24, -1, 62, -36, + -29, 37, 29, 58, -36, 10, 4, -8, -59, 51, -11, 43, 8, 45, 13, -15, + 9, 21, 16, -40, 31, -41, -5, -27, 29, -31, -1, -5, -23, -29, 18, -13, + 63, -46, 25, -36, 27, 64, -49, 1, 18, 38, -32, -24, 40, 12, 11, -44, + 42, -14, 21, -23, 53, 33, 11, -19, -26, -50, 47, -28, -4, 28, -63, -47, + 52, -4, 11, -16, -7, 27, 42, 73, 5, -14, -27, 8, -68, 46, -34, 75, + -100, 85, -48, 49, 5, -56, -27, 50, -49, 2, -3, -11, 52, 9, -92, 45, + -69, 26, 53, -42, -44, 69, -79, 85, -77, 31, -45, -39, -26, -41, 56, -51, + 11, -16, -38, -32, -23, 2, -44, 9, 45, -8, -47, 47, -37, -9, 0, -36, + 79, -37, 46, -4, -60, -10, 68, -35, -31, -62, -23, -32, -7, -54, 16, 44, + -46, 49, -61, 43, -19, -33, -26, -62, 48, -69, 25, 49, -18, -48, -18, -5, + -19, 23, -22, -47, -11, -8, -26, -2, 2, -5, 26, 23, -7, -11, 2, 50, + -64, 50, -7, -22, 41, -1, -14, -1, 55, -55, 53, -34, -70, 36, -5, -19, + -26, 78, -47, 40, -19, 64, -79, 51, -61, 59, 8, 75, -58, -48, 21, -30, + -23, -46, 37, -75, 61, 15, -6, 7, 66, -52, 51, -45, -36, 10, -31, 23, + -33, 45, -68, 9, 11, -2, 2, 62, -25, -56, 29, -14, 5, 2, 47, -32, + 18, -7, 22, 7, 18, 12, -49, -15, 18, 72, -24, 58, -57, 43, -56, 21, + 18, 8, -49, -15, -35, 50, -56, 10, 26, 10, 48, -71, -22, -7, 23, -32, + 0, -13, 10, 12, -3, 58, -62, 23, 19, 21, -18, 73, -12, 60, 8, -42, + -30, 31, -41, 35, -41, -44, 29, 55, -97, 36, -48, 21, -31, 50, -28, 36, + -31, -5, -50, 86, -90, -16, -11, 43, 54, 27, 14, -20, 21, -2, 23, 97, + -105, 35, -8, -4, -38, -25, -20, -73, 38, -40, 28, -49, 76, 8, 15, -55, + 71, -14, -24, -74, 69, -14, 18, 25, -17, 33, -40, 71, -104, 53, 89, -63, + 64, -10, -22, 26, 1, -11, 62, -60, 52, -53, 31, 30, 28, 39, 4, 26, + 32, -54, 89, 6, 27, 14, 32, -52, -21, 64, -49, 6, 52, -50, 60, -20, + 0, -31, -12, -30, 28, 46, -15, -55, 58, 33, 43, 19, 42, 43, 19, -23, + 45, 15, -21, 12, -12, 45, 19, 71, -19, 27, -25, -69, 67, -22, 48, 7, + -21, 33, 7, 28, 17, -40, 67, 0, -83, 48, -46, 54, 27, -47, -2, -15, + 14, 2, -38, -7, -21, 46, -74, 59, -32, 34, -42, 21, 34, 2, 8, 36, + -29, -43, 0, 41, -43, 13, 11, -11, -1, 33, -34, -65, 48, 28, -16, 10, + 0, 45, 29, 50, -49, 13, 37, -62, -12, 45, -17, -44, 68, -73, 87, -63, + 14, -8, 39, 37, -60, -5, -61, -1, -30, 26, -7, 40, -57, -26, -5, 7, + 47, -41, 22, 2, -26, 1, 7, 25, -7, -79, 27, 45, -51, 4, 45, 7, + -29, 57, -7, 3, -13, -23, 51, -48, 45, -42, -59, 94, -32, 34, 6, 6, + -38, -34, 38, -45, 42, -58, 84, -60, -1, 15, -83, 1, -20, -56, -6, 7, + 61, -25, 71, -83, 84, 34, -21, 1, 48, -29, 31, -26, -32, -56, 44, -52, + 14, -16, 11, -47, 71, -6, -17, -39, -45, -35, 29, -24, 3, -38, -44, -32, + 39, 67, -44, 26, 31, 50, -25, 14, 51, -14, 17, -57, 41, -35, 8, -12, + -11, 37, 9, 27, -55, 52, 20, 4, -37, 67, -51, 10, 42, -56, -58, 25, + -70, 30, -40, 25, 65, -41, -56, 89, -23, 55, -57, -16, 47, -66, 10, 12, + -17, 22, -66, 19, -61, 62, -85, 48, 22, -64, 12, 16, -42, 21, -50, -5, + 52, -29, -35, 59, -25, -64, 19, 52, -15, 23, -54, 41, -33, -40, -7, 12, + -32, 2, -38, 55, -5, -20, -3, -42, -26, 19, 43, 32, -14, -41, -6, -26, + -18, -13, -56, 30, 15, -65, 26, -17, 65, 38, -44, -24, -36, 15, 39, -20, + 35, 45, -6, 14, -44, 31, -2, -7, 16, -21, 20, -56, -2, 18, -43, 19, + 30, -4, -2, -7, 28, 1, -32, 25, -30, -39, 58, -32, 31, -31, 34, 10, + 12, -35, -78, -6, 51, -2, -43, 46, -60, 18, 10, 35, -68, 57, -4, -33, + 26, -41, 52, -75, 26, 59, 17, 64, -53, 8, -44, 49, 80, -33, 31, -6, + -44, 46, -31, 11, 8, -12, 37, -22, -29, 71, -42, 6, -1, 7, -4, -35, + -23, 26, -56, 32, -22, 27, -11, 36, -58, 43, 21, -84, 64, -87, 49, -43, + 66, 38, 38, -17, -26, 16, -20, -3, -42, 45, 58, 29, 13, 37, -58, 63, + -43, -1, -9, 42, -49, -51, -25, -41, 24, 24, -28, 41, 37, 83, -62, 51, + 26, 25, 61, -35, 9, 15, 27, 68, -5, 28, 12, 66, -41, 60, 34, 13, + -48, -78, 71, -67, -20, -47, 23, -55, 23, -13, 62, -4, 12, -51, -9, -11, + 55, -62, 25, -12, 56, -56, -1, -62, 60, -60, -54, 43, 24, 48, -39, 49, + 62, -27, -9, -16, -37, 3, 11, -90, 61, -77, 46, 5, -73, 56, 28, -67, + -32, -6, 17, 26, 3, 11, 56, -60, 40, 38, -47, 52, 15, 6, 66, -15, + -4, 52, -3, 51, -52, 67, 66, -95, 57, -26, 13, -65, 3, 9, -37, 2, + 35, 9, -5, -26, 15, -44, 41, -26, 45, 13, -82, 34, -47, 91, -80, 84, + 47, 18, 67, -72, 16, 67, -41, 3, -68, 27, -5, 54, -64, 36, -57, 40, + -64, 11, -62, 25, 15, -16, 12, 15, -35, 73, -48, 18, 53, -69, 2, 8, + 41, -32, 58, -10, -29, -15, -30, 15, 31, 9, -37, 69, -57, 16, 0, -19, + -49, 25, 58, 48, -66, 22, -16, 8, 15, 1, -43, 23, 22, 21, -27, 69, + -33, 29, -26, 28, 3, -35, -52, -23, 59, 11, 27, -63, -43, -34, 17, -29, + 53, -25, -15, -2, -30, 28, 26, 25, -1, -44, 7, -77, 42, 6, 24, -17, + -1, -39, 33, 45, -18, 56, -39, -13, 1, 49, -45, 31, 17, 65, -92, 76, + -63, -22, -57, -30, 30, 3, 27, 35, 50, -55, -87, 73, -92, 80, -20, -4, + -42, -27, -3, 8, -41, 75, 57, -9, 20, -16, -18, 36, -56, -24, 20, -51, + -20, -15, -50, -16, 7, -60, -48, -38, -27, -24, -24, -5, -44, -7, 2, -54, + 33, 82, -5, 14, 52, 18, -26, 2, 26, -22, -86, 28, 21, -1, 86, -94, + 59, -34, 1, -33, -20, 12, 6, 17, -7, 47, 41, 11, -53, -39, 43, 1, + -29, 10, 16, -43, 63, -23, -7, 23, 27, 1, -1, -23, 56, -50, -9, 63, + 14, 53, -78, 63, -74, 34, -57, 60, -64, 57, -42, -15, -26, -44, -49, 23, + 0, -32, 10, -40, 38, -69, -73, 29, 4, -20, 51, 0, 69, 0, 3, 19, + -52, 18, -19, 17, -43, 65, -35, -6, 30, -7, 73, -73, 9, 9, 36, -57, + -50, -17, -37, 60, -49, -17, -34, 55, 69, -33, -14, 33, 7, 19, -43, 67, + -61, 53, 5, -3, 12, 12, 43, -11, -26, 20, -42, 46, -21, 73, 11, -3, + -40, -11, -8, 8, 30, 27, -8, 2, 32, 10, -28, 0, -42, 30, -2, 11, + 4, 74, -81, -33, 18, 39, -26, 25, -8, 38, 12, -60, 43, -49, 37, -100, + 39, -49, 15, -35, 25, -2, 37, 29, -15, -28, -36, 38, 35, 20, -52, 8, + 37, -36, 33, -5, -29, -12, -44, 30, -77, 33, 37, 36, 42, -60, 38, 20, + 46, -15, 47, -16, -38, -21, 77, -28, 24, -88, 76, -61, 41, -88, 57, -29, + -10, 1, 66, -5, 12, 56, -86, 2, -28, 60, 7, 5, -9, -11, -66, 65, + 20, 58, -54, 62, -5, -39, -79, 78, -32, -25, 9, -30, -2, -22, 11, 0, + 49, -11, 92, -9, -24, 74, 54, 19, 30, -4, 17, -72, 71, -49, 55, 34, + -28, -73, -12, 6, -54, 13, 3, 16, -16, 49, 21, 44, -47, -1, -26, 52, + 14, 2, -46, 73, -20, -28, 57, -62, 61, -64, -39, 8, -18, 80, -92, 34, + -54, 35, -26, -5, 42, -27, 43, -6, -13, -2, 4, 11, 28, 45, -35, 5, + -56, 11, 20, -13, 42, -42, 24, -21, -6, -8, 37, 15, 4, 83, -60, 5, + -12, -62, 63, -33, 16, 9, 99, -37, -3, -9, 37, -61, -17, -37, 18, -22, + 87, -50, 67, -6, -7, -1, -50, 45, -53, -38, -6, 10, 39, -1, -34, -1, + 72, -64, 62, -61, 44, 29, 33, -74, -49, 0, -30, 2, 7, 21, 42, -30, + 53, 15, -35, 30, -24, -22, -21, -7, -33, 12, 69, -54, -25, -64, -2, 39, + -32, 3, -18, -19, -41, 47, -41, 24, -36, -29, 45, 0, 41, 5, -71, 44, + -29, -33, 15, 32, -9, -9, 12, 26, -55, -12, 26, -30, 36, -33, 46, 16, + 47, -40, 99, -94, 41, 44, -7, -37, -3, -26, 69, -63, 40, 12, 83, -43, + -38, 0, 45, -20, 52, 0, -58, 28, 40, 33, -104, 15, -59, 71, -27, -63, + -58, 2, -48, -17, -3, 44, -56, -19, 13, 33, -13, 28, 0, 9, 46, 9, + 31, 30, -46, 21, -70, -4, -12, 91, -39, -16, -5, 1, -49, 77, 13, -7, + -51, 32, -13, -24, -23, 34, 62, -65, 42, -27, 56, -36, 46, -12, 40, 8, + -36, -44, -56, -8, 13, -37, -26, 11, -1, 50, -82, 92, -4, 20, -19, -48, + -3, 75, -6, 8, 43, -41, 26, -56, 31, -24, -32, 6, -18, 23, -29, 2, + -19, -28, 25, -6, 27, -46, 8, 11, -60, 57, -27, 65, -54, 18, 41, -28, + 13, -21, -24, -33, -4, 27, -32, 3, -21, 52, -64, 23, -66, -35, 63, -13, + 3, 33, -19, -23, 42, 16, -27, 47, -63, 42, 7, -20, -10, -3, 39, 49, + 6, 83, -45, 9, 13, 12, -58, -29, 0, -29, 5, -4, 18, -2, 78, -50, + -24, -17, -51, 46, 27, -8, -9, 65, 2, 21, -15, 15, 39, -68, 37, 43, + -90, 80, -43, 69, -42, 0, -66, 74, 37, 42, -3, -11, -32, -24, -10, -24, + -10, 5, -44, 0, -42, 53, -30, -6, 56, -25, -90, 75, 0, 50, -4, -17, + -11, 51, 5, -26, 13, 13, -35, -5, -19, -8, 1, -12, -2, 27, -11, 62, + -32, 49, -51, -14, 2, -12, 35, -66, 25, -20, 77, -42, -1, 5, -1, 14, + -11, -21, -74, 68, 22, -81, 4, -22, 10, 27, -14, -52, 30, -47, -57, 57, + 15, -37, -49, 49, -60, 28, 45, 32, -58, 37, 48, 9, 0, -6, -15, 82, + 42, -21, 70, -15, 13, -63, 0, 51, -3, 47, -57, -35, 55, -64, -31, 14, + -37, -18, -18, 0, 73, -28, -10, -55, 0, -12, 19, -2, 72, -65, -4, -3, + 8, -56, 50, 56, -16, -25, 33, -55, -27, 34, -18, -37, 54, 1, 23, -79, + 61, 56, -12, 65, -80, 81, -56, -3, -39, 14, 49, -105, 51, -47, 37, -4, + 18, 11, -54, 60, -102, 53, 34, -32, 39, -14, 5, 59, -36, -56, 66, -83, + 75, -40, 44, 27, -66, 83, -50, -16, 42, -62, 12, -5, -2, -51, 17, 48, + 22, 38, 12, 22, 22, 27, -38, 70, -62, 16, 29, -28, 65, 9, -54, -8, + 55, -71, 23, -42, -47, 32, -17, 21, 45, -63, 3, -22, 9, -41, -3, -72, + 77, -86, -44, 38, 27, -56, 22, 20, 59, -49, 56, -25, 20, -37, -50, 7, + -40, 39, 7, -26, -41, 45, 59, -59, -50, -8, 4, -13, -40, 33, -19, -21, + 44, -4, -40, -22, 26, 47, -29, 26, -59, -28, -28, 38, -10, 39, -46, 49, + -56, 21, 42, -5, 3, 16, -13, -18, 14, 22, 73, -61, -2, -17, -25, 40, + 8, -4, -16, 21, -3, 26, -20, 20, 44, 30, -9, -18, -31, 5, 14, -31, + -39, 8, 21, 36, -34, -14, -43, 82, -2, 49, -82, 7, -27, 23, -64, 61, + -55, 39, 0, 12, -83, 89, -4, -23, 7, 20, -13, 72, -10, -13, -21, -9, + 9, 72, -42, 23, 40, -61, -7, 12, -68, 8, 4, -29, -32, 62, -52, -29, + -30, 25, -71, 38, 20, 32, 35, -26, 21, -37, -13, 80, -35, 29, 34, -42, + 3, 15, 66, -61, 19, -37, 58, 46, -40, 0, 35, -56, 0, -64, 34, 42, + -9, 20, -13, -64, -18, 2, 23, 61, -8, 24, 47, -46, -5, -23, -54, 36, + 29, -96, 51, -10, 9, 14, 0, 29, -4, -13, 32, 58, -18, -3, 36, -67, + -4, 4, -28, 7, 33, 16, -22, -15, 46, -43, 0, -61, 38, 4, 61, 7, + -24, 41, -101, 52, -3, 2, 14, 58, 36, -10, 57, -51, 53, 27, -18, -22, + -32, -19, 7, 30, -31, -41, -17, -44, 7, 23, -16, -47, -40, -19, 22, 44, + -68, 18, 24, 64, -10, -15, 51, -70, 23, 5, -35, 44, -34, 46, -42, 51, + -74, 76, 6, 32, -65, 68, 33, 2, -7, -35, 26, 18, 13, -15, 45, 37, + 62, -41, 38, -54, 36, -40, -65, -5, 73, -10, -5, -26, 67, -73, 61, -45, + -19, 0, 46, 7, -28, 29, -65, 72, -65, 70, -15, 40, -20, -40, 46, -55, + 54, -7, -11, -11, 54, -57, 57, 22, 6, -26, -53, 24, 9, -57, 49, 6, + -28, 43, -49, 35, -27, -9, 33, 0, -14, -37, 5, 28, 18, -71, 77, -30, + 59, -38, 26, -32, 2, 18, -22, -73, 26, -49, 62, -27, -17, 52, -41, 54, + -11, -26, 21, 35, 55, -32, 28, -16, 28, 68, -86, 24, -37, 61, 5, 54, + -52, -14, -14, -20, 29, 2, 20, 0, 51, -23, 40, -26, -47, 55, -43, 61, + -27, 48, 10, -45, -16, -64, 29, -48, -51, 40, -7, -59, 38, -17, -35, 48, + -3, -12, -29, 12, 19, 72, -90, 34, -24, 47, 8, 8, 41, 50, -46, -23, + 10, 22, -3, 71, 65, -44, -44, -56, 35, -22, -9, -24, 38, -20, 95, -60, + 74, -32, 14, 14, -62, 53, -47, -16, 23, -37, -38, 3, -43, 12, 40, 28, + -24, 0, 62, -19, -17, 14, -12, -1, -32, 36, -1, 73, -50, 25, -61, -49, + 31, 21, 32, 0, -1, -36, -15, -62, -11, -30, 12, -31, 18, -17, -26, 9, + -45, 73, -31, -18, -8, 56, 30, 30, 22, -24, 32, 42, 33, 44, -78, 4, + 18, 53, -37, -30, -58, 16, -30, -32, 29, 41, 1, 33, -5, 43, -47, 18, + 10, 18, -47, -24, 39, -75, -27, 7, -4, 60, -49, -29, 34, 0, -71, -6, + -41, 0, 33, -27, 53, 27, 17, 43, 8, -58, 50, -31, 28, 26, 21, -4, + 34, -58, 41, -30, -58, 40, 3, -7, 3, 9, 13, -16, -38, 46, 4, 15, + -52, 9, -41, 6, -29, 57, -30, -58, 66, -82, 28, 18, 43, 5, 5, 5, + 16, -57, 43, -20, 48, -10, -56, 28, -61, 97, -55, 0, 33, 54, -55, -3, + -5, -38, 10, 30, 26, -7, 42, 38, 13, -8, 28, -15, 64, -35, -43, 17, + -32, 67, -68, -11, -50, 8, -43, 18, -38, -67, 73, -49, -53, 47, -39, 20, + -50, 82, -54, 83, 5, -74, 46, -58, -12, -19, 24, -8, 49, 53, -64, -24, + 30, -59, 13, 70, -22, 70, -29, 28, 93, -48, 38, 73, -61, -20, 23, -49, + 44, -6, -20, -26, 19, -77, 66, -54, 47, -45, -7, -6, -23, -2, 61, -63, + 28, 6, -26, -71, -21, 3, 65, -22, 10, 3, -12, 41, -31, 37, -68, -13, + -31, -32, 0, 54, -1, -56, 60, 39, -8, 36, -30, 61, -38, 3, -73, 57, + 32, -28, -39, -42, 31, 22, -11, 16, -40, 77, -44, -3, 20, -31, 56, 52, + -44, -47, 10, 15, -11, 23, -17, 73, -80, 54, 27, -50, 45, 52, -60, 49, + -14, -57, 30, 14, 15, -30, -40, 42, -56, 27, -56, 27, -38, 31, -12, 65, + -52, -16, 11, 7, 51, 62, -27, 67, 13, -26, -57, 26, -47, -14, 18, 9, + -22, 0, 37, -24, 25, 55, -37, -23, -16, -34, 32, 15, -38, -4, 53, -13, + 62, -35, -51, 48, -68, 5, 18, -87, 48, -8, 45, -74, 48, -78, 53, -48, + 62, -30, 5, -16, 67, -27, 36, -49, 53, -38, 77, -58, 63, -13, 21, -5, + 52, 22, 19, -17, 40, -55, -9, 16, 17, 50, -24, 22, -42, -9, -43, -46, + 29, 7, 7, -38, 53, -66, 20, 31, -5, -7, -61, 37, -52, 18, -5, -24, + 17, 40, -14, -48, 25, -3, 4, -33, 18, -8, -25, 30, -18, -19, 99, -57, + 59, -39, 14, 43, 9, -45, 46, -58, 56, 15, -33, 67, -26, 69, -24, -34, + 32, -16, -32, -28, -52, 45, 8, 6, 27, 33, -13, 2, -57, -17, 14, 60, + 43, -48, 45, -54, -17, -17, 19, -36, -29, -9, -56, -30, 84, -55, 32, 0, + -1, 27, 6, 42, -10, 12, -22, 6, -56, 27, 37, -8, -20, -10, -53, 50, + 6, -25, -26, 90, -15, 21, -77, 54, 42, -55, -4, 43, -63, 65, -56, 74, + -1, 43, 8, -46, -47, 48, -53, -43, 11, -79, 42, 17, 10, -33, 72, -76, + -45, 73, -52, 71, -4, -58, 59, -14, -5, -36, -32, -29, 44, -43, -61, -19, + 74, 12, 2, -38, -32, 33, -19, 16, 56, -63, 40, -23, -4, -6, -5, 49, + -28, 6, 20, 39, -5, 25, -32, 23, 18, -49, 52, -22, -10, 18, 13, -41, + 6, -15, -21, 29, -37, -65, 55, -76, -25, 1, 10, 23, 67, -67, 43, -36, + 33, -9, -24, -47, 52, -46, 46, -4, 15, 3, 4, 60, -2, 34, -60, 56, + -84, 66, 27, -50, 66, -41, 15, -25, 21, 38, -64, 58, 36, 36, -76, 37, + -61, -5, 2, 37, -11, -18, -9, -41, 45, -50, -25, -29, 10, -19, -63, 34, + -64, 66, -55, 10, -37, 20, 45, -44, -30, -2, 47, -17, -18, 34, 39, 11, + -32, 16, -13, 20, 1, 26, 21, -22, 12, 20, 42, -25, -38, 83, -65, 33, + 46, -93, 81, -49, 0, -9, -62, 56, -29, -49, -27, 3, 53, -54, -46, -23, + 6, -13, 37, -77, 81, -10, 40, 23, -54, 15, 59, -44, 33, -72, -34, 60, + -63, 80, 2, 37, 7, 8, -48, 6, -12, -10, -49, 14, 45, -41, 28, -67, + 8, -8, 10, -5, 49, -15, -2, 0, 15, -6, 19, 48, -55, 45, -16, -28, + 38, -77, 70, -102, 36, -49, 49, -37, 47, 51, -84, 54, -52, 48, 28, 16, + -56, 7, 15, -68, 43, 40, -8, -30, -72, 66, -61, -16, 18, -10, 45, -75, + 2, 15, -34, -17, 44, 32, 10, 35, 35, 51, -10, -51, 27, 20, -58, 72, + 27, 23, -67, 53, -8, -2, -51, 25, -29, -2, 61, -17, 49, 25, 53, -13, + -14, -70, 64, -33, 73, 9, -32, 42, -54, 60, -84, 74, -47, -52, 41, -85, + 25, 42, -62, -39, -16, -22, 41, -51, 3, 13, 30, -21, -19, 7, 33, -5, + 12, 26, 58, -16, 7, 0, -9, 18, 49, -8, 32, -75, 3, 12, -17, -4, + -17, 2, 32, -5, 24, -31, 46, -48, 59, -29, 1, -69, -50, -5, 25, 35, + -36, 19, -20, 2, 3, 65, -82, 59, -37, 45, -41, -24, -33, -5, 46, -20, + 67, -68, 39, -21, -17, -19, 42, -39, 66, -25, -33, 67, -28, 46, 7, -2, + 32, -67, -4, 10, 55, -42, -15, -18, 78, -38, -5, -52, 18, 25, -11, 20, + -40, 6, -24, -42, 48, -86, -12, 41, -46, 9, -14, 16, 24, -32, 18, -34, + -1, 34, 11, -51, 32, 49, 5, 44, -47, 84, 59, -94, 54, -23, 71, -86, + 89, -69, -9, 65, -37, -70, 26, -34, 49, -19, -31, 13, 21, 41, 42, -54, + 15, -19, -9, -18, -33, 21, 56, -16, 11, 20, 16, 22, -30, 7, 46, -32, + 27, 0, -33, 70, -47, 53, -27, -28, -33, 3, -24, 45, -9, -41, 53, -7, + 6, -53, 20, 31, 31, 11, -15, 32, -5, -35, 45, -63, 74, -57, -9, 31, + 38, 12, 34, -37, 46, -50, -8, 49, 15, 46, 29, 68, -65, 31, -32, 33, + 45, -45, 35, 2, 54, -76, 14, -18, -21, -87, 60, -8, -2, -23, -3, -74, + 57, -74, 23, 11, -65, 53, -8, 14, 21, -35, 12, 58, -73, -52, -19, 28, + 2, 2, 12, -14, -27, -37, -54, 58, -57, 41, -16, 9, 43, 14, 40, 49, + -1, -28, 25, 59, -41, -8, 11, 13, 14, -38, 10, 3, 9, -25, -27, 31, + 1, -47, -67, 74, -27, -53, 71, -57, 46, -35, -28, 59, 74, -70, 50, 26, + -3, 8, -9, -38, 32, -27, -36, -23, -32, -8, 17, 44, 74, -37, 10, -32, + -29, 40, -46, -31, 52, -101, 54, -4, -6, -45, 33, -2, -16, 22, -74, -3, + 36, -16, 41, 0, -5, 14, 41, -75, -12, -13, 66, -42, 49, -14, -11, 52, + -64, 67, -4, -76, 63, -43, 62, -19, -18, -6, 25, -13, 45, 12, -81, 97, + -39, 60, -6, 58, 16, 12, 78, -28, -19, 55, -19, 57, -24, -20, 38, 0, + -48, -20, -9, 38, 1, -26, -31, -80, 102, -114, -2, 58, 1, -21, 22, 46, + -24, 24, 38, -49, -24, 86, -15, -24, 43, -38, 9, -55, 2, -59, 16, -25, + 26, -26, -6, -29, 48, -7, -52, 32, -20, 8, -4, -11, 0, 24, -63, 39, + -47, -15, -23, -13, -53, 24, 15, 60, 20, 18, 36, -37, -31, 27, -2, -3, + 37, 46, -1, -8, -18, 34, -6, -58, 60, -45, 16, -49, 12, 46, -39, -39, + -35, -2, 9, 9, -45, 4, -28, 61, -54, -18, -46, -44, 33, -17, 10, 0, + -32, 14, -33, 49, -80, 61, -78, 47, 37, 50, -74, 19, 25, -21, 48, 23, + 8, 32, -54, 52, 23, -49, 18, 41, -13, 75, -72, -33, 26, 51, 35, 26, + -42, -31, 43, -57, 59, 67, -44, 40, 0, -25, 27, -61, 38, -25, -69, -23, + 41, -65, 8, 4, 0, 3, -21, 48, -54, 50, -48, 33, -9, -11, 35, -23, + -14, 15, 41, -48, -16, 89, -87, 90, -69, 38, -43, -24, -37, -23, 58, -61, + 11, -27, 51, 39, 10, -33, 30, 20, 46, 40, -3, -35, -44, -40, 50, 7, + 15, -7, 48, 66, -42, 58, 16, 14, 38, -53, 52, 17, -41, 22, 67, -39, + 19, 2, -56, 1, 38, 30, -35, 64, 39, 51, -37, -28, -11, -46, 3, -4, + 0, -7, 26, 48, -41, 7, 31, -47, 30, -11, -2, 32, -49, 38, 0, -52, + -23, -32, 28, -72, -2, -36, -41, 5, -48, -13, 6, -61, 31, -50, 37, 26, + 7, 7, 10, 46, -42, 28, 63, 37, -77, 75, 14, -36, -22, 44, -34, 24, + -11, -59, 50, 10, 4, -83, 78, -47, 5, -8, -7, 65, -16, 3, 30, 77, + -63, 53, 65, -15, -24, 73, -47, -6, 11, -5, 43, -77, 8, -19, 47, 33, + 40, 39, -26, 53, 15, -6, -15, -76, 13, -33, 48, -33, -23, 50, -48, -31, + 5, -45, -26, 47, -71, 31, -29, 32, -48, -9, 28, 21, 8, -28, 13, 32, + 21, -44, 14, -58, 42, 28, -41, -3, 10, -15, 30, -27, 34, 0, 12, -14, + 59, -51, -30, 42, 0, 12, 6, 54, -74, -25, 45, 65, -83, 36, -6, -10, + 52, -86, 34, -34, 11, 14, 24, -41, -57, -8, 24, 74, -72, -31, -56, 51, + -55, 24, -1, 43, -43, -47, 27, -47, 22, 24, -47, 66, -71, 88, -31, 54, + -13, 58, -45, 0, 45, -47, 56, 17, 4, -19, 24, -4, 15, -52, -14, 18, + 33, -42, 8, 51, -28, -21, 17, -68, 71, -12, 65, -60, 44, -4, -46, 31, + -33, 22, -36, -50, 2, 51, -1, 32, -67, 1, -37, 49, 17, 47, -25, -57, + 61, -51, -31, -63, -6, 5, -28, -33, -25, 6, -31, 39, 0, -21, -61, 29, + 40, -20, 49, -27, -39, 17, -64, -2, -63, 8, -24, 64, -49, 16, 27, 19, + 23, -22, -68, 46, 9, -2, -3, -43, 29, -15, 66, -18, -29, 10, -63, 69, + 6, 64, -63, 85, 2, -19, 9, 25, 32, 22, -49, 85, -27, -9, -2, 23, + -45, 21, 45, -56, -5, -24, -74, 45, 24, -43, -38, 55, -8, -25, 48, -46, + -41, 88, -78, 69, -42, 39, -41, 67, -47, 45, 14, -57, 50, -11, -25, -45, + 12, -41, -56, 7, -38, -24, -10, 57, -41, 0, 17, 52, 36, 7, -33, -39, + -11, -48, 64, -41, 43, -30, -36, 54, 6, 40, -56, 68, -36, -23, 48, -19, + 37, -61, 55, 20, 7, -37, 16, 23, 61, -28, 10, -12, 6, 11, 51, -58, + -37, 64, -5, 76, -70, 15, 64, -52, 56, -58, 44, 45, -14, 21, -19, -62, + 30, -34, 100, -57, 20, 18, -64, 25, -39, 84, -56, -62, 91, -61, 4, -31, + -48, 50, 36, -57, 13, 36, -16, -31, 80, -47, -38, -14, 41, 0, 48, -23, + 63, 1, 7, -10, 7, 8, 45, 14, 3, -50, 53, -10, 30, -83, 20, -37, + 45, -38, 35, 23, -13, -28, -65, -4, -13, -43, 91, -101, 51, 29, 4, 15, + 3, -20, -49, 30, 44, -42, 21, 2, -21, -23, 30, 23, -2, -2, 4, -28, + 56, -33, 17, 15, 1, -64, 3, -14, -3, 3, 19, -24, 0, -84, 59, 36, + -32, -20, 49, 72, -35, 13, -11, 27, 48, -52, 4, -15, 13, 27, 59, 3, + -67, -39, 44, -8, 9, -2, 41, 29, -29, 39, -65, 1, 4, 70, -56, 34, + -52, 0, 40, -31, 37, -35, -27, 49, -20, 25, -63, -44, 25, -30, 64, -10, + -42, 25, -59, 29, -57, 93, -15, -22, 0, -12, 71, -86, 25, -49, 53, 0, + -12, 25, -50, -16, 52, -63, 82, -72, 67, -45, 30, -5, 16, -4, -42, 40, + 68, -62, 41, -37, -34, 58, -41, -3, -15, -60, 7, 53, -39, 0, -19, 38, + -42, 31, 55, 14, 23, 70, -50, 4, 40, -4, -56, -44, 6, -42, -18, 12, + -54, 17, -3, -40, -24, 25, 18, -1, 31, -39, 22, -77, 51, 33, -14, 37, + -29, 40, 22, -60, 14, 30, 28, -3, -75, 34, 25, 8, 17, 33, -82, 90, + -29, 24, -73, 26, -22, 52, -49, -12, -24, 36, -37, -65, 49, -76, 41, 45, + -2, -8, -52, -15, -34, 43, 0, -43, 42, -72, 75, 13, -74, 95, -9, 3, + 15, -9, 20, 28, 3, -41, -45, 44, 24, -21, 56, 13, 1, 18, -15, -32, + -69, 36, -22, -9, -15, 25, -28, -68, 67, -24, 14, -46, -19, 101, -43, 28, + -4, -23, 30, -71, -7, 38, 48, -11, -3, 63, -104, 93, -40, 20, -46, 26, + -9, 1, 35, 7, -30, -19, 79, -30, 27, -5, -41, 35, -39, 5, -5, 47, + 9, 2, -52, -3, -14, 63, 14, 17, -3, 29, 0, -56, 25, 60, -15, 38, + -36, -1, 13, -47, 9, -7, 27, -65, 57, 33, 38, -51, -10, -1, -31, -31, + 109, -21, 35, -13, -18, -22, 25, 28, -46, 5, 30, 39, -29, -44, 14, -9, + 56, -69, 81, -39, 2, 1, -2, 19, -9, -27, 78, 35, 35, -26, -66, 41, + -29, 37, -34, 63, -27, -55, 19, -6, 6, -5, -64, 69, 15, 14, -32, -28, + 38, -51, 37, -22, 28, 42, 31, -17, -35, 60, -57, 0, -61, 11, -27, 19, + -56, 9, -29, 19, -22, 1, 9, 19, 25, 39, -12, -27, -50, 56, 3, 63, + -33, 13, -68, 53, -39, -20, -32, -14, 40, -45, 12, 59, -7, 19, -21, 54, + 20, 26, -41, 98, -36, 33, 1, -78, 6, -29, -10, 55, -41, -33, 51, -40, + 31, -67, -47, 53, -63, -17, -25, -35, 26, 18, -91, -4, -39, 4, -45, 48, + -55, -2, 73, -19, -20, 32, -20, 89, -66, 68, 46, 0, -33, 41, 3, -2, + -6, 65, -12, 37, -56, 5, 10, 41, -49, 72, -70, 22, -7, -42, 5, -24, + 39, -38, -26, 53, -72, 53, 44, -83, 26, -9, -2, -48, -15, -53, 61, -5, + 73, -61, 17, -54, 84, -73, 103, -71, 73, -85, 60, -10, 23, -80, 0, 43, + -11, -60, 51, 2, 63, -8, -14, 45, -31, -41, 75, -32, -38, 36, -30, 10, + -55, 47, -57, 91, -50, 9, -53, -46, -8, 36, -57, 10, 20, 4, 31, -56, + 10, -23, 43, 39, -54, -4, -11, -35, 15, -21, 33, 32, -25, -26, -21, -37, + 46, -11, -42, 38, 26, -36, 52, -42, -19, -74, 35, 50, -4, 1, -21, -3, + -62, -14, -23, -22, 20, -6, 20, -59, 75, -57, 69, -80, -8, 75, -20, -17, + -23, 49, -64, -31, 55, 30, -1, -69, 57, -40, -74, -25, 27, -37, 57, 39, + -13, 62, -52, -50, 18, 28, -16, -30, 70, -42, 27, -3, -64, 22, 7, 7, + -7, 24, 6, -32, 1, -60, 2, -11, -19, -18, 86, -56, 79, 67, -52, -2, + 68, -45, 51, -7, 16, 9, 0, -22, 33, -78, 57, 34, 54, -39, -23, -27, + -9, -35, 44, -10, -26, -47, 80, -27, -2, 29, 0, -30, 43, -22, 28, -16, + -18, -13, -26, -15, -81, 14, 33, 31, 32, 21, -1, 12, -12, -8, -41, 11, + -18, 35, 58, -14, 40, 55, -36, 7, 15, -4, 73, 11, -28, 54, -51, 80, + -43, 3, -24, -8, -18, -2, -18, -11, 6, -34, -73, 24, 2, -8, -58, 62, + -47, -46, 0, 34, 46, 3, -28, 45, -13, -10, -17, 27, -36, 49, -4, 22, + -87, 80, 8, -32, -23, 56, -28, 30, 50, -1, 3, 1, 46, -2, -70, 69, + -28, 33, 40, -7, -35, 14, -53, 3, 0, 21, -21, -37, -31, 74, -8, -55, + 62, -29, 32, -69, 2, -62, 35, -52, 69, -77, 11, 21, -6, 32, 32, -64, + 38, 5, 19, -59, -35, 61, 14, 62, -39, 17, 21, 0, 21, -13, -58, 28, + 20, -4, 30, -79, 64, -32, 13, 40, -9, -34, -35, 72, -32, 16, -27, 34, + 7, -1, 21, 1, -8, 11, -25, 65, -27, -3, 11, -70, 51, 2, 19, 42, + 17, 25, -28, 20, 44, 1, -30, -24, 16, 25, -34, 49, 30, -40, 19, -30, + 54, -96, 80, -27, -15, -16, -36, 42, 10, 26, 44, 39, -20, 22, 2, -48, + -57, 9, -8, 73, -58, 62, -64, 64, -47, -5, 12, -70, 55, 68, -39, 47, + -44, -24, 56, 0, 62, -48, 23, 2, 41, -17, -24, 1, -45, -47, 61, -41, + 60, -43, -32, -63, 88, -70, 84, -21, 37, -8, -30, -21, -36, 23, 59, 22, + -63, 88, -56, 26, 26, 29, -45, 46, -49, 74, -43, 47, -72, 50, -7, 36, + 37, 31, -63, 76, 50, 44, -56, 17, -35, 14, 24, 36, -35, 62, -15, 0, + 12, 24, -47, 22, -22, 14, -43, 42, -15, 23, -62, 47, -35, 39, -3, -50, + 24, 37, -10, 23, -2, 20, -22, -52, 34, -47, 71, 67, -55, 35, -8, 24, + -49, 56, -60, 9, -34, 4, 13, -35, -40, 25, 32, -6, 35, -68, 43, -35, + 113, -115, 56, -24, 46, -69, 29, -61, -24, 25, -42, -27, 60, -24, 71, -89, + 10, -60, 19, -1, 49, -59, 40, 27, 37, -3, 4, 36, 74, -97, 62, 47, + -83, 53, -41, 95, -68, 49, 26, -26, -12, 77, 11, -18, -1, 4, -37, 31, + 14, -48, 18, 25, -12, -22, -5, -48, 46, 24, 12, 21, -67, 60, 32, -52, + 12, 62, -92, 76, 11, 57, -56, -30, 34, 5, 17, -27, -20, -19, -26, 62, + -77, 29, -6, 14, -19, -67, 61, -73, 63, 0, 51, -79, 11, 11, -40, -16, + 6, -21, -3, -2, -52, 2, 0, 74, -45, -8, -12, -9, -39, 3, 3, -15, + 61, 29, 59, -60, 65, 16, -33, 46, 8, -54, 62, -98, 60, -75, 38, 19, + 17, 34, 6, -18, -4, -10, 30, -14, 40, 18, 8, 86, -73, -57, 16, -86, + 62, -25, -51, 21, -72, 39, -12, -13, 21, -5, 41, 14, 20, 2, -32, -5, + -33, 42, 37, 27, -32, 5, -59, -29, -67, 36, 63, -76, 88, -22, -69, 18, + 11, -53, -7, 10, -23, 38, -22, 11, -6, -59, -9, -52, 31, -5, -58, 0, + -66, 46, -24, 3, -88, -5, 34, -43, 7, 2, -33, -36, 80, -81, 50, -2, + 0, -24, -13, -12, -7, -6, 50, -22, 20, -79, 63, -70, 5, 0, 15, 17, + 8, -30, -51, 26, 26, 24, 2, 99, -74, 63, -43, -23, -17, -44, 37, 20, + -9, 53, 26, 16, -22, 20, -9, -26, 31, 44, -46, -48, 15, 60, -12, -34, + -65, 33, -2, 22, -40, 5, 27, 11, 12, -38, 46, -15, -44, -17, 27, 40, + -13, 63, -46, 48, -12, 3, 39, -51, -4, -33, -1, -55, -73, 82, -55, -27, + 21, 71, -35, -46, 2, 54, -48, 41, -45, -29, -35, -6, 29, -60, 63, -8, + 34, -55, 30, -26, 48, 3, 42, -32, 35, -64, -13, 66, -77, 25, -65, 41, + -3, -67, 54, -62, -30, -57, 52, -13, -4, 41, 10, -38, 78, 10, -42, 47, + 7, 18, -45, -3, -13, 50, 28, -77, 57, -91, 61, 27, 37, -68, 58, 2, + 6, 16, 11, 14, 33, -36, 62, -47, -15, 9, 5, -27, 84, -9, -55, 35, + -68, -36, -65, 24, -80, 56, 4, -39, -63, 37, -70, 78, -3, 48, -26, -38, + -48, 11, -27, 64, -51, 52, -63, 0, -73, 10, 22, -77, 68, 2, -5, 69, + -2, 28, 1, 54, 31, -84, 64, -9, 16, -78, 4, -53, 33, 6, 4, -27, + -4, 47, -76, 18, 27, -55, 77, -7, 48, -28, 5, 43, -60, 5, 27, 3, + 22, 49, -7, -14, 57, -4, -50, 4, 16, 26, 48, 22, 1, -39, 21, 66, + -33, 21, 12, 9, 51, 0, -41, 39, -69, 72, -48, -20, -50, 33, 34, -56, + 25, -3, 20, 18, -81, 68, -79, 52, -15, 80, -74, 99, -67, 25, 25, -68, + 17, -5, 64, -31, -43, -68, 60, -110, 62, 8, -36, -8, 20, 50, -48, -48, + 20, -85, 28, -57, 41, 23, -41, 10, 25, -41, 13, 61, -49, -20, 64, -11, + 76, -2, -15, 17, 31, -46, 41, -11, -18, -36, 47, -13, 61, -63, 53, -68, + -45, 6, 13, -61, -16, -11, 21, -50, 85, -77, 41, 52, 15, 35, -16, 11, + 4, -72, 7, 7, 15, -52, 70, 15, -21, 60, 19, -34, 56, -35, -25, 37, + -14, 9, 40, -69, -8, -16, -25, 0, 20, -20, 3, -82, 80, 1, 3, -4, + 32, 24, 37, -53, 73, 7, 51, -61, 2, -33, 6, -39, -6, 30, -24, -6, + -17, 49, -23, 84, -37, 22, -41, 76, -5, 49, -92, 49, -16, 28, -17, -26, + -15, -48, 20, -41, 63, -34, 3, -29, 37, 25, -3, -25, -31, 6, 17, 35, + -9, 77, 7, 16, 55, -59, 34, -14, 50, 36, 3, -30, -37, 14, -16, 25, + 47, 34, 6, 5, -30, -50, 75, 4, 69, -24, -39, -21, 41, -35, 67, -72, + 5, 8, -48, -41, 0, 17, 5, -7, -5, 78, -4, 22, -33, 67, -26, 23, + 12, 50, -77, 65, -80, 70, -48, 62, -61, 51, -28, -32, 19, -18, -18, 14, + 19, -61, 43, -1, -67, -9, 55, 14, -1, -22, -1, -31, 23, 35, 3, -30, + 3, 7, -54, 41, -38, 44, 1, 17, -12, 7, 33, -1, 45, -39, 0, 0, + 29, -57, 30, 13, 32, 32, -6, -32, -24, 25, -13, 35, -41, 38, 6, 60, + -67, 46, -52, 14, 18, 65, -76, 83, -41, 66, 6, 20, -46, 45, 43, 53, + -77, 83, -32, 50, -27, 36, -67, 58, -18, 1, -24, 12, -36, 3, -39, -4, + -58, -5, 29, 10, -48, 52, -44, 42, 43, -25, -25, 26, 38, -52, 18, 57, + 63, -73, 75, -27, 40, 41, -38, -3, -20, 40, 46, -3, -57, -44, 56, -79, + 45, -1, 31, -52, 24, -13, -58, 3, -14, -35, 0, -24, -27, 80, -29, -55, + 35, 35, -24, 44, 13, 29, -13, -11, 13, -41, 56, 22, -19, 16, 7, -42, + -11, -24, -27, 42, -13, -23, -35, 55, 1, 46, -76, 78, -2, -2, -53, 37, + -40, 19, -19, -50, 12, -6, -3, -69, 56, -47, 47, -26, -46, -8, 21, 15, + 39, 56, -36, -1, -62, 54, -45, 67, -38, -17, 13, 26, -7, 32, -43, 22, + -62, -21, 17, 28, -56, -32, 16, 28, -61, -26, -30, 0, 27, -4, 25, -43, + -20, -77, 25, -7, 12, 44, -83, 73, -83, 78, -4, 15, -31, 35, -70, 63, + -55, 63, -18, 3, 49, 30, -39, 7, -28, -45, -11, 26, 15, -37, -36, -33, + -11, 31, -19, 68, -32, 10, 40, -37, 9, -7, -65, 81, -56, -20, 35, 4, + -60, 45, 10, -73, 52, 28, -51, -28, -37, 75, -63, -16, -34, -35, -20, 3, + -6, -4, -8, -39, 3, -53, 4, 10, -9, 13, -1, 10, 44, -20, -56, 73, + -71, 24, 61, -78, 14, -45, -21, 87, -68, 24, -36, -22, 36, -49, 20, -77, + 37, 60, -51, 75, -76, 51, -15, 16, 0, -71, -4, -13, -11, -29, -62, -25, + 84, -58, -4, 13, -42, 10, 30, -3, -35, 41, 29, 1, 53, -39, 55, 7, + -15, 59, -55, -25, 18, -11, 60, -72, 51, -41, -26, 32, -37, 14, -10, -45, + -30, 44, -95, 69, -46, 15, -2, 18, -9, -43, -50, -11, 16, 30, 18, 23, + -1, 14, 25, -4, 20, 10, 13, -19, 26, 49, -53, 92, -43, 4, -20, 2, + 34, -78, 14, -28, 27, 35, -40, -5, 61, -36, 37, -32, -25, -5, 22, 28, + -15, 61, -55, 71, -36, 62, -65, 58, -38, -50, 88, -51, 6, -59, 85, -20, + 0, -33, 48, -33, -21, 64, 23, -21, -23, -6, 14, -31, 52, 5, -30, -37, + -33, -58, 70, -7, 68, -64, 36, -37, -11, -6, -15, 13, -1, 19, -58, 36, + 36, 58, -68, -38, 52, 13, -35, 28, 36, 48, -34, 32, -16, -36, 36, 20, + 11, 78, -41, -30, 32, 12, 39, -30, 13, -70, 40, 12, 0, 15, 11, -23, + 23, -28, 23, -7, -88, 54, -9, -70, 70, 15, 31, -70, 44, -40, 78, 13, + -24, -78, 51, -87, 71, -34, -61, 84, -55, 50, -6, 48, -10, 70, -49, -34, + 3, 53, -6, 22, 17, 40, 9, 27, 25, -64, 79, 11, 21, 65, -68, 60, + 33, 17, 26, 38, -54, 67, -10, -10, 43, -41, 2, -29, -69, 51, -5, 10, + 3, 44, -73, 4, 57, 35, -36, -14, 76, -49, -5, 46, -57, 0, 2, 105, + -86, -34, 28, -45, 9, -30, 36, -42, -15, 72, -40, 12, 32, 14, 84, -52, + 35, -62, 42, -3, 25, 63, -56, 54, -60, 6, -36, -43, -7, 28, -79, 37, + -70, 30, 21, -31, 63, -32, -18, -18, -55, 29, 22, 46, -51, 42, -86, 61, + 4, 31, 17, -20, 12, 31, -72, 22, 58, -32, 52, 27, -79, 72, -67, -38, + 4, 21, -52, 1, -73, 32, 10, -34, 0, 21, -62, 22, -38, -35, 3, 36, + 8, 55, -49, 0, -22, -23, -5, -19, 21, -15, -46, 83, -39, -19, 31, 29, + -64, -4, 4, -38, -5, -30, 16, 9, 22, 22, -71, 54, 7, 35, -4, -14, + -11, 39, 4, 62, -17, -25, -52, 64, -12, -6, 24, 0, 1, 29, -21, 33, + 60, -26, 23, -83, 46, -30, 26, -35, 28, 5, 50, -30, -14, -23, 4, 28, + -48, -10, 33, 8, -13, 49, -62, 78, -94, 65, -36, 18, -8, 46, -58, 17, + -17, -68, 4, 67, -24, -23, -41, -22, -54, 82, -73, 0, -42, 43, -77, 66, + -33, 68, -79, 63, 46, -31, 23, 53, -37, -26, -1, 15, 18, 37, -20, -55, + 78, 47, 47, -12, -76, 67, -16, -65, 59, -26, -10, -29, -15, -18, 55, 25, + 14, -87, 13, -45, -31, -16, -43, 20, -13, 26, -26, -26, -5, 18, 12, -30, + -12, -37, 14, 17, -26, 25, 11, -27, 13, -27, 4, 34, 51, -10, -8, -28, + -7, 48, -40, 59, -81, -19, -20, 54, -94, 101, -51, 13, 10, 26, -45, -85, + 56, 37, 41, -36, 38, -25, 0, -14, 23, -11, 44, -21, -12, -20, -29, 43, + -66, 60, 4, -17, -20, -29, 3, -42, 95, -50, 65, -22, 15, 39, 4, 8, + 55, -64, 62, -10, -13, -43, 28, 54, 57, 5, -21, -55, 46, 16, 52, 0, + -21, -5, -83, 32, 30, -79, 81, -1, -28, 0, 34, -54, 65, -65, 80, -14, + 0, 13, 52, 43, 37, -30, 41, 51, -48, -47, 50, -13, 24, 40, -5, -17, + -20, -24, 37, 40, -9, 35, -29, 50, -21, 6, -28, -67, 73, -49, 25, -58, + 60, 0, -47, 66, -26, -8, 22, -62, -26, -16, 58, -68, 4, -52, -21, 6, + 26, -46, 26, -48, -8, -29, 77, -44, 16, -57, 34, -12, -28, -52, 62, -76, + 19, 40, 1, 53, -45, -14, 64, -27, 45, -13, 9, -49, 45, 40, 31, 8, + -17, -6, 19, -47, -3, -7, 52, -94, 43, -41, 0, 29, 5, -64, 90, -32, + -30, 56, 46, -69, -56, 50, -4, 56, -26, 33, 70, -35, 53, 4, 59, -78, + -39, 16, -20, 15, -47, -24, 22, 15, -12, -34, 30, 52, -74, 24, -42, 7, + -23, -67, -28, -14, 57, 24, -12, 7, 32, -39, 24, 17, -29, 22, -11, -43, + -48, 70, 46, -30, 76, 4, -36, 0, -11, 22, -44, 57, -22, -16, -69, 55, + -3, 0, -5, -16, -37, 34, 12, -38, -23, 6, 34, -42, -32, 6, 15, 5, + -9, -42, 34, -34, 71, 29, 24, -15, 20, -81, 5, 58, -43, 11, 38, 36, + 32, -51, -38, -37, 59, 33, -7, 0, -53, 58, -19, -20, 33, -57, 18, 17, + -7, -5, -8, 26, -7, -9, -52, 38, -76, 24, 7, -19, 62, -23, -51, 29, + -10, 0, -51, -11, 67, -15, 21, -56, -15, -60, -4, 51, -54, -48, 0, 2, + -22, 65, 55, -5, -87, 101, -66, -28, -2, 17, 10, 9, -76, 95, -62, 49, + -31, 9, -55, -64, 26, 25, -43, -50, 39, 8, 45, 16, 23, 16, -13, -32, + 54, -44, 15, 27, -44, 19, 24, -13, 7, 14, 53, 25, 12, -10, -13, 40, + 3, -9, 76, -29, -2, 0, 0, 58, 42, -25, 11, 39, -63, 73, 25, 52, + -46, 22, 10, 0, 11, -22, 5, 3, 23, 22, -27, -28, 49, 41, -43, 56, + -27, -65, 52, -50, 1, 18, -47, 16, -76, 64, -47, -13, 63, -62, -24, -44, + 17, 13, -10, 29, 59, -34, -19, 54, 19, 35, -73, 44, -19, 8, -28, 2, + -4, -41, -6, 33, 50, 52, -55, 44, 43, -34, -72, 47, -36, -69, 12, 51, + 54, -31, 15, 5, 26, -45, 0, -15, 58, 12, -31, -59, 54, -5, 51, -47, + 106, -22, 57, 44, -32, -38, 60, -57, -8, 20, 0, 43, -73, 23, 39, 10, + 42, -15, -19, -3, -20, 2, 53, -50, 50, 11, -21, 11, -25, 56, 24, -23, + -35, 42, -35, -13, 70, -67, 38, -11, 48, -30, -21, 71, -36, -15, 47, -58, + 42, 55, -21, -11, -3, -77, 33, -2, 30, 70, -15, -20, 69, -103, 53, -82, + 61, -44, 23, 45, -47, -52, 17, -29, 13, 31, -51, 75, -49, 65, 4, 21, + 21, -41, -23, -2, -56, 38, 18, 36, 54, -57, -8, 12, -59, -15, 47, 49, + -24, 0, 44, -24, 19, -38, 54, -63, 72, 24, 5, 33, -3, -17, 73, -51, + 32, -60, -22, 3, 87, -60, 14, 51, -31, 23, -32, -31, 69, -83, 27, -33, + 16, -32, 22, 61, -28, -41, 97, -34, 47, -7, -62, -30, -45, -25, 18, 18, + -54, 55, -47, -13, -31, 0, 16, -30, 0, -85, 30, -42, -20, -5, 1, -20, + -9, -48, -20, 12, -26, -23, 36, -78, 45, 33, -67, 26, 26, -30, -24, -72, + 0, 0, -36, 41, -68, 43, 48, -39, 33, 11, 0, 25, 37, -71, 15, -32, + -17, 28, 18, -15, 41, -13, 4, 24, -5, 22, 24, -31, 3, -12, -8, 34, + 8, -14, -24, 0, -36, -47, 66, -118, 44, -45, 57, -19, -8, -58, 53, -8, + 48, 6, 44, 12, -79, -17, -23, -14, -95, 66, 19, -27, 57, 24, 35, -49, + -54, -29, 69, -31, 0, 65, -3, -31, -35, -51, 48, 13, -37, 30, -49, -6, + -26, -50, 49, -81, 12, -35, 13, -25, 36, 11, -28, 24, 12, 1, -78, 7, + 34, -34, 0, -22, 58, -21, -60, 46, -43, 59, -64, 51, -1, -45, 41, 8, + -23, 10, 26, 10, 32, -29, -42, 10, 43, 16, -22, 27, -15, 20, -12, -36, + 5, -33, 5, -28, 50, 12, -39, -28, 6, -16, -35, -58, 3, 68, 20, -46, + 24, -42, 53, -4, -24, 99, -50, 20, 13, 12, -22, -23, -33, -6, -61, 5, + 26, -31, 75, -21, 39, 23, 12, -10, -51, 42, -45, 53, 28, -36, -29, -22, + -8, -64, 38, 13, -50, -13, -55, 45, -8, -78, 27, 1, -20, 55, -59, 6, + 2, -11, 85, -59, -53, 38, 13, -40, -22, 83, -45, 46, 25, -4, -3, -6, + 25, -32, 39, -51, 24, -35, -16, -45, -48, 45, 23, 27, 42, -27, -66, 72, + -60, 94, -46, -8, 20, 8, -28, 42, -11, 58, 27, 26, -16, -44, 45, 6, + -7, 71, -60, 43, 60, -51, 69, -47, -60, -7, 29, 10, -10, 48, 20, 34, + 25, 38, -55, 2, 9, 13, -54, -31, 8, -60, 17, 17, -40, 50, -10, 41, + -19, -11, 20, -47, 25, 0, -37, 60, -40, -17, -10, 40, -52, -15, -1, 45, + -82, 53, -23, 35, 2, 23, -5, 75, -5, -17, -4, 9, 24, 45, -10, -26, + 0, -65, 21, -58, 46, 15, 28, -2, 87, -40, 9, -70, 15, -85, 55, -6, + 79, -3, -41, 5, -38, -49, -16, 49, -2, 75, -4, -19, 69, -85, 63, 4, + 1, -13, -10, 23, 61, -26, -35, 39, -24, -1, 53, -78, 18, 31, 19, 32, + -21, -26, -29, -2, -46, -3, 82, 9, -10, -26, 84, -49, -10, 17, -13, 16, + 40, 27, -78, 35, -57, 23, 16, 6, -68, 1, 21, -74, 15, -21, 9, 25, + -17, 58, -75, 64, -93, 70, -27, 34, -19, -24, 39, 29, 56, -76, -24, 7, + 57, -6, 5, -80, 83, -91, 68, -62, 30, -6, 5, -19, 40, 2, 36, -33, + -1, 56, -99, 41, 33, -33, -22, -36, 34, 5, 54, -49, 28, -4, -10, 49, + 28, -2, 12, 12, 16, 8, 67, -56, 48, 53, -45, -13, 31, -77, 82, -4, + -10, -26, -56, 89, -27, -6, -50, 111, -39, -50, -18, 22, -30, -1, 39, -6, + -26, 24, 42, 56, -61, 74, -75, 80, 24, -31, -5, -1, 10, -15, 64, -3, + 20, -84, 12, 56, -37, 38, 40, -44, 69, -70, -17, -25, 29, 57, -35, 29, + -23, -18, 5, 16, -48, 30, -37, 44, 19, 33, -19, 7, -24, -19, -66, 63, + -52, 22, 30, 11, -11, -25, 67, -37, 45, -49, 41, -24, -24, -25, -32, 26, + 7, 22, -56, 64, -46, 0, 36, -89, 26, -38, 14, 44, 6, 51, 8, 19, + 8, 17, -3, -28, -4, -8, 35, -101, 43, 7, -19, 14, -18, 7, -21, 1, + 6, 56, -31, 51, -79, 67, -19, 20, -35, -22, 35, 29, 52, -20, -7, 14, + -38, -46, 92, -14, 19, 30, 16, -38, 9, -41, -12, -39, 34, 11, -6, -34, + -28, 12, 12, -49, 34, -33, 72, 29, -25, 1, 11, -19, 86, -77, 67, -66, + -14, 60, 20, 25, 32, -32, -50, -52, -9, -2, -16, -39, 45, -3, 1, -50, + -56, 74, -16, 66, -32, -10, 29, 1, 60, -24, 50, 30, -2, 18, 30, -1, + 13, -13, 30, -9, 57, -15, 24, -82, 74, 34, -59, 22, -57, 6, 51, 3, + -22, -38, 5, 37, -4, -1, -12, 12, 34, -44, -9, -14, 39, 36, 25, -11, + 3, -42, 69, -43, -54, 40, -30, 77, -54, -17, 5, -10, 41, -9, -37, -15, + 23, -15, 64, -88, 86, -64, -11, 15, -68, 3, 11, 32, -13, 39, -15, -16, + -2, 32, 11, -61, 54, 5, -20, -53, -54, 95, -34, 62, -46, 26, -17, -11, + -10, -28, -41, -58, -20, 16, 23, -24, -9, 16, 10, -47, -9, 56, -77, 23, + -32, 36, 58, -36, 10, -57, -31, 18, -89, 70, -19, 1, -39, -7, 8, -11, + 34, 1, 20, -42, 23, -39, -4, 15, -3, 31, -69, -23, 64, -43, 60, -30, + -36, 54, -13, -34, 64, 26, -26, 64, -38, 54, -72, 62, -24, 47, 6, -38, + -29, 69, -65, 69, -73, 41, 8, 74, 1, 73, -62, -2, -44, -68, 64, -55, + 48, -46, 2, 41, -42, -18, 17, 49, -24, -46, 40, -20, 54, -75, 71, -5, + -43, -35, 3, -56, 65, -43, -17, 8, -42, 16, -58, -14, -21, 36, -5, -20, + 5, 3, -46, 15, -27, 65, -38, 49, -46, -17, 34, -23, 5, 2, 12, 23, + 18, 38, 29, 25, -31, -15, -30, -53, 33, -53, 0, -49, -35, -42, -1, 31, + -42, 44, -87, 33, 7, 19, 28, 36, 53, -40, -41, 29, 25, 19, -49, 27, + 20, -40, -66, 13, 9, -22, 31, -89, 21, -41, -65, 44, -54, 32, -51, 12, + 8, 1, -33, 1, -91, 62, -62, 112, -86, -9, 7, 19, 36, 17, -34, -37, + 48, -30, 81, -86, 12, 35, -34, -74, 48, -46, 53, -39, -30, -61, 3, 1, + -21, 10, 28, -13, 42, -53, -5, 19, -42, 33, 4, -35, -7, 34, 19, -21, + -24, 12, -50, 78, -59, 11, 46, 40, 7, -26, 30, -13, 4, 1, 8, -13, + 23, -33, -12, 60, -57, 58, 14, 38, 67, -81, 56, -78, 87, -54, 1, -49, + 25, 6, 53, 22, 47, -5, -3, 19, -38, 34, -57, 94, -49, 9, 73, -31, + 36, -38, -37, -17, -29, 66, 54, -59, 88, -1, -37, 45, 11, 23, -59, 17, + -75, 78, -30, -14, 31, 31, -13, 32, -60, 40, 53, -19, -19, 28, 6, -14, + -18, -60, 4, 6, -84, -18, 46, -87, 56, -1, 48, 11, -15, 50, -74, 49, + 39, -78, 52, -53, 70, -52, -17, -57, -15, -57, 31, 33, 76, 5, -38, -14, + 10, 15, 34, -15, 64, -17, -10, 15, -20, 16, -2, 34, -23, 46, -16, -54, + 107, -17, 23, 48, 23, -23, -28, 82, -28, 62, 41, -10, -28, 56, -34, 36, + 0, -29, 1, 7, 40, -65, 3, 51, 0, 61, 24, -64, 54, -29, -22, 14, + 10, -66, 41, -28, -38, 69, -41, 34, 5, 54, 12, 35, 57, -19, 48, -46, + 45, -56, 95, -38, 0, 3, -59, 50, -56, 65, 49, -69, -14, -29, 53, 6, + -36, 3, 94, -10, -19, -55, 48, 73, -78, 61, 82, -58, 18, 27, 11, -32, + -24, 17, 24, 5, 52, -1, -13, -72, 66, -14, -49, 33, -24, -52, 37, 38, + -27, 23, -60, 49, 40, -67, 70, 46, 21, 8, 40, -34, 46, -10, -2, 13, + -10, 39, -41, 16, 0, 2, 35, -42, 45, 55, -47, 40, -66, 50, -58, 42, + 4, -19, 25, -45, -6, -11, -28, -51, 28, 32, -12, 23, -3, -18, 0, -48, + -47, 54, 6, 24, -6, -15, -27, -28, -30, -7, 16, 9, -47, 17, 50, 22, + 70, -66, 37, -50, -27, 27, -20, -30, 81, -79, 92, -65, -1, -2, -35, -24, + 62, -5, 85, -52, 112, -91, 2, -23, 11, -47, 25, -19, 31, 6, -14, 28, + 42, -44, -37, 16, -35, 0, -12, 44, -25, -7, -51, 37, 22, -57, 53, -22, + 38, 27, -4, 15, 72, -31, -30, 14, -61, 50, -64, -22, -1, -21, 67, -82, + -4, 65, -35, 64, -35, 62, -4, 54, -22, 51, -22, -69, -36, 0, 41, -27, + 2, 0, -45, -25, 22, -46, 14, 69, -60, 55, -61, 8, -40, -43, 24, 51, + -84, -44, 45, -22, -79, 24, -11, -50, 9, -79, -18, 31, -7, -64, 44, 15, + 5, 23, 45, -30, -47, 34, -33, -36, -14, -32, 3, 12, -4, -5, 18, 9, + -11, 4, -35, -3, 63, -15, 48, -27, 7, -59, 45, 11, -67, 29, -32, 36, + -9, 34, -62, 41, -60, -25, 62, -39, 12, -65, 8, 54, -6, -36, -34, 40, + 9, 17, -61, -34, 72, 49, -17, -29, 81, -40, -39, -7, -77, 66, -67, 54, + -8, -31, -45, -5, -43, 31, 13, 75, -72, 3, 65, -10, 31, -2, -3, -74, + 53, 0, -46, 27, -54, 15, -64, -62, 42, -28, -34, 64, -28, 29, -11, 33, + 27, 22, -37, -23, 14, 76, -54, 38, -24, -49, 31, -25, 10, 56, -44, -18, + 20, 10, -57, 39, 47, -14, -44, 42, 12, -24, 9, -55, -18, -60, 49, 65, + 64, -57, -30, 13, -48, 43, -38, 39, 27, 13, 30, -63, 18, 45, -28, -67, + -30, 4, 55, -39, 27, 20, 30, -29, -21, 7, -19, 14, 17, -36, 25, -22, + -65, 7, -19, -17, -63, 39, 11, 15, -32, -20, 15, 36, -21, -42, 40, -1, + 0, 28, 54, -42, 16, -7, -18, -5, 29, 30, -21, -43, 41, -1, -35, 11, + 9, -21, 27, 10, -46, 11, 8, 10, 62, -43, 33, -2, 16, -23, 29, 41, + 31, -9, -34, -8, -49, -21, 36, 18, -58, 50, 30, 65, -17, -31, 31, -8, + -55, 45, -25, 37, -42, 77, -48, -4, -35, 19, 13, -10, 88, -10, -44, 20, + 76, 20, -74, 59, 18, 28, 7, 70, 18, 2, 65, -72, 63, -3, -11, -52, + -21, 20, -17, 0, 5, 26, 17, 0, 28, -27, 45, -30, 19, -37, -24, -14, + 10, -12, 21, -1, -43, -47, 6, -60, 52, -38, -30, 23, 25, -11, 26, 32, + -28, -22, -31, 5, 34, 41, -51, 1, 38, 16, 8, -38, 51, 11, 53, -42, + -50, -21, 64, -48, -10, -69, -12, -14, -31, -17, 39, 19, 60, -33, 22, -62, + 41, 25, 43, 26, 2, 46, -77, 17, 30, 23, -84, 17, 0, -55, 80, -3, + -20, 19, 9, 7, 23, 39, 45, 62, -81, 15, 42, -50, -15, -2, 9, -37, + -41, -49, 45, 17, -66, -57, -23, 25, 25, -10, -16, -6, -2, -28, 53, 32, + -77, 14, 0, 39, -21, -5, 55, -10, -52, 18, 37, 0, 47, 62, -12, -66, + -45, 1, 64, -54, 51, -62, 74, -76, -6, -38, 2, 47, -7, -40, 35, 17, + 68, -65, -6, -27, 31, -74, 36, -6, 5, 4, -26, 15, -18, 15, -8, -4, + 95, -37, 52, 2, 4, 23, 4, 19, 18, 65, -20, -24, 6, -25, 57, -65, + 10, -49, -27, 70, -59, 81, -29, 21, -56, 19, -43, 73, -67, 24, -38, 62, + -33, 53, -69, 67, -27, 37, 8, -44, 39, -41, 32, -28, 0, -8, -23, 1, + -30, 20, -22, 16, -7, 62, -111, 42, -33, -41, 0, -67, 31, 39, -29, 16, + 49, -4, 6, -11, 35, -71, 32, -14, -48, 61, -22, -18, -78, 16, 52, -9, + -59, -33, 59, -38, 24, 12, -20, -101, 27, 41, -61, 9, 27, -37, 51, 9, + -27, -34, 21, -5, -4, -34, 41, -1, -33, -40, 52, -52, 55, 6, 3, 54, + 15, -35, -7, -23, 43, 32, -21, 13, 15, 46, -43, 24, -69, 74, -77, -12, + -23, 57, 35, 1, 43, 13, -22, -45, 41, 23, -36, 41, -73, 17, -42, 76, + -66, 89, -53, 65, -3, 61, 15, -12, 1, 4, 24, -26, -24, 31, 9, 20, + -21, -22, -51, 24, -33, -6, 35, -43, -51, 58, 18, -21, 49, -48, -16, 71, + -56, 35, -1, 25, -15, -36, -58, 17, 22, 45, -40, -23, 69, -21, -28, -8, + 63, -17, 17, 16, 45, -6, 74, -79, 31, 19, 35, -20, 41, -49, -38, 44, + 17, 31, 0, -16, -43, 49, -75, 80, -5, -16, -45, -32, 21, -48, 33, -7, + 71, 5, -47, 67, -55, -13, 26, 35, 52, -6, -44, 21, 3, 14, 0, -49, + -24, 72, -1, 0, -8, 22, -46, 57, 27, 3, -32, -2, 16, 15, 15, 14, + -36, -43, -6, -2, -24, -40, -25, -35, 11, -82, 60, -45, 28, -42, -57, 71, + -61, 69, -33, 30, -56, 20, -22, 16, 42, -12, -28, 33, -70, 91, -40, -33, + 47, -52, 31, -62, 7, -7, 9, -42, 54, -44, -16, 10, -15, 9, -37, 17, + -43, -11, 75, -72, 76, -78, 84, 29, 36, -29, 35, 73, -82, 51, -37, -28, + -31, 23, -1, -36, -39, 64, -50, 75, 13, 0, -29, 67, 43, -11, -13, -74, + 85, -34, -39, 60, -41, -61, 30, 87, -38, -24, 54, -27, -38, 53, -35, 37, + -16, 37, 27, 5, 0, -52, 25, -42, 36, 57, -65, 38, -43, 2, 31, -62, + -1, 14, 36, 13, 10, 5, 0, 68, -61, 2, -4, 12, -14, 48, -29, 34, + -1, -69, 8, -58, -21, -21, -14, 71, -96, -15, -17, -42, 54, 61, -43, 19, + 54, -46, -11, -43, 49, -80, -35, 56, -24, 9, -38, 39, -18, -4, -33, 47, + -1, 51, 58, -50, 5, -48, 81, -40, 43, -26, 4, 34, -27, 88, -38, -46, + -16, 6, 8, -40, -10, 45, -82, 74, -62, -24, 37, 55, -64, -16, 32, 23, + -65, 25, 35, -40, 38, 13, -16, 48, -31, -39, -16, -5, 51, -24, 52, -90, + 1, 45, -40, -23, 55, -31, 21, -51, 2, 58, 32, 9, -51, 6, -37, -2, + -29, -33, 61, -87, 93, -29, 42, -84, -31, 40, 13, -31, -7, -32, -29, 106, + -74, 19, -57, 46, 20, -39, 51, -77, -10, -11, 25, -41, 69, -104, 64, -57, + 4, 60, -1, -40, 71, 50, -18, -17, 43, 15, 5, -62, 56, 28, 39, 0, + -8, -41, 59, -51, 54, -6, -26, 44, -25, 57, -19, 23, 77, -91, 56, -50, + 4, 73, -54, 41, 30, 9, -71, 72, -61, 19, 50, -43, 30, 18, 61, -81, + 82, 11, -58, 5, 36, 3, -49, -19, -44, 21, -33, -53, 32, 55, -34, 14, + 67, -4, -38, 35, 58, -53, 52, -74, 62, -32, -18, -44, 49, -61, 21, 67, + -20, 5, -11, -49, 39, 5, 32, -69, -27, 66, -92, 44, 22, -29, -11, -4, + 13, -27, -35, 21, 18, 45, 6, 25, -49, 1, 45, -54, 43, -8, -37, -4, + 69, -27, -18, 41, -43, -39, 31, -39, -45, 87, -76, 47, -60, -10, -29, 42, + 22, 48, 0, 8, 30, 2, -25, 43, 42, 49, 53, 17, -18, -92, 77, -52, + 9, -5, 58, -9, 15, 14, 39, 3, -11, 41, -20, 14, -52, 64, 19, -56, + 35, -93, 40, -34, -24, 66, -73, -20, 50, -28, -16, -34, -25, -42, 18, 51, + 16, -18, -18, -39, 47, 8, 55, -47, 61, 17, -39, -24, 12, 49, -21, 44, + 25, -31, -14, -23, -15, -32, 19, -56, 28, 29, -21, 7, -19, 19, -75, 98, + 37, -25, -5, 55, -18, -10, -24, -25, 25, -68, -22, 27, 10, 30, 51, 6, + 5, -26, 45, 8, 0, -38, -18, 63, -4, 27, -35, 66, -46, 17, 60, -117, + 83, -41, 79, -63, -24, 79, -58, 114, -48, 24, 30, 25, -53, 58, -36, 45, + -40, -20, -25, 34, -65, 29, -41, 57, -49, 32, 29, 31, -47, 33, -22, 40, + 46, -9, -58, 29, -34, -24, 4, -56, 53, -47, -29, -32, -44, 28, 50, -58, + 83, -110, 50, -62, 70, -95, 111, -90, 43, -7, 10, -76, 45, -85, 60, -9, + 15, -66, 63, -5, -20, -64, 46, 67, -42, 77, -49, 35, 5, -73, 34, -22, + -50, -10, -6, 37, -42, 10, -41, 8, -49, 36, -35, 24, 22, -33, -15, 0, + -31, 45, 61, -19, 48, 0, -17, 10, 22, -16, 32, 23, -36, 14, -16, 21, + 22, 20, 33, -39, -47, 24, -11, -30, 6, 20, 57, -75, 84, -53, 60, -21, + -32, 14, 14, -42, -35, 54, -41, 52, 5, -38, 43, 42, 2, 65, -5, -45, + 7, -76, 12, 18, 18, -32, -23, -78, 50, -77, -52, 36, -47, 31, 19, -36, + -31, 13, -14, 19, -31, 40, -71, 52, -70, 54, -23, 1, 78, -80, -47, 70, + -55, 70, -22, 57, 36, -22, 44, -1, 8, -46, -16, 36, 47, -24, -15, -66, + 13, 4, -10, 82, -43, 20, -4, -20, -4, -52, -17, 62, -47, -39, 0, -33, + 7, 37, -45, 27, -64, 93, -81, 79, -55, 6, -21, 26, -27, 6, 59, -82, + -63, 19, -61, 19, -61, 33, 28, 9, 16, 77, -53, 47, 21, -28, -63, 51, + -36, 18, -57, -28, 20, -29, 83, -45, -6, -25, -37, 28, 40, -71, 59, 37, + -21, -31, -30, 0, 40, -58, -53, -14, -53, -4, -32, 44, 17, 17, -2, 54, + -68, 85, -27, -20, 73, -74, 68, -25, 27, -68, -17, -4, -11, -15, -54, -15, + -19, -15, 86, -69, 21, 35, -15, 46, -71, 55, -17, 50, -2, -49, 4, 19, + -90, 69, 60, -47, -63, 67, -44, 18, 36, 6, 16, 87, -79, 94, -26, -6, + -20, 2, -21, 65, -55, 99, -31, -70, 56, -107, 65, -47, -9, 14, 45, -11, + 26, 53, -38, 23, 0, 47, -33, 41, -18, 42, -8, 1, 0, 60, -39, -3, + -11, 15, -51, -5, -18, 22, -1, -33, 14, -29, -7, 27, 44, -15, -21, 7, + -33, 7, -87, 104, -11, -37, 3, 67, -45, -24, -33, 81, -91, 29, -60, 6, + -18, 2, 33, -5, 47, 23, -9, 0, -29, -9, 4, -56, -6, -27, -10, 33, + 59, -3, 50, -55, 53, -44, 76, 26, -25, 19, 34, -36, 36, 3, -2, 47, + -31, 2, -1, -33, -39, 58, -13, 0, -53, 37, -11, 21, -93, 83, -12, -63, + 36, -70, 2, -48, -17, -48, 48, -37, 3, 15, 61, -24, -5, 26, 0, 32, + 22, -12, 23, -87, 25, -48, 8, 8, 52, 66, -37, -71, 79, 13, -40, 2, + 13, -35, 19, 31, 15, 19, 6, -15, 10, -25, 26, 25, 64, -82, 4, 56, + 57, -43, 80, -24, 54, -19, 48, -14, -4, -62, 46, -63, -7, 32, 40, -58, + 10, 5, 64, 51, -41, 1, -65, 31, 9, 53, 1, -23, 33, -38, -22, 9, + 28, -56, 98, -34, -2, 38, 34, 51, 38, -13, -10, 4, -15, -71, 3, -5, + 19, -28, -27, 16, 5, 11, -20, -13, -27, 68, 19, -12, -62, 56, 21, 42, + -64, 54, -98, 60, -10, 30, -7, -21, -17, 46, 38, -35, 77, -12, 63, -30, + 89, -35, -35, 24, 51, -45, 53, -51, -28, 0, -40, -30, 24, -38, -23, 23, + 72, -29, -5, 4, -24, -80, 83, -44, 35, 27, 23, 46, -52, 44, -20, -27, + -16, -8, 30, -98, 51, -27, -6, -38, 51, -24, 3, -18, 0, 39, -53, 81, + -50, 0, 0, -7, 19, -57, 14, -16, 43, -5, 4, -37, -20, 40, -42, 41, + -55, 55, 36, -60, -37, 54, -10, -37, 44, -33, 51, -50, 68, -12, 55, 43, + -50, -10, -61, 23, -32, -21, 75, -84, 73, -36, -18, -7, 90, -43, 61, -50, + -48, 29, -43, -19, -37, 8, -27, 25, 9, -88, 71, -22, 4, 39, -72, 46, + -20, 4, 19, -1, 41, -28, 7, 23, 0, 10, -44, 1, 52, 12, -25, 75, + -13, 77, -44, 92, -13, 32, -8, 65, 3, 7, -26, -15, 8, 2, -39, 9, + 39, -19, 45, 16, 46, -7, 7, -17, -75, -11, 34, 55, -26, -10, 53, 58, + -74, 73, 9, -32, -7, -31, -1, -58, 38, -1, -15, -10, -45, 37, 66, -87, + -43, 66, -9, -68, 0, -66, -16, -13, 0, -11, -15, 68, 9, -51, 32, 49, + -49, 12, -78, 9, 17, -9, 51, -4, -37, -36, 49, -64, 47, 50, -13, -61, + 34, 59, -67, -24, 45, -34, -4, -62, 18, 45, -51, 0, -35, 80, 36, -50, + -29, 65, 13, 21, -46, 0, -9, 2, 35, -60, 37, -21, 65, 10, -26, 1, + 19, 5, 42, -3, -47, -14, 37, 35, -4, -33, -37, 24, -58, -61, 21, -23, + -60, 17, -27, -18, 15, -12, 22, -16, 39, -34, 64, 2, -23, 10, 7, -28, + -10, -14, 31, -37, 29, 46, -68, 57, 31, -40, -48, 42, -45, 52, -48, 6, + 0, -7, 18, 73, 15, 8, 6, -33, 38, -45, 72, -53, 75, -63, 15, -42, + -10, 71, -21, -48, 33, -2, 51, -44, 26, -33, 7, -43, -8, 19, -14, -25, + 72, -66, -13, 52, 9, 49, -39, 13, -20, -47, 13, -46, -40, 63, -56, 15, + 47, 21, 33, 20, -40, 55, -79, 41, 52, -12, 63, -35, -45, -29, 51, -32, + 21, -62, 52, 16, 52, 36, -26, -27, 54, 50, -3, -44, 20, -11, 35, 16, + -15, -2, -37, -34, 71, -57, -55, 72, -51, 76, -57, 36, -81, 64, -14, -1, + -68, 2, -19, -49, -22, -16, -25, -55, -36, 31, -73, 62, -51, 67, -4, 1, + -72, -13, 20, -52, -13, 27, -75, 78, 38, -15, -24, 15, -28, -19, -42, -34, + 19, -17, -48, 37, 39, -5, 19, 27, 20, -2, 29, -55, 32, -73, 2, 24, + 27, -66, 44, 37, 31, 24, 64, -31, 64, 2, 4, -73, 14, -20, -33, -57, + 69, -28, 55, -31, 22, -11, -29, 8, 2, -29, 18, 47, -67, -48, 15, 42, + -18, -42, 67, -62, 42, -11, 6, 83, -92, 24, 29, 22, -17, -62, 24, 44, + -33, 11, -51, 26, 33, 20, 9, -29, 47, -8, -59, 66, -65, 17, -1, 12, + 34, -75, 45, 15, 9, -13, -6, 0, -50, 38, -14, -31, 30, 86, -84, 64, + -1, -34, 52, -31, 52, -76, 42, 28, -60, 33, -27, 14, -19, 71, -44, -15, + -35, -54, 60, 2, -7, 28, -29, 11, -66, 0, 27, 6, -27, 20, -8, 42, + -60, 16, -19, -83, 11, -80, 27, 7, 28, -23, 5, -36, -42, 52, -9, -24, + 66, -85, 84, -36, 54, -82, 44, 36, -17, 14, 13, 49, -4, -18, 35, -2, + 35, -46, 60, -23, -63, 16, -65, 49, 23, 4, 59, 72, -29, -20, -11, -35, + 21, -41, -1, 0, -16, -19, -17, 47, -68, -38, 13, 17, 17, 21, -40, -28, + 0, 75, -52, 3, -40, -18, -4, -4, -46, -17, -33, -14, 33, -13, -24, -30, + 9, 46, -8, 34, -70, 78, 28, -82, 74, -84, 69, -18, 45, -83, 66, -58, + 104, -52, 53, 1, -4, 43, -5, 54, -21, 32, 17, 35, -47, -18, -37, 11, + 80, 23, -15, -15, 12, 44, -12, 19, -43, -45, 63, 28, -50, 26, 68, -58, + 36, -21, 12, -44, -7, -72, 37, -14, -2, 4, 1, 11, 35, 35, -45, 55, + -54, 36, -95, 58, -36, -7, -23, -12, -23, -15, -49, 23, 44, 48, 23, 15, + -8, -65, 29, 48, -64, 53, -17, 45, -3, -15, 3, -27, 47, 49, -24, -33, + 10, 13, -75, 42, 33, 2, -25, -58, 53, -38, 28, -5, -29, 24, -46, 19, + 20, -35, 22, -29, 40, -69, 3, -8, -7, -69, 75, -76, 88, -59, -4, -39, + 19, 11, -45, -15, 47, -47, 41, 7, 1, 36, -23, 75, -75, 22, -3, 18, + 3, 47, -38, 19, 5, 57, -67, -33, 58, 29, -47, 53, -60, -22, 43, 33, + 49, 62, -75, 35, -26, -26, 6, 18, 28, 23, -22, 65, -54, 49, -27, 20, + 60, -46, 45, 38, 40, 3, 28, 0, -4, -56, -3, 35, 19, -28, -1, 33, + -32, 55, -59, -3, 7, 18, -47, 19, -24, 30, -21, -14, 40, -37, 5, 0, + -21, -20, 15, -59, 86, -24, 80, -22, 21, -6, -46, -69, 32, -17, 70, -34, + 23, -25, 45, -41, 31, 12, 47, -53, 60, -12, 31, -42, 16, -69, 69, 46, + -13, -54, 92, -59, 56, 38, 6, 6, -20, 64, 6, 40, -50, -21, 73, 11, + -16, -16, 5, 74, -37, -6, -54, 80, -21, 35, -52, -38, 60, -17, -33, -26, + 22, -51, 13, -22, 55, 8, 18, -71, 43, -76, 36, 20, -40, 55, -26, 3, + -34, -42, 18, -4, -31, -11, -19, -36, 2, 28, -8, -61, 38, -30, -15, 6, + 3, 21, 17, -1, 59, 6, 33, -1, -6, 5, -49, 49, -40, 23, -9, 9, + 12, 1, 68, -79, 8, -8, -17, 33, 20, -3, 69, -3, -64, -6, -67, 69, + -39, 58, 2, -51, 30, -43, 71, -76, 71, -89, 82, -72, 41, -70, 34, 18, + -49, 34, 35, 11, -38, -18, -5, 74, 0, -38, -19, 37, 22, 2, 55, -52, + 3, 10, -40, 56, 19, -64, 85, 15, -42, 53, 42, -38, -25, 46, 12, -12, + 22, 12, -27, 49, -10, -19, 28, -40, 45, -29, -24, -41, 75, -67, 14, -22, + -22, 25, -10, -38, 62, -71, 76, -26, -65, 54, -37, 1, 13, 34, 3, -60, + -50, -1, 12, 40, -40, 52, -63, 35, 3, -19, -22, -2, -37, 26, 5, 4, + -14, -41, -34, 19, -46, 29, -6, -40, 37, 52, 19, -57, 23, -4, 22, -55, + 5, -57, 81, 4, 25, 49, -23, 6, -39, -13, 25, -8, -23, 41, -34, 37, + -7, -6, -27, 71, -34, -36, -32, -29, -40, -40, 21, 53, -20, 63, -70, -15, + 12, -60, 50, -68, 58, 6, -29, -51, 5, -36, 8, 11, 11, 38, -17, -27, + -33, 90, -89, 31, -47, -21, 34, -24, 28, -41, -77, 35, 51, -47, -33, 2, + -38, 47, -32, -70, 32, 38, -16, -53, 40, -19, 62, 16, -4, -19, 43, 22, + -23, 61, -44, 28, -63, 26, -3, 10, 14, 22, -13, 5, 34, -18, 42, 27, + -21, -14, 9, 0, 58, 31, 10, 30, 3, 3, -54, 61, 10, 54, 16, -46, + 10, 0, 9, 3, -46, -25, -17, -60, 60, -2, 41, 5, -49, 53, -31, -57, + 32, 9, -27, 62, 9, -22, 27, -51, 40, 30, -89, 35, 21, 63, -41, 9, + -23, 29, -87, 75, -58, 34, -49, -52, 55, 48, -45, 64, -8, 11, 37, -14, + 21, 12, -20, 0, 5, -19, 38, -93, 56, 10, 45, -29, 13, -72, 78, -82, + 104, -75, 97, -90, -6, 58, -80, -16, 26, -5, -5, 10, -20, -38, 19, 18, + -56, 20, -44, -25, 0, 31, -18, -14, -15, -41, 57, 52, -41, 33, 37, -41, + 63, 0, -39, -19, 10, -29, 41, -36, 79, -79, 56, -55, 18, -26, 42, -5, + 38, 25, 28, -34, 27, -56, 14, 32, -26, -18, 17, -16, 76, -71, 3, 15, + 21, 60, -32, 7, -65, 75, -35, 62, -68, -47, 37, 16, 29, 9, -61, 68, + -3, 64, -71, -33, -65, -26, 21, -21, 17, 40, -17, 35, -28, -12, -13, 11, + 43, -18, 73, -88, 33, 3, 44, -17, 52, 48, -68, 18, -6, -29, 56, -22, + 0, 53, -32, 40, -61, 61, 10, 53, 37, -31, -10, 65, -56, -1, 15, 0, + -48, -1, 0, 43, -28, 17, -37, -7, -27, -7, 78, 0, 14, 43, -29, 1, + -27, -27, 53, 30, -39, -7, 9, -27, -15, 27, -63, -64, -6, 26, -50, 21, + -52, 23, -45, 30, -22, -11, 12, -59, 29, -7, -53, 52, -53, -53, 34, -35, + -24, 30, 61, -3, -70, -27, 13, 18, -57, 37, 14, 5, -9, -80, -5, 49, + -2, -7, -55, 50, 37, 27, -36, 76, -46, -34, 0, -10, -21, -19, 25, -20, + 53, -53, 78, -128, 63, -7, 34, -27, 11, -50, 52, 21, -42, -54, 41, -67, + 41, 12, 40, 10, 33, -66, 57, 45, -34, -68, 66, -71, -20, -9, 7, -4, + -41, 13, 6, -46, 8, -31, -2, 50, -25, -51, 10, -6, -4, -37, 25, -1, + -56, 24, -52, 46, -14, 45, 0, 17, 26, -31, -51, -17, 29, 14, 9, 51, + 2, -50, 65, 7, -29, -26, -5, 17, -19, 73, -58, -51, -31, 29, -24, -24, + -37, -5, 48, 47, 14, -22, 5, 3, -16, 6, 23, -21, -5, 35, -57, 7, + 35, -58, -2, -45, 11, 17, 27, -61, -4, 34, -51, 31, -26, -9, 4, 0, + -84, -4, 15, -12, 68, -111, 67, -44, 33, 21, 8, -78, -3, 38, 31, -17, + -46, 61, -40, 46, 23, 59, 33, -70, 30, 8, 21, -55, 6, -3, 40, -76, + 59, -76, 15, 31, -47, 10, 24, 38, -19, 2, 21, 36, -19, 32, -54, 27, + -13, -2, 5, -51, 28, -56, -30, -73, 46, 15, -22, -65, 54, 41, -42, 21, + 29, 29, -13, -43, 47, -55, 90, -72, 49, 42, -68, -1, -16, -21, -37, 91, + 63, -2, -63, 0, 45, -32, 39, -3, 50, 7, 2, 82, 15, 13, 27, 1, + 9, 50, 34, -33, -36, 69, -51, 78, -1, 13, 17, -52, 53, -31, 63, -9, + 71, -73, -62, 20, -10, 82, -38, -16, 39, 13, -53, 10, -12, 76, -39, -59, + 53, 33, -4, -67, 0, 33, -57, 6, -13, 18, 27, -59, 56, -21, 24, -4, + -34, 62, -67, 86, 4, -16, -39, 21, -36, 6, 9, -8, -6, 46, 21, -20, + 42, -44, 0, -2, -42, 90, -69, 13, -22, 27, -21, 37, 61, -48, 6, 4, + -63, 66, -55, 82, -19, 47, -43, 18, -49, 92, -68, 45, 21, 55, -79, 54, + -28, 69, -25, 3, 12, -22, -61, 28, 25, 22, 44, 21, 19, -16, 0, -68, + -13, 45, -2, 37, -1, 70, -54, 14, 40, -51, -6, 84, -31, 16, -3, 44, + -15, 62, -58, -33, -22, -26, 68, -92, 63, -32, 27, 48, -31, -35, 38, 20, + -47, 54, -9, 41, 12, 3, -6, 1, 41, 40, -20, -14, -4, 40, 12, 44, + 9, 68, -94, 87, -59, 72, 14, -57, 14, 10, 12, 46, -55, 31, -45, -3, + -22, -12, 40, 18, -61, -12, -58, 93, -74, 1, -33, 53, -2, -30, 19, 69, + -69, 61, 27, -39, 36, 10, -41, -54, 0, -59, 58, -34, 38, -76, 29, 36, + 7, 18, 0, 19, 24, 15, 10, 90, -85, 45, 6, -27, 30, -36, -49, 20, + 11, 36, -42, 29, -19, 7, 10, 37, -19, 4, -10, -12, -13, 67, -38, -51, + -2, 17, 38, -14, -26, 10, -26, 9, -38, 41, -8, -59, -57, 52, -103, 58, + -25, -46, -4, 56, 21, -55, 77, -73, 40, -77, 18, -35, 64, 2, -39, 22, + -63, 56, 40, 6, -8, -49, -63, 66, -72, 21, 59, -49, -6, 61, -59, 117, + -88, 2, 35, 26, 16, -11, 55, -42, 47, -30, -12, 10, 7, 40, -48, 73, + 30, -69, 40, -66, -22, 9, 32, -29, 1, 41, -22, 26, -6, -18, 1, 43, + -44, 25, -32, 59, -35, -31, -32, 59, -49, 27, -36, 59, -69, 17, 29, 23, + 41, -14, 90, -81, -35, 60, -20, 4, -8, 14, -12, -17, -40, 26, 42, -19, + 7, -42, -2, 17, -52, 47, 7, 0, -29, -58, -9, -9, 29, -35, -5, 0, + 47, -49, 14, -50, -48, 16, 7, 28, -19, 31, 58, -91, 32, 6, 20, -89, + 65, -84, 71, -54, 73, -27, -24, 58, -51, 68, -7, -53, -28, 48, 0, -45, + 2, -45, -39, 21, -90, 41, -53, 17, -19, -50, 62, -52, 57, -53, -35, 26, + -72, 15, 34, -63, -3, -56, 63, 4, -39, -2, 15, -11, 18, -36, 9, 19, + -29, 47, -53, 0, 15, 39, -50, 33, -3, 53, -51, 39, -43, 9, -34, -4, + -3, -54, -8, -11, -11, -33, 71, 12, 63, 14, -54, -20, 38, -3, 37, -57, + -12, -52, 5, -8, -14, 10, 2, -48, -1, -14, 28, -22, 70, -60, 43, 58, + -50, -20, -15, -6, 41, -16, -50, 0, 35, -59, 53, 2, 43, -10, 60, -32, + 45, -75, 61, -44, 52, -39, 19, -26, -32, -16, 27, 52, -22, -22, 46, -14, + 56, -23, -45, -2, -15, -19, -52, -1, -5, 55, 36, -42, -4, -13, -9, -24, + 13, 41, -42, 6, -10, 84, 39, -19, -5, 5, -47, 60, -48, -19, 5, -85, + 44, -11, 17, -64, 5, 15, -65, 46, -12, -63, 50, 31, -12, -56, -21, -29, + -46, 6, 30, 7, -3, 14, 34, 41, -48, -33, 3, -22, 8, 24, -22, -33, + -56, 59, -73, 27, 7, 5, 10, 30, -9, -21, 71, -72, 11, 49, -41, 30, + -43, -35, -64, 43, 37, -51, -12, 56, -22, 71, -37, -34, 55, -15, -56, 75, + -23, 7, 3, 16, 28, -79, 46, -49, 31, 33, 11, -27, -10, 20, 37, 10, + -22, 35, -2, -8, 47, 50, -55, -44, 49, -62, -14, 16, 10, -12, -2, 42, + 25, -32, 40, 4, -49, -8, 27, 41, -34, -27, -43, 53, 10, 17, -1, 7, + 23, 57, 15, 10, 72, -5, 60, -9, 26, -27, -15, -7, -2, 59, -41, -13, + 66, 20, 27, -7, 20, 59, -65, 8, 53, -19, -38, 13, -68, 53, 2, 21, + 40, -35, -6, 46, -54, 22, -27, 41, -11, 16, -36, -6, 18, -13, 60, -11, + -24, 36, 25, 33, -8, 50, -67, -17, -64, -7, 57, -33, 1, -3, 53, -62, + 101, -26, 25, 36, 28, -67, 50, -8, 45, 5, 9, -1, -59, 2, 40, -63, + -22, 15, 56, -7, -22, -28, 75, -63, 36, 1, -2, -40, -16, -25, -39, -30, + 10, 68, -62, -22, 31, 35, 0, 46, 12, 3, -46, 13, 42, 30, 42, -79, + -20, 36, 8, -19, 77, -10, 49, 32, -61, -28, 35, -21, -8, 53, -9, -29, + 62, -45, -21, 33, -49, -67, -21, 33, -34, 40, 23, -16, 34, 11, -3, 73, + -16, -29, 21, -9, 26, -30, 71, -19, 17, 39, 20, -61, 39, 75, -37, 56, + -6, 34, -10, 4, 24, -85, 19, -60, 47, 71, 11, -12, -27, 65, -37, 29, + 63, -16, 39, 0, -54, 83, -94, 61, -11, 27, -78, 12, 27, -21, -34, -68, + 77, -24, 44, 2, -9, -35, 73, -65, -36, -14, 10, 7, -44, 37, -32, -32, + 15, -47, 52, -36, 31, 30, 0, 41, -16, 0, -45, -13, 82, -61, -55, 33, + -20, 12, 16, -66, 29, -41, -25, 70, -23, 19, -57, 65, -47, 15, -29, 32, + -8, -37, -19, -3, 56, 63, -56, -23, 3, -5, 16, -35, -8, 29, -27, -52, + 1, 13, -59, 20, -56, -26, -44, 25, 18, -9, 48, -63, 77, -89, 81, -10, + -50, -53, 58, -80, -6, -36, 8, 16, -3, -69, 92, 9, 57, -65, 57, -32, + -74, 59, 14, -28, 16, -55, 92, -102, 5, 38, -20, 13, 40, -39, -53, 93, + -67, 65, -80, -3, -34, 0, 80, 0, -12, 75, -25, -24, -20, -31, 9, -10, + -21, -9, -3, -23, 8, -2, 6, -50, -22, 8, 24, -67, 30, 31, -72, 76, + 30, -51, -31, 32, 1, -10, -38, 82, -67, 43, -42, 49, -51, 39, 67, -19, + -32, -24, 30, -1, 37, -95, 52, -87, 52, 13, -26, -14, -57, -42, -41, 83, + -30, 1, 14, 63, -71, -48, 52, -51, 100, -84, 69, -96, 54, -1, -2, -7, + -50, 53, -6, 14, 67, -5, 67, -19, 68, -69, -27, -18, -22, -5, -61, 42, + -33, -35, 60, -23, -11, 10, -5, -46, 27, -44, -38, 27, -68, -16, 37, -56, + 2, -17, -40, -10, 26, 83, -70, 72, -67, -29, -44, 29, 23, -30, -23, 48, + -78, 38, 22, -21, 24, -36, 52, -61, 17, 11, 22, 10, -29, -20, 45, 15, + -21, 63, -70, -8, 47, -49, -37, 89, -11, 28, -13, 40, 6, 13, -8, 33, + 3, -1, -58, 70, -23, 18, -68, -35, 8, 17, 70, -47, -37, 62, 26, 10, + -3, 17, -38, 22, 38, 15, 20, -82, 64, 8, 59, -21, 19, -12, 7, -62, + 46, -34, 66, -43, -32, -73, -3, 38, 40, -31, 51, 62, -62, 23, -5, 40, + -24, 57, -38, -14, 6, 47, -3, -29, 32, -45, 69, -57, 47, -27, -19, -13, + 49, -22, 19, 69, -18, -28, 49, -49, 5, 41, -87, 35, -39, 40, -63, 42, + 30, -38, 75, -63, 10, 10, -29, 66, 30, -23, -51, 10, 9, 23, -30, -34, + 20, 56, -63, 103, -41, -32, -55, 24, 27, -39, -30, 63, 27, 4, 12, 21, + -64, 55, -13, 15, -65, 79, -64, 70, -41, -8, -19, 66, 1, 22, -4, -28, + -1, 36, -21, 31, -11, 25, 2, -37, 37, 25, -36, 45, -42, 69, -77, 5, + 18, -12, -13, 35, -25, 59, 0, 27, -55, -41, 26, 54, 39, 66, -8, -11, + -12, 34, -21, -42, -7, 70, -17, -33, 5, 31, 6, 61, -22, 30, -46, 13, + -12, 4, 37, -17, -37, 7, -61, 5, -39, 37, 0, 13, 40, 14, 53, -65, + 46, -2, -27, -27, -20, 48, -60, 55, -47, 82, -19, 33, 1, 46, -64, 95, + -57, 88, -38, 16, -46, 15, -47, 67, -15, 24, 0, -43, -2, -5, 15, -43, + 28, 14, -75, 40, -35, -1, -16, 18, -69, 72, -65, 43, 8, -13, 20, 19, + 6, -24, 2, 23, 14, 22, 34, -37, -29, -37, -13, 7, -43, 0, -23, 50, + -48, 44, -14, -14, -62, 55, 56, -24, 53, -30, -27, 36, -38, -31, -15, -4, + -28, 60, -6, -15, 17, -43, 14, 63, -77, 27, -74, 15, -41, 47, -34, 15, + -5, 27, 17, -7, 24, 51, 17, -23, -5, 1, -52, -13, -3, -26, 35, -6, + -33, -25, 42, 15, -6, -2, 2, 49, -69, 37, -36, 28, -16, 38, -54, 73, + -5, -37, 44, -88, 72, -6, 29, -32, 33, -6, 51, -57, -21, 29, 28, -26, + -62, 53, -80, 70, -48, 21, -13, -17, -43, 22, 38, 9, -7, -44, 56, 51, + -53, -32, 91, -112, 58, 25, -3, -3, -3, -19, 32, -42, 43, -81, 69, -86, + 119, -90, 62, -74, 72, -42, 23, 17, 36, -4, 40, -44, 10, -7, -43, 45, + 34, -84, 59, -45, 43, -97, 60, -31, -3, -9, 35, -68, 14, 2, -9, 3, + -36, 44, 2, -45, -37, -3, -51, 62, 15, 52, -43, -8, -62, 6, -66, 41, + -49, 28, -27, -26, 68, -76, 16, -9, 24, -60, 31, -63, 18, 5, 46, -41, + 19, -13, -46, 17, 16, -38, 64, -31, 75, 3, 17, -53, -42, 11, 13, 10, + 26, -74, 89, 27, -14, -35, 47, -4, 0, -50, 3, 11, 18, -10, -15, -16, + 31, -70, 60, 46, -16, 31, -31, -12, -32, 52, -4, 31, 17, -18, -16, 0, + 1, -26, 62, -18, -8, 23, -40, 56, 71, -93, 78, 0, -57, 90, -81, 48, + -56, -40, 58, -16, 18, -103, 68, -84, 101, -2, 16, -23, 15, 26, 49, -39, + -35, 11, 25, 27, 8, -80, 43, -22, -51, 70, -48, -11, 51, 4, -20, 61, + -22, -62, 18, -40, -24, 25, -29, -67, 56, 17, 22, 9, 17, -1, 21, 36, + -50, -13, 3, 13, 0, -46, 52, 8, -39, -18, -30, 48, -4, 10, 16, 41, + 38, -47, 33, -4, 6, -16, -48, 0, 48, 25, -55, 39, -47, 26, -28, 1, + -16, -13, -52, 53, 1, -58, -1, 54, -55, 35, 3, 43, -31, 4, -15, 38, + 12, -9, 44, -51, 30, 20, 8, -1, 14, -15, 16, -5, -13, 6, -78, -1, + 17, -21, -46, 91, -58, 17, 9, -15, 18, -1, -42, 20, 0, 41, 2, 4, + -30, 6, -9, 91, -64, -36, -17, -27, 10, -27, -20, -34, 52, -39, 30, -58, + -38, 79, -56, 31, 13, 57, 42, -42, 4, -73, 14, 51, 33, -15, -36, 65, + -7, -20, 29, 13, 43, -19, -38, -11, 17, -46, 30, 14, 28, -38, 56, 15, + 39, 28, -14, 7, 23, -15, 40, -53, 20, 17, -45, -14, 24, -33, -7, -24, + 89, -80, 52, -6, -38, 62, -81, -14, -70, 11, 2, 21, 39, -2, 1, 6, + -52, 70, -87, -20, -9, 59, -45, 50, -14, 13, 25, 1, 7, -41, -49, 32, + -69, 69, -73, -11, 3, -46, 46, 8, 28, -20, -33, -15, 32, -16, 68, -50, + 44, -52, -4, 32, 36, 12, 10, -42, -47, 43, -103, 57, 20, -76, 19, -5, + 47, 17, -49, -32, 29, 25, 40, 21, -23, -63, 50, 39, -9, 13, -70, -31, + 59, 24, -66, 37, -34, 84, -93, 59, -13, -68, 39, 46, -58, -26, 36, -74, + 61, 45, -11, 29, 35, -4, -1, 80, -6, -58, 50, -91, 61, -80, -16, 21, + 8, 11, 4, -46, -8, 42, -80, 49, 21, 32, -11, 65, -54, 2, -38, -24, + -15, 0, 1, 20, 34, -80, 67, -38, -32, 21, 4, -30, 13, 17, 59, -40, + -1, 33, 3, 15, -49, 46, 4, -53, 45, -32, -54, 17, 29, -65, 26, 5, + -32, -6, 33, -27, 7, -19, -13, 41, -62, 32, 8, 17, -18, 39, 66, 17, + -26, 16, -4, 16, -71, 66, -15, 40, -65, 57, -27, 21, 14, -78, 9, -52, + 56, -26, -9, -75, 27, 40, 45, 22, -14, 45, 16, -38, 32, -19, 35, 30, + 63, -64, 49, -46, -25, -77, 33, -37, 28, 61, 21, -25, -38, -1, -6, 4, + -13, 13, 39, -74, 5, 42, 57, -56, 50, -1, -29, -40, 45, -32, -27, 4, + -67, 7, 0, -34, 48, -34, 31, 31, -24, -21, 73, -38, 52, 12, -19, -8, + -75, 78, -41, 26, 44, -51, 100, 17, 58, -68, 49, -48, -40, -14, -51, 0, + 64, -16, 60, 53, -51, 26, -16, -14, -55, -33, 7, 25, -16, 15, 49, 2, + 36, -24, 33, 16, 21, 20, -29, -39, 50, -44, 64, -42, 18, 26, -19, 13, + -19, 43, -26, -6, -55, 19, 40, -45, 62, -47, 76, -25, -61, 98, -66, 50, + -72, 37, -12, 62, -45, 28, -49, -8, -50, 79, -72, -8, -24, 18, 40, 54, + -43, -20, 21, -2, 58, -70, 39, 13, 12, 63, -39, 21, 18, -5, 38, -38, + -11, 0, -49, 44, -44, 9, -46, -29, -15, -3, 39, 24, 39, 0, 34, -40, + 74, -85, 60, 35, -22, -5, 22, -69, -11, 35, 44, -84, 1, 46, -32, -33, + 1, -19, 43, -48, -13, 70, -2, 30, -28, 3, 30, -62, 95, -80, -31, 71, + -30, -14, 20, -29, 50, -56, 22, -22, -39, 39, -12, 27, -35, 21, 18, -6, + 30, 3, -46, 14, 4, 47, -52, 47, -20, 7, 5, -45, 59, -54, -65, 54, + -43, 18, -4, -47, 97, -83, 29, -46, 67, -96, 83, -73, 37, 39, 53, -6, + 18, -63, 77, 50, 42, -86, 35, -50, 32, -29, 6, -11, -23, 7, -44, 30, + -77, 51, -47, -4, 38, 43, -11, -2, 16, -70, 22, -13, -7, 8, 36, 7, + 18, 5, -2, 17, 34, -85, 37, -10, -2, -57, 61, 28, 20, -51, 10, 34, + 42, -5, 55, 2, -27, 6, -25, -44, 43, 33, -35, 53, -60, -29, -10, 44, + 46, 8, -38, -20, 20, -32, -47, -19, -58, 36, 22, 27, 61, 2, 24, 22, + -79, 23, -51, 22, -33, 5, 2, 12, 61, 35, 6, -61, 40, -12, 10, -9, + 4, -22, -21, -7, -24, -4, 23, 18, -26, 10, -27, -16, -18, -68, 80, -74, + 58, -68, 17, 10, 5, -45, 0, -6, 19, 21, -37, 32, 13, -10, -9, 52, + -10, 45, -57, 62, -72, 46, -28, 8, -13, 16, 27, 6, 51, -33, -11, -31, + 41, -19, -9, -50, -4, 16, 12, -3, 4, -54, -46, 53, -10, 6, 37, -41, + 54, -31, -49, 79, -58, 34, 18, 39, 17, -21, -34, -30, 13, 14, 0, -7, + -58, 60, -73, 2, -22, 42, 16, 51, -34, -46, 8, 17, 65, -22, 76, 9, + 39, -70, 4, 37, 25, -77, -34, 69, -42, 3, -59, 72, -72, 50, 57, -78, + 45, -37, -4, 11, 32, -14, 13, 47, 28, -16, 5, -6, 53, -21, -23, 31, + -34, 33, -1, 8, -74, 66, -29, -40, -7, -12, 54, -18, -61, 52, -31, -12, + 38, 27, -27, 43, -27, -18, 72, -67, 30, 7, 27, 16, -39, -32, -22, 28, + -63, 84, -70, -74, 56, 1, -13, -40, 49, -61, 7, 47, 24, 4, -32, 14, + 1, 27, 25, -55, 68, -47, -16, 6, -5, 75, -68, 58, -71, 16, -14, -67, + -18, 23, -43, -39, 53, 0, -4, 5, -28, 54, -39, -43, 5, 18, 56, -66, + -14, -24, -22, 1, 4, 12, -14, 9, -26, -30, -28, -16, 52, 27, 8, -5, + -55, 35, 25, 32, 59, -49, 21, -8, 73, -4, -17, -30, -43, -28, 5, 18, + -12, 47, -6, -34, -6, 0, -8, 7, -34, -10, -31, -2, 43, -33, -11, 51, + -56, -19, 60, -33, 31, -30, 5, 4, -54, 52, 35, 11, 4, 54, -72, 72, + -25, 17, 39, -2, 50, 0, -8, -19, 32, -29, 22, 37, -54, -26, 32, -55, + 7, -5, 11, -47, 64, 21, 8, 41, 3, -13, -22, -26, -55, 8, 56, 15, + -79, 92, -58, 68, -35, 25, -50, -33, -57, 67, 64, -46, -23, 46, -48, 41, + -59, 21, 74, -44, 4, 21, -48, -19, -60, 31, -3, -19, -49, -13, 51, -35, + -10, 21, 56, -14, 24, -52, 6, 16, -51, 14, 27, -55, -43, -13, -72, -8, + 8, 35, 8, -49, -34, 65, 2, -18, -33, 62, 9, -22, -11, -35, -5, 37, + -28, -14, 46, 15, -29, 18, -26, 7, -25, -18, 47, -37, -33, 76, -67, -16, + 50, 4, 29, -42, 33, -53, 19, 62, -21, 7, -26, 28, 9, 5, 53, 37, + -103, 47, -20, -8, 41, -32, -33, 73, -20, -14, -56, 68, -37, 16, -49, 92, + -95, 60, -31, 47, -38, -30, 38, 2, -25, 79, -31, -45, -21, 54, 13, -28, + 31, -27, -34, 11, -27, 27, -40, 39, 6, -35, 11, 7, 28, 7, 20, 50, + 28, -61, 19, 81, -60, -41, 20, 0, 34, -22, 24, -4, 6, -3, -56, 20, + 69, 2, -25, -24, 45, -7, -43, -1, 57, 40, -27, 21, -1, -75, 31, -31, + -4, -45, -20, -16, -52, 32, 50, -47, -5, 10, -21, 36, 48, 8, -39, 16, + 28, -9, -38, 56, 38, -21, 0, 6, 38, 1, -5, -19, -8, 63, -13, -15, + 44, -10, 27, -72, 5, 59, -48, 63, -31, 18, 30, -54, -5, -54, 98, -70, + 53, -89, 58, -54, -27, -52, 91, -68, 29, -21, -19, -20, -8, 45, 25, -32, + 30, 18, -43, -30, -24, -34, -64, -18, 43, 0, 36, -48, 57, -17, -55, -7, + 45, -55, 43, 36, -40, 8, 39, 39, 46, -48, -39, 2, -20, -51, 5, 39, + 33, 18, -45, -51, 84, -81, 41, 35, 57, -41, 52, 0, 54, -38, -52, 32, + -34, 53, -57, 16, -4, -14, 1, -11, 33, 18, 18, 19, 71, -41, 70, 5, + 13, 8, 19, 36, 59, -49, 7, 9, 10, -3, -10, 6, 18, 30, -18, -48, + 19, 9, 17, -85, 72, -49, 31, 9, -57, 17, -30, 65, 0, -59, 37, 15, + -51, 0, -53, 68, 3, 23, 16, -10, -14, 6, 3, -63, 55, -32, -64, -14, + 49, 2, -27, 56, -81, -1, 41, -88, 48, -63, 84, -52, 7, 20, 22, -51, + 41, 4, -13, 27, 19, -13, -43, 59, -21, -15, -55, 17, 60, -99, 41, 11, + 37, -23, 16, 32, 9, -46, 91, -41, -39, 83, -29, 31, -31, 65, -55, -7, + 31, 29, -40, -46, 39, 13, 2, -39, 67, -33, 7, 18, 0, 17, 6, -8, + -49, -11, 3, 26, 4, -27, 42, 20, -55, -42, 11, 62, -39, 75, -49, 83, + -38, 49, 12, -8, -5, 30, -32, -6, -23, -58, 79, -44, -10, -12, 52, -31, + 14, -39, 6, -47, 21, -13, -56, 38, -36, 2, 30, 20, -2, -77, 3, -10, + -2, 53, 1, 56, 18, -65, -49, 52, -30, -23, -45, 50, 35, -18, -3, -24, + -35, 61, -27, 22, 44, -32, 5, -59, 67, -66, 77, -38, -2, -23, 52, -43, + 6, -15, 50, 52, -12, 70, 11, 54, -87, 55, -28, 0, 26, 33, 55, -32, + 31, -22, -38, -20, 14, 15, -5, -25, 62, -35, 48, -49, 75, 27, -24, -26, + -25, 0, -32, 83, -65, 62, 0, -42, 32, -56, 43, -19, 48, -17, 65, -31, + 38, -86, 94, -56, 43, 9, 22, 29, -55, 41, -79, 77, -75, 29, -46, -30, + 11, -46, -5, -52, -45, 61, -47, 45, 36, -71, 12, 10, 0, -3, 1, 9, + 49, -45, 17, -13, 31, -30, -40, 38, 62, -61, 60, -96, 32, 47, -37, -14, + -28, 27, -7, -9, -11, 5, -27, -35, 54, -52, -6, 30, 26, -17, 73, -33, + 41, -19, 23, -31, 93, -54, 21, 57, -6, 10, 57, -49, 36, -38, 0, 40, + 20, 25, -37, -17, 2, -10, 42, -23, 11, 29, 66, -36, -48, 63, -2, -81, + 0, -19, 24, -17, 35, -26, -18, -53, 87, -69, -34, -4, -5, -16, -28, 6, + -19, -35, 59, 19, 17, 0, -42, -7, -26, -39, 22, 15, -61, -8, 20, 34, + -44, 62, -58, 46, -64, 28, -14, 31, 27, 52, -37, -43, -37, -44, 34, -19, + 15, 0, -42, 4, -26, -11, 32, -16, 37, 31, -61, 9, 51, -61, -17, 58, + -11, 23, 5, 21, -46, 11, 11, 52, -51, 49, -73, 25, -52, 75, 30, 31, + -26, -66, -27, -19, -17, 71, 59, -76, 40, -38, 66, -11, -45, -29, 0, 34, + 65, -58, -35, 41, -23, 46, 27, 34, -3, 54, -81, 33, 26, -77, 36, -32, + -40, 34, -55, -12, 16, -58, 10, -40, 6, -15, 27, -13, 26, -49, -41, 15, + -35, 22, -24, 63, -30, -27, 37, -57, -69, 42, 0, 51, -87, -22, 81, -33, + 5, -34, 53, -86, 48, -26, 25, -47, 67, -67, 8, 18, -37, -14, 39, -26, + 49, -20, -6, -20, 16, -41, -13, 37, -48, -36, 25, -72, 38, -13, -40, 67, + -11, 73, -76, 45, -10, -7, 16, -40, -37, 51, 6, 18, -17, 60, -46, 0, + -62, 18, 13, -6, -2, 73, -39, 49, -63, 61, -6, 47, -89, 48, 8, 41, + 19, 26, 2, 0, -49, 57, 6, 13, 49, 16, -8, -4, -31, -19, 26, 5, + -60, -14, 55, -2, -42, -5, 4, -12, -52, -21, -29, -3, -42, 73, -40, -73, + -6, -3, -24, 54, -39, 74, -39, -19, -12, -16, 2, -9, 68, -51, 62, 30, + -1, 47, -7, -35, -51, 60, 18, 3, -50, 81, -4, -24, 27, 29, -8, -3, + -55, 31, -50, 15, -22, -10, 55, 23, 38, 2, -13, 2, 48, -14, 7, 1, + 0, -35, 32, 14, 2, -17, 42, -31, -34, -22, 3, 66, 37, 63, -28, -31, + 18, -5, 14, 93, -59, 17, 9, 36, -55, -19, 10, 16, 19, -20, 7, -43, + 42, -56, 43, 36, -14, 54, -61, 25, -34, 52, 24, -55, 70, -81, -28, -31, + 8, 81, -33, 14, -7, -49, -10, 33, 35, -38, -7, -11, 20, 61, 12, -41, + -57, 23, 56, -9, -17, -21, -54, 10, -74, 35, 17, 38, -13, 78, -18, 0, + 59, -2, 88, -39, 58, -35, 65, -15, 36, -50, 39, -57, -8, 20, 15, -13, + 75, -68, 77, -47, 53, -76, 36, -6, 67, -9, 2, -11, 3, 75, -81, 5, + 0, 59, -9, 33, -4, 7, -52, -38, 21, 41, -19, -48, 9, 16, 6, -46, + 53, -28, 13, -5, 9, 6, -23, -34, 59, 1, 50, -2, 16, 23, 28, -53, + 30, -53, 81, -78, 89, -66, -4, 14, 42, -37, 24, -43, -18, -36, -1, 71, + -6, 41, -71, 67, -53, 0, -3, -12, -31, -45, 7, 3, 77, -19, -68, 6, + 12, -45, -56, 40, -27, 1, -5, -47, -67, -12, 3, -13, 21, 33, -47, -40, + 40, 13, -73, 21, 33, 0, -59, 78, 8, 21, 9, 36, -44, 51, -23, 51, + 58, -6, 27, -70, 76, -67, -16, 79, -20, 28, -64, 72, -57, -15, -70, 19, + 14, -38, 23, -7, 44, -9, -11, -15, 14, -59, 53, -42, 56, -71, -27, 61, + -14, 66, -41, -21, 50, -38, -3, -22, 36, -12, -6, 51, -42, -25, 25, -52, + 70, -25, 0, 11, -22, -35, 42, 11, -10, -6, 70, -100, 21, -93, 81, -26, + -39, 57, -35, -48, -4, 35, -46, 78, -47, 45, 26, 13, -32, 26, 46, -26, + -20, -21, 5, -58, 11, -7, 20, 23, -49, -5, -23, 3, 13, 5, 11, 24, + 3, -80, 68, -5, 48, -39, 49, -71, -54, 48, 42, -2, -15, -22, -5, -8, + 75, -67, 37, -47, 60, -44, 39, 7, 53, -40, -22, -33, 49, -75, 2, -11, + -17, -24, -71, -36, -4, 42, -74, 4, -32, 32, -3, 54, -11, -8, 2, -34, + -7, 67, -48, -3, -66, 79, 1, 48, -66, -9, -17, 61, -67, 25, -13, -8, + 53, -78, 11, -8, -63, 45, 65, 3, 10, 33, -53, 99, -80, 22, -72, 17, + -37, -22, 37, -8, -40, 40, -22, 0, 18, -10, -9, -28, -10, 1, 28, -16, + 57, -49, 5, 46, -73, 49, -28, 38, -22, 0, 26, 14, -49, 98, -75, 13, + -29, 40, 30, 0, 17, -11, -36, -19, 67, -15, 20, -2, -45, -11, 40, 39, + -4, -6, 48, 47, -25, -28, 21, 19, 61, 25, -5, -53, 15, -12, -7, 85, + -42, -4, 23, 49, -32, 21, -13, 13, -74, 41, 31, -39, -16, 22, -51, 43, + -62, -53, 35, 14, -21, 29, -6, -18, -17, 30, -63, 42, -47, 44, 27, 13, + -65, 0, -23, 35, -85, 77, -6, -13, 55, -31, -33, 42, -15, 26, 34, 19, + 7, -22, -34, 36, 29, 2, -47, -9, -33, -5, -34, -19, 67, 24, 51, -62, + -1, -2, 39, -30, 24, -46, 13, -24, -54, 71, -101, 60, -32, 70, 7, -30, + -17, 9, 66, -9, -56, 43, -36, -25, -21, -2, 7, -44, -9, -3, -55, 49, + -62, 82, 54, 28, -51, 3, 17, -43, 21, 30, 44, 10, -7, -6, 38, 34, + -28, 83, -79, 11, 33, -12, 15, 45, 45, -45, -32, -56, 46, -12, 30, 9, + -38, 57, -65, 8, -37, 59, -11, 14, -24, 9, -2, 73, -61, 16, 31, 2, + -45, 24, 39, 59, -55, -4, 33, 20, 3, 0, 21, -37, -21, 31, -54, 44, + -13, -63, 46, -31, 68, -97, 44, -89, 51, 10, -45, 11, 8, 31, -64, 69, + -58, 49, 18, 19, 6, -13, -39, -25, -3, -37, 35, -28, 50, 15, 47, 31, + 18, 28, -48, 9, 67, -66, 52, -18, 5, 41, -37, -10, 27, -31, -16, -22, + -50, 64, -14, 27, -14, 63, -72, 60, -62, 46, -44, 60, -16, -26, 62, -24, + -20, -60, 46, -54, -1, 6, 21, 65, -51, 49, -23, -38, -11, 24, -45, 4, + -7, 41, -8, -67, 61, -10, 38, 33, -63, -28, 72, -16, 43, 2, 22, -81, + 81, 2, -34, -57, 40, 12, -17, 13, 36, -1, -51, 58, -42, 50, -14, 29, + -4, 52, 3, -39, -21, 49, -38, 17, -78, 70, 23, 35, 10, -53, 39, -5, + 21, 32, 40, -3, 21, -43, -35, -48, 11, -26, 51, -39, 49, -71, -8, -14, + 24, 56, -30, 26, -17, -38, 90, 5, -28, 50, 6, -40, -32, -40, 2, 43, + -63, 17, -26, 12, 3, 3, 47, -41, 83, -46, 50, 32, 19, -66, -2, -30, + 49, -14, -63, 6, 46, 25, 51, -39, 49, -39, -28, 52, -24, 48, 0, 12, + 25, -54, -47, -63, 15, 52, -36, 42, -28, -61, -27, 59, -59, 34, -70, -32, + -10, -39, 36, -25, -44, -17, -46, 28, -26, 28, -4, 53, -1, -39, -41, 62, + -56, -19, 56, 19, -30, -37, -44, 11, -33, 40, -42, -27, -25, -3, -9, 7, + 26, 36, -40, 16, -53, 62, -53, 35, -24, 56, -56, 81, -85, 36, 27, -48, + -11, 44, 32, -10, 0, 27, 34, 61, -35, 2, -2, 16, -8, 26, -17, -26, + 19, 43, -40, -52, 38, 6, 49, -11, 28, -7, -26, 31, -31, -55, 41, -53, + 17, -24, 36, -10, -30, 38, -50, 74, -90, 23, 6, 44, -53, 66, -18, -18, + 50, -2, -48, 38, -70, 65, -85, 70, -13, -28, -1, -11, 2, -16, 33, -79, + 66, 4, -18, 3, -14, 60, -58, -5, -21, 28, -31, 62, -13, 54, -57, 24, + -21, -8, -50, 22, -15, -21, -14, 13, -38, 56, -106, 64, -60, 29, 14, -57, + 2, -41, -20, 55, 24, -19, -21, -30, -62, -13, 53, -7, -35, -31, -19, 5, + -16, -71, 62, 8, -32, -9, -10, -9, 101, -49, -40, -55, 41, 37, -40, -14, + 29, -18, -51, 24, 24, -38, 69, 30, 11, 29, -67, 34, 31, 19, -6, -53, + -7, -47, 19, 2, -28, 76, -64, -19, 84, -39, -16, 68, -62, 37, -34, 34, + 33, -18, 40, 1, 26, -1, -35, -5, -33, 34, -33, -24, -49, 55, -46, 27, + 2, 38, 3, -49, 16, -38, -47, 6, -15, 36, -10, 16, -35, 17, 8, -53, + -7, -2, 52, 46, 28, -49, 16, -70, 55, 51, 13, -58, 6, 14, 67, -20, + 35, -35, 20, -12, 37, 36, 72, -47, 13, -38, 17, -2, -41, 17, 49, -57, + 33, 34, -34, 4, 49, 15, 40, 36, -3, -52, 79, 29, 24, 50, -20, 26, + -93, 27, 13, 12, 36, -8, 43, -44, -38, -34, 55, -58, 45, 8, 20, 18, + 13, -56, -34, -33, 16, 20, -57, -56, 99, -40, -17, 26, 28, -6, -39, 63, + -7, -52, 39, -34, 71, -56, 17, -45, 53, -32, 0, 29, -41, 16, -33, 26, + -5, -12, 48, -48, -11, 52, -15, -43, 67, -5, -37, 32, 41, -56, 40, -7, + -8, -20, 32, -10, 0, 46, 9, -10, -54, 30, 40, -31, -4, -29, 58, 5, + -8, 2, 57, -63, 42, -68, -1, 16, -6, 10, -4, -31, 52, -103, 63, -34, + -17, 5, 26, 29, -18, -25, -39, -4, 34, 25, 52, -61, -23, 13, 0, 58, + 7, -1, 88, -98, -5, -12, 24, 55, 33, 43, -32, 23, 73, 2, -26, -1, + 29, 56, -99, 37, 46, -45, 0, 51, -81, -39, 95, -41, 34, -14, -6, -32, + 56, -46, 12, -15, -21, 51, -33, -28, 4, -8, 61, 13, -61, -77, 66, 32, + 58, -59, 41, 34, -15, -56, 31, -37, -37, -1, -18, 29, 16, 32, -64, 13, + 38, -27, -70, 26, -36, 4, 38, 73, -63, 28, 23, -40, 55, -6, 48, -38, + -3, 24, -36, 43, 0, 0, 44, 24, 24, -47, 17, 21, -74, 61, -39, 105, + -36, 16, -4, -45, 40, -24, 8, 60, 27, -76, -40, 51, 56, -57, -10, 16, + 24, 13, 10, 21, -54, -28, -17, -53, 28, 35, -4, 19, 65, -80, 19, 56, + 3, -45, -7, -23, -42, 13, -57, -36, 42, -5, -77, 40, -38, -32, 2, -33, + 88, 12, 9, -53, -51, 60, -87, 53, 27, 38, -28, 1, 50, -49, -2, -10, + -25, 49, -1, 30, -31, 47, -37, 34, -62, -19, -27, 1, -25, -21, 23, -3, + -39, 4, 37, -26, -68, 49, -34, -35, -5, 18, 29, -45, 73, -44, 44, -18, + -19, 14, -48, 51, -18, -13, -11, 33, -13, 18, -26, -58, 36, 16, 15, -74, + 95, -58, 12, -47, 28, -49, -42, -33, 83, 18, -19, 56, -55, 28, -15, -43, + 73, -5, -45, -3, 49, -7, 66, -66, 86, -72, -14, 15, -7, 47, 27, 16, + 68, -78, 35, -3, -13, 53, 27, -35, 10, -18, -35, 52, 28, 17, -52, 42, + -66, -10, -47, 86, 51, -12, -38, 26, -58, 2, -3, -70, -12, -23, 39, -53, + 1, -16, 44, 21, -16, 40, -5, -26, 81, 20, -80, 49, -30, 7, 35, -30, + -13, 44, -37, -23, 55, -20, -3, -20, 56, 3, -57, -23, 56, 43, -2, -49, + -3, 8, -15, -45, -42, 55, -28, 78, -25, 0, 28, -36, 27, -54, 61, -6, + -64, 54, 58, -67, 50, -60, -41, -39, 14, -29, 40, 6, -16, -33, 8, 38, + 44, -54, -28, 28, 14, -24, 42, -117, 76, 12, -12, 4, 45, -49, 3, -53, + 6, 5, -52, 52, -23, 3, -15, -66, 35, 54, 15, -48, -39, 15, -23, -29, + 20, -6, -53, -22, 38, 54, -38, 54, -33, 30, -8, -6, -84, 95, -25, -40, + -26, 13, 39, 13, 18, 25, 19, -10, 45, -42, 73, -92, 16, 65, -25, -21, + -46, -53, -24, 71, -63, 37, 19, -29, 31, -68, 52, 8, -54, 2, 72, -61, + 49, 9, 44, 3, 38, 2, -14, 15, 23, 48, 18, -19, 60, 14, 18, -45, + 97, -35, -64, 55, 62, -12, -3, 39, 39, -41, -9, 25, -5, -34, 56, 5, + -52, 79, -64, 53, 10, -10, -6, -35, 12, -46, 77, -40, 40, -42, -16, 31, + -7, -4, 9, -9, 49, 33, 64, 16, -82, -17, -17, 11, 38, -10, -52, 48, + -67, -20, 37, -2, -2, -65, 36, 19, -63, 50, 19, 17, 46, -80, -6, -42, + -42, 53, 27, -32, 25, -18, 21, 6, 65, -61, -6, 10, -15, -6, -26, 21, + 5, 76, -43, -44, -48, -44, 50, -54, 48, -39, 61, 20, 29, -35, 52, 79, + -41, 55, -56, 42, -28, -32, 12, -26, -35, 4, 45, 19, -35, -37, -26, 28, + 67, -40, 20, 44, -15, 10, -41, -44, 32, -84, 86, -7, -25, 35, -25, 27, + 6, 14, -29, 74, -1, 16, -59, 42, -59, 63, -5, -6, 42, 33, -84, 82, + -48, 8, 15, 37, -87, 83, 37, 22, 25, 10, -51, -24, 30, 12, 32, -32, + -66, 90, -73, 39, 0, -57, 16, 86, -66, -15, -24, 37, 43, -41, 57, -23, + -31, 10, 34, -56, 31, 5, -39, 38, -39, -42, 3, 11, 46, -33, 74, -60, + 38, -56, 43, 57, -59, -10, 57, -70, 45, -26, -18, 27, 58, -70, 27, 12, + 44, -40, 50, -54, 29, 0, -29, 47, -57, -10, -1, 79, -21, 18, -78, 80, + 19, 45, 35, 27, -45, 79, -88, 78, -61, -1, -4, 33, -23, -37, -25, 47, + -47, -26, -41, -42, -64, 32, -54, -16, 39, 14, -40, 3, -37, -26, 20, -13, + -53, -10, 69, -24, -67, 59, -29, -21, -55, 73, -51, 2, 23, -17, -4, -40, + 46, -15, -30, 21, -79, -7, 59, 42, -59, -6, -26, 1, -27, 24, -13, 5, + -37, 0, 35, -49, 1, -86, -13, -18, 61, 43, -45, 27, -77, 6, 44, 3, + 59, -36, 1, 39, -17, 7, 25, -25, 35, -108, 82, -104, 28, 11, 21, 42, + 50, -47, -34, 16, -22, -17, 28, -65, -33, 76, 19, -54, 1, 2, 50, -79, + 26, -90, 101, -50, 61, 23, 27, -48, 29, 43, -44, 15, -42, 51, -48, -58, + -24, -14, -13, -46, 57, -31, -14, 91, -89, 78, -75, 16, 7, 44, -9, -24, + -70, 32, -21, 15, -33, -55, 67, 18, 57, -8, 6, -19, -45, 27, -16, -31, + 47, 1, -22, -26, 21, 33, -34, 41, 29, -32, -24, -16, -55, 31, -11, -13, + -33, 70, -65, -1, 105, -68, -51, 48, -40, 30, 66, -25, -7, -44, -6, -63, + 27, 1, 9, 0, 0, 74, -40, -23, 5, 10, -11, 11, -87, 40, 12, -54, + 17, 45, -31, 38, -81, 57, -10, -28, 19, 5, 12, 29, 27, -62, 63, -12, + -44, 6, 38, -17, 35, -49, 17, 21, -19, -17, -22, -19, -41, -21, -4, 39, + -40, -18, 12, -23, -61, 73, -26, 22, 11, -18, 29, -65, 14, 6, 15, 1, + -57, 2, -53, 8, 10, -46, -2, 32, -17, 51, -50, -15, 39, 56, -36, 37, + 13, 43, -47, 93, 14, 26, 38, -8, -52, -22, -3, -16, 76, -43, -9, -45, + 63, 0, 22, -49, 7, 59, -83, 92, 14, -34, -1, -35, 71, 22, -58, 54, + -38, -7, 45, 41, 64, 0, -68, 30, 26, 27, -1, 9, 6, 11, 28, 8, + -14, -3, 10, 52, -35, 65, 19, 64, -85, -16, -35, 52, 37, -29, 46, -64, + 12, 28, -49, -20, 86, -62, -10, 25, 19, 74, -19, 32, 24, -37, -28, -65, + -13, 46, -29, -43, 8, 36, 21, 23, -35, -47, 11, 60, -12, -31, 20, 25, + 36, 67, -91, 88, -69, -9, -12, 52, -40, -69, 21, -39, -6, 33, -33, 97, + -19, -32, 62, 58, -62, 54, -28, -66, 61, 27, -45, 0, -35, 34, 54, -27, + 81, -32, -30, 41, -18, 60, -43, 38, -81, -6, -33, -15, 47, -14, 14, -33, + 6, -50, 55, 37, -46, -37, 89, -72, -36, 78, -40, 22, 60, -55, 51, -5, + 5, -42, 47, -46, -44, -18, 107, -57, 8, -71, -19, 44, -45, 24, 53, 27, + 32, 10, -6, -44, -23, -1, -26, 9, 12, -49, 54, -14, 31, -12, 49, 29, + 35, -36, 47, 17, 4, 16, 20, 5, 45, -31, 25, -32, -61, 82, -73, 68, + -14, 63, -75, 31, -48, -40, 68, 4, -17, 32, 40, 38, -8, 52, -9, -31, + -15, 11, -51, 84, -1, -54, 55, -49, 13, 21, -21, 51, -24, 6, 4, 33, + -38, 44, -6, -13, 11, 2, -51, 59, -45, -56, 51, 46, -72, -13, -25, -11, + 28, -16, 6, -75, 21, -68, 11, -26, 22, 13, 12, 56, -49, 1, 53, 40, + -34, -11, -37, 77, 14, -59, 76, -91, -29, 4, 54, -2, -61, -33, 45, 27, + 20, -45, -36, -20, -51, 5, -6, 44, -41, -28, 26, -24, 33, -10, -13, -61, + 66, 0, -36, 19, 38, -99, 27, -85, 52, 26, -17, 7, 20, -72, 42, -13, + -47, 29, -2, 5, -86, 83, -55, 4, -8, -54, -20, -35, 30, 0, 10, 48, + 39, -12, 5, 38, 27, -60, 22, -37, 68, -22, -18, -10, -41, 52, 18, -30, + -4, -51, 38, 5, -48, 45, 36, -58, 61, 55, 0, 26, 14, -55, -5, -52, + 14, 69, -73, -8, -54, 53, 13, 86, -111, 69, 7, -18, 54, -72, 12, -29, + -21, -48, 55, -48, 58, -43, 22, 22, 20, -6, 19, 54, -7, -37, 17, -44, + 41, -24, 0, -56, 29, 27, -67, 41, 0, -33, 43, -47, 29, -5, -21, 68, + 12, -31, -8, 5, 55, -62, -35, -35, -5, 95, -61, 54, 35, 22, -71, 44, + -76, 11, 46, 26, -69, 87, -74, 31, -12, 44, 10, -39, -62, 80, -112, 24, + -53, 28, -68, 36, -10, -21, 22, 16, -28, -36, 51, -50, 70, -75, -28, 28, + 14, -74, -7, 20, 75, -16, -52, 0, -68, 50, -13, -60, 39, -16, 26, 24, + 30, 28, 26, -31, -34, 29, -41, -7, 17, -62, 33, -38, -51, 34, -69, 45, + 9, -46, 24, 2, -2, 80, -59, 33, 36, 61, -96, 57, -24, 60, 14, -60, + 22, -19, 2, 53, 7, 50, -40, -5, 49, 18, 25, -79, 25, 47, -80, -12, + -29, 52, -42, -59, 37, -47, 40, 14, 51, 28, -20, -50, 97, -32, -14, -16, + -22, 80, -18, -7, 42, -9, 2, -7, -17, 11, 7, 36, -47, 36, -39, 62, + -15, 14, -24, -29, -11, 40, 52, -29, 39, -48, 14, 8, -43, 96, -66, 24, + 51, -26, 46, -40, 60, -44, 78, -27, -33, 68, -26, 22, 2, -10, 12, -82, + 25, -18, -7, -15, 0, -32, 64, -24, -14, 5, -39, 78, 12, -49, 0, -37, + 21, -19, -3, -33, 32, -20, -30, 57, -90, 4, -30, 49, -67, 61, 34, 75, + -23, -26, -2, 40, 20, -32, -19, -49, 65, -29, -37, -13, 15, 23, 31, -23, + 46, 37, -35, 15, -39, 69, -58, 11, -32, 43, -46, 6, 6, -31, 16, 32, + -40, 39, 30, -6, 8, -63, 48, -23, 6, 31, 36, -38, 3, -10, -10, -57, + -28, 20, 18, 4, -10, 59, 48, 65, 8, -76, 42, -49, -12, -33, -28, 86, + -64, 62, -60, 9, 51, -13, 47, -28, -10, -9, -40, 50, 14, -10, 54, 27, + -64, 13, -14, 0, -8, -28, 1, 33, -6, -46, 41, 4, -50, 75, -11, -50, + 36, 31, 16, -8, -53, -1, 70, -4, 57, -37, -7, 4, 36, -50, -33, 36, + -22, -16, -60, 45, -26, 8, 13, 28, 22, 41, -24, 73, 13, 73, -25, 1, + -7, 96, -74, 73, -11, -76, 35, -16, -16, -81, 93, -51, 3, -47, 62, 39, + 16, -33, 67, -91, 78, -53, 40, 30, -43, -41, -5, 63, -78, 77, -9, 26, + 59, -25, 29, 0, 31, -37, 55, -68, -43, 38, -47, 58, -62, -18, 14, 37, + -16, -60, 44, -41, 17, -37, 61, 8, 12, -5, -37, 33, 10, 23, -24, 19, + -12, -10, -50, 82, -22, 69, -117, 72, 21, -27, 4, 55, -25, -48, 31, 17, + -41, -46, 7, 4, -23, 10, -20, 6, -26, 44, -72, 53, -42, 17, -18, 55, + 36, -4, 31, -11, 5, 38, -33, -11, 43, 64, -25, -43, -48, 44, 44, -24, + 71, -53, 55, -26, 63, -69, 56, -56, 74, 22, -35, 6, -1, 33, -53, -35, + -36, 49, -32, 35, -9, 41, -38, 21, 29, -20, 26, 49, -48, 5, -40, -50, + -17, 39, 2, 22, -21, -51, 60, -91, 105, -76, 50, -28, 25, 19, -39, 24, + -22, 0, -12, -56, 10, 44, -15, 7, -10, -15, -34, -2, 18, -8, -19, 110, + -66, 48, -17, -26, -30, -18, -37, -64, -18, 82, -30, -18, 8, 55, -61, -41, + 20, -2, -36, -19, -22, 5, -17, 1, 19, -26, 68, -61, 56, -45, -48, 23, + 52, 51, -76, 95, -32, 39, -70, 47, -18, 0, 23, 59, -72, 30, 42, 19, + 3, -63, 27, 14, 57, -22, -42, 0, 48, -73, 50, 14, -57, 62, -16, -62, + 52, -27, 59, 19, 5, 46, 5, -35, -21, -4, -46, -4, -44, -54, -23, 31, + -27, -81, 41, -64, 3, 61, 15, -54, 62, -12, 39, -45, 40, -21, -41, -54, + 17, -28, -50, 28, -73, 18, -19, 4, -42, 7, 64, -48, 38, -37, -56, 44, + -62, 1, 35, -13, -20, 14, 15, -39, 90, -14, 17, -17, 27, -7, 4, -51, + 32, 22, 1, 30, -61, 83, -76, -39, -16, 63, 8, -25, -48, -13, 70, -43, + -38, 55, 4, -12, -17, -46, 82, -68, 27, -43, 54, -82, 57, -4, 0, -40, + 46, 34, 23, 15, 17, 46, -60, -23, 31, -24, 7, 18, 59, -46, 64, -86, + -50, 0, 5, -42, 23, -50, 27, -17, -20, -52, 3, 77, -30, 31, -62, -26, + -29, 14, 53, -39, 9, 43, -34, -13, -51, 29, -30, 25, -43, -22, 39, -15, + 12, 41, -5, -18, -68, 51, -25, -17, -70, 51, -52, 3, 19, -39, 14, 53, + 39, -29, -57, 13, -13, 11, 26, 41, -50, -2, -31, 4, -29, 45, 5, 21, + -7, 37, 51, -14, 59, -71, 67, -41, -2, -50, 25, 9, -26, -23, 33, -58, + 30, -12, 23, 58, -65, 54, 49, -21, 78, -124, 84, -52, 65, -48, 92, -10, + 0, 38, 58, -6, -16, 66, -13, -27, 47, 74, -80, 28, -44, 22, -5, 24, + -64, -10, 43, -31, -27, -7, 42, -43, 11, 10, -27, -65, 99, -73, -13, -3, + -22, 23, 26, -35, -10, -25, 67, -25, -32, 44, -15, -19, -24, 39, 24, 7, + -24, 7, 1, -61, 36, -55, -3, -52, 32, 21, -16, 22, 34, 45, -47, 78, + -49, 86, -24, 40, -41, -53, 38, -29, 65, -48, 22, -9, -16, 6, 48, -18, + 59, -19, 47, -5, 27, 33, 2, -25, 15, 50, -89, 0, 13, -27, 5, 43, + -61, 51, -16, -32, 59, -75, 4, 48, -60, -47, -35, 23, -4, 33, 27, 0, + -20, 17, -75, 72, -29, 36, -28, 78, 15, -52, -37, -16, 5, 41, -75, 44, + -9, -32, 36, -35, 21, 16, -74, 60, 0, -6, -50, 95, -47, -44, 22, 7, + -12, -20, -62, 43, -56, -10, 42, 42, -6, 80, -45, -22, 21, -58, 19, 47, + 7, 36, -51, 51, 39, -29, 49, -21, -9, 64, -57, -36, 37, -30, 37, -14, + 47, 30, -68, -33, -38, 33, 0, 47, 31, 50, -37, -17, 83, -53, 3, -19, + 2, -26, -23, 18, 3, 31, -7, 60, 24, 42, -41, 20, -32, 55, 16, -47, + -3, 50, -13, 52, 25, -54, 43, -61, 99, -60, 62, 39, -48, -35, -32, 12, + -36, 10, -95, 69, -55, 28, 21, -58, 29, 83, -19, 28, 36, -27, -15, 51, + -42, 29, -38, 6, 29, -16, -52, 31, -22, 86, -55, 22, -93, 51, -60, 6, + -38, -15, -21, 33, -28, -52, -2, 32, -71, -83, 66, -62, -13, 45, 7, -24, + 49, -41, -17, -11, 40, -42, 49, -51, 14, -25, 42, 21, -66, 77, 25, -40, + 6, -67, 21, 13, -9, -3, -14, 11, -61, 47, -13, -11, 67, -90, 55, -14, + -3, -55, 45, 20, -25, 5, 9, 37, 36, -7, -40, 64, -65, 54, -90, 53, + -78, 36, -39, -24, 63, -22, 56, -60, 9, -30, 34, 10, -16, -15, 25, -37, + -10, 19, -75, 94, -87, 37, -4, 62, -79, 34, 54, 3, 11, 42, -60, 43, + 15, 2, -47, -12, 37, 30, 1, -39, 75, 58, 29, -45, -14, -3, -29, 39, + -53, 1, 24, -27, 0, 11, -21, -12, -64, 87, 45, 18, 50, -67, 56, -19, + 25, 3, 5, -3, 8, -66, 52, -18, -41, 18, 21, -15, -51, 102, -54, -29, + 2, 55, -12, 46, -52, 48, -49, -49, 15, -57, -35, 15, -35, 21, -5, 43, + -46, 1, -16, 0, -6, -23, -43, 16, -9, -20, 59, 15, -5, 34, 38, -77, + 53, -63, 67, 21, 52, -84, 76, -35, -44, -63, 57, -28, -6, 14, -31, 45, + 20, 12, 23, -19, 21, -34, 25, -53, -50, -10, 15, -2, 6, -40, 27, -32, + 25, -17, -39, 4, 0, -52, 43, 18, -79, 32, -72, 10, 48, -10, 3, 20, + 69, -73, 84, -55, -11, 12, 0, 34, -21, -46, -60, 48, -23, 63, -50, 0, + -18, -21, 48, 21, -47, 30, 3, 5, -35, -42, 42, 47, 45, -16, 19, 10, + -5, 37, -38, -37, 26, 53, -10, 6, 71, 35, -8, 55, -11, 44, -73, 80, + -91, 69, -7, 0, -39, 61, 2, 22, -7, 7, -2, -30, -1, -43, 35, -12, + 26, 59, 11, -46, 40, -33, -36, 18, 52, 21, -31, 18, 20, -7, -33, 33, + -48, 89, -72, 19, 20, -15, 66, -49, -26, 4, -14, -28, -9, 21, 49, -42, + 51, -31, 35, 2, -10, 54, -72, 19, 11, 11, -51, -37, 32, -25, 32, 28, + -60, 47, -25, -67, 40, -8, -62, 11, 15, -5, -60, -10, -19, 27, 28, -24, + -42, 10, 35, 53, -62, 61, -66, 38, -64, -56, 22, 12, -18, 33, -19, 13, + 15, 29, 29, -28, -23, -23, -41, 67, -12, -63, -60, 43, -105, 84, -54, -6, + -44, 22, 26, -11, -5, 64, 12, 6, -19, 56, -63, 34, -24, 23, -30, 73, + -28, -21, -30, 22, 5, -22, 20, 47, -30, 42, 21, -1, 24, -2, 8, -72, + 32, 14, -30, 47, -20, -4, 14, -5, 38, -8, -45, -9, -55, 23, -68, 62, + -59, 8, -19, -18, 38, -28, 12, -64, 119, -41, 6, 0, 64, -62, 61, -44, + 20, -45, 17, -36, -13, 28, 27, 1, -3, 76, -10, 10, -4, 55, -68, 37, + -37, 48, -7, -52, 48, 16, -54, 26, 5, 33, 19, -31, 44, -38, 34, -24, + 6, -50, 27, 47, 48, -15, -16, -28, -1, 59, 44, -71, 60, -105, 98, -44, + 86, -45, -42, -10, 4, -6, -2, -16, -22, 73, -21, -51, -17, -15, 37, 11, + -1, 3, 32, 6, -41, -53, 42, 13, -81, -18, 39, -96, 21, 3, -42, -24, + 58, -56, 65, -64, 77, -71, -19, -18, -24, 61, -32, 31, -25, -10, -17, 5, + 37, -49, -44, 72, -68, 67, 16, -18, -18, -33, 13, -13, -55, 39, -16, 69, + -41, 29, 7, -53, 49, 11, -36, -28, 20, 18, -3, -7, 31, 38, -65, 17, + 52, -53, 27, -15, -8, -55, 33, -1, 9, -43, 58, 10, 34, -25, -16, 10, + 30, 26, 56, 28, 9, -46, 64, 25, 27, -32, 23, 31, -60, 17, -8, -39, + 99, -88, 10, -56, -8, -79, 46, 33, -20, 51, -14, 27, 52, -62, 13, 56, + -72, 2, -11, -1, 55, 21, -10, 18, 10, 83, -35, 52, -12, 46, -56, 27, + 48, -49, 44, -50, -4, -39, 12, -4, -50, 4, -1, 63, -1, -42, 59, -47, + 51, 31, -47, 82, -56, 13, -11, 49, -51, 44, 32, -88, 32, 40, 1, 27, + -10, -24, 4, 17, 36, -7, -16, 16, -9, 6, 31, -33, 61, -5, 40, 10, + -46, 61, -3, -37, 6, -8, -45, 71, -49, -43, 17, 42, -62, 24, 5, -17, + 36, -15, -15, 34, 33, -16, -38, 18, -6, -78, 43, -81, 49, -36, 31, 24, + -35, 0, -45, 60, -11, -27, 21, 43, -7, -22, 22, -22, 37, -35, 43, -15, + -16, 65, -58, -53, -14, -3, 7, 15, 23, -46, 38, -31, 26, 39, -25, -22, + -57, -14, 86, 3, 30, 0, 17, -53, 69, -69, 8, 38, 1, -22, -55, 66, + -49, -26, 47, 0, 43, 27, -34, -34, 45, 29, -5, 44, -19, 34, 44, 20, + -46, 73, -54, 76, -56, 58, 61, -5, -6, -34, 45, -15, -4, 53, -47, 18, + -34, 24, -46, 28, 24, -19, -40, 53, -18, 56, -11, -44, 87, -62, 61, -56, + -25, -24, -42, 40, -24, -42, 61, -16, -10, -15, 3, 47, -24, -65, 39, 2, + -59, 51, 5, -27, -22, 67, 14, -16, 63, -61, 25, 7, -28, 0, 65, -20, + 37, -73, -82, 63, -85, 81, -85, 0, -34, 54, -55, 45, 9, 17, -15, -42, + -24, 87, -43, 60, 28, 72, -33, 28, -39, -27, 9, -36, 3, -22, 70, -60, + -20, 54, 45, -64, 43, -80, 79, -86, 54, -121, 57, -42, 42, -55, 46, -5, + -24, 61, -45, -25, 65, -13, 29, 21, 18, -22, -5, -51, 22, -2, -43, 51, + -42, -9, -2, -54, -15, 64, -36, -46, 91, -80, 15, 65, -39, -35, -34, 21, + -30, 16, 54, -59, -38, 58, -66, 40, 35, -47, 56, -46, 15, -19, -46, 74, + 1, -52, 39, 49, -32, -29, 97, -49, -7, 13, 46, 0, -49, -9, 3, -24, + 36, -50, 6, -30, -33, 2, 78, -30, -32, 78, -8, 80, -72, 34, 17, -4, + 40, 4, 26, -62, 69, -7, -20, -55, -21, -33, 50, -48, 38, -60, -3, 4, + -29, 32, 9, 35, 15, -5, 20, 0, -24, -18, -9, -17, 43, -64, -41, 60, + 43, 36, -104, 36, -67, -24, 56, -25, 22, 12, -3, -48, 23, 9, 22, -69, + 61, -36, 32, -71, 20, -52, 0, 53, -38, 46, -15, -55, 35, -35, -56, 56, + -59, -26, 36, -62, 16, -37, -36, -31, -50, 65, -50, 49, -19, 43, 0, 72, + -59, -34, 62, -1, -13, 8, 47, -76, -20, 49, -35, 5, -11, 36, -60, 26, + 48, 36, 25, -5, -19, -41, 36, -45, 25, 6, 29, -91, 60, 35, -79, 28, + 65, -72, 30, 14, 23, -61, -30, 39, -97, 66, -51, 34, 9, -23, -57, -2, + -83, 71, 67, -69, 52, -29, 19, 20, -9, -19, 60, -81, 48, 3, 43, 17, + 25, -34, 10, -23, -42, 5, -71, 9, 12, -20, -36, 65, -25, -23, -25, -14, + 73, -101, 4, 37, 13, -9, -36, 44, -26, 80, 4, -11, 19, 42, -29, 13, + -59, 12, 20, 7, -39, 42, -79, 49, 40, -55, 64, -19, -5, -41, 64, -35, + 0, 42, -57, 61, 18, -32, 12, -52, -13, -23, 32, -92, 56, 35, -16, 62, + -16, -26, -22, 75, -42, -6, 64, -67, 31, 28, -47, 43, 28, -48, 17, -82, + 51, -11, 55, -64, 53, -40, -9, -27, 9, 40, -50, 11, 43, 19, 2, -65, + 57, 37, 81, -59, 2, 36, -69, 0, 8, -9, -52, -58, 40, -3, -29, -33, + 12, 35, -38, 12, -57, 19, 10, 67, 8, 52, -29, -10, -28, 69, -7, 3, + 57, -28, -9, -20, -45, 13, -17, -35, 44, -14, 10, -11, 23, 29, 27, -35, + 4, -71, 82, 17, 49, -6, 14, -20, -56, 36, -28, 6, -15, 23, 58, 1, + -29, -19, 18, -16, 37, 28, 12, 15, -42, -33, -54, 73, 22, 36, -15, -32, + 49, -2, -11, 4, 10, 38, 25, 47, 41, -42, 19, -38, -48, -18, -8, -47, + 38, 70, -38, -30, 33, -51, -38, 84, -18, -18, 60, -40, -8, -30, 64, -71, + 31, -89, 38, -29, 82, 16, -30, 23, 14, 13, 23, 60, -62, -18, 67, -4, + -40, 2, -25, -38, 22, 5, 47, -7, 36, 43, -49, -11, -53, 81, -8, 24, + 84, -70, -72, 65, 14, -13, -8, -3, -6, -7, -38, -6, 30, -54, -69, 53, + -27, 8, -38, -20, 75, 43, 17, 15, 7, 72, -64, 34, 18, -7, 16, 11, + -22, 47, 29, -47, -38, -43, 59, -16, 22, -89, 48, -50, -1, -55, -14, 34, + 18, -19, 30, -8, -12, 26, 0, -68, 37, -42, 30, -14, 49, 6, -12, 18, + -5, -56, 73, -21, -23, 4, 39, 58, -6, 53, -45, 44, -5, -36, 20, -82, + 37, -13, 3, -41, -19, 29, -54, -5, -26, -57, 14, 10, -56, 65, -35, 82, + -54, -22, -43, -5, 3, 61, -13, 3, 20, 0, -52, 27, -68, 32, 4, 75, + -45, -28, -62, 33, 73, -48, 68, -53, 21, -5, 60, 32, -15, -37, 4, 0, + -29, 3, 13, 41, -32, 62, -60, -50, -13, -56, 13, -10, 82, -89, 8, -14, + -29, -37, 71, -56, 44, 6, -37, 55, 58, -51, 67, -21, 12, -33, 10, 0, + 49, -37, 5, -29, -45, 12, -40, 20, 38, -4, 41, 19, 41, -52, -31, -30, + 12, 68, -23, -9, 14, -9, -44, 14, 0, 43, 59, -58, -42, 2, 11, 54, + 27, -33, -26, 52, 5, -47, -26, 14, -50, 33, -23, 57, 36, -18, 60, -48, + -15, -39, 14, 65, -9, 22, 16, -43, -5, -31, -30, 11, 40, -49, 15, 39, + -16, 41, 11, -14, -27, -50, 71, -57, 10, -50, -23, -55, 59, -26, -32, 75, + -27, 34, 80, -44, -4, -14, -18, 18, 27, -73, 46, 48, -1, -25, -23, 31, + -89, 68, 47, -13, -73, 62, 19, 35, -51, 63, 2, 47, -66, 75, 15, -32, + 36, 0, 41, -39, -65, -78, 49, 28, -59, 7, 4, -25, -6, 30, -58, 51, + 29, -73, -34, 57, 55, 51, -12, -62, 84, -35, 21, 69, -59, 48, -4, 36, + -54, -50, 67, -55, -37, 61, -53, 43, 5, -11, 38, -28, 0, -29, -4, -6, + -29, 49, -46, -8, 8, 24, -42, -49, 47, -51, 0, 51, -10, 31, -1, 25, + 45, -3, 70, -47, 38, 43, 49, -27, 10, 54, -22, 36, 28, 34, -34, -64, + 16, 31, -14, 56, -49, 11, -21, -50, 13, -31, 68, -32, -21, 35, -74, -48, + 44, -21, 31, -25, -45, -20, 4, 51, -28, -38, -21, 57, -58, 60, 56, -14, + 16, -14, -21, 0, 21, -44, 51, -11, 70, 26, 47, -59, -31, 62, -2, -38, + 58, 47, -48, 87, -72, 62, -2, -34, -42, -3, -38, -17, -10, -27, 33, 4, + -61, 71, -20, -11, 8, 55, 18, -33, 12, -4, 10, -54, -29, 90, -43, -19, + 39, -45, -2, -18, -39, 30, -19, -22, 64, -32, -6, -37, 74, -68, 25, -51, + -50, 58, -50, -17, 21, 36, 15, -22, 2, -42, 4, 29, -42, -17, 8, 27, + 43, -18, -40, -75, 69, -36, -23, 43, 41, 35, 70, -26, 62, -8, 27, -57, + 0, 25, -15, -46, 47, -35, -13, 73, -42, 64, 15, 10, -24, 17, -20, -78, + 28, -38, -80, 40, 24, -1, -6, 2, -39, 28, -59, -11, -53, 36, -8, 30, + 4, -2, 29, -81, 59, -43, -41, -10, -13, 37, -19, 4, -35, 31, -25, 72, + -65, 34, -21, 35, 52, 69, -64, -17, 30, -21, 29, -9, 38, 50, -56, -23, + -11, 74, -14, -14, -67, -31, 10, 16, -38, -43, 46, -58, 58, -38, -17, 24, + 26, 29, -42, 54, 30, 21, -39, 0, -34, 14, 46, -66, 50, -49, 51, -36, + 96, -105, 98, -41, 7, -2, 29, 22, -3, 6, -31, -45, 2, -53, 76, -29, + -53, 36, -77, 69, -49, -42, -25, 13, 63, -77, 47, 11, -56, -32, 37, 75, + -50, 36, -68, 65, -30, 34, -21, 27, 70, -18, 19, 6, 22, 1, 46, 35, + -29, -68, 32, 27, -51, 84, -26, -7, -52, 89, 29, -39, -23, 11, -79, 38, + -16, -3, 1, -9, 14, 47, -47, 43, -52, -59, -33, 39, 38, -58, 49, -39, + -43, 34, -67, -12, 12, -48, 33, 28, -18, 9, 37, 33, -38, 54, -71, -15, + 75, -27, -67, 59, -65, -42, 18, -3, 0, -46, -17, 1, 31, -63, 37, 27, + 0, 42, -2, -19, 50, 24, 37, -37, -18, -23, 52, -3, -58, 36, 42, -37, + -20, 39, 51, -12, -53, 6, 2, -3, -2, 83, -65, 11, -44, 41, 31, 5, + -6, -38, 84, 18, -28, 22, -1, 11, -71, -17, -52, 4, -73, 52, -45, -30, + 38, -51, 16, 37, 15, -15, 16, -14, -29, -24, 12, -11, -1, 22, 65, 12, + 20, 14, 88, -78, 11, -21, 23, -24, 30, 6, 4, 36, 3, 55, -79, -4, + -46, 48, -57, 75, 18, 20, 4, -31, -7, -45, -7, -20, 30, -9, -65, 15, + -30, -44, 33, -37, 2, -37, 77, -22, -50, 44, -61, 15, -32, -69, 74, -7, + 39, -58, 17, 30, 36, 35, 32, -83, 87, -51, 12, 25, -33, 36, -15, 5, + -23, 13, 64, -80, -47, 47, -14, 5, -7, 28, -66, 54, 16, -31, -7, 17, + -56, 63, -43, -24, 72, -45, -49, 27, -39, 28, -5, 32, 53, 4, -67, 1, + 23, -55, 18, -19, 40, 38, -49, -16, -1, 6, -18, -36, 5, 11, 7, -21, + -18, 66, 10, -39, -48, 25, 45, -25, -33, -66, 71, -82, 10, 33, -59, 28, + 32, 68, -14, 20, 30, -4, -25, -23, 52, -56, -5, -28, 56, 27, 18, -66, + 66, -41, -12, 46, 17, -58, -32, 83, -48, 78, 20, -14, 38, -21, -10, 42, + -24, -54, 34, 70, -11, 38, -50, -14, 38, -30, -20, 0, -73, 67, -3, 69, + -114, 49, 15, 19, 49, 20, 26, -75, 58, 18, 37, 28, -41, -3, 15, -11, + 0, -49, 33, -43, 52, -31, -22, 4, -1, 59, -89, 28, 25, 10, -35, 41, + 27, -50, -6, -32, 61, -47, 11, 16, 31, -61, 58, -78, 67, -58, 11, -34, + -35, 61, -47, -47, -25, 31, -17, 2, -2, 36, -38, -1, 14, -11, 39, 33, + 0, 2, -18, -13, 54, -44, -16, 26, -10, 43, 6, -36, -17, -47, -42, -31, + 52, -23, -50, 90, -89, 82, -7, 11, 6, 23, -6, 43, -70, 17, 42, 31, + -17, -28, 11, -52, -18, -7, 21, 29, 15, 4, 30, 14, 35, -75, 88, -12, + 35, -13, 16, 43, -31, -16, -49, 24, 57, -72, 50, 16, 41, 0, 21, -61, + 68, -64, -3, -68, 37, -88, 53, -23, 32, 37, -60, -12, 58, -71, -19, -1, + -23, 31, -54, 44, 38, -34, 3, 27, 16, -46, 25, -21, 51, -25, 32, 23, + -18, 16, 27, -48, -59, 45, -6, 38, -14, -6, -12, -41, -19, 5, 25, 60, + -68, 67, -47, 74, -74, 73, -6, 44, -45, -3, -42, 69, -43, 17, -39, 7, + -3, -72, 18, 4, 66, -49, 7, -37, 11, 66, -74, 85, -65, 12, 46, -21, + 4, -54, -35, 32, -88, 37, -25, -32, 53, 0, -21, -9, -55, 0, 19, 13, + -9, 13, -10, -37, -4, 27, 11, -60, -13, -37, 46, -33, -49, 31, -8, -1, + 51, 55, -46, -62, 31, -9, -26, -2, 53, -56, 24, 66, 39, -47, 8, -62, + 64, 34, -15, -39, -44, 32, -41, 61, -31, -16, -50, 56, -45, 77, -30, -54, + 36, 16, -59, 11, -50, -22, 37, 28, -17, -39, 100, -71, 33, -15, -8, -4, + -5, -54, 68, 13, 50, -18, 16, -47, 24, 39, -59, 83, -21, 9, -29, -2, + 88, -69, 16, 61, -28, -43, 33, 19, 6, 0, 68, -15, -12, -31, 16, -1, + -52, 43, 24, -2, -32, -20, 8, 55, -81, 19, 32, 35, -33, 67, 59, -6, + -59, 44, -3, -24, 87, -70, -43, 34, -59, -61, 49, -34, 7, 50, -74, 51, + -12, 64, -56, 62, -60, 64, 20, -46, 16, -7, 49, -82, 2, 43, -29, 33, + -43, 49, -51, -46, 75, -57, 61, 19, -60, 58, -58, 41, -36, -31, 33, -24, + -25, 37, 60, 6, 15, 11, 13, -10, -56, 1, 6, 50, -51, 79, -18, 49, + -6, 0, -35, -18, -15, 48, -19, -64, 11, 9, 40, -46, -39, 34, -50, -14, + -47, 40, -25, 64, 19, 6, -46, 62, -63, 68, 8, -10, 46, -37, -35, -28, + 55, -42, 61, -16, -16, -61, -17, 16, 22, -34, 40, 0, 9, 25, 19, 22, + 41, 4, 26, -9, -22, -15, 37, -31, 79, -97, 19, 27, -27, 52, -63, -29, + -58, 74, 15, -32, 73, 2, 41, 31, -64, 54, -34, 40, 50, -70, 35, -14, + 19, 3, -42, 58, -19, 18, -30, 49, 18, 33, -57, 52, 8, -16, 49, 0, + -21, -36, 69, -28, -28, 16, 45, -26, -29, 83, -58, -31, -64, 47, 11, 29, + -29, -82, 22, 61, -7, 31, 1, -54, 15, 73, -35, -33, 19, -79, 43, 41, + -7, 17, 66, 21, -1, 66, -78, 40, 9, 5, -68, 58, -58, 52, -11, -12, + 54, -19, -19, -25, -45, -37, 13, 71, -67, 49, -39, -8, 16, 40, -28, -27, + -6, -22, 28, 17, 34, 44, 0, -14, -49, 71, -54, -9, 60, -3, 6, 21, + 50, -45, 2, -31, 10, 42, 23, -19, -8, 60, -62, -14, 61, -41, -4, -6, + 31, -38, -18, 0, -93, 83, 48, -44, 53, 56, -24, 11, -16, -28, 35, -26, + -15, 28, -37, 58, 12, -72, 1, -56, 79, -43, -31, 48, 10, 19, -50, -45, + 73, -30, -22, 90, -88, 92, -103, 38, 7, -31, 19, -51, 38, 50, -31, -42, + 18, -6, -49, -32, 22, 9, -11, 11, 71, 15, -43, 16, 2, -32, 28, -50, + -6, 43, -27, 48, 39, -30, 16, 16, 70, -66, 30, 28, -2, -31, 34, 39, + 0, 12, 51, -53, 3, -37, 55, -24, -17, -52, 58, -29, 16, -7, 59, -19, + 12, -13, -37, -15, 29, 35, 44, -43, 37, -14, 67, -72, 29, -16, 38, -41, + -26, 46, -31, 34, -48, 29, -51, -9, -13, 70, 31, -32, -4, -6, 9, 48, + 39, -3, -45, 7, -67, 19, -10, -54, 15, 30, -71, 76, -86, 107, -69, 33, + 16, 0, -39, 40, 17, -24, -36, 2, -61, 23, -2, 13, -10, -23, 21, -55, + 18, 11, -64, 64, -34, 71, -91, 60, 25, -77, 23, 54, -47, 64, -34, 48, + -5, 39, 12, -15, -60, 14, 15, -9, 9, -9, -34, 67, -11, 17, 28, -46, + -39, -26, -44, 30, -31, -24, -12, 31, -19, -34, 40, 6, -46, 81, -53, 13, + 53, -65, 66, 21, 7, 14, -29, -38, -31, 10, -48, 71, -75, 18, 45, -52, + 99, -92, 44, -68, -3, -68, 30, 31, -42, -23, -27, -23, -35, -24, 55, -81, + -32, 46, -48, -15, 4, -17, -21, -22, 46, -41, -19, -22, -10, -35, -11, -12, + -55, 59, -12, 2, 93, -55, -27, -12, 25, -62, -35, 50, 19, -10, -11, -39, + 73, -40, 12, -50, 6, 17, 30, 29, -78, 70, 0, 7, -58, 27, 51, -49, + 21, -52, 35, -20, -4, 12, 6, 26, 11, 32, 7, 8, -83, 31, -2, 61, + 10, 40, -14, 33, -14, -22, -39, 28, -93, -8, 64, -48, -7, 30, -71, 79, + -1, -2, -3, -70, 10, -64, 86, -43, -54, 29, 2, -55, 44, -76, 63, -81, + 67, -93, 19, -12, -39, 34, 18, -44, 6, 56, -71, 33, -5, -22, 41, -39, + -17, 15, -1, 11, -17, -61, 15, -24, 58, -60, 2, -14, -16, -6, -15, -61, + 46, -65, -2, 17, 78, -86, 79, -53, 38, -77, -37, 0, 12, 37, -50, 20, + -82, 51, -19, 10, 23, 23, 22, 40, -23, -7, 55, -48, 50, -89, 22, -39, + -46, 36, 78, -103, 26, 55, -13, 4, 66, -28, 27, -27, -27, -16, -24, 1, + 61, -18, 37, 19, -31, 24, -15, 19, -95, 87, 12, 27, -43, 20, -51, -19, + -50, 60, -42, -32, 64, -4, -11, 54, -66, 23, -27, -36, 40, -26, 1, 9, + 60, -3, 2, -30, -17, 24, 34, -38, 8, 35, -57, 38, -25, -57, 60, -35, + -56, -5, -43, 38, 18, 50, 3, 62, -37, 84, -20, -46, -8, 39, 19, -9, + -35, 77, -7, 12, 6, -39, 66, -83, 65, 42, 16, 35, 38, 18, -84, 76, + 49, -32, 46, 31, -20, 20, -9, 39, -21, 40, 82, -61, 47, 41, -11, 74, + -13, 35, 14, -35, -38, 31, 8, -36, -29, 46, 64, -57, 34, -33, -11, 4, + -2, -30, -42, 72, -10, -2, 9, -38, 11, 0, -12, -5, -25, 39, -69, 66, + -23, 57, -67, 87, -53, -20, 25, -17, -44, 34, -10, 22, 38, 3, -62, -31, + 31, -42, -18, -54, 88, -65, 46, -22, 44, 32, 21, -49, 13, 11, 47, -72, + 17, 10, 27, 40, -45, 73, -86, 4, 16, -11, 53, -4, -66, 89, 1, 30, + -71, 72, 53, -86, 75, -39, -13, 45, 1, -21, 30, 39, -73, 56, -67, 46, + 24, -59, 7, 10, 46, -8, 51, -14, -76, 66, 21, -56, 70, -44, 39, 81, + -64, 84, -28, -20, -50, 40, 24, 3, 58, 33, 49, -45, -18, 7, 28, 13, + 43, -27, -2, -23, 53, -58, 38, -61, -7, -11, -55, 56, -31, 47, 10, 29, + 27, -40, -51, 68, 27, -93, 12, 3, -6, -69, 36, 39, 45, 30, 24, -13, + -51, -59, 57, -64, -4, 41, -27, -17, 91, -47, -26, 1, -31, -1, -1, 63, + -18, -18, 71, -60, 12, -11, 55, -54, 57, -13, 78, 2, -40, 0, 41, -47, + -24, 40, -48, 67, -7, -8, -18, -3, -2, 19, -73, 76, -53, 1, 35, -10, + 69, 13, -7, -23, -57, -53, -23, -6, 22, -31, -34, 53, 50, -45, -57, 38, + -27, -7, -29, -4, 46, 52, -71, 27, -28, -56, 6, -18, 8, -19, 71, -33, + -63, -13, 46, -60, 44, -36, 71, -68, 31, -64, -44, 51, -18, -35, -31, -8, + 16, 16, -48, 46, 5, -34, -31, 82, -18, 39, -36, -35, 3, 9, 38, -3, + 45, -18, 42, -61, 21, 9, 21, -15, 18, 32, -39, -20, 92, -46, 36, -18, + 24, 4, -27, -72, 68, -65, 79, -43, -5, 11, -56, -14, 17, 4, 49, 33, + -65, -5, 59, 53, -57, 56, -40, 54, -59, -17, -19, 17, 23, 3, 28, -1, + -55, 63, -48, 38, -31, -32, 95, -46, 78, -55, 12, -5, 46, -42, -67, 27, + 46, -66, -14, 48, -16, 10, 49, -68, -4, -37, -27, 21, 50, -39, -19, 60, + -56, 38, 35, -20, -63, 26, 0, -51, 115, -89, 9, 19, -31, 21, -31, -58, + 63, -81, -23, 8, 69, -80, 46, -38, -46, -49, -43, 68, -28, -21, 29, -21, + -52, 40, 19, -22, 24, -8, -10, 39, -39, 94, -33, 31, -3, -7, 44, -36, + 43, -40, -22, 14, -53, 51, 51, -34, 39, 71, -35, -62, -14, -71, 12, 10, + 92, -26, 47, -10, 25, -38, -38, 87, -81, -2, 21, 12, 40, 0, -27, 0, + 1, -12, -50, 53, -32, -25, -21, -26, -17, 3, -58, 0, 5, -12, 64, -46, + 64, 3, 36, -39, 15, 30, -42, 39, 17, 43, 12, 15, -35, 54, -23, -43, + -26, -6, 34, 16, 32, 54, -17, 53, -73, 61, -21, -11, -19, -13, 64, -18, + -49, 13, 30, 34, -62, -44, 44, 12, 62, -25, 33, -11, 1, -28, -18, 33, + 68, -4, -9, 22, -21, -37, 12, 4, 16, 63, -33, 5, -24, 54, 1, -37, + -42, 5, -34, -5, -20, 83, -17, -21, -22, -45, 73, 0, -12, -19, -28, -57, + 7, 11, -20, 47, 16, -46, -7, -10, 43, -64, 57, -57, -33, -7, -27, -10, + 6, -31, 7, 96, -76, 91, -59, 23, -21, -17, 96, -45, 10, -28, -2, -55, + 51, 67, -73, 9, -51, 17, -62, 70, 15, 39, -58, -14, -30, -17, -26, 0, + 45, -71, -5, 65, -78, 75, -47, -8, -37, -14, -18, 19, -41, 15, 69, -43, + 24, -62, 64, -27, -16, 32, -25, 4, 36, 20, 13, 43, -108, 84, -68, 51, + -61, 37, 2, -32, 49, 30, -14, -19, -50, 22, 29, 11, -14, 34, 74, -61, + 35, 26, 40, -26, 31, 11, -44, 3, 51, 29, -48, 40, -2, -8, -7, 8, + -1, -29, 59, -50, 4, -22, -3, -19, 63, -69, 1, -51, 57, -52, -60, 61, + -95, 80, -32, 50, -49, 14, -54, -17, -29, -8, -32, 52, 7, 49, 0, -45, + -39, -20, -42, 24, -27, 47, -15, -55, 40, -13, -13, 9, -8, 30, 8, 3, + 2, 62, -30, 32, -3, 61, -61, 85, -53, 9, -3, 60, -87, 89, -104, 10, + -33, -11, -59, 10, 62, -73, 46, -25, -27, -28, -48, 27, 25, 2, -10, 10, + 20, 20, -27, -35, 10, -32, 41, -41, 29, -20, -15, 53, -26, 13, -42, 10, + 60, -31, -44, 29, 23, -10, -23, 50, -58, -10, 19, -20, 9, -29, 56, -49, + -31, -47, -18, 13, 22, 1, -16, -46, 7, -13, -30, -10, -20, 3, 27, 41, + 74, -37, 48, -6, 35, -77, -16, 43, 20, -22, -74, 76, -50, 41, 80, -16, + 71, -72, 64, -57, 30, -56, 46, -56, 11, 47, -33, 84, 7, -7, 69, -37, + 22, 13, 63, -94, 42, -91, 88, -36, 21, -20, -43, 18, 46, -31, -41, 79, + -14, -42, -25, 86, -46, 88, -15, -89, 25, -22, 85, 2, -52, 58, -3, 21, + -17, 23, 64, -72, 33, 4, 2, -44, 63, 7, 18, 17, 40, -10, 2, -38, + 3, 62, -84, 27, 18, -61, 23, 23, -87, 51, -74, -35, 52, -5, 67, -24, + -14, 39, -5, -40, -10, 37, -58, 31, 22, 51, -20, -10, 12, -88, 14, -53, + 53, 15, -80, 81, -39, -55, 54, -31, 34, 4, -11, 30, 13, -28, 49, 34, + -29, 26, -78, 66, -9, 2, -15, 82, -86, 73, -25, 30, -17, 19, 44, 19, + 9, 23, -6, -4, 66, -39, 58, 33, -55, 24, -8, -25, 49, -14, 11, -19, + 83, -9, 66, -68, 48, -24, -37, 60, 37, -33, -7, 23, -55, -22, -38, 58, + -77, 33, -60, 70, -53, -17, 67, -83, 66, -30, 18, -18, 64, -59, 43, 76, + -63, 79, -54, 77, -82, 5, 5, 27, 23, -16, 26, 37, -62, 28, -1, 3, + -11, 51, -32, 39, -30, -16, 11, 33, 16, 8, -7, -20, 29, -26, 29, 62, + -90, 66, 43, -37, -31, 15, -11, -57, 71, 4, 40, -67, 5, -2, 5, -33, + 0, 71, 26, -3, -18, 10, -9, 72, 6, 50, 22, 44, -16, -16, 4, -23, + -48, -12, -6, 15, -83, 90, -13, 8, -3, -10, 86, -91, 89, -21, -72, -19, + -37, 13, 4, 53, -66, 92, -18, 25, 36, -59, 37, -84, 9, -51, 0, 23, + 2, -67, -43, 20, 49, 37, -35, 10, -7, -19, 50, -39, 36, 0, 9, -43, + -6, -44, 60, -27, -20, -7, -29, 90, -5, 46, -58, -21, 87, -36, 41, -42, + 36, -44, -45, 11, 36, -26, 64, -68, 48, -26, -38, 14, -79, 28, 11, -24, + 55, -16, 20, 26, 9, 23, 22, 4, 36, 23, 39, 27, -45, 10, -40, -39, + 68, -69, 9, 9, 3, -17, 38, -14, -45, -30, -23, -20, 38, 46, -2, 50, + -28, -26, 51, -61, -1, 35, 30, -76, 1, 3, 45, -73, -46, 68, -96, 64, + -77, 25, 0, 30, -41, 24, -12, -40, 24, -39, -5, -36, 31, 39, -80, -29, + -53, 40, -32, 9, -19, -30, 0, 38, 35, -45, 62, 47, -70, -59, 92, -71, + 9, -36, 11, 11, 69, -62, 64, -45, -36, 50, 12, -25, 76, 1, 28, -58, + 9, 40, -2, 23, -30, -15, -2, 36, -42, 29, 38, -23, -3, 25, -16, -44, + -1, -41, 59, -59, 36, 28, -10, 18, 26, -27, -42, 4, 41, -15, -1, -50, + 20, -92, 64, -14, -20, 37, -31, -5, -25, -62, 31, 3, 26, -10, -37, -69, + 81, -65, -3, -12, 30, 50, -25, 23, -79, -16, 34, 23, 75, -40, 43, -6, + -10, 9, -88, 41, -43, 16, -32, -41, 10, -57, -37, -24, -3, -7, 13, -5, + -2, 33, 40, -37, 96, -92, 12, 13, -27, 8, -29, 5, -52, -7, 72, -24, + 34, 43, -50, -41, -7, -45, -24, 50, -45, 22, -35, 35, 32, 39, -44, -1, + 11, 59, 20, 10, -68, 4, -11, 43, -51, 96, -64, 0, -51, 34, 19, -28, + 55, 31, -15, 12, -49, 67, -53, -21, -30, -19, -21, -11, -46, -8, -18, 59, + -46, 6, 48, -25, 37, -93, 46, 36, -77, 53, 28, -38, 67, -7, 16, 16, + -35, -69, 59, -55, -8, -5, -11, -60, -44, 28, -48, -21, 47, 29, -17, 4, + -54, 87, -19, 1, 56, -36, -20, 63, -13, 21, 29, -54, 67, -100, 39, -41, + -50, 33, -23, 30, 11, -62, 36, 27, 69, -71, -44, 57, 19, -4, -37, 69, + 12, 10, 20, 22, -30, -16, 9, -23, -10, 34, -8, -3, 47, -66, 38, 48, + 34, -59, 49, -24, 10, 18, -48, -27, 10, -10, -33, -28, 83, -11, -25, 13, + -62, 62, 43, -78, -54, 24, -41, 39, -32, 50, -36, -3, -101, 91, -66, 74, + -80, 55, -62, 46, 6, -44, 42, 12, 13, -23, -42, -9, 38, -42, 25, 27, + -9, 47, 8, -2, -32, -15, -34, 11, -71, -1, 55, -58, -41, 24, 33, -4, + 17, 78, -99, 91, -40, -45, 33, 8, -37, 62, 15, 24, -44, 21, 17, 48, + -9, 1, -23, 32, -4, -30, -18, 28, 77, -47, 26, -70, -51, 35, -16, 23, + 9, 0, 52, 4, -8, 29, -21, 49, -5, -19, 44, 9, 54, -42, 20, -17, + 12, 21, -42, -10, -73, 40, 20, -4, 11, -12, 28, 48, -8, -21, -22, 21, + 24, -29, 39, 1, 57, 47, -24, 4, -56, 84, -71, 64, -68, 54, 10, -29, + 11, -2, -62, 40, 7, -25, 26, -41, -52, 32, -21, -16, 70, 33, -59, 66, + -70, 38, -37, -36, 44, -22, 12, 35, -7, 53, -9, 20, 48, -57, 57, -49, + 45, -43, -2, -39, -3, 63, -55, 14, 0, -48, 51, 8, -18, -38, -8, -19, + 74, 10, -19, -14, 63, 19, 55, -12, 42, -21, -10, 14, 23, -61, 95, -31, + -7, -34, -13, 52, -98, 66, -30, 5, -26, -3, -48, 25, 2, 0, 46, -35, + 78, -52, 15, 31, -29, 37, -10, -22, -52, 34, 18, -9, -8, 61, -38, -35, + -50, 54, -55, -37, 14, -15, 31, 37, 13, 39, -22, 2, -19, -20, 28, -77, + 25, 19, -24, 0, -10, 20, 5, 41, -38, -3, 39, -38, -50, 35, -25, 0, + 5, -41, -25, 81, 39, -24, 56, 12, -18, 2, -48, 26, 76, -62, -41, 40, + 42, 1, -17, -21, -49, 51, 5, -22, -46, 17, 30, 11, -81, 38, 11, 14, + -41, -36, -6, 26, 30, -9, -25, 42, 47, -2, 4, 29, 19, 29, -25, 2, + -46, 15, 4, -28, 15, -17, 40, -4, 16, 12, -53, 45, -56, 68, -60, -19, + -45, 85, -72, 63, -31, 20, 57, -48, -69, 0, 41, 21, -3, -7, -53, 59, + -57, 15, -77, 25, 58, -54, -4, 19, 11, 2, -38, 56, -65, 51, -30, 32, + -2, -24, -8, 33, 78, -73, 17, 7, 3, 25, -8, -25, -6, 41, 55, -28, + 1, -9, -34, -5, -48, 25, -79, 72, -68, -2, 52, -16, 7, -24, 6, -53, + 9, 3, 50, 28, -67, 67, -27, 62, 32, -18, -38, 82, -94, -33, -6, 12, + -20, -2, 35, 40, -72, 56, 0, -37, 16, -27, 30, 19, 17, -57, 39, -40, + 36, 54, -67, 61, -8, -13, 61, -61, 46, 58, -44, -29, -7, 47, 0, -8, + -58, -24, 94, -35, -54, -5, -49, -12, 2, 49, -52, 23, -73, -5, -76, 22, + 78, -50, 34, -27, 64, -38, 25, 17, -8, 50, 6, 4, 0, -56, 63, -3, + -31, 63, 0, 10, -29, 48, -64, -12, 68, -49, 40, 31, 11, -96, 56, 32, + -23, 5, -33, 68, 17, 26, -22, -58, 42, -78, 48, -22, 14, 45, 18, 33, + 22, -23, 2, -6, 3, -1, 33, -62, 72, 14, -61, 53, 13, 34, -53, 47, + -22, 10, 21, -78, 1, -37, 1, -45, 15, -4, 32, 44, -59, 11, 72, -33, + -41, -19, 15, -12, 75, -74, 30, 12, 75, -68, 9, -13, 65, 18, -23, -23, + -32, 92, -47, 10, -78, 60, 17, 10, -51, -6, -11, 23, -60, -25, 50, -76, + 62, -24, 10, 5, -4, 1, -3, 4, 37, -54, -34, 6, 51, -54, 39, 61, + -4, -60, 26, -11, -44, -8, -37, 17, 56, 59, -94, 90, -37, 97, -21, -29, + -5, 61, 64, -69, 6, -15, 29, -50, -3, 17, 51, -69, 88, -10, -7, -11, + 20, 20, 31, 11, -84, 64, 13, -4, 20, -75, 89, -48, -19, -25, -20, 29, + -22, -24, 21, 9, 29, -36, 47, 18, 29, 13, -56, 58, -42, 35, -45, 44, + 37, 5, -47, -78, 42, -70, 44, -42, -48, 34, -13, -33, 87, -11, 57, -80, + 66, -22, 23, -51, 33, 13, -19, 8, -46, 26, -30, -57, 46, -55, 50, 44, + -58, -33, 30, 6, -34, 31, -98, 54, -39, -16, -15, 24, -28, -47, 6, 67, + 31, -26, -36, -39, 52, 12, 13, 28, 28, -32, 65, 12, 48, 57, 1, 71, + -78, 7, 5, 26, -100, 52, -18, 6, -39, -2, 49, -56, 47, 0, -16, -21, + -2, -37, -26, -53, 35, -30, 37, 36, -59, 39, -22, -75, 18, 85, -79, 45, + -56, 37, 0, -40, -23, 23, 25, 18, 4, 14, 44, -19, -46, -40, -11, -28, + -11, 26, 17, -28, -8, -3, -53, 67, -56, -14, 78, -62, -1, 30, 11, 22, + 26, -40, 29, 49, -34, 35, -11, 56, -19, 6, -71, 2, 24, 28, -52, -2, + 18, 36, -9, 74, -67, 37, 8, 5, -50, 34, 3, 16, -40, -6, -28, 57, + 10, -55, 46, 3, 66, -62, 25, -48, 40, -3, 44, -29, -6, 56, -10, 73, + -7, -50, 55, -18, 43, 5, -5, -32, -59, 58, 32, 7, -82, 79, -78, 31, + -85, 114, -73, 90, -52, 96, -24, -51, 9, -82, 44, -52, -57, -34, -41, 38, + 12, -78, -11, 1, 22, 16, -10, 27, 8, -22, -39, 25, -80, -4, -49, -25, + -33, -15, -76, 17, -15, -34, -2, 34, -18, -10, -46, 21, 18, -24, -35, -21, + -12, 21, 0, 39, -27, -23, 0, 17, -30, 32, -53, 33, -38, -37, 22, -41, + -16, -4, 55, 29, 54, 17, 42, -23, 67, 11, 18, -11, -79, 47, -4, 14, + -20, -29, 3, 55, 0, -57, 1, 39, 23, -20, -22, 54, -25, 67, -41, -37, + 35, -28, 59, -44, 49, -6, 57, 13, 13, 61, -38, 35, 2, 53, -54, -36, + -46, 3, 45, -6, 1, -56, -28, -36, -6, 14, -38, -30, -18, -34, -8, -69, + 75, -41, 20, -15, 79, -28, -33, 31, -1, 38, -63, 71, -48, 10, -30, -18, + 46, 15, 39, -5, 24, 38, -11, -43, -9, 44, -45, 91, -53, 16, -60, 68, + 22, 2, -27, 57, -62, 49, -57, -2, -30, 14, -27, -10, 59, -24, 28, 54, + -40, 38, -57, 77, -25, 64, -37, -63, 37, 7, -43, 0, 4, -68, 84, -89, + 25, -27, 14, 47, -90, 64, -20, -15, -20, 25, 68, -12, -40, 29, -43, 16, + -4, -6, -11, -43, -2, 10, -21, -20, 0, -6, -30, -10, 27, -36, 19, -19, + 23, -23, -35, 30, -64, 64, -80, 60, -25, 48, -95, 79, 8, -39, 0, -80, + 18, 53, -67, 82, -62, 13, -38, 35, 40, -6, -32, 7, 19, -25, 60, -48, + 85, -108, 112, -111, 81, -117, 51, 0, 51, 42, -2, 23, 67, 56, 1, -14, + -1, 39, -28, 43, -61, 35, -26, 55, -74, 45, -37, 13, 42, 17, 55, 28, + 41, 36, 24, 24, 18, 3, -38, 32, -58, 74, -12, -19, 25, 49, 62, -24, + 51, 0, -48, 64, -65, 24, 12, -33, -31, 42, 27, -81, 59, 27, 43, 39, + 4, -12, -15, -17, -40, -45, -45, 21, -65, 13, 5, 65, 8, 3, -23, -44, + 64, 14, -47, -68, -20, 72, -45, -12, 13, 55, -11, 15, 11, -37, 25, -54, + 84, -57, -31, 68, -67, 25, -31, 2, -36, -48, 3, 6, 9, 16, 54, 20, + -21, 74, -25, -15, 28, 2, 62, 12, -10, -18, -1, -55, 49, 54, -49, 74, + -78, 12, 6, -2, -65, 84, 22, -27, -35, -66, 29, -25, 8, 34, -40, 77, + -32, -2, -5, -5, -28, -36, 40, -12, 48, -52, 11, -5, -44, 72, -6, -40, + -31, 41, 2, -23, 57, -64, 11, 63, -34, -17, 7, 36, -3, -1, 54, -60, + -36, -9, 4, -69, 53, -55, 50, 43, 24, 0, 17, -54, -2, 37, -73, 36, + -13, 55, -72, 0, 50, -8, -6, -33, 28, 24, -103, 31, -34, 61, 36, -5, + -4, -19, 53, -51, 19, 38, -34, 48, -28, 39, -9, 43, -27, 41, 15, -55, + 6, 31, 28, 8, -37, 33, 19, -72, 35, -12, 26, -70, 16, -31, -12, 64, + -22, -26, -5, -69, 76, -61, 53, -54, 34, -30, -28, -54, 70, 9, -53, 20, + -55, 67, -72, 36, 14, 51, -4, -23, -26, -57, 12, -78, 13, -101, 52, 61, + -47, 40, 8, 55, -53, 44, -62, 16, 32, -60, 54, -9, 8, 29, -47, -38, + 39, -63, 31, -47, 59, -42, 79, -37, 47, -9, 22, -29, 26, -21, -72, 56, + -35, -44, 51, -55, 24, 21, 48, -26, -30, 10, 17, 39, 14, -64, -63, -10, + -57, 36, 53, -24, -23, 61, 35, -40, 62, -51, -16, -54, -8, -25, 46, 19, + -36, 8, 59, 88, -31, 41, -22, 0, 21, -62, 2, -15, -21, -19, 34, 7, + -74, 58, 19, -44, 61, -52, 3, -6, -3, 45, -40, 20, -54, -43, -30, 1, + 13, -58, -6, 45, 1, -7, -14, 4, 33, 28, 42, 68, -98, 22, -20, -37, + 27, 32, -1, -10, -8, -69, 10, -26, 47, 42, 31, -6, 55, -58, -28, 17, + -21, 26, 7, -8, -38, 58, -17, 17, -17, 6, 27, 30, -4, -35, -62, 95, + -73, 51, -18, -45, 11, 59, -20, -41, 35, 16, -42, 8, 13, -42, -69, 55, + 46, 0, 34, 31, -33, 24, 19, -65, -28, -14, 21, 30, 12, 41, 29, 3, + 15, -83, 76, -72, 42, -44, 29, -25, 5, -28, 99, -49, 59, -87, -54, 0, + 10, -50, -16, 58, 9, -36, -19, -63, 83, -95, 34, -2, -41, 32, -29, 32, + 12, -23, -63, -8, 31, 4, 39, 10, -11, 24, 24, -16, 51, -7, 59, -46, + 46, -33, -4, 21, -1, -1, -7, -16, 19, -34, 76, 32, -58, 24, 6, 13, + 31, 6, -19, 33, -20, -89, 74, -12, 49, 7, 60, 24, -20, 85, -50, -43, + -56, 13, 0, 12, -13, -32, 56, 0, -8, 51, -42, 24, -59, 55, -26, -23, + 1, -21, 9, 5, -44, 15, -44, 0, -13, -8, -74, 48, -53, -24, 77, -75, + 46, -23, 2, 23, -27, 0, -44, 59, -55, 54, -41, -15, 11, 36, 29, 44, + 65, -69, 15, -45, 39, -7, -22, -37, -37, 4, 61, -28, 47, -1, -5, -44, + 71, -75, -49, -53, -16, 19, -48, 39, -39, 50, -47, 72, -64, 36, 51, -54, + 98, -33, -44, 45, -64, 41, 32, -29, -23, 38, -2, 67, -21, 90, -6, -39, + 70, -26, 10, -28, 55, 25, -52, -12, -33, -14, -35, -24, 59, 53, -27, 63, + -60, 31, 8, 16, 3, 28, 10, 45, -37, -27, 4, -2, -57, 60, 13, -45, + 1, -45, 15, -38, 45, -17, -18, 50, 4, 11, -48, -2, -21, 33, -7, 30, + 10, -48, -19, 47, -10, -73, 40, 46, -32, -11, -22, 6, -52, 71, 12, 12, + -72, -30, 39, 0, 15, -46, 36, -7, 39, 9, 53, -46, 4, -24, -82, 46, + -3, 0, 20, 65, -35, 0, 20, 22, 21, 60, -70, -28, 39, 40, 32, 24, + 38, 1, 8, -52, 28, -24, 72, 26, -38, 62, 7, 23, -27, -60, 48, 13, + -37, 51, 28, 44, -51, -26, 0, -39, -23, 29, -29, -15, -32, 52, -91, 20, + -6, 14, 62, -36, -39, 38, 53, -21, 2, 63, -71, 38, -38, -35, -6, -20, + 32, -44, 0, -50, -2, 70, -84, 37, -35, 14, -76, 73, -32, -30, -3, 38, + 77, -26, -28, -26, -16, -7, -27, 45, -74, 4, 29, -43, 66, -59, 35, 38, + -38, 38, -17, 18, -13, 29, 35, -42, -13, 20, 61, -14, 60, -11, -39, 36, + 25, -10, 11, 28, 14, -41, 32, -5, 56, -71, 40, -6, -41, -18, -72, 8, + -76, 61, -61, 42, -15, 38, 25, 73, -6, 20, -24, 20, -59, 72, -79, 73, + -38, 72, 14, 44, 41, -58, 25, 5, -8, 13, -30, 16, 62, -29, -41, -32, + -42, -8, 35, 19, -8, 5, 12, 43, -7, -19, -51, -2, -59, -20, -35, 45, + -51, 69, -16, -41, -53, -55, 60, -6, 36, -25, -12, -4, -35, -39, 0, -8, + 56, -58, -7, -66, 80, -104, 85, -66, 20, -23, 45, -8, -13, 2, 34, -10, + 59, -8, 13, 21, -28, 13, -2, -62, 7, -26, 1, 58, 1, 31, -24, 2, + -52, 67, -35, 28, 33, 24, -29, -16, 21, 45, 6, 41, 21, -23, -6, -14, + 95, -56, -12, -1, 23, 3, 0, -70, 2, 23, -76, -14, 30, 11, 43, 8, + -11, -33, 9, -60, 19, 0, -4, -58, 17, -95, 117, -65, 18, -31, -16, 7, + -9, -7, 42, 36, 29, -25, -61, 31, -24, -81, 49, 2, 23, 22, 21, -68, + 91, -82, -28, -18, 28, 31, 10, -16, 68, -23, -13, -13, 54, -32, 93, -18, + -36, 67, -92, 88, -23, -16, -13, -15, -10, 17, -43, 85, -22, 33, 71, -53, + 63, -25, 40, 12, 79, -77, 63, 9, 7, -47, 8, -43, 35, -25, 23, 25, + -92, 28, 21, -49, 76, -61, 38, -27, 58, 16, -10, -30, 12, -16, -17, -33, + -2, 0, 47, -20, 25, 3, -40, 1, 48, -43, 24, -46, -3, -45, 56, -14, + -65, 0, 43, -89, 48, -25, -30, 11, -67, 51, 24, 6, 41, 29, 47, -17, + 35, -17, 39, -2, 3, -26, -35, -51, -12, 27, 13, -39, -9, 2, 43, -20, + -52, -12, -62, 21, 0, 24, -15, 62, -31, -23, 34, -21, -67, 19, 45, 36, + -22, 69, -46, 43, -68, 40, -73, 33, -42, 5, 63, -11, 74, -23, 58, -54, + -19, -64, 42, 30, 64, -6, 46, -44, 27, -24, 11, 19, 69, 2, 24, -23, + -34, 45, 39, 8, -44, 92, -88, 43, 1, -30, -37, 7, 8, 48, -51, 44, + -79, -3, -9, 39, 16, -26, -28, 20, 13, 46, -58, 10, -63, 1, 39, 1, + -20, 14, 29, -39, 15, -58, 7, -7, -24, -35, -20, 16, -89, 74, -29, -31, + -39, 90, -58, -7, -32, -28, 12, 48, 14, -3, -5, 77, -51, -30, -25, -21, + 43, -43, 52, 17, -32, 52, -2, 18, -41, 85, -73, 1, 57, -32, 0, -32, + -33, -7, -42, -33, -34, 37, -16, -7, -10, 80, -68, 15, -63, 50, -64, 11, + -56, 86, 23, -30, 71, -89, 32, -41, -61, 64, -37, 88, -104, 56, -82, 0, + -48, -6, 23, -17, -7, -49, 59, 20, -42, 6, -10, -37, -48, -5, 0, -47, + -5, -53, 12, -42, -34, -8, 0, -39, 45, 23, -48, 83, -15, 8, -21, -24, + 31, 32, 14, 14, 12, 45, 8, -27, -47, 34, -36, 7, -13, 61, -38, 40, + 11, 38, -49, -51, 59, -16, 6, 44, -55, 22, 5, -10, 29, 1, 17, 0, + 45, 39, -49, 29, -6, 24, 31, 12, 35, -41, -46, -53, 56, -65, 9, 11, + -45, 62, 25, -47, 5, 0, -21, 50, 43, -1, -65, 73, 6, -42, 6, -39, + 56, 22, 62, -16, -15, 7, -46, -49, 74, -33, -29, 42, 37, -45, -14, 40, + -57, -6, -33, 22, 45, -32, 0, 6, 54, -14, -21, -38, -28, 43, -8, 0, + 50, 8, 47, -41, 0, -45, 13, -25, 1, 31, 43, -65, -45, -4, -46, -31, + 60, -90, 53, -35, 11, -54, 111, -76, 40, -13, 30, -24, -9, -53, 86, -66, + 65, 21, -4, -70, 46, 30, 3, -17, 37, -53, -15, 37, 19, -6, -46, 10, + 40, -56, 21, 40, -44, 71, -31, -1, -4, 33, 14, 19, 49, -39, 38, 40, + 6, -62, 99, -50, 107, -30, 0, 12, -27, 9, 16, -24, -20, 75, 22, 7, + 40, -25, 15, -39, -23, 23, -49, 7, -50, 35, -14, -20, -34, 54, 15, -10, + 66, 20, 4, 40, 11, 21, 22, -6, 28, -45, 27, 42, -1, -15, 42, 7, + -41, -33, -10, -1, -63, 54, 38, -18, 65, -85, 22, -72, 107, -61, 27, 33, + 52, -80, 41, 39, -55, 80, -41, 33, -3, -31, 41, 37, 32, 28, -50, 55, + 19, 44, -35, 87, 32, -36, 0, 33, -55, 50, 24, -43, -42, 14, -33, 69, + -43, -44, 48, -45, 63, -59, 2, 0, -17, 29, 58, -56, 26, -72, 95, -57, + 40, -46, 6, 34, -50, 28, -63, 28, -20, 0, 5, -22, 39, 41, -12, -27, + -36, -27, 19, 55, -56, 47, -78, 9, 16, -44, 97, -16, -46, 58, -8, 45, + -50, -70, -14, -7, 24, 23, -50, -23, -37, 28, 50, -57, 42, -29, 15, 28, + 7, -75, 29, -80, 53, 20, 42, 43, -84, 29, 46, -81, 19, 44, -55, 45, + 0, 20, -28, -3, -51, -4, 30, -24, -44, 28, 22, 33, 62, -69, 39, -9, + -39, -3, -16, -55, 5, -10, 46, 3, -39, 31, -15, 54, -10, 67, -6, 84, + -54, 70, -46, 31, -2, 1, -66, 26, 46, 17, -7, 39, 43, -32, -20, -28, + -3, 20, -55, 104, -85, 58, -29, -24, 0, 58, 16, 3, 17, -12, 55, -41, + -6, -24, 17, -9, -5, 17, -21, 18, -1, 28, -44, -50, 20, -1, -12, -4, + -55, 22, -36, -38, -49, 30, -68, 20, -2, 47, -18, -13, -1, -62, -23, 1, + -56, 62, -47, 47, 14, -31, 48, 23, 19, 39, -60, 56, -28, -44, 50, -56, + 9, -51, -24, 21, 19, -24, 2, -6, -13, 53, -43, 23, -83, 77, -24, -30, + 68, 1, 63, 0, -37, 41, -13, -50, 56, 21, 45, -6, -41, 58, -33, 23, + 10, 41, -9, 1, -26, -30, -42, 70, -50, 25, -11, -74, 38, -53, 25, -21, + 35, -13, -22, -66, 0, 34, -15, 0, 33, -72, 16, 11, 58, -42, 18, -7, + 63, -61, 7, -21, -31, 30, -38, -28, 47, -24, -21, -6, 61, -27, -37, 24, + -1, -32, 67, -66, 39, 39, 4, -58, 62, 19, 9, 25, -57, -34, -17, 71, + -74, 63, -42, -42, 87, -48, 37, 42, 26, -32, -25, 12, -25, 34, -48, 31, + 27, 59, 34, -5, 35, -66, 60, 41, -48, 4, -9, -38, -4, 48, -68, 19, + -8, -10, 72, -22, -5, -8, -47, -48, 33, -1, -1, 65, 9, -76, 63, -70, + 71, -8, 34, 36, 19, -1, 6, 64, -22, -13, -63, 30, -65, 10, -6, 18, + 26, -26, 61, 39, 30, -17, -29, 26, -14, -25, 0, 9, -50, -73, 43, -77, + 27, -30, 54, -32, -56, 35, 3, -17, -79, 10, -43, -45, 15, -30, 48, -59, + 12, 32, -44, 5, -40, -43, 60, -34, -8, -42, 15, -30, -4, -41, 31, -43, + 72, -12, -14, 48, -70, 60, -40, -6, 0, -11, -15, 52, -3, -44, -34, -24, + 93, -42, 45, 40, -20, 16, 32, 23, -88, 29, -31, 10, 19, 32, -12, 0, + -56, 44, -29, -43, 24, 7, -26, 30, -12, 20, 23, -51, 39, 16, -12, 3, + 48, 0, 20, -13, -54, 28, -19, -8, -37, 13, 25, 55, 6, -34, 9, 32, + -73, 86, -110, 65, -9, -23, 33, -14, -34, -19, -7, -35, -15, -59, 74, -74, + 13, -40, 4, 18, 47, 50, -26, -37, -8, 24, 32, 75, -74, 16, 5, -12, + -26, 34, -49, 111, -72, 49, -55, 20, -63, 47, 25, -53, 14, -10, -29, -27, + 16, 37, -44, 46, 20, -50, 30, 44, 13, 3, 19, 50, -82, 22, -23, -12, + 53, -54, 3, -50, 54, -24, -35, 98, -108, 56, -85, 51, -23, 32, -49, 35, + 77, -69, 24, 4, -55, -22, -5, -88, 54, -53, 80, -2, 2, -50, -8, -4, + -42, -27, -21, -41, 23, 37, -69, 45, 27, -8, 34, 36, -2, 8, 14, -14, + 26, -31, -63, 62, -40, 1, 55, 39, -28, 29, 8, -46, -55, 59, -18, 3, + -11, -75, 20, -53, 30, 16, -32, 6, -78, 98, -13, 29, 39, -33, -16, 5, + -32, -20, -19, -21, 2, -27, -1, -21, 9, -30, 4, -48, 71, 41, -9, -40, + 66, -55, 17, 38, 28, 40, -60, 54, 39, 21, 12, 17, 23, 17, 21, 37, + 35, -26, 9, 8, 7, 22, 60, -79, 95, -3, -29, 70, -28, 84, -73, 10, + -74, 76, -55, 54, 7, -41, 31, -11, -20, -13, 23, -16, 31, 25, 41, 58, + -78, -19, 8, -5, 61, -30, 20, 30, 89, -73, 68, -49, 36, 24, -5, 76, + 16, 9, 14, 82, -66, 22, 4, -62, 41, -98, 53, 5, 19, -6, 19, 0, + -1, -47, 3, 6, 51, -36, 5, 38, -26, 15, -69, -19, -29, 29, -59, 46, + 1, -63, 57, -44, -15, 43, -37, -45, 83, -77, 72, 0, 50, 18, -24, -16, + 0, 38, -69, 30, -66, 29, -30, -25, 76, -60, 16, -82, 61, -17, 33, -74, + 49, -16, -22, -39, 11, 2, 24, 1, 51, -13, -62, 1, 79, -26, 50, 18, + -57, 37, -23, -20, 6, 21, 14, -51, 21, -66, 17, -22, 61, -18, 42, -29, + 6, 36, 13, -20, 29, -35, 50, -61, 24, 8, 0, 6, -22, 15, -15, -9, + -37, 33, 0, 0, 95, -51, 67, 37, -48, 40, -77, 26, 21, 64, -27, 32, + 17, 38, 52, -58, 67, -8, -16, -7, -29, -56, -35, 20, 0, -14, 43, -5, + 52, 12, -26, 43, 12, -31, -14, 17, 6, 6, -15, 4, 12, 10, 53, -72, + 29, 69, -32, 31, -35, 30, -74, 40, 38, -50, -11, -60, 34, -32, 32, -10, + 8, 26, 9, -29, 59, 14, 47, -2, 4, -1, 25, 62, -75, 12, 52, 2, + 28, -22, -23, -58, 40, -79, 93, -46, 0, -20, 31, -68, 23, -72, 39, -76, + 63, -68, -7, 13, 52, -28, -39, 43, -56, -15, 18, -39, -34, -23, 61, 25, + 18, -61, -20, 8, -52, 72, 15, 19, -6, -6, 21, 20, -13, -13, -89, 24, + 26, 7, -26, 16, -89, 65, -73, -41, -48, 17, -14, -5, 24, -53, -43, -29, + -16, -32, 11, -39, -26, 45, -51, 6, 27, 40, -44, 18, -37, 2, -60, 20, + 31, 29, -27, 36, -10, -34, 58, -25, 50, -57, 70, 9, -42, 44, 18, -39, + -43, 10, 22, -32, 54, 6, -1, 54, -23, 42, -61, 41, -94, 9, 0, 36, + 34, 29, 10, -3, -35, -12, 59, 35, -51, 32, -43, 43, -16, 7, 26, 38, + -33, 18, 71, -10, -5, 30, -26, -30, -20, 11, 75, -15, -81, 18, -83, 61, + -18, 51, -25, 20, -15, -22, -37, 34, 46, -29, -27, 31, -54, -11, -16, -5, + 50, -44, 43, -4, -30, -24, 11, 1, 27, -2, 52, 13, -15, -6, 36, 26, + -19, -54, 73, -62, -28, -48, 47, -61, 41, -55, 59, 3, -25, -39, -15, -22, + 22, -75, 20, 2, -45, -37, 44, -3, 30, 69, 15, -62, -1, -20, 1, -50, + -31, 1, -1, -39, 35, -54, 15, -58, -1, -34, 51, -11, -5, -63, 43, 43, + -76, 2, -13, -65, 70, -53, 58, 20, -41, 8, 68, -16, 22, -4, 8, 18, + 32, 36, -57, 42, -77, 13, 15, -55, 44, -34, 43, -58, 3, 32, -80, 23, + -27, -21, 57, -6, 24, 21, -92, 68, -33, -16, -12, 48, -25, 52, -34, -19, + 31, 3, 55, 10, -73, 6, 80, -52, -15, 62, -59, 48, 33, 5, -66, 36, + -2, 98, -44, 0, 40, -32, -32, 39, -33, 27, -49, 2, -24, 17, 77, -56, + -51, 30, 44, -16, 11, 35, 8, 28, 3, 5, -33, -67, 71, -31, 73, 17, + 9, -36, 41, 39, -5, -47, 47, -7, -7, 26, -29, -19, 41, -38, 10, 59, + -83, -9, -38, 34, -67, 70, -80, 30, -44, -19, 30, -39, 45, 6, 7, 72, + 38, -24, 49, -78, 24, -43, 17, -17, -29, 21, -3, 4, 79, -51, 72, -79, + 1, -60, 30, -7, 47, 2, -38, -56, 52, 53, -36, -5, -3, 31, -29, -6, + -12, -23, -8, -71, 77, -88, 32, -27, 71, -43, -48, 80, 1, 57, 32, 23, + -80, 4, -24, 40, -56, 42, 39, -74, -1, 61, 30, -41, 87, -35, 65, -41, + 17, -55, 9, 18, 6, -35, 68, -44, -11, -54, -55, 35, -29, -54, 28, -77, + 42, -49, 39, 8, 34, 7, 16, -46, 24, -4, -19, -4, 45, -27, 70, -21, + -3, -25, 40, 4, -18, 38, 7, -21, 23, -84, 0, 89, -30, -31, 51, 38, + -44, 62, -52, 74, -55, 57, 14, 56, -39, 4, -40, 53, 7, 8, -54, 55, + 0, 56, 2, 40, -11, 5, -5, -11, 22, -39, -22, 9, -12, 10, -55, 0, + -66, 3, 1, 13, -5, 0, -23, 12, 1, 20, -22, -22, 52, -20, 5, 4, + -8, 63, -37, -51, -30, 53, 3, 62, -50, -6, 12, -30, -5, -2, 35, 26, + -60, 9, -61, -7, 45, 13, -61, 12, -26, 5, 51, -31, -51, -45, 61, 2, + -42, -63, 42, 27, -35, -3, 19, -17, -22, 32, -14, 49, 7, -6, -28, 38, + 44, 16, -71, 21, -39, 8, -61, 5, 31, 31, 38, 94, -81, 35, -6, -50, + 55, -39, -10, 30, -62, 79, -88, 25, 17, 2, -4, 32, -44, 66, -35, -27, + 66, 0, 91, -104, 98, -71, 39, -2, 59, -34, 38, -61, -13, -6, -27, -76, + -15, -5, 24, 26, -17, 69, -45, 9, 0, -21, 22, 23, -22, -45, -25, 8, + 63, -34, -33, 19, -80, 60, 4, -20, -3, -31, -11, 54, 2, -48, 80, -73, + 77, 1, 29, 24, -10, 24, 53, -48, -27, 43, -47, -43, -62, -13, -39, 48, + 11, 38, -31, -3, 60, -99, 75, 2, 15, -45, -4, -29, 7, -37, -34, 13, + 15, 71, -47, -12, 37, -66, 44, -46, 55, 63, -25, 68, -52, 74, 13, 23, + 45, -25, -7, 2, -20, -36, 46, 3, 28, -59, 88, -44, -10, -65, 49, -79, + 55, 11, -6, -5, 54, -78, 55, -2, 54, -42, 41, -77, 1, 10, 51, -99, + 87, -64, 52, -66, 36, -45, 50, -39, 45, 28, 32, -73, 35, -34, -52, 34, + -81, 24, -71, 38, 18, -43, 19, -7, 3, 0, 25, 34, -49, 16, 39, 44, + 45, -4, -13, -20, 49, -67, 47, -17, 34, -27, 26, 3, -24, 26, -61, 30, + -48, -19, 13, 75, 29, -27, 4, -71, 98, -69, 30, 36, 8, -32, 50, -47, + 87, -59, 75, 35, -74, 18, -22, 51, 52, -70, 4, -7, 56, 43, -37, -10, + -6, 71, -45, -37, -21, 20, -11, -18, 19, 36, 41, -80, -27, 30, 10, -45, + 29, -55, 74, 17, 24, -58, 50, 9, -36, -12, -33, -54, 7, 30, -37, 19, + -28, -28, 23, -15, 28, 6, 51, -45, 9, 0, 1, -37, 5, 36, -13, 12, + -59, -19, -60, 59, -11, -35, 10, 41, -47, 45, 19, 15, 14, -10, -10, 83, + -44, 33, -6, -48, 46, -54, 31, -38, 43, 35, -8, -43, 51, 63, 28, -43, + -40, 16, 57, 11, 50, -29, 16, -1, 29, 42, -47, -69, 50, -3, -44, 8, + -23, 1, -11, -78, 16, 14, -41, 28, 35, 30, 48, 45, 77, -27, 63, -74, + -42, 17, 20, 38, -36, 50, -24, -54, -8, 19, -8, -25, 61, -33, 63, -40, + 34, -86, 24, -7, 33, 33, -65, 28, -1, -94, 42, -16, 4, -25, -6, -2, + -65, 33, 4, 28, -48, 48, -31, 14, -37, 51, -73, -2, 49, 10, -1, 24, + -13, 42, -81, -3, 13, -19, -31, -2, -46, 37, 33, 30, -13, 10, -46, 64, + -49, 63, -53, 33, 12, 52, -25, -50, 1, -44, -23, -15, 45, 29, 74, -34, + 89, -68, 96, -27, -30, -42, 60, 12, -55, 68, -71, 2, 8, -6, -87, 23, + -49, 0, -38, 28, 45, -38, 48, -15, 31, -87, 35, -39, 48, 8, 65, 1, + 36, 55, -33, -63, -17, -36, 17, 25, -85, 39, 13, -4, -58, 69, -71, -4, + -29, 9, -49, -33, 46, 23, 8, -64, 36, -19, 9, 45, -71, 21, 14, -60, + 11, 40, -59, 36, 28, 10, -35, -47, 30, -79, 18, 38, 61, -1, -26, -23, + 79, -51, -33, -9, 44, 35, -4, 20, -35, 4, 14, 25, -39, -29, 17, 23, + 61, 21, -49, 51, -40, 11, -95, 72, -10, -12, 9, 18, -53, 6, 9, -67, + 61, 45, -11, 0, 23, -27, 35, -87, 47, -59, 0, 31, 3, -44, 17, -22, + 35, 34, 4, -12, -28, 17, -48, 95, -109, 24, -25, -29, -4, -74, -8, -3, + 37, 37, -91, 28, -79, 33, 35, -65, -50, -30, 68, 23, -5, 25, -25, 2, + -6, 8, 20, 34, 45, -2, 30, -61, 23, -61, -25, -42, -62, 29, -40, 83, + -16, 7, 8, -1, -26, -16, 27, -8, 61, -1, -51, 24, 48, -61, -33, 15, + 13, 51, -47, 31, -24, 42, -4, 40, 13, 80, -99, 49, -32, 5, 35, -19, + 62, -22, -17, -21, 59, -1, -10, 31, -28, 26, 23, -37, 22, -17, 8, -22, + -27, 26, 65, 14, 5, 0, 45, -12, -28, 50, -65, 41, -58, 74, -13, -50, + -25, -4, 18, -17, -36, -52, -9, 33, 38, 8, 32, 32, -68, 0, -55, 25, + -44, -10, -63, 22, 17, 88, -50, -35, 68, -45, 35, 52, -49, 57, 64, 3, + -4, -7, 42, -12, -33, 55, -70, -24, -29, 58, 43, -1, 0, -31, -77, 18, + -56, -27, -15, 66, -32, 29, 58, -101, 85, -13, 52, -61, 16, 16, -12, 70, + -52, 14, 33, 2, -66, 24, 8, 4, 28, -22, 59, -79, 87, -65, 46, 53, + -4, -50, 55, -15, 38, 24, 15, 48, -18, 34, -52, -34, -58, 34, -57, 14, + -53, 36, 50, -54, -30, -16, -18, 9, 34, -30, 32, -22, 33, 10, 8, -72, + 33, -63, 32, 26, -29, 29, 33, 5, -77, 51, -1, -26, 30, 16, 22, 37, + -21, -28, 43, -17, 29, -8, 4, 28, 28, 3, -14, 2, -48, 57, 11, -21, + -36, -9, -39, -7, 42, 27, -35, -53, 55, 35, 12, 19, 57, 3, 39, -34, + 70, -57, 50, -3, 42, -22, 2, 38, 46, 45, -27, -72, 69, -68, -7, 66, + -18, -8, -12, -9, -38, -9, 30, -46, 36, -27, 70, -22, 47, -40, 16, -35, + -1, -11, -24, -16, 28, 42, -41, 10, -20, -11, 34, -42, -17, 66, 0, -30, + -43, 8, -17, -15, -20, -38, -8, 3, -39, -63, 79, 39, -2, -3, -54, 61, + -23, 20, -14, -15, -39, 9, 20, 44, -70, 45, -33, 44, 10, 3, -5, 35, + -18, -35, -54, 20, -59, 46, -59, 6, 75, -73, 10, -8, 3, -9, -49, 61, + 68, 4, -25, -26, 66, 60, -51, -35, 37, -32, 36, -56, 75, 7, -1, -6, + 62, -28, 54, 66, -45, -77, 36, -17, -64, 42, -46, 6, -26, 6, -43, -54, + 68, -38, -56, 75, -34, -40, 67, 35, -8, 2, -84, 29, -45, -30, 60, 39, + 4, 13, 40, 8, 28, -55, 28, 16, 24, -44, -60, 54, 22, -63, 70, -33, + 15, -49, -25, 43, 9, -40, 9, -40, -60, 21, 20, -10, -78, 44, -82, 18, + -45, 60, -71, 48, -92, -32, -6, 36, -20, 3, 75, -46, 68, 18, 35, 26, + -18, -13, -25, 37, 46, -66, 43, 3, 24, -3, 20, 41, -80, 70, 0, 2, + 17, 61, -39, 41, -48, -59, 50, 6, 40, 2, 36, 9, -20, 14, -75, 60, + -52, 38, -34, 14, -9, -27, 1, -26, 36, -11, -44, 57, -41, 15, -1, -24, + 10, 60, -45, 38, -22, 43, 3, 3, 1, -21, -32, 0, -72, 14, -43, -26, + -68, 30, 16, -17, 28, -10, -35, 6, -8, -46, -2, 71, -107, 101, -62, 3, + 16, -34, 8, 27, -66, 75, -86, 72, -46, 17, -15, -13, 36, 6, -33, 36, + 69, -40, 21, 40, -36, 3, -46, 34, 14, 26, 5, 44, -6, 1, -18, -11, + 60, 28, 37, 26, 37, -40, 37, 26, -28, 82, -92, -54, -14, -27, 71, -69, + 27, -47, 36, 10, 32, -75, 25, -57, 42, -39, -46, 2, -65, 3, 18, 27, + -32, 27, 64, -54, 84, -37, 54, -50, -45, 65, -46, 15, -60, 66, -5, -7, + -86, 9, -14, 36, -69, 5, 73, -49, -17, -31, 28, -26, 4, -30, -33, -27, + -59, 85, -70, -66, -7, 94, -58, 7, 64, -43, 89, -56, -8, -12, 42, -29, + 0, 16, 74, -98, 30, 53, -84, 3, 25, 0, 51, -29, 35, 35, -30, -83, + 37, -3, -56, -25, 2, -22, 55, -35, 2, 40, -24, 56, -70, 75, -111, 61, + 1, 64, 57, -54, 14, 25, 43, 27, -7, 61, -38, -3, 47, 32, 9, 38, + -30, 16, 37, 9, 52, 38, -19, -5, -5, 16, -63, 25, -14, -42, 26, -44, + -10, 17, 29, -60, 21, -4, 28, -68, 16, -52, 40, -48, 77, -58, -34, -17, + 54, -74, -31, 37, 62, 1, -40, -5, -61, 26, -63, -1, 44, 0, 55, -57, + -22, 17, -12, -3, 63, -55, 33, -2, -34, -25, 19, 36, -29, 50, -44, -6, + 36, -23, -34, 12, 37, -12, -55, 38, 40, -45, 19, 16, 43, -13, 56, 15, + 64, -63, -17, 23, -26, -10, -1, 4, -19, 65, -40, 24, 40, 15, -47, 32, + 52, -25, -24, 21, 20, -9, 48, -4, 28, -32, -16, -44, 19, -70, 76, -62, + -39, -5, -59, -5, 14, -11, 51, 28, -19, -49, 17, -79, 31, 3, 14, 54, + -53, -44, -12, -9, -1, 12, -66, 58, -23, -47, 88, 64, -21, 72, -62, 39, + -27, -12, 56, -16, -7, 56, -45, 36, 4, 37, 53, 16, 34, 12, -29, 11, + -13, 51, -59, -38, -32, -30, 55, 12, -19, 46, -26, 21, 19, 11, -45, 62, + 63, -40, 8, -8, 43, -8, -38, 45, 23, -19, 0, -46, 30, 28, 72, -15, + 62, -81, 17, 89, -25, -25, 6, 48, -9, -44, 8, -20, 35, 51, -51, 27, + 40, -12, -46, 89, -53, 16, 5, -5, 33, -101, 53, -17, 38, -9, 76, -4, + 40, -17, 63, -48, 85, -41, -53, 13, -18, 5, 16, -73, 4, 31, 47, -18, + -13, -64, -36, 4, 16, 35, -61, -22, 58, -69, -24, 37, 2, -59, 1, -27, + 49, -67, 14, 4, -52, 16, -88, 43, -34, 14, 18, 6, -12, 40, -78, 73, + 2, -20, 13, 28, -36, 5, 75, -32, 35, -25, -47, 6, -14, 6, 55, -72, + 38, 4, 40, -66, -73, 14, 40, 1, 6, 31, -65, 83, -61, -49, 18, 37, + 25, -17, -34, 0, 14, -59, 73, -13, -10, 43, -16, 3, -5, -25, 70, -57, + 46, 13, -30, 37, -64, -11, 6, 7, 4, -34, -3, 39, -33, -41, 4, 22, + -69, 84, -32, 82, -48, 21, -16, 13, -40, 48, -58, 26, -42, -47, 89, -100, + 34, -34, 50, 28, -13, -53, 4, -41, -22, 29, 72, 14, 26, 24, -54, 92, + 7, 16, 66, 30, -41, -3, -36, -16, -42, 9, 73, -21, -4, 28, -23, -41, + -12, -8, 55, -6, 9, -33, 12, -28, 26, -15, -83, 22, -66, -4, 9, 8, + -29, 22, -26, -35, 45, -33, 6, -1, 6, -21, -59, -1, -14, -22, -3, 0, + 36, -46, 56, 65, 24, 0, -15, -23, 52, -35, 36, -16, 22, -11, 12, -76, + 35, -1, -5, -4, -6, 27, -30, 13, -19, 1, 52, 1, 13, -30, -62, -14, + -18, 55, -16, -24, 0, 37, 9, -41, 12, -25, 53, -47, 32, -50, -6, 7, + -21, 13, -19, -16, -26, -25, 63, -17, 7, 85, -74, 23, -46, -36, -97, 71, + -85, 5, -55, 11, -62, 62, -1, 11, -18, -7, 30, 44, 1, -68, 19, -45, + 35, 38, 5, 34, -67, 16, -49, 78, -31, 8, 25, -7, -9, 20, 3, 42, + -84, 89, -41, -4, 27, 35, 58, 35, -55, 31, 7, 1, 17, -59, 90, -87, + 70, -1, -42, -61, 72, -43, -40, -30, 28, 12, 66, -44, 10, -4, 31, -5, + 14, -56, 29, 47, 55, -12, 19, -54, -4, -2, 56, -88, 40, 19, -38, 42, + -74, -23, 52, 39, -30, 73, -83, -34, 18, 46, -50, 60, -16, -14, -34, 38, + -37, -27, 30, 31, 25, 15, -42, -48, 49, 42, -78, 29, 3, 14, 22, -5, + 10, -24, -5, -53, 18, 12, -31, 77, -49, -13, 38, -2, 28, -14, -12, 74, + -9, -53, 42, -91, 3, 68, -39, 27, 51, -34, -46, -45, 4, -4, 12, -52, + -56, 70, -86, 0, -8, 20, -6, 15, 57, -32, -21, 16, -18, 31, -28, 28, + 34, -48, 28, -29, -64, 43, 27, 18, 18, 45, 45, -36, 52, 2, -2, 39, + -28, 23, -69, 67, -63, 34, -27, 36, -16, 29, 27, -20, -6, 53, 25, -35, + -44, 23, 0, -61, -22, -33, 58, -41, -39, 26, -14, 3, 56, -81, 12, 0, + 7, 6, -58, 6, 58, -51, 5, 18, -26, -33, 20, -52, 59, -4, 16, 40, + 13, 41, -43, 3, -61, 35, -18, -26, -27, 55, 10, -38, 86, -49, 31, -10, + 27, -4, -37, 30, 31, 25, -43, -61, 67, -95, 27, 32, 0, 69, 46, -12, + 46, 25, 11, 55, 34, -64, 44, 35, -73, 61, -96, 40, -4, 0, 1, 35, + -79, 57, -78, 61, 0, -18, 58, -63, -25, 23, -59, 70, -41, 37, -18, -20, + 65, -43, 4, 1, -28, -48, -58, -27, 74, -53, -10, 23, 0, 51, -76, 60, + -21, -53, 55, 73, -55, 67, -20, 57, -41, -15, -14, 8, -1, -60, 55, -81, + -18, -2, 5, 0, -56, -1, 60, -39, 54, -70, 48, -15, 51, 25, -42, 0, + 36, 35, -30, -48, 2, -21, 36, 62, -59, -3, -23, -9, 0, -30, 28, 31, + 0, -33, -20, 0, 0, -27, 69, -14, 5, -16, 68, -1, 13, -47, -39, -14, + 56, -36, 8, 36, -53, 8, 0, -47, 73, 4, 7, -25, 42, -40, -15, -33, + -6, 24, 19, 26, 20, -24, -21, -5, -32, -40, 89, 19, -46, 45, 38, -10, + 16, -21, 58, -16, 53, -51, 28, -19, 24, -25, -20, 11, -3, -51, 48, -18, + 38, -1, -5, 28, 45, 19, -31, -59, 41, -77, -9, 83, -67, 2, -34, -21, + 2, 22, 52, 8, -30, 21, -38, 32, 21, -39, 8, -48, 37, -74, 43, -27, + 33, -14, -43, 6, 82, -62, -12, 56, -2, -53, 53, -45, -18, 47, 34, -51, + 43, -7, 15, 43, -78, 77, -20, 36, 8, -32, 48, 46, -74, 28, -41, 13, + 8, -26, -46, 70, 5, 11, 6, 20, 48, -70, 44, -45, -42, 39, -62, 57, + -97, 53, 38, -77, 67, -45, 92, -19, -16, 75, -69, 23, -32, -21, -28, -41, + 19, -44, 51, -74, -26, -3, -14, 8, 27, -27, 29, -19, 42, 29, 4, -80, + 90, -46, -26, 21, -2, -74, 38, 34, 69, -59, 38, -30, -6, 43, -3, -21, + -24, 20, -26, -19, 59, 20, 56, -15, -46, 51, -40, -29, 13, -6, -12, -18, + 36, 18, -49, -27, 36, -71, 9, 2, -43, 51, 10, 9, 40, -25, 31, 78, + 53, -48, -2, -25, 89, -56, 26, -71, 64, 40, -18, 15, -47, -21, 68, -72, + 57, 13, 4, 11, 43, 1, 45, -104, 32, 15, 19, -27, 62, 0, -19, -19, + -9, 0, 59, -52, 43, -25, -32, 37, -38, 39, -75, 5, -44, 73, 25, -33, + 25, 38, -2, 0, 24, 8, 31, -48, -33, -25, 26, -41, 16, 24, 41, -14, + 4, -3, -54, 34, 6, 29, -15, 69, -39, 45, -38, -19, -13, 10, -32, -63, + 64, -65, 34, -47, 43, -20, -18, 78, -50, 61, -72, 60, -42, 82, -94, 64, + -56, -24, 41, -83, 55, -34, 3, -6, 52, -8, 1, -56, -19, 69, -51, 55, + 19, 16, -95, 40, -41, 30, 6, -19, -51, 54, -28, 45, 2, 6, -13, 29, + 13, -36, 57, 2, -35, 45, 32, -55, 7, 6, -17, 29, -25, 18, -20, 4, + -15, -18, 30, 2, -50, -13, 29, -42, -20, 10, -55, 9, 5, -8, -10, -42, + 50, -44, 94, -62, -61, 53, -51, 12, -62, 25, 35, -2, -1, -15, 36, 3, + 59, 12, -67, 66, -62, -21, -44, -19, 21, -77, 93, -65, 59, -12, 25, -4, + 4, -12, 9, 34, -44, 47, 39, -44, -16, 11, 7, 43, -69, -5, 0, 90, + -96, 38, 56, -53, 46, 44, -5, -6, -47, 8, 35, -63, 66, -89, 37, -5, + 37, -56, 59, 6, -97, 30, 13, -13, 21, 8, -15, 60, -62, 62, 8, -26, + 32, -25, 0, 23, -42, 84, -76, 54, 2, 13, 13, -63, 27, -60, 1, -88, + -15, 2, 39, -11, -60, -5, 33, 28, -54, -43, -19, -63, 48, 24, -41, 26, + -60, 22, -57, -7, 8, -64, 42, 36, 21, -20, 37, -65, 0, -27, -26, 64, + 0, 40, -84, 50, -63, 95, -18, 18, -50, 38, -24, 76, -45, -4, -47, -6, + -45, -21, 11, -8, -32, 24, -58, 77, 80, -52, -34, 44, -15, -11, 13, -51, + -26, 28, 35, -25, 26, -89, 43, -25, 36, -34, 26, 27, -10, 25, 49, 49, + -64, 37, -20, 33, -62, 0, 6, -85, 12, 8, 35, 20, 58, -91, 76, -98, + 79, 2, 9, 6, 23, -19, -17, -16, -28, 0, 45, 57, -45, 36, -8, -17, + -20, 40, 43, 13, -21, -43, 18, 18, 58, -49, 12, 12, -35, -19, 54, -68, + 68, -51, 12, 10, -27, -14, 0, 35, -35, 16, -9, -29, 32, -73, 62, -93, + 65, -11, 31, -60, 87, -56, 67, 12, -7, 8, -29, 13, 25, 20, 8, 60, + -53, -19, -16, 4, 81, -75, 106, -97, 81, -15, -11, 6, 15, -32, -13, 5, + -61, -14, 46, 24, -11, 55, 7, 38, -39, 79, -22, -39, 24, -41, -39, 65, + -24, 9, -24, -12, 55, -43, -9, 11, 4, 62, -73, -3, -31, 46, -61, -25, + 42, 16, -61, 0, 3, 29, -53, -21, 56, 7, -34, 12, 11, 21, -3, -13, + -37, 34, -25, 18, 82, -54, 1, 49, -65, 55, -23, -29, -13, -48, 5, -24, + -58, 41, -26, 38, -11, -19, 61, -61, -35, -31, -5, 29, -5, 47, 55, 19, + -14, -11, -34, 3, 26, 62, -42, 19, 15, 16, 60, 43, 16, 9, -44, 59, + -54, 37, -3, 29, -44, -26, 33, -64, -18, -37, 50, 27, 46, 32, -24, -5, + -36, 9, 27, 11, 5, -88, 5, -48, 53, -70, 54, -61, 9, 47, 65, 15, + 20, 2, -12, 28, 46, -78, 75, -89, -50, 40, 46, -50, 31, -43, 18, 45, + 29, -27, 4, -33, -12, 82, -80, 68, -55, -21, -50, 8, 50, -86, -4, -32, + 2, 42, -64, -11, 23, 50, -30, 80, -5, -53, -44, -32, -26, 44, 4, 57, + -79, 26, -44, -1, -27, 9, 12, 30, 14, -2, -52, 2, 4, -23, 74, -47, + 26, -81, 23, -76, 57, 60, -63, 31, -50, -4, 29, -52, 71, 0, -11, -43, + 60, -40, 4, -27, 37, 7, 29, -40, -29, 67, -2, 42, -16, 8, 14, 31, + -2, 17, -70, 50, -17, -14, -44, -2, -19, 43, 42, -1, -43, 49, -25, -7, + -11, 70, 27, -75, 14, -19, -48, 74, -6, -53, 64, -95, 57, 6, 39, 15, + 8, -35, -28, 21, -65, 25, -52, 25, 3, -61, -11, 55, 21, 30, -16, -22, + -1, 33, 0, -3, -48, 38, -49, 8, 49, -86, 48, 12, 17, 10, 9, -35, + 44, 0, 48, -48, 15, -74, 81, -68, -29, -44, 107, -86, 55, -61, -9, 23, + -39, 15, 11, -27, -3, -44, -8, 22, -33, -24, -25, 46, 56, 9, 32, 37, + 24, 3, 58, -70, 28, 34, -57, 59, 69, -57, 40, 16, -21, -36, -49, 11, + 60, 23, 41, 13, -50, -1, -23, -10, 1, -23, -78, -7, -41, -33, 0, 4, + 57, -60, 58, -8, 41, 55, -34, 38, 61, -42, 0, -63, -15, 1, 11, -26, + 12, -23, 13, -7, 21, 58, 44, -6, -21, 62, 23, -34, 51, -75, -59, 44, + -81, 62, -19, -73, 24, -4, 3, 21, 76, -72, 64, -47, 39, -35, 30, -60, + 51, -58, 39, 31, -24, -25, 54, -18, 21, 47, 39, -26, 4, 78, -64, 65, + 40, -51, 87, -18, 31, -17, -33, -1, 12, 69, 61, -14, -29, -21, -3, 45, + -10, -33, 28, 23, 34, 16, -40, -19, -30, 27, 12, -46, 34, 31, -86, 61, + -66, 100, -60, 79, -23, -29, 43, -34, 4, 0, 11, -5, 20, -36, 24, -29, + 4, 37, 19, -29, 0, 11, -22, 33, 18, -75, 45, -76, 28, 14, 26, -13, + 23, -75, 75, -30, 2, -5, 42, -11, 27, -19, -75, -22, 16, -25, 19, -46, + 20, -57, -18, 55, -8, 52, 27, -25, -42, 41, -33, 69, -23, -16, 36, -39, + 10, 17, 2, -1, 80, -18, -3, 7, 11, 15, -32, -30, 10, -29, 18, -16, + 12, 53, -63, 5, 53, 31, 5, 35, -23, -17, 42, -3, 3, -11, 57, -66, + -38, -13, 38, -74, 99, -66, 46, 41, 54, -32, -36, -5, 17, 44, 41, -32, + 34, 1, 29, -4, 9, 33, 39, -92, 81, -16, 40, 7, -83, 29, 18, -48, + -36, -3, -19, -33, 37, -12, -39, -28, -13, -28, 45, -57, 3, 18, 37, -74, + -15, -7, 25, -33, 19, 3, -3, -33, 8, 35, 51, 26, 0, 48, -63, 70, + -56, 13, -28, -46, 27, -84, 36, -43, -1, 15, 2, 58, -10, -26, 24, -5, + 35, -10, 68, -86, 54, -85, -18, 25, -36, -37, -10, 16, 43, -7, 40, -37, + 72, -5, -12, 50, 19, 5, 36, -51, -44, 4, -49, 0, 0, 64, -65, 17, + -35, 59, -16, -6, -47, 34, 11, -58, -33, -66, 59, -55, 35, -41, -5, 5, + -75, 47, -91, 43, -51, 97, -70, 58, -44, -66, -86, 61, 70, -42, -15, -55, + 46, 27, -2, -69, 31, -10, -18, 72, -39, 34, 46, -33, 13, -13, 25, 0, + -33, 47, -31, -12, 33, -18, -57, 96, -25, -36, 69, -51, -17, -9, 20, -2, + -73, 76, -47, 64, -31, 6, 6, 21, -26, 25, 18, 12, 34, -17, -78, 30, + 57, -12, -7, 27, -19, -9, -5, 14, 13, -15, 67, 50, 2, -1, -48, 51, + -29, 8, -5, -35, 65, -68, 3, -21, 51, -79, 85, -49, 2, -32, 0, -5, + -21, 8, 47, 23, -90, 19, -21, 21, 68, -51, 39, 7, 8, 52, 1, -54, + 33, -64, 52, -3, -39, -79, 32, 11, -59, 57, -57, 3, 19, -40, 1, 60, + 34, -6, -7, 74, -78, 58, -5, -49, -21, 9, 48, 39, -40, -11, -78, 60, + -25, 43, -33, 6, 44, -55, -12, 51, 2, -16, -32, -3, 45, -70, 1, 22, + 10, 50, 0, 13, 12, -64, 35, 60, 9, 18, 0, 59, -95, 55, 18, 22, + 47, -36, -35, 18, -46, 7, -21, 63, 24, 5, -46, 6, 17, 18, -7, -20, + 0, 58, -32, -8, 51, 60, -50, 21, 16, -49, 13, 3, -59, -22, 51, -2, + 1, -48, -40, 24, -7, 39, -5, 16, -23, 80, -37, -19, 3, -20, 13, -29, + -51, 34, -21, -70, -3, -2, -18, 50, 6, 72, -41, 51, -22, -3, 16, 40, + -35, 5, -3, -32, 10, 47, -24, 62, 38, 65, -57, 38, -53, 53, 0, 6, + -11, 53, -5, 28, 16, -87, 61, -78, 77, 62, 76, -48, -16, -17, 94, -31, + 25, -50, 36, 6, 15, -37, -2, -57, 86, -65, 12, -40, -43, -18, 27, 5, + -30, -37, -33, 52, -72, 23, 31, -93, 23, 0, -42, 32, 49, -20, -20, 8, + 64, -45, -4, -22, 4, -16, -15, -32, 50, -66, 6, -9, -9, -59, 70, -20, + -39, -31, -21, -16, 35, 39, -11, 3, -17, 27, -30, -57, 40, -27, 49, 13, + 25, 39, 11, 64, -67, 13, -35, 44, -35, 33, -49, 18, 26, -6, -59, 46, + -4, -13, -29, -60, 84, -16, 3, -30, -89, 38, -31, 49, -52, -30, -4, 63, + -57, -19, 20, -34, 16, 98, -79, 49, -8, -5, 4, -40, 56, -26, 43, -81, + 15, 37, -78, 6, -45, -5, 33, -25, -2, -18, -43, 21, 2, 30, -12, 40, + -64, -1, -64, 19, -12, -9, -3, 13, -24, -1, 45, -72, 66, 20, -47, 14, + -11, -26, -38, 20, 27, 24, 14, -77, -16, -51, 44, 8, 74, -60, 25, -92, + -5, -6, -13, 50, 6, 26, 32, -79, -16, 16, -21, 31, -31, 24, -48, 35, + 9, -56, -14, 36, -57, -57, 61, -20, -39, 42, -27, -22, 81, 27, -50, 49, + -49, 40, 5, 15, -4, -34, 70, -83, 91, -91, 50, -47, 6, -16, 27, -50, + 70, -81, 69, 71, -38, 35, -43, 14, -22, -44, 38, -32, -18, -37, -49, -1, + 21, 27, -5, 22, -34, 1, 4, -80, 5, -59, 18, -53, 75, -62, -1, 3, + -16, 2, -29, 5, -64, 73, -41, 62, -44, -62, -74, 43, -28, -9, -82, 57, + 39, 13, -16, -21, -51, 94, -34, 62, -85, 12, 40, 54, 53, 3, 0, -62, + 72, 33, 8, -48, 50, 30, 10, 44, 0, 42, -42, 66, -72, 10, 26, 63, + -88, -9, -28, -5, -10, 8, 76, -26, -48, 88, -82, 72, -32, 7, 37, -20, + 23, 14, 24, -30, -19, -3, -29, -10, -27, 25, -38, -32, 25, 51, -31, -50, + -60, 0, -28, -69, 74, -43, -14, 63, -50, 6, 32, 15, -51, 49, 46, 29, + -39, 12, -35, 43, 29, -62, 24, 49, 30, 49, -57, 27, 35, -25, -1, 12, + 12, 39, 43, 28, -37, -43, 24, -55, 59, -37, 53, -24, -44, -6, 30, 14, + -72, 26, 48, -2, 56, -17, 4, 23, -1, 70, -20, -24, -21, 35, 42, -64, + 51, 27, 9, 47, -49, 18, -42, 49, -24, 10, 13, 25, -43, -15, 56, -20, + -12, 51, -43, -12, -34, 21, 34, 34, 34, -14, -33, -7, -82, 75, -51, 75, + -19, 61, 24, 23, -66, 47, -39, 20, 34, -10, 0, -15, -17, -27, 14, -41, + 54, 7, 41, -10, 11, 45, -10, -17, 85, -21, 36, -26, -47, 28, -42, -59, + 58, 7, -26, 33, 35, -50, 19, -5, -38, 42, -18, 8, 48, 25, 30, 36, + -27, 36, -44, -59, 16, 44, -15, 13, -30, 82, -16, 30, 51, 36, 52, 18, + 16, -44, 20, -21, 36, -59, 44, 19, 58, 3, -6, 60, -45, 0, 34, 49, + -48, -29, 66, -8, 79, -23, -28, -27, 2, 45, 67, -48, 14, 10, 58, -65, + -52, 7, 12, 5, 12, -49, -13, -2, 18, 39, -28, -73, -18, -26, 88, -16, + -20, 13, 41, -9, -22, -65, -2, -16, 21, -41, 35, -27, -17, 30, -33, -51, + 86, 34, 47, 37, -41, 6, -65, 61, -38, 9, 58, -62, 48, 16, -16, -39, + 42, -19, -18, 42, -3, -46, 55, -25, 36, -30, 41, 38, 37, -89, -31, 56, + 78, -41, 4, 62, -51, 39, 30, -23, -17, 5, 24, -62, 36, -57, -11, -37, + 27, 70, -23, -5, -40, 63, -35, 17, -72, -48, 68, -55, -42, 56, 68, -99, + 65, -39, -70, -9, -26, 69, 21, -14, 14, -11, 18, -52, 37, 73, -27, -26, + 74, -19, -44, 64, -90, 57, -7, -30, -61, 11, 6, -1, 12, -17, -16, -11, + 35, -52, 8, 47, -23, 7, -34, 22, -10, 12, 28, -61, 26, 61, -32, 10, + -30, 33, 12, 14, 21, -7, -80, 24, 17, -6, -5, -25, 70, -25, -7, -12, + 48, -97, -8, -65, 14, 1, 11, 32, -62, 11, -18, -24, 10, 12, 5, 47, + -17, -40, 27, -27, 1, 2, -30, -3, -59, -10, 1, -45, 69, 33, -8, 48, + -91, 57, 7, -42, -18, -7, -34, 21, 42, -23, 57, -49, -42, 6, -62, 0, + -3, -5, 79, -18, 8, -58, 9, 3, 1, -84, 17, -38, -49, -22, -52, -8, + -57, 60, -27, 27, -79, 71, -52, 55, -61, -25, -13, 0, 48, -18, -19, -23, + 74, -56, 23, -26, -39, -29, 55, 21, -12, -22, 43, -33, 3, 29, -11, 10, + 34, -24, -28, 11, 42, 15, 60, -48, 56, -93, 61, 38, -1, -34, -41, -1, + -23, 5, -15, -49, 52, -20, 89, -63, 33, 27, 6, -37, 73, -77, 71, 4, + -37, -34, -1, -67, 84, -41, 26, 46, -43, -14, -11, 14, -26, -18, 48, 9, + -33, 10, 32, 30, 10, 46, -71, 50, 12, 23, -50, 0, -27, 56, 36, -8, + -77, -25, 15, 34, 0, -45, 15, -5, -17, 77, -88, 95, -52, 65, -3, 10, + -38, -31, 2, -13, -16, -5, 22, 9, 52, 36, -63, 22, 50, -55, -73, 78, + -45, 56, 17, 55, -38, -16, -32, 46, -43, -18, 5, 40, -33, -54, -16, -2, + -24, 20, 10, -41, 88, -96, 62, 39, 73, -69, -3, 18, -39, -1, 6, 19, + -56, 90, -69, -24, 0, 5, 47, -36, 40, 2, -55, 73, -35, -36, -26, 46, + 5, 3, -62, 35, 27, -62, 47, 11, -79, 80, -33, 20, -28, 5, 25, -21, + -7, 67, 21, 70, -45, 10, -38, 37, 69, -21, 37, -21, -6, 66, -37, -20, + 9, -3, -44, 16, -9, 72, -37, 46, 51, -43, 90, -38, -75, 16, 1, 21, + 19, -31, -10, 12, 33, 25, 1, 41, -49, -10, -56, 87, -40, 12, -33, 34, + 26, -19, -53, -13, 20, 0, 71, -61, 26, 63, -26, 42, 27, -20, 39, -30, + 74, -80, 73, -30, 76, -21, 19, -53, 67, 61, -37, -8, -29, 19, -34, -53, + 63, -30, 11, -15, 49, -31, 19, -6, 3, -35, -20, 84, -74, 72, -70, 25, + 48, -58, 9, 30, -15, -51, -20, 8, 52, -34, 38, -78, 46, 23, -32, 59, + -56, 29, 50, 12, 27, -8, -53, -35, 20, 9, -69, 69, -11, -16, 39, -24, + -9, -10, -14, 60, -71, 21, -21, -79, 43, 47, -61, 9, 13, -4, -66, 45, + -44, -45, -7, -70, 19, 0, -6, -20, -50, 15, -42, 7, -3, -10, -28, 14, + 43, 56, 14, -45, -26, 61, -79, 66, 10, -42, 6, -31, 35, -19, -41, 64, + -3, -13, 51, -20, -3, -11, 27, -65, -4, 6, 46, -32, 19, -16, 71, -49, + -26, -12, -15, -14, -23, 9, 17, -56, 51, 24, -3, 0, -28, 67, -32, 65, + -55, 3, -13, 3, -24, 42, -32, -83, -44, 106, -54, 91, -49, 80, -74, 0, + -7, -7, 34, 47, -31, -37, 1, 51, -74, -17, -9, -40, 62, -3, 0, -52, + 51, 24, 17, -29, -23, 76, -61, 34, 47, -51, 39, -58, -2, 45, -34, 20, + 4, -60, -34, 7, -31, 79, -37, -9, -77, -16, 9, 18, 33, -50, -51, 27, + 27, -18, 87, -35, -5, -37, -32, -51, 2, 45, -109, 65, 37, -10, 32, -54, + -17, 35, -15, 15, -22, 42, -59, 50, -33, 56, 39, -90, 57, 7, 25, 27, + -61, 56, 64, -2, -8, -32, -21, 17, 15, -53, 3, -26, 35, -64, 54, -7, + -55, 49, -42, 52, -41, -1, 2, 13, -49, -60, 58, -51, 55, -45, 38, 43, + -54, 38, -24, -2, -3, 43, -68, 29, -62, 52, -24, -84, 82, -81, 7, 29, + -40, 24, -7, -22, 53, -28, 8, -25, -33, 54, -81, 92, -81, 56, 32, -46, + 29, -56, 9, -69, 30, 0, 34, 56, -28, -53, 74, -42, -40, 13, -63, 2, + 30, 17, -49, 30, 49, -43, 28, 90, -83, 47, 70, -67, 36, 45, 17, -19, + 60, 45, 9, 26, -14, -3, -10, 45, 7, -28, 66, -17, -14, 32, 52, -37, + 16, -65, -42, 6, -15, 53, -3, -39, 30, -18, 10, 47, -69, 83, -53, -60, + 62, 11, 22, 23, -17, -17, -27, 47, 18, -18, -38, -36, -20, -18, -8, 72, + -19, 30, -53, 42, 9, 44, -37, 27, -79, 70, -32, -3, 81, -61, -16, 19, + 76, -61, 18, -31, -4, 11, 21, 37, 63, -81, -31, -58, -7, 1, 73, 16, + 0, -4, 18, -47, -28, 80, 1, -68, 54, 29, -26, 81, -88, 45, 34, -28, + -40, -50, -37, 2, 33, -81, 18, 33, -66, 22, 41, 35, -42, 55, -57, 13, + -42, 64, 6, -45, 40, -64, 7, 9, 35, 43, -36, 31, 35, -29, 58, 11, + -9, -34, 0, 0, -14, 45, 61, 7, -23, 10, 64, -14, 2, -25, -49, 51, + 43, -31, 35, -8, 10, -15, -34, 6, -50, 14, -63, 55, 15, -61, 49, -61, + 5, -53, -42, 2, -29, -33, 47, -35, 52, 13, 54, -3, 19, 54, -50, 28, + 23, -49, -14, -33, 0, -23, 4, -15, 32, 32, -55, 11, 2, 52, -54, 72, + -55, 41, -14, -55, 73, -66, 7, 19, 34, -4, 17, 62, -17, 52, -45, 41, + 5, -29, 37, 23, -17, 0, -22, 14, -16, -10, 22, 11, -19, -59, 26, -24, + 86, -46, 34, 57, -15, -44, 50, -87, 60, -44, 45, -73, 91, -74, 80, -8, + 7, 49, 19, -38, -40, 58, -1, -32, -17, -31, -42, 18, 5, -41, -59, 22, + -66, 32, -8, -20, 65, -13, 29, -21, 19, 0, -13, 7, 35, -8, -29, 4, + -16, 60, 29, 43, 18, -30, -47, 74, -2, 2, 5, -57, 25, -19, 31, 27, + -51, -32, -27, -53, 13, 25, 27, -32, 0, -46, 79, 62, 43, -8, 6, -43, + -20, 57, 17, 31, -42, -52, 36, 14, 5, -10, -39, -27, -64, 63, 20, -7, + -61, 95, -32, 13, 22, -64, 37, 10, -88, 67, 21, 82, -11, 0, -67, 24, + -17, -38, -5, 8, -9, -21, -34, 34, 27, -46, 71, -61, -4, 35, -14, -18, + 44, 52, 70, -30, 52, 43, -43, -42, 74, -59, -26, -45, 1, -27, 49, -4, + -24, -46, 48, -16, 40, -11, 0, -6, 6, -39, 37, -68, -18, -9, -19, 76, + -51, 13, 7, -40, -11, 19, -17, -29, 36, -23, 0, -62, 52, -46, 62, -70, + -15, 3, 29, -91, 64, -85, 47, 4, 23, -5, 43, -18, 12, -44, 2, 15, + -32, 76, 17, 25, 3, 51, 23, -55, 0, -47, -22, -51, -20, 32, -51, 30, + -20, 37, 42, -42, 52, -43, 64, -68, 44, -5, 68, -48, 32, -42, 69, -74, + 7, 12, 9, 33, -19, 1, 42, 4, 24, -35, -42, -23, -27, -25, 70, -56, + 39, -16, 5, -8, 46, -3, 34, 18, -31, 24, 0, -8, 50, 12, 44, -5, + -40, 13, -71, 28, -38, -5, 9, 44, -48, 29, 65, -22, 42, 31, -18, 12, + -47, -39, -25, 56, 15, -48, -15, 51, 1, 79, -24, 24, 25, -48, 84, 12, + 28, -76, 11, 2, -63, -44, -2, -25, 22, -42, 16, 17, -68, 6, 10, -12, + 19, 12, -60, -63, 30, -18, 43, -67, 4, -47, 22, 49, -43, 47, -36, 16, + 24, 49, -35, 62, 22, 18, -62, 62, -82, 77, -55, -57, -50, 20, -48, 50, + -53, -34, 8, 5, 18, 1, 39, 12, 13, 35, 0, 63, 18, -63, 45, -29, + -16, -90, 51, 2, 35, -29, 17, 10, 52, -22, 12, -67, -12, -63, 58, -41, + 7, 8, 57, 50, -52, 75, -7, 13, 11, -35, 23, -47, 24, -28, -5, 37, + -21, -61, -16, -51, -55, 14, 60, -32, 15, 18, -20, 62, 18, -30, -44, 61, + 38, -35, 43, 29, -65, 31, -6, -2, 38, -44, 52, -8, 31, -32, -26, -57, + 11, 22, -34, 61, 17, -38, -30, -30, 27, -5, -19, 19, 24, -16, -13, 23, + 17, -9, -26, 38, 30, 57, -29, 64, -60, -7, -44, 39, -2, 2, 46, 7, + 55, -91, 6, 6, -39, 4, -28, 67, -57, 86, -46, 100, -70, 47, -27, 51, + -69, 48, -61, 55, -27, 15, -7, 50, -46, -42, -16, 1, -9, -27, -3, 10, + 16, -60, 53, -32, 12, 2, -29, 40, -52, 23, 33, -17, 19, -43, -37, 20, + 37, -38, -14, -20, -40, -63, 54, -68, 3, -10, 10, -18, 25, -66, -32, -22, + -24, 60, 7, 14, -10, -55, 18, 1, 27, -44, -43, -46, -22, -56, 12, 51, + -27, 62, -33, -36, 52, -65, 32, -80, 20, -66, 38, -48, -29, 40, -45, -26, + 0, 102, -70, 71, 42, 9, 14, 5, 28, -5, 39, -48, 76, -20, -5, -19, + -28, -5, 14, 67, -12, -52, 61, 36, -48, 6, 49, -23, 1, -44, 14, 29, + -77, 28, 33, -65, 13, -14, 43, -66, 77, -23, -9, 53, 32, 3, 39, -14, + 58, -18, 37, -19, -17, 24, -75, 15, -50, -52, 55, -34, -38, 44, -58, 23, + 14, 84, -17, 53, -40, -9, -43, -28, 29, -30, 70, -38, 69, 25, 14, 55, + -53, 45, -62, -5, -26, -40, 69, -38, -28, 39, -12, 32, -5, 52, -46, -54, + 38, 33, 31, 29, 49, 50, -96, 51, -52, 20, 26, -50, -6, 51, -46, 29, + -2, 2, -57, 14, 42, -48, 37, 0, 50, -50, 15, -21, 38, 17, 29, 45, + -10, 14, -3, -33, -2, 1, 47, 40, -24, 53, -33, -33, 25, -37, 74, -81, + 50, -63, 44, -27, -44, 0, -3, -53, 53, 34, 24, -5, -13, -17, -31, 1, + -5, 0, 43, -33, -24, 29, 38, -41, 20, -65, 55, -58, 32, 1, 3, -45, + 36, -49, 41, 21, -15, 27, 29, -63, 33, 23, 40, 17, 1, 58, -41, -5, + 27, -31, 0, -5, 21, -29, -33, -4, 4, 29, -16, 79, -35, 97, -37, -26, + -57, 64, 22, -6, 27, 35, -5, 91, -52, 0, -1, 46, -72, 97, -54, 96, + -81, 11, -25, 24, 39, 57, -22, -6, 2, 74, -34, 74, 26, 36, -93, 43, + -51, 43, -44, 57, -33, 49, 7, 51, -14, 27, -5, 41, 12, 6, 0, 42, + -18, -81, 17, -77, 24, -5, 7, -14, 0, 30, -50, -7, -43, -4, -29, 56, + -32, 34, -33, -12, 16, -11, -65, 24, 33, 25, -22, -6, -39, 25, 23, -25, + 54, -47, -2, 10, -42, -63, 58, -21, 44, -91, 81, -73, 6, -57, 25, -13, + 16, -37, -36, -37, 26, -55, 72, -40, 75, -64, 55, -64, 74, 6, 10, 13, + -70, -34, -33, -42, -21, 58, 32, -6, -44, 5, -45, 0, 35, -89, 71, -52, + 16, -36, -10, 33, 7, -6, -35, -15, -9, 43, -15, -42, 29, -76, 77, 19, + -36, -52, 34, -9, -46, -23, 52, -65, 57, 36, 17, -5, 50, -20, 34, -59, + 45, -71, 96, -83, 7, -35, -34, 31, -78, 83, -71, 5, 37, -61, 1, -45, + -3, -48, 65, -13, 27, -18, 15, -25, -7, -43, 63, -62, 43, -2, -19, 16, + 34, -33, 42, -20, 36, -14, -55, 51, -42, -26, -51, 74, -60, 37, -22, 6, + 11, 30, 13, -31, 26, -37, -26, 52, 18, 15, -36, 66, -53, 34, -47, 38, + 56, -33, -44, -2, 8, -74, 53, 2, -6, -58, -27, -39, 8, -17, 62, -39, + 28, 8, -45, 48, 2, 23, 35, -4, -78, 63, -43, -58, -6, -67, 72, 3, + 42, -69, 29, 35, -45, 20, -59, -28, 37, -20, 43, -49, 67, -33, 1, -39, + 69, 19, -12, 14, -43, -44, -29, 23, -36, -40, 16, -10, -9, -31, 54, 27, + -34, 0, -3, 18, -41, 4, 52, -73, -36, 24, -31, -33, -32, 35, 8, -49, + -11, 68, 25, 65, -67, 64, -62, -6, -42, 2, 47, 24, 41, 2, 16, -36, + 2, -47, 50, 31, -92, 73, 58, -65, 38, -64, -44, 38, 41, 0, 58, -67, + 5, 20, 21, 31, 27, 94, -79, 47, -36, 61, -27, -3, 49, -39, 69, -51, + 14, 9, 48, 1, 33, 32, -4, -21, 36, 34, -30, 40, -24, -47, 8, 39, + 47, 5, 48, 5, -11, 25, -20, -47, 25, 52, 18, 9, -49, 15, -12, 18, + -29, 6, 40, 31, -59, 49, -23, 83, -45, 4, -4, 32, 18, -20, 18, -14, + 72, 2, -34, 32, -27, 10, -25, 52, -38, -67, -34, 1, -22, -15, 60, -22, + 7, 40, -59, 99, 0, 18, 41, 22, -51, 9, 18, 32, 17, -20, 3, 59, + 2, 16, -56, 28, -76, 53, -45, -10, 51, -36, 25, 52, 5, 18, -31, 19, + -1, 3, 21, -42, -9, -1, 66, -27, -20, 44, -28, 24, -2, -6, 5, -21, + -51, 19, 4, -31, -13, 56, 17, -59, -20, 5, -32, -11, -28, -2, 37, 28, + -54, 0, 52, -3, -57, 61, -14, -54, 4, 56, 30, 42, -45, 12, -85, 25, + -67, 23, 18, -14, 19, -50, -15, 41, 24, 22, -66, 60, 43, 43, -11, -55, + -22, 15, 0, -16, -54, 58, -8, 21, 13, -22, -3, -66, 17, -30, -9, 54, + -67, -13, -31, 24, 4, 63, 23, -33, 2, 56, -70, 18, 5, 16, -9, 11, + 26, 20, 56, -93, 84, -52, -12, 35, -3, 31, 34, -9, 7, -1, -13, 37, + 10, 8, -45, -56, -1, 52, -24, 74, 10, -6, -10, -90, 28, 36, -4, 30, + 46, 14, -4, -17, 55, -55, -46, 20, -46, 60, 36, 16, -46, -43, -40, 55, + 3, -61, 34, -68, -46, -22, -19, 31, 0, -33, 42, 7, -23, -7, -30, 20, + -40, 57, 33, -53, 15, -42, 5, 15, -71, 6, -24, -27, 34, -7, 73, -77, + -4, 27, -76, 14, 50, -67, 31, 27, 24, -37, -23, -33, 63, -18, -13, 39, + -13, -15, 24, -11, 13, -1, -24, -36, 32, -16, 39, -67, 43, 0, -43, 10, + -46, -5, 2, -19, -16, 18, 46, -85, 53, 55, -48, 28, -31, 22, -60, -18, + -8, 65, -54, -48, -13, -16, -26, 25, 33, -3, -39, -26, 26, -64, 47, -91, + -28, 86, -29, 31, 47, -42, 69, 39, -97, 68, -65, -28, -3, -28, 53, -22, + -28, 26, -47, 70, -82, 67, -42, 52, -51, 21, -76, 48, -12, 19, 57, -67, + 85, -72, 54, 27, -25, 20, -20, 9, 38, 2, 41, -62, 68, -11, -20, -23, + -36, 17, 32, -62, 58, -31, 50, 45, -32, -47, 18, -20, 31, -11, 49, 18, + 42, 0, 17, -17, -36, 58, -23, 13, -35, -45, 86, -60, 12, -72, 23, 35, + 23, -11, -47, -5, 56, 18, -29, -80, 83, -74, 45, 39, 25, 23, 36, -14, + -5, -2, 34, 3, -45, -23, -1, 19, 35, -46, 58, -19, -11, -27, -4, -56, + 29, -64, 0, 61, -67, 24, 52, -83, 48, 27, -67, 33, 20, -66, -1, -59, + 24, -60, 32, 42, 20, -69, -3, -22, -12, -40, 42, 30, 23, -73, 48, -68, + -35, -60, 79, -42, 41, 29, 6, 34, -6, -15, -24, -41, 22, 35, -23, -49, + 38, 15, 35, -2, 84, -1, -44, 1, -8, 48, -60, -59, 46, 45, -13, -22, + -32, -51, 2, -30, -7, -28, 40, 0, 37, -48, 60, -16, -30, -50, 8, -65, + 87, -27, 36, 29, -5, 44, -31, -46, 0, 6, -6, 23, -46, -9, 28, -44, + 37, -28, -35, 50, -30, -23, 2, 64, -14, 0, -39, 12, -43, 21, 18, -56, + 86, -44, -19, 20, 65, -55, 39, 4, 10, 15, 12, 29, -11, -4, 46, 27, + -7, -81, 16, 63, -7, -34, 66, 0, -21, -41, -7, 40, 13, 0, 52, 40, + 49, -81, -10, 1, -11, -40, -48, -61, 85, 2, 32, -14, 1, 41, -54, -42, + 57, -16, 55, -93, 74, -22, 15, -40, 41, 22, 63, -9, -5, 33, -31, -20, + 16, 12, -61, -24, 41, -54, -19, 22, -45, -49, 73, -27, 68, -49, 7, 22, + 68, -43, 36, 51, -57, 51, -85, 40, 0, -39, 2, 33, 15, 32, -54, 39, + -24, 7, -34, -3, 17, -32, 61, 9, -6, 72, -81, -11, 52, 15, -51, 27, + -13, 48, -19, 25, -46, 5, 13, 57, -18, -20, 63, -9, -55, -25, -25, 25, + 50, -39, 47, -22, 39, 51, -49, -17, 27, -46, 40, -10, -1, 54, -11, 1, + 31, 37, -43, -6, 0, 67, -79, 75, -53, -34, 36, -42, -2, 45, 71, -6, + -11, 50, 18, -59, 17, 22, 42, -20, 50, -28, 58, -41, -30, -15, 0, 61, + 53, 18, -39, -18, -11, 5, -40, -3, 24, 7, 46, -34, 22, 12, 43, -57, + 54, -3, -19, -10, -6, -51, 101, -54, -10, 29, 21, 13, 46, -87, 10, 28, + 28, 28, 55, -23, 50, -61, 76, -61, 20, 36, 3, -28, 45, 14, 14, 49, + -46, -45, -15, 10, -30, -32, 51, -19, 69, -33, -36, 47, -20, 46, 22, -55, + 47, 2, 19, -39, 54, -14, -1, -3, -19, -36, 38, 35, 16, -12, 0, 28, + -38, 56, -35, 26, -110, 80, -56, -32, -10, -22, 47, -5, -42, 9, -13, 5, + 49, 35, 20, -10, -48, 19, -66, -4, 18, 74, -41, -31, -11, 54, -76, -78, + 54, 1, 19, 57, -41, 58, 52, 6, -65, 0, 46, -48, -18, -19, 80, -42, + -5, 33, -14, 43, -26, 15, 61, -72, 62, -41, -15, -5, -31, 12, -51, 46, + 1, 24, 43, -38, 29, 32, 20, 57, -31, 43, -61, 10, -40, -35, 26, 10, + -64, 20, -50, -4, -32, -16, -14, 38, -33, 69, -42, 32, -57, -25, 21, -46, + 12, -4, 7, -40, 90, -46, -33, -45, 20, -74, 42, 42, -40, 4, 29, -39, + 26, -17, 19, 30, 64, -89, 61, -71, 82, -44, -51, -12, 38, 27, 7, -50, + -71, 60, -14, -75, 37, -40, -7, 12, 23, -30, -36, 32, -38, 19, -44, -27, + -37, 41, -32, 41, -50, -52, 22, 58, -66, 69, -54, 74, -17, 24, -86, 16, + 14, -38, 13, 15, -10, 48, -73, -23, 50, -24, -29, 2, 96, -53, 30, -32, + -74, 18, 38, -49, 29, 3, -52, 63, -35, -32, 22, 52, -85, 51, -31, 36, + -65, -34, -20, 66, -48, 12, -63, 68, 13, -29, -31, 13, -26, 35, 52, -32, + -1, 16, -27, -28, -13, 45, -60, 10, 39, -58, 16, 10, 41, -84, 27, -43, + -26, 79, -48, -7, -17, -1, -41, 63, -55, 33, -10, 53, -40, -18, -59, 65, + -98, 49, -63, 19, -33, -33, 68, -57, 14, 11, 57, -43, -6, -7, -19, 25, + -25, 34, -43, 37, 54, -19, 32, 2, -17, -5, -48, 5, 3, -3, -13, -12, + -49, -15, 25, -11, 35, 23, 25, -17, -26, -16, 26, 76, -51, -9, 76, 52, + -45, -42, 36, -98, 58, -50, -40, 38, -19, 26, -46, 83, -51, 43, -19, 24, + -29, -23, 68, -75, -20, -3, -36, 14, -45, -31, 30, -47, 11, -31, 71, -8, + 6, -13, 22, -41, 31, -86, -20, -49, 25, 33, -31, 50, -21, 53, -57, 37, + -24, -13, 67, -21, 89, -28, 28, 25, -3, -5, -4, -42, 62, 54, 1, -2, + 18, -40, 59, -16, -10, -32, 7, 47, 13, 30, 26, -51, 15, -21, -42, 46, + -47, 53, -78, -13, -57, 87, -47, 49, -55, 1, 64, -20, -2, -36, -1, 45, + 20, 5, -67, 73, 10, 6, 13, -20, -7, -16, 27, 49, -8, 33, -6, 50, + 7, 19, -9, -69, 45, -2, 46, -99, 66, 8, -25, 4, -58, 72, -49, 38, + 6, -20, 6, -63, 71, -67, 65, -28, 12, -6, -17, -37, -51, 77, -86, 66, + 8, -23, 53, -56, 41, 36, -62, 44, -19, 10, -48, 34, 8, 6, -35, 51, + 29, 76, -75, 51, -76, 91, -50, 40, -54, 2, 29, 5, -20, 44, -76, 44, + -48, -32, 17, 50, -28, -67, 68, 13, -5, -40, -19, 33, -11, 46, 19, -4, + 16, 36, -30, 50, 28, -17, 30, -86, 91, -41, 15, -69, 74, 11, 49, 20, + 39, -4, 84, -61, 68, 13, 25, -45, 76, -68, -30, -6, 54, 1, 21, 5, + 50, -74, 20, -32, 1, -49, 29, 13, 15, -55, 96, -10, 19, 35, -20, 25, + 12, -38, 23, -72, 39, -27, -15, 17, 5, 15, -51, -12, 10, -52, -46, -4, + -39, 91, -80, 112, -58, 47, 3, 16, 4, -5, -28, 3, -12, 13, -3, -58, + 98, -50, -21, 89, -20, 30, 9, 59, -34, 71, -22, 50, 39, 44, -54, -61, + 23, -41, -50, 70, 31, 46, 28, 13, 2, -32, -19, 27, -4, -30, 40, 6, + 11, -26, 32, -48, -58, -25, 41, -34, -9, -2, -28, -4, -31, -11, -32, 33, + -22, -28, 39, -32, -39, 36, 44, -59, 28, -40, -7, 4, 62, -11, -11, 13, + 0, 51, 0, 41, 3, 14, -70, 21, 82, -66, 46, -49, -11, 46, 23, 18, + -45, 12, 79, -65, -53, 34, -26, 84, -53, 95, -22, -50, -24, -7, -21, 14, + 8, -32, 23, 77, 0, 10, 9, 8, 12, -44, 28, -32, 14, -6, 37, -6, + -55, 36, 28, -2, 18, -28, -35, 48, -58, 13, 56, 29, -18, -15, 5, 11, + -3, -73, 68, -34, 13, -35, 53, -43, 62, -18, 17, -30, -52, -8, 52, -41, + -27, -11, 8, 17, 55, -86, 73, -70, 64, 2, 19, -32, -3, -68, 77, 26, + -37, 47, 19, 24, -43, 80, -57, -12, 2, 59, 12, -11, -38, -24, 35, -41, + 27, -9, -17, 21, -35, 50, 18, -6, -4, -33, -2, 54, -37, -33, -16, -57, + 42, -17, -31, 0, -40, -23, -16, 25, -96, 102, -48, 1, -55, 43, -13, -48, + -29, 37, 34, 44, 32, 22, -32, -3, 46, 13, -47, -58, 21, -35, -10, 12, + 56, -11, 19, 34, 36, -52, 4, 70, -57, 50, -27, 34, 0, 16, 74, -42, + 16, 32, -54, -21, -8, -29, 36, -48, 28, 55, -38, 24, -9, 44, -37, 5, + 1, -24, -17, -35, -25, 46, -63, -6, -8, -29, -19, -31, -50, -48, 22, 45, + 55, 32, -6, -19, -60, -36, -10, 51, -30, -30, 17, -13, 48, 3, 22, -55, + 84, -64, 52, -33, 62, 8, 20, -7, -51, 59, 24, 6, -9, -14, -55, 64, + 3, 5, -5, 41, 33, -78, 10, 60, -38, -2, 17, -43, -28, 4, 33, -47, + 8, -48, 14, -6, -40, -15, 82, -59, -58, 13, 8, -2, 31, 4, -39, 14, + -50, 53, -77, 60, 34, 32, 10, -72, -13, -64, -18, 28, 12, 57, -24, 49, + -56, -35, -18, -45, 10, -50, 0, 12, 0, 27, 47, -41, 10, -52, 30, -12, + 28, 15, -62, -10, -19, 49, -7, 11, 11, 34, -65, -40, 16, 44, -53, 33, + 35, 34, -31, -18, 41, -11, 30, -35, -38, 13, -12, 30, 61, -3, -10, 21, + -52, -10, 39, -9, -20, 36, -1, -1, -26, -15, -11, -32, 2, 64, -64, -19, + -3, -36, 32, -59, 49, -37, 37, -13, -19, -36, -56, 68, -22, 0, -6, -16, + 47, -31, -21, -32, 39, -36, 0, -57, 67, 40, -49, -39, 17, -11, 11, 44, + -15, -27, -4, 7, 41, 25, -9, 50, 47, -44, 51, -68, 90, -47, 11, 43, + 12, 14, -66, -15, -56, -1, 25, -45, -22, 10, -13, 62, -7, 18, 15, -46, + -73, 28, -29, 29, -77, 52, 6, -86, 10, 6, -37, -28, 14, 35, -54, -5, + 27, -38, 53, 15, 59, -46, 70, -72, 61, -95, 58, 12, -64, 4, 55, -47, + -10, -3, 46, 6, -7, 0, 2, 7, 25, 38, -52, 56, 44, 31, -52, 1, + -83, -24, -14, 66, 3, -8, 69, -45, -7, 18, 27, -18, -67, 26, -1, 12, + -39, 19, -51, 9, 0, 7, -41, 48, 14, 2, -5, -4, -42, 50, 65, -84, + 59, -15, -43, -16, 4, 74, 10, -71, 39, 0, -21, 74, 3, -44, 17, 30, + 0, 29, -49, 18, 6, -1, -74, 58, 59, -4, -10, -50, -16, -5, 0, -20, + 41, -62, 27, -50, -17, -29, -14, 60, 6, 33, 65, -25, -52, -14, 34, -27, + 50, 43, 50, 2, -52, 65, -42, -26, 2, 2, -79, 48, 24, -18, -24, 13, + -28, 1, 39, 34, 64, -75, 23, -34, 47, -35, 20, 52, 18, -11, -2, 36, + -38, -17, -32, 38, -38, -13, 10, 27, 19, -9, 18, 15, -72, -41, -32, 8, + 13, 72, -59, 20, -37, -35, -4, -47, 25, 38, 66, 15, -1, 0, -16, 28, + 40, -26, -23, -18, 12, 43, -62, 9, -10, 60, -38, 2, 40, 1, -18, 34, + -31, 54, -10, -1, 11, -15, 13, 8, -45, -22, 51, 15, 75, -66, 11, 27, + -37, 78, -27, -52, 14, -58, 12, -44, -60, 50, 13, 48, -59, -25, 16, 15, + -83, 90, -56, 90, -8, 34, -56, 83, -63, 66, -14, -73, 54, -1, 13, -16, + -4, 57, -25, -49, 62, 16, -36, 77, 28, -45, 56, 40, -22, -12, 22, 32, + -31, 23, -38, 18, -87, 14, -27, -15, -3, 60, -57, -11, 70, -77, 44, -50, + 73, -56, -7, 31, -25, -38, 52, 30, -27, 13, 68, -56, 3, -16, 48, 1, + 85, -50, 37, -76, 59, -76, -14, -18, 63, -16, 46, 10, 40, 25, -74, 55, + -59, 19, 24, -25, 42, 20, -20, -31, 0, -49, -13, 44, 38, -75, 15, 10, + -24, -21, 48, -33, 18, -80, 25, -20, 20, -4, 46, -48, -21, 69, -63, -14, + -14, 22, 14, -26, -24, 61, -5, 27, -104, 45, 1, 13, 61, -39, -9, 2, + 1, 77, -9, 89, -59, 24, -37, 8, -1, 30, -69, -32, 81, -66, 16, -31, + 55, -103, 43, -66, 62, 22, 38, -67, 55, -26, 42, 15, -8, 54, -43, -26, + 65, 8, -24, -62, -35, 10, 12, 41, -46, 2, 33, -70, 32, -48, 4, -11, + -46, 72, -6, -59, 72, -37, -57, 29, -5, 33, -14, -30, 69, 38, 28, 32, + 14, -88, 70, 11, 14, 31, -18, 54, -33, -7, -41, -65, -1, 1, -14, 18, + -28, 52, 11, -6, -51, 57, -48, 59, 13, 44, -21, 20, 2, -60, 20, -7, + -21, 0, -27, 24, 47, -9, 19, -46, 85, 11, -44, 21, -62, 49, -60, 8, + 34, -63, -28, 59, 47, -35, 47, 41, -30, -37, -40, 37, -37, 84, -73, 11, + -19, -23, -24, -31, -74, 34, 15, -37, 11, 13, 11, 19, -35, 16, 18, 35, + 52, -102, 55, 27, -57, 48, -4, -21, -65, 93, -55, -33, 48, 14, -60, -32, + 45, -35, 16, 17, 60, 23, 38, -28, 4, -24, 19, 27, -67, 46, 0, 36, + 3, 36, 4, 48, 5, -19, -48, 9, -60, 32, -57, 5, -12, -11, -40, 51, + -63, 31, 4, -29, 38, 15, 40, 10, -40, -10, -67, -13, -104, 72, -46, 10, + -9, 29, 18, -19, -26, -60, 55, -20, 13, 64, -32, 16, -88, 71, -15, -13, + 49, -41, 39, 11, -49, 20, 59, -82, 42, -72, -28, 51, -58, 31, -15, 36, + 30, -43, 43, 27, -40, 46, -65, 39, 42, 20, -21, 24, -51, 66, -18, 8, + -15, -40, -41, -44, 67, -44, 14, 28, -49, 63, 5, -10, -19, 54, -43, 27, + -87, 93, -76, -2, 37, -80, 53, -21, 32, -29, -19, -9, -24, 27, 14, 35, + -110, 85, -70, 115, -64, 43, -6, -49, 35, 36, -9, -30, 37, 3, -13, 43, + 9, -38, 66, -13, 20, 23, 35, -19, -25, -39, 32, 7, -80, 16, -32, -49, + 8, 35, -79, 37, -58, -17, 43, 44, -46, 17, -49, 88, 43, -9, 21, 1, + -43, 2, 34, 39, -11, 25, -28, 24, -61, -43, -2, -27, 46, 35, -17, 21, + -33, 33, -47, 15, -89, 75, -46, 8, -52, -2, -14, 9, -40, 43, 57, -14, + -24, 75, -62, 26, -14, -14, -16, -3, -5, 54, 30, -25, 28, -49, 60, 29, + 0, 57, -14, 64, 28, 38, -41, -13, -34, -23, -20, -9, -3, -18, 2, 6, + -53, 65, -2, 9, -9, -28, -29, 53, -15, -14, -38, 45, -15, -81, 84, -37, + 63, -43, -51, 52, -62, -27, 42, -31, 52, -32, -5, 33, 10, -40, 6, 16, + -67, -23, -6, -50, 8, 2, 64, -7, 80, -43, 39, -9, -28, -22, 62, -52, + 13, 31, 37, 35, -59, 41, -61, -34, -16, 38, 62, 22, 63, -20, 4, 58, + 14, 33, -63, -9, 53, -37, 51, -12, -16, -18, 60, -8, 71, -18, 20, -24, + -12, 31, -44, 58, 13, -46, 25, 25, 33, 53, 20, 16, -7, -35, 73, -22, + -29, -53, 0, 40, -66, 24, -28, 15, -65, 6, -63, 72, 7, -11, -24, 7, + -14, 73, -31, 97, -67, -5, 54, -43, -19, 10, -58, 42, 2, 54, -37, -61, + 66, -9, 73, -58, 31, -15, 28, 22, -8, 21, 39, -29, 14, -40, 32, -16, + 86, -92, 47, -89, 25, 14, -66, 78, -73, -48, 16, 54, -92, 38, 47, -94, + 7, 29, -56, 0, -74, 22, 22, 5, 20, -2, -4, 21, 27, 7, 26, 9, + 8, -35, 59, -57, 54, 43, -73, -79, 84, -30, 64, -77, -20, 62, -73, 53, + -15, -19, -76, 12, -74, 85, -85, 60, -15, 48, 14, -61, -19, -38, 41, -72, + 72, 0, -2, 65, -9, -48, 71, -60, 51, 16, 2, 0, 11, -9, -44, -62, + 58, -53, 18, 62, -62, 37, 21, 12, 22, -37, 52, -60, 34, -12, -70, 5, + 53, -51, 5, -69, 20, -47, 17, 7, 70, 12, 42, -19, 5, -33, 19, -46, + 32, -17, -64, 71, -88, 56, -21, 36, -46, -24, 25, 15, -7, 63, -37, 13, + -45, 73, 57, -46, 2, -33, 19, -34, -43, 18, 17, -46, 52, -22, 0, -2, + 25, 27, -25, 41, -60, 46, -57, -6, -52, -7, -13, 38, 49, 45, -41, -33, + 59, -51, -23, -31, 20, 59, -31, 37, 41, -48, -42, 34, -53, 44, -21, -53, + -31, 14, 52, 6, 0, -44, 33, -24, -5, -12, -47, -35, -66, 16, -36, 65, + -10, -2, -34, -19, 26, -8, 44, -62, 2, -37, -72, 53, 43, -6, -50, -44, + 68, 20, 36, -59, 91, -6, 55, -57, 90, -62, 46, -70, 26, 3, 66, -23, + 14, -76, 59, -69, 21, 21, -14, -41, 64, 1, -37, 14, 14, -105, 67, 24, + 4, 1, -60, 60, -36, -11, -26, -12, -40, 14, -60, 46, -20, -12, -33, 64, + -64, 60, 27, 27, -1, -20, 73, -64, 38, 57, -73, -3, 75, -64, 7, 58, + 0, 1, 61, -68, 61, 28, -48, -42, 22, -12, 44, 2, -4, -61, 4, -14, + 33, 5, -10, -15, 43, -66, 55, 55, -68, 39, -10, 25, -18, -30, -23, 38, + 30, 29, 26, 30, 69, -88, 84, -48, -8, -10, 20, 48, 44, 0, 14, 31, + -38, -24, -17, -47, -11, 74, -84, 66, 13, -4, -18, -62, 55, -49, 70, 64, + -45, 25, 23, -77, 56, -16, -32, -16, -17, -8, -27, -50, 55, 14, 54, -33, + -71, 74, -21, 37, 50, -14, -6, 44, -88, 6, 0, 74, -68, 49, 35, -16, + -11, 7, -8, -27, 86, -16, 20, -53, 41, 49, -30, 38, 33, -85, 54, 28, + -40, -45, -13, -53, 39, 47, 23, 14, 1, 31, -5, 14, 23, -46, 53, -46, + 36, -65, 31, 12, 61, -46, 57, 6, 10, -19, 9, -59, -7, -43, 76, -25, + -8, -38, 29, -43, -45, -25, 25, 6, -15, -1, 2, -61, 63, -50, -5, 25, + 28, -47, -20, -23, 41, -23, 60, 26, -7, -3, 49, 48, 32, 13, 2, -51, + 42, 52, 10, -32, 8, -60, 46, 13, 19, -20, 81, -67, -3, -25, 21, 46, + -41, 28, -103, 90, -91, -45, 25, -11, -15, 35, 8, -21, -41, 25, -45, -31, + 29, 18, -30, -31, 73, -57, 83, -24, -9, 27, -28, 13, 44, 58, -1, -28, + 29, 22, -27, 24, 42, -26, 31, -29, 36, 40, -31, 64, 3, 22, -42, -23, + -25, -9, -39, 34, -9, -9, -47, 48, 36, -9, 31, 55, -16, -10, -3, -61, + 35, -6, -49, 51, -7, -36, 52, 0, -28, -51, -38, 0, 6, -8, 49, 2, + 10, -63, 53, -21, -5, 66, -43, 10, -7, 48, -6, -55, -33, 53, -17, -54, + -15, -7, 57, -52, -62, 40, -21, -28, 31, 1, 36, -35, -79, 81, -95, 74, + -39, 67, -22, 60, 23, 12, -10, -44, -10, 55, -35, 57, 2, 55, -69, -37, + -20, 59, -30, -4, 5, 9, 16, -12, 17, -6, 48, 44, -58, 13, -31, 2, + 4, 22, -54, -35, -5, 8, -55, 51, -34, 13, 38, -85, -14, 35, -74, 13, + 33, -38, 52, -9, -58, -20, 34, -14, 25, -22, -40, -62, -27, 42, -36, 5, + -3, 29, 37, 52, -65, -52, 44, -49, 20, -11, -9, -46, 8, 8, 41, -54, + 40, -8, 33, -49, -54, 8, -7, 34, -70, 56, 33, -29, 38, 16, -93, 57, + 29, 36, -7, 51, 52, 19, -19, 50, -57, 22, 29, 33, -56, 6, 75, -50, + -30, 52, 0, 8, -7, -48, -47, -45, 82, -80, 14, -26, -41, 16, -15, -5, + -5, -63, -20, 13, 11, 21, -62, 38, -51, -31, 19, -13, 13, 2, -1, 34, + -67, 57, 76, -78, 86, -34, 14, 54, -48, -7, -8, 3, 53, 1, 37, -20, + 7, 3, 62, -19, -37, -38, -32, 5, -70, 20, 21, 0, -77, -10, -28, -20, + -13, -14, 26, -22, 5, -28, -28, 18, -39, -5, -40, -9, -76, 33, 17, 42, + 0, 36, -41, 44, 8, -3, -15, 30, -51, -14, -37, -64, 2, 6, -19, 63, + -7, 34, -30, -66, 46, -28, 27, -59, 63, 54, 0, 52, -3, -49, 23, -64, + 44, 80, -83, 21, -25, -8, -33, -13, -7, -26, -15, 73, 36, -5, 30, 37, + 9, -34, -56, 17, 0, 27, 23, -38, 28, -19, -34, -8, 71, -75, 20, 10, + -75, 30, -42, 4, -78, -38, 46, -1, 22, -55, -6, 30, -59, -31, 0, 51, + -17, 21, -48, 56, -53, 87, -90, 74, -44, 3, -47, -66, 18, 20, 12, 19, + -17, 9, 51, 20, -55, 13, 40, -3, 41, -23, -32, 58, 4, 45, 1, 47, + -34, 24, 12, 0, 10, 29, -34, 65, -59, 37, 63, 57, -21, 9, -30, 67, + -18, -40, -17, -12, 66, 0, -34, 45, 4, -7, 43, -21, 24, -27, -59, 36, + 26, 18, -26, 12, 11, 35, -52, 47, -3, -16, -4, 66, -68, -62, 80, -27, + -36, -40, 69, -79, 23, -48, -50, -38, 39, 17, -21, -26, 66, 0, -79, 64, + -13, -15, 1, -24, 0, 55, 48, 17, -59, 44, 39, -29, 59, -19, 44, -85, + 57, 40, -15, -21, 65, -54, 44, -16, 65, -21, -59, 50, 16, -58, 38, -60, + 61, -52, -46, 39, 29, -71, 41, -62, 87, -25, 3, -7, 19, -68, 16, 3, + 9, 17, -77, 22, 63, 32, -23, 37, 71, -31, 4, -5, 44, -15, 68, -30, + 61, -42, -18, 21, -44, 54, -3, 33, 19, 54, -29, 23, 46, 21, -43, 3, + 0, -21, -21, 6, -54, 46, -21, 0, -8, -42, 84, 27, 2, 50, -36, -46, + 38, -53, 52, 48, 27, -59, 28, 44, -29, -40, 31, -76, 41, 13, 28, 10, + -24, -102, 84, -23, 22, -30, 34, 36, -7, 21, 24, -76, 8, 15, -18, -55, + 48, -26, 17, 40, 7, -59, 33, 33, -36, -31, 61, -41, -39, 43, 9, 2, + 51, 41, -18, -11, 68, 78, -46, -9, 28, 40, 12, -16, -6, 63, 17, -21, + -1, -23, -4, 38, -42, -59, 46, -16, 7, 20, 51, 68, -33, 19, -11, -40, + 0, 29, -9, -34, 43, 3, -16, -22, 22, -23, 19, 36, -71, -16, -16, -32, + -37, 24, -59, 9, -20, 54, -37, -28, 34, -58, -33, -61, 64, 24, -4, -29, + -8, 52, 0, -58, 30, -57, 15, -7, -50, 56, -66, 15, -20, 32, 41, 24, + -79, 50, -69, 36, 36, -43, 71, -48, 28, -26, 29, -38, 60, 45, -6, -15, + 86, -43, -8, 45, -52, 58, 74, -19, 64, -92, 63, -67, 0, 1, 25, 11, + -13, 49, -8, 1, -37, -41, 5, 26, 30, -21, -44, 17, -72, 16, -3, 34, + -4, -41, -11, 53, -71, 43, -26, 41, 12, -31, 110, -54, 46, -9, 61, -37, + 9, -19, -4, 3, -25, 63, -25, -28, -58, -17, 27, -57, 74, 3, -44, 34, + -13, 13, 30, 10, -96, 70, -24, 24, -63, 1, 23, 46, -79, 59, -72, 41, + -74, 32, -16, 44, -9, -16, -1, -30, 40, -57, 35, 13, -38, 22, -46, 53, + -75, 86, 0, -29, 93, -86, 82, -72, 8, 74, -88, -1, -2, -22, -19, 37, + -1, -12, -22, -69, 41, 44, -36, 12, -45, -21, -1, -16, 25, 16, -24, -48, + 47, 71, -43, 3, 52, -31, 34, -35, -51, 76, -95, 88, -47, -14, -8, 59, + -1, 26, -85, 41, -23, 11, -34, -7, 23, 22, 11, 11, 56, -45, 26, -14, + -49, -51, -41, 59, -67, -64, -1, 28, -50, 3, -18, 1, 11, -5, -41, 28, + -12, 9, -34, 34, 49, 34, -32, 36, -15, -24, -22, -71, 62, -42, 30, 36, + -36, -68, 51, 3, -75, 51, 56, -55, -5, -30, -32, 13, 31, 31, -62, 80, + 36, -34, 42, 1, 60, -63, 18, -17, 8, 33, 13, 11, -79, 0, -17, -13, + -10, 29, 8, -17, 34, 2, 16, -69, 38, 8, 35, -28, 7, -68, -28, -30, + -30, 33, 38, -36, -22, -7, -31, 39, -36, -15, -10, -19, 20, -33, 27, -53, + -19, -40, 39, -63, 66, -52, -37, 33, -93, 56, 16, -26, 69, -78, 35, -32, + -33, 9, -14, -28, 68, 60, -44, -26, -25, 1, -13, 37, 6, 2, 21, 8, + 39, -42, 54, 2, 0, -51, -15, -3, -52, -1, -53, -21, -39, 41, -60, -7, + 7, 26, 22, -7, 17, 5, -16, 38, 76, 36, -25, 4, -29, -47, 26, -19, + 0, -9, -87, 71, 0, -23, -2, -15, 4, 15, -49, 28, -34, 28, -45, 45, + -16, 44, -53, -54, 21, 6, 46, 0, -27, -16, -52, 40, -25, -21, 48, 0, + 64, -98, 40, -44, 4, -19, 16, 61, 35, -70, 40, 22, 55, -70, 71, -65, + 39, 47, -11, -2, -3, -74, 60, 37, -26, 79, 9, 36, -44, -5, 8, -13, + 22, -90, -22, 48, -71, -45, 24, 46, -42, -6, 46, -58, 54, 19, -24, -18, + -17, 17, 88, -80, 53, 9, 52, -50, 34, -47, 49, -47, -37, -12, -21, 59, + -22, 58, 47, -32, 78, 52, -13, -39, 19, -38, 3, -35, 18, 5, 21, -64, + 34, 11, -18, 14, -35, -80, 61, -61, 22, 19, 3, 78, -58, -60, 36, -27, + 55, 32, -97, 68, 10, -13, -72, 57, 2, 4, 25, 48, -85, -14, 73, -59, + 49, -67, 48, -34, -42, 51, -34, 42, -33, 30, 16, -22, 63, 38, -47, 61, + -6, -43, 28, 34, -46, 28, 0, 56, -30, 6, 39, -25, 58, 26, 17, 14, + 54, -36, 42, -52, 26, -17, 48, 23, -16, 40, -7, -12, -30, 12, -48, 58, + -6, 44, 3, -54, 46, -23, -21, -10, 74, 5, -12, 24, 0, 0, 18, 28, + -34, 39, 31, 19, -55, 21, -28, 37, -25, 34, 9, -36, 33, 27, -68, -4, + -19, 18, -24, -35, 67, 10, 14, 47, 18, -1, 50, -47, 62, -32, 43, 46, + -71, 13, -36, -25, -26, 7, 29, -32, -66, -50, 28, 44, 14, 59, -24, -7, + -7, 16, 46, -30, -19, 28, -13, 24, 49, -65, 77, 16, -7, 59, -7, 23, + -32, 35, 59, 49, -30, 24, -83, 9, 37, 50, -10, -7, 9, -7, 33, -61, + -24, 26, 1, 25, -7, -50, -5, -67, -51, 10, 13, 0, -30, 16, -41, 65, + -40, -13, 13, 22, 41, 32, -66, 18, -27, -22, -27, -67, 67, 46, -31, -12, + 14, 63, 49, -3, 83, -25, 80, -78, 53, 16, 25, -55, -12, -57, 80, 9, + 6, -9, -32, -33, 53, -81, 54, -28, 10, 50, -26, 9, 41, 21, 25, -56, + 11, 5, -59, 33, -54, -55, 19, 19, 34, -18, 73, -44, 4, 17, -12, 62, + -88, 47, -38, -50, 71, 52, -22, 12, -3, 29, -84, 10, 29, 43, 20, -43, + -18, 19, 41, 2, -70, 50, -8, 69, -39, -28, 48, -43, 51, -13, -39, 39, + -50, -21, 70, -53, 6, -12, 4, 35, -46, 5, -55, 47, -36, -18, -44, 48, + -40, -11, 17, -30, 25, 47, -66, 48, -56, -41, 13, -65, -1, -11, 27, 34, + -81, 42, 39, -18, -8, 29, -54, 14, -46, 29, -6, 2, 60, -5, 19, -31, + 1, 25, -3, 3, 16, 20, 16, -27, -91, 71, -70, 21, 32, -57, -15, 45, + -56, 9, -51, 8, -25, -28, 48, -87, 58, -91, 25, 24, 11, -96, 105, -56, + 71, -41, 21, 41, -42, -67, 66, -67, -16, -55, 45, 34, -50, -18, 20, -37, + 52, 18, 1, 86, -49, 33, -90, 82, 9, 30, 16, -83, 17, -17, -5, 32, + 0, 35, -54, 63, -52, 32, -38, -12, 40, -47, 6, -78, 30, -75, 22, -49, + 76, -82, -29, -76, 49, -50, 104, -41, -55, 18, -35, 0, 34, -8, -25, 58, + -1, 13, 4, 9, -20, 40, 23, 56, 61, -76, 72, -45, -3, -8, 40, -44, + 20, -57, -1, -68, -9, -5, -1, -31, 52, 29, -60, 100, -82, -36, 12, 10, + -58, -2, -57, -15, -28, -33, -26, -31, 0, -19, -7, 46, 46, -4, -43, -42, + -35, 14, -31, 21, 17, 25, -68, 40, -54, -39, 18, -40, 17, -53, 34, 32, + -15, 52, -87, 62, -35, -4, 54, -7, 33, -25, -14, 1, 1, -22, -4, 0, + 49, 31, -4, 41, -57, -14, -12, -2, 15, 45, 25, -20, -39, -43, 21, 42, + -45, 44, -3, 19, 0, 30, -37, -25, -23, 23, -23, 15, 18, 32, -50, 28, + 10, 45, -76, 78, -69, 19, -32, 58, -46, 32, 45, -6, -39, 50, 0, 14, + 58, -26, -4, -41, 27, -37, -12, 22, 40, 63, -32, 46, 32, 18, -38, 0, + -7, 14, -55, 32, -43, 17, -18, 24, 8, 8, -65, 35, -52, 2, 10, -45, + 36, 9, -24, -20, 22, -2, -35, 51, 19, -1, 17, -6, -34, 47, 9, 8, + -18, 62, -32, 22, 2, 12, 32, 57, 22, 63, -1, -60, 3, 74, -83, -17, + 21, -15, -7, 19, -44, 96, -28, 40, -22, 89, -103, 54, 31, 2, 21, -32, + -11, 4, 8, -64, 27, -27, 77, -52, 2, 8, -53, 73, -6, -4, -37, -44, + 38, -10, 0, 15, 6, -52, 51, -30, -40, 41, -81, 97, -56, 81, -72, 66, + -52, 44, 56, 50, -63, 80, -81, 52, -5, 12, -3, 53, -15, 22, -66, -2, + -69, 45, -52, 54, -88, 41, 33, -89, -18, 96, -84, 61, 30, -66, 61, -40, + 66, 20, 30, 57, 18, -37, 13, 59, -8, -55, 86, -62, 31, 66, 5, 29, + 67, -59, 53, 51, -48, 38, 59, -13, 37, -62, 23, -32, -41, -10, -5, 51, + 54, -44, 78, -9, -29, -2, -3, 44, 43, -37, 78, -27, -8, 47, -23, -41, + 6, 25, 70, -9, -14, 62, -60, -30, -65, 60, -1, -33, 50, 14, -47, 77, + -77, -20, 0, -10, 34, 39, -28, 14, -48, -48, 9, -33, 34, 51, -3, -21, + 33, 0, -37, -31, -2, -2, -5, 42, -37, 14, 23, -45, -31, 36, 57, -55, + 47, -62, 47, -18, 53, 43, -28, -74, 82, 10, -52, 30, -4, 68, -67, -23, + -1, -7, -22, 72, -9, 10, 9, 12, -53, -51, 25, -26, -73, -11, 29, -55, + 52, -52, 17, 17, -40, 51, 27, -53, 29, -42, 60, 67, -71, 105, -60, 65, + -37, -15, 0, 20, 3, 51, -74, 60, -83, 66, -41, -2, -9, 63, -88, 83, + -63, 38, -7, -35, 27, -32, 3, -83, -14, -68, 52, 5, -44, 20, 58, -25, + -16, -9, 52, -48, 12, -55, -51, 3, 68, -57, 52, -30, -55, 67, -49, -12, + 20, 16, -22, 16, -74, 80, -34, 7, -30, -1, 64, -19, -5, 35, 9, 31, + -65, 6, 45, -6, 11, 59, -74, 63, -26, 50, 56, -50, 57, -95, 36, -21, + 51, -49, -69, 74, -31, 4, -13, -41, 56, -87, 34, -78, 51, -46, 64, 47, + 28, 10, 0, 15, 29, 24, -57, 75, 7, -65, -16, 5, -61, 82, -42, -35, + -26, -53, 73, -62, 20, -48, 31, -50, -23, -28, 8, -36, 23, -38, -59, 21, + -56, 69, -78, 41, -16, -30, -23, 61, -42, 67, -30, 4, 54, -6, -6, 21, + -38, 4, -24, -35, 30, 39, 2, -46, -54, 79, -98, 47, -13, -22, -30, 3, + 36, -65, -95, 61, -46, -4, 27, 18, 28, -28, -12, -11, -17, 41, -43, -38, + 27, -6, -20, 5, -33, 15, -30, -10, 51, -24, 35, 31, 12, -61, 2, -8, + -30, 14, -2, -8, 68, -39, -18, -2, -3, -6, 61, -45, 54, -47, -56, 49, + -10, 22, -58, 51, -59, 18, -69, 92, -78, -49, 59, -4, -52, -58, 87, -48, + 55, -45, 24, -12, -66, 37, -79, 44, -28, 54, -25, 26, 35, 18, 30, -20, + -24, 37, 47, -15, 24, -71, 5, 47, -34, 9, -21, -58, 33, -60, 9, -39, + -45, 43, 8, -38, -11, 3, 24, -1, 18, -23, 20, 11, -41, -35, 56, 0, + -29, 15, 40, -7, -2, -9, -11, 60, 36, -4, 32, -28, -6, 40, -36, 9, + 61, -58, 76, -54, 52, 1, 71, -34, -46, -4, 49, -27, 24, -26, 34, -21, + 48, -60, 75, -19, 58, -54, -11, 18, 29, -21, -36, -32, -47, -8, 3, 37, + 30, 19, -84, 12, -50, 22, 30, -29, -20, -11, -42, 0, 0, 59, 6, 14, + -33, 80, -37, -33, -39, 8, 38, 31, -13, 77, 27, 2, 5, -1, -32, -68, + 45, -54, 18, -60, -23, -5, 4, -46, 9, 29, 52, -17, 13, 30, -72, 83, + 13, -5, -58, 11, -14, 91, -57, 71, 30, 58, 0, 4, -35, 68, 10, -13, + -18, -37, 27, -1, -11, 21, 17, -59, 19, 4, -24, 67, -59, 2, 16, -2, + 18, 60, -33, -24, 43, -31, -27, 55, -34, -2, 52, -42, -8, 2, 31, 3, + -35, 58, 62, 15, 15, 15, 8, 56, -43, -9, 63, -40, 60, -11, 44, 10, + -15, 65, 35, -27, -25, 41, 53, -6, -35, 40, 3, 14, -53, 20, -7, 34, + -28, -9, -17, 7, 26, -35, 14, 39, -17, 16, -59, 1, -28, -46, 75, -25, + -85, 17, 48, -59, -13, 45, 8, 8, 29, -12, -13, 26, 2, 63, -79, 34, + -76, 42, -34, 49, 29, 40, 48, -42, -11, 39, 15, -19, 12, 4, -75, 80, + -77, 78, -87, 14, 7, 35, -15, -8, -58, 77, -59, 23, 34, 9, -36, 42, + 63, -41, 12, 36, -4, -25, 12, 12, -14, 32, -36, -17, 100, -56, -41, -34, + -9, -25, -1, 2, 30, 44, -42, -60, 57, -77, -1, 11, -8, 15, -13, -5, + -35, 3, -58, 19, -36, 46, -71, 61, -15, -8, -60, -13, -2, -31, -13, -9, + -30, 58, -67, -34, 46, -6, -18, 13, 11, -49, 6, 64, 16, 51, -29, -35, + -41, 5, 47, 36, -41, 47, -17, 17, -23, 29, 42, -25, 22, -114, 69, -43, + -33, -31, 25, 66, 24, -57, 56, -61, -18, -39, -66, 58, -47, -20, 93, -50, + 49, 6, 6, 58, -4, -35, 4, 3, 55, -26, -48, 40, 7, -42, 62, -39, + -22, 1, 8, 66, -26, -37, -51, 13, -43, -46, -6, 5, 30, -55, 12, -27, + 92, -16, -32, -22, 5, 0, 38, -1, -35, -40, 67, -41, -26, 16, 7, -17, + -51, -41, 18, 24, -47, 7, -48, 7, -16, -15, 8, 14, 31, 0, -41, 25, + 8, -17, -59, -12, -32, -46, 16, -47, -17, 27, 9, -21, -18, -41, 19, -37, + 13, -43, -63, 61, 18, -56, -22, -52, 62, -35, -56, 30, 57, -44, -3, 0, + 12, -1, 24, 3, 0, -23, 29, -6, 42, -59, 45, 52, -1, 46, -51, 66}; diff -Nru ghostscript-9.10~dfsg/base/expat.mak ghostscript-9.25~dfsg+1/base/expat.mak --- ghostscript-9.10~dfsg/base/expat.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/expat.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for expat, the XML stream parsig library # @@ -23,7 +23,7 @@ # EXPATOBJDIR - directory for object files. # Define the name of this makefile -EXPAT_MAK=$(GLSRC)expat.mak +EXPAT_MAK=$(GLSRC)expat.mak $(TOP_MAKEFILES) # local aliases EXPATSRC=$(EXPATSRCDIR)$(D)lib$(D) @@ -31,7 +31,8 @@ EXPATOBJ=$(EXPATOBJDIR)$(D) EXPATO_=$(O_)$(EXPATOBJ) -EXPATCC=$(CC_) $(I_)$(EXPATSRC)lib$(_I) $(EXPAT_CFLAGS) +EXPATCC=$(CC) $(CFLAGS) $(I_)$(EXPATSRC)lib$(_I) \ +$(D_)XML_POOR_ENTROPY$(_D) $(EXPAT_CFLAGS) expat.clean : expat.config-clean expat.clean-not-config-clean @@ -46,7 +47,8 @@ expat_=$(EXPATOBJ)xmlparse.$(OBJ) \ $(EXPATOBJ)xmltok.$(OBJ) \ - $(EXPATOBJ)xmlrole.$(OBJ) + $(EXPATOBJ)xmlrole.$(OBJ) \ + $(EXPATOBJ)loadlibrary.$(OBJ) expat_xmlparse_hdrs=$(EXPATSRC)expat.h \ $(EXPATSRC)xmlrole.h \ @@ -70,25 +72,28 @@ $(EXPATSRC)expat_external.h \ $(EXPATSRC)internal.h -$(EXPATOBJ)xmlparse.$(OBJ) : $(EXPATSRC)xmlparse.c $(expat_xmlparse_hdrs) +$(EXPATOBJ)xmlparse.$(OBJ) : $(EXPATSRC)xmlparse.c $(expat_xmlparse_hdrs) $(EXPAT_MAK) $(MAKEDIRS) $(EXPATCC) $(EXPATO_)xmlparse.$(OBJ) $(C_) $(EXPATSRC)xmlparse.c -$(EXPATOBJ)xmlrole.$(OBJ) : $(EXPATSRC)xmlrole.c $(expat_xmlrole_hdrs) +$(EXPATOBJ)xmlrole.$(OBJ) : $(EXPATSRC)xmlrole.c $(expat_xmlrole_hdrs) $(EXPAT_MAK) $(MAKEDIRS) $(EXPATCC) $(EXPATO_)xmlrole.$(OBJ) $(C_) $(EXPATSRC)xmlrole.c -$(EXPATOBJ)xmltok.$(OBJ) : $(EXPATSRC)xmltok.c $(expat_xmltok_hdrs) +$(EXPATOBJ)xmltok.$(OBJ) : $(EXPATSRC)xmltok.c $(expat_xmltok_hdrs) $(EXPAT_MAK) $(MAKEDIRS) $(EXPATCC) $(EXPATO_)xmltok.$(OBJ) $(C_) $(EXPATSRC)xmltok.c +$(EXPATOBJ)loadlibrary.$(OBJ) : $(EXPATSRC)loadlibrary.c $(expat_xmltok_hdrs) $(EXPAT_MAK) $(MAKEDIRS) + $(EXPATCC) $(EXPATO_)loadlibrary.$(OBJ) $(C_) $(EXPATSRC)loadlibrary.c + # Copy the target definition we want -$(EXPATGEN)expat.dev : $(TOP_MAKEFILES) $(EXPAT_MAK) \ - $(EXPATGEN)expat_$(SHARE_EXPAT).dev +$(EXPATGEN)expat.dev : $(EXPAT_MAK) \ + $(EXPATGEN)expat_$(SHARE_EXPAT).dev $(MAKEDIRS) $(CP_) $(EXPATGEN)expat_$(SHARE_EXPAT).dev $(EXPATGEN)expat.dev # Define the compiled in target -$(EXPATGEN)expat_0.dev : $(EXPAT_MAK) $(ECHOGS_XE) $(expat_) +$(EXPATGEN)expat_0.dev : $(EXPAT_MAK) $(ECHOGS_XE) $(expat_) $(MAKEDIRS) $(SETMOD) $(EXPATGEN)expat_0 $(expat_) # Define the external link target -$(EXPATGEN)expat_1.dev : $(EXPAT_MAK) $(ECHOGS_XE) +$(EXPATGEN)expat_1.dev : $(EXPAT_MAK) $(ECHOGS_XE) $(MAKEDIRS) $(SETMOD) $(EXPATGEN)expat_1 -lib expat diff -Nru ghostscript-9.10~dfsg/base/fapi_bs.mak ghostscript-9.25~dfsg+1/base/fapi_bs.mak --- ghostscript-9.10~dfsg/base/fapi_bs.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/fapi_bs.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # makefile for Bitstream as part of the monolithic gs build. @@ -24,7 +24,7 @@ # BITSTREAM_CFLAGS - The include options for the Bitstream library # Define the name of this makefile. -FAPI_BS_MAK=$(GLSRC)fapi_bs.mak +FAPI_BS_MAK=$(GLSRC)fapi_bs.mak $(TOP_MAKEFILES) # Bitstream bridge : @@ -36,7 +36,7 @@ $(GLOBJ)t2ktt.$(OBJ) $(GLOBJ)cstream.$(OBJ) $(GLOBJ)fft1hint.$(OBJ) $(GLOBJ)ghints.$(OBJ)\ $(GLOBJ)glyph.$(OBJ) $(GLOBJ)t1.$(OBJ) $(GLOBJ)t2kstrm.$(OBJ) $(GLOBJ)truetype.$(OBJ)\ $(GLOBJ)util.$(OBJ) $(GLOBJ)fnt.$(OBJ) $(GLOBJ)pclread.$(OBJ) $(GLOBJ)t2ksc.$(OBJ)\ - $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ) + $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ) $(MAKEDIRS) $(SETMOD) $(GLD)fapib1 $(GLOBJ)fapibstm.$(OBJ) $(ADDMOD) $(GLD)fapib1 $(GLOBJ)t2k.$(OBJ) $(GLOBJ)t2kextra.$(OBJ) $(GLOBJ)fnt.$(OBJ) $(ADDMOD) $(GLD)fapib1 $(GLOBJ)tsimem.$(OBJ) $(GLOBJ)t2ktt.$(OBJ) $(GLOBJ)util.$(OBJ) @@ -48,50 +48,50 @@ $(GLOBJ)fapibstm.$(OBJ) : $(FAPI_BS_MAK) $(GLSRC)fapibstm.c $(AK)\ $(stdio__h) $(memory__h) $(math__h) $(strmio_h)\ - $(ierrors_h) $(iplugin_h) $(gxfapi_h) $(gxfapi_h) $(gp_h) + $(ierrors_h) $(iplugin_h) $(gxfapi_h) $(gxfapi_h) $(gp_h) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)fapibstm.$(OBJ) $(C_) $(GLSRC)fapibstm.c -$(GLOBJ)t2k.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2k.c" $(AK) +$(GLOBJ)t2k.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2k.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2k.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2k.c" -$(GLOBJ)t2kextra.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2kextra.c" $(AK) +$(GLOBJ)t2kextra.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2kextra.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2kextra.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2kextra.c" -$(GLOBJ)tsimem.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)tsimem.c" $(AK) +$(GLOBJ)tsimem.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)tsimem.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)tsimem.$(OBJ) $(C_) "$(BITSTREAM_LIB)tsimem.c" -$(GLOBJ)t2ktt.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2ktt.c" $(AK) +$(GLOBJ)t2ktt.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2ktt.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2ktt.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2ktt.c" -$(GLOBJ)cstream.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)cstream.c" $(AK) +$(GLOBJ)cstream.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)cstream.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)cstream.$(OBJ) $(C_) "$(BITSTREAM_LIB)cstream.c" -$(GLOBJ)fft1hint.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)fft1hint.c" $(AK) +$(GLOBJ)fft1hint.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)fft1hint.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)fft1hint.$(OBJ) $(C_) "$(BITSTREAM_LIB)fft1hint.c" -$(GLOBJ)ghints.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)ghints.c" $(AK) +$(GLOBJ)ghints.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)ghints.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)ghints.$(OBJ) $(C_) "$(BITSTREAM_LIB)ghints.c" -$(GLOBJ)glyph.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)glyph.c" $(AK) +$(GLOBJ)glyph.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)glyph.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)glyph.$(OBJ) $(C_) "$(BITSTREAM_LIB)glyph.c" -$(GLOBJ)t1.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t1.c" $(AK) +$(GLOBJ)t1.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t1.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t1.$(OBJ) $(C_) "$(BITSTREAM_LIB)t1.c" -$(GLOBJ)t2kstrm.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2kstrm.c" $(AK) +$(GLOBJ)t2kstrm.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2kstrm.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2kstrm.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2kstrm.c" -$(GLOBJ)truetype.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)truetype.c" $(AK) +$(GLOBJ)truetype.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)truetype.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)truetype.$(OBJ) $(C_) "$(BITSTREAM_LIB)truetype.c" -$(GLOBJ)util.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)util.c" $(AK) +$(GLOBJ)util.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)util.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)util.$(OBJ) $(C_) "$(BITSTREAM_LIB)util.c" -$(GLOBJ)fnt.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)fnt.c" $(AK) +$(GLOBJ)fnt.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)fnt.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)fnt.$(OBJ) $(C_) "$(BITSTREAM_LIB)fnt.c" -$(GLOBJ)pclread.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)pclread.c" $(AK) +$(GLOBJ)pclread.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)pclread.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)pclread.$(OBJ) $(C_) "$(BITSTREAM_LIB)pclread.c" -$(GLOBJ)t2ksc.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2ksc.c" $(AK) +$(GLOBJ)t2ksc.$(OBJ) : $(FAPI_BS_MAK) "$(BITSTREAM_LIB)t2ksc.c" $(AK) $(MAKEDIRS) $(GLCC) $(BITSTREAM_CFLAGS) $(BITSTREAM_INC) $(GLO_)t2ksc.$(OBJ) $(C_) "$(BITSTREAM_LIB)t2ksc.c" diff -Nru ghostscript-9.10~dfsg/base/fapibstm.c ghostscript-9.25~dfsg+1/base/fapibstm.c --- ghostscript-9.10~dfsg/base/fapibstm.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/fapibstm.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,7 +21,7 @@ #include "stdio_.h" #include "memory_.h" #include "math_.h" -#include "ierrors.h" +#include "gserrors.h" #include "iplugin.h" #include "ifapi.h" #include "strmio.h" @@ -89,7 +89,7 @@ else written = FF_serialize_type2_font(ff, own_font_data, length); if (written != length) - return (e_unregistered); /* Must not happen. */ + return (gs_error_unregistered); /* Must not happen. */ } /* It must be type 42 (see code in FAPI_FF_get_glyph in zfapi.c). */ else { @@ -97,14 +97,14 @@ long length = ff->get_long(ff, FAPI_FONT_FEATURE_TT_size, 0); if (length == 0) - return e_invalidfont; + return = gs_error_invalidfont; /* Load the TrueType data into a single buffer. */ own_font_data = gs_malloc(mem, 1, length, "Type 42 fotn copy"); if (!own_font_data) - return e_VMerror; + return_error(gs_error_VMerror); if (ff->serialize_tt_font(ff, own_font_data, length)) - return e_invalidfont; + return_error(gs_error_invalidfont); } } face->font_data = own_font_data; @@ -176,7 +176,7 @@ } static FAPI_retcode -get_font_bbox(FAPI_server * server, FAPI_font * ff, int BBox[4]) +get_font_bbox(FAPI_server * server, FAPI_font * ff, int BBox[4], int unitsPerEm[2]) { return 0; } @@ -318,6 +318,17 @@ return 0; } +static FAPI_retcode +gs_fapi_bstm_set_mm_weight_vector(gs_fapi_server *server, gs_fapi_font *ff, float *wvector, int length) +{ + (void)server; + (void)ff; + (void)wvector; + (void)length; + + return gs_error_invalidaccess; +} + static void gs_fapibstm_finit(i_plugin_instance * instance, i_plugin_client_memory * mem); @@ -334,6 +345,7 @@ {0}, 0, false, + 1, {1, 0, 0, 1, 0, 0}, ensure_open, get_scaled_font, @@ -351,7 +363,9 @@ get_char_outline, release_char_data, release_typeface, - check_cmap_for_GID NULL /* get_font_info */ + check_cmap_for_GID, + NULL, /* get_font_info */ + gs_fapi_bstm_set_mm_weight_vector }; plugin_instantiation_proc(gs_fapibstm_instantiate); /* check prototype */ @@ -369,7 +383,7 @@ (fapi_bitstream_server), "fapi_bitstream_server"); if (r == 0) - return e_VMerror; + return_error(gs_error_VMerror); memset(r, 0, sizeof(*r)); r->If = If0; r->client_mem = *client_mem; diff -Nru ghostscript-9.10~dfsg/base/fapi_ft.c ghostscript-9.25~dfsg+1/base/fapi_ft.c --- ghostscript-9.10~dfsg/base/fapi_ft.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/fapi_ft.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,6 +32,8 @@ #include "gdebug.h" #include "gxbitmap.h" #include "gsmchunk.h" +#include "gxfont.h" +#include "gxfont1.h" #include "stream.h" #include "gxiodev.h" /* must come after stream.h */ @@ -53,9 +55,15 @@ #include FT_OUTLINE_H #include FT_IMAGE_H #include FT_BITMAP_H +#include FT_TRUETYPE_DRIVER_H +#include FT_MULTIPLE_MASTERS_H +#include FT_TYPE1_TABLES_H /* Note: structure definitions here start with FF_, which stands for 'FAPI FreeType". */ +#define ft_emprintf(m,s) { outflush(m); emprintf(m, s); outflush(m); } +#define ft_emprintf1(m,s,d) { outflush(m); emprintf1(m, s, d); outflush(m); } + typedef struct ff_server_s { gs_fapi_server fapi_server; @@ -86,6 +94,8 @@ /* Non-null if font data is owned by this object. */ unsigned char *font_data; int font_data_len; + bool data_owned; + ff_server *server; } ff_face; /* Here we define the struct FT_Incremental that is used as an opaque type @@ -106,6 +116,15 @@ gs_fapi_metrics_type metrics_type; /* determines whether metrics are replaced, added, etc. */ } FT_IncrementalRec; + +static void +delete_inc_int(gs_fapi_server * a_server, + FT_Incremental_InterfaceRec * a_inc_int); + +static void +delete_inc_int_info(gs_fapi_server * a_server, + FT_IncrementalRec * a_inc_int_info); + FT_CALLBACK_DEF(void *) FF_alloc(FT_Memory memory, long size) { @@ -162,7 +181,7 @@ status = sgets(ps, buffer, count, &rlen); if (status < 0 && status != EOFC) - return (-1); + return_error (-1); } return (rlen); } @@ -221,6 +240,9 @@ } } } + else { + goto error_out; + } if ((code = savailable(ps, &length)) < 0) { goto error_out; @@ -253,7 +275,7 @@ static ff_face * new_face(gs_fapi_server * a_server, FT_Face a_ft_face, FT_Incremental_InterfaceRec * a_ft_inc_int, FT_Stream ftstrm, - unsigned char *a_font_data, int a_font_data_len) + unsigned char *a_font_data, int a_font_data_len, bool data_owned) { ff_server *s = (ff_server *) a_server; @@ -264,7 +286,9 @@ face->ft_inc_int = a_ft_inc_int; face->font_data = a_font_data; face->font_data_len = a_font_data_len; + face->data_owned = data_owned; face->ftstrm = ftstrm; + face->server = (ff_server *) a_server; } return face; } @@ -278,15 +302,18 @@ FT_Incremental a_info = a_face->ft_inc_int->object; if (a_info->glyph_data) { - gs_free(a_info->fapi_font->memory, a_info->glyph_data, 0, 0, "delete_face"); + gs_free(s->mem, a_info->glyph_data, 0, 0, "delete_face"); } a_info->glyph_data = NULL; a_info->glyph_data_length = 0; + delete_inc_int(a_server, a_face->ft_inc_int); + a_face->ft_inc_int = NULL; } FT_Done_Face(a_face->ft_face); FF_free(s->ftmemory, a_face->ft_inc_int); - FF_free(s->ftmemory, a_face->font_data); + if (a_face->data_owned) + FF_free(s->ftmemory, a_face->font_data); if (a_face->ftstrm) { FF_free(s->ftmemory, a_face->ftstrm); } @@ -331,6 +358,7 @@ gs_fapi_font *ff = a_info->fapi_font; int length = 0; ff_face *face = (ff_face *) ff->server_font_data; + gs_memory_t *mem = (gs_memory_t *) face->server->mem; /* Tell the FAPI interface that we need to decrypt the glyph data. */ ff->need_decrypt = true; @@ -342,16 +370,17 @@ unsigned char *buffer = NULL; length = ff->get_glyph(ff, a_index, NULL, 0); - if (length == 65535) + if (length == gs_fapi_glyph_invalid_format + || length == gs_fapi_glyph_invalid_index) return FT_Err_Invalid_Glyph_Index; - buffer = gs_malloc((gs_memory_t *) a_info->fapi_font->memory, length, 1, "get_fapi_glyph_data"); + buffer = gs_malloc(mem, length, 1, "get_fapi_glyph_data"); if (!buffer) return FT_Err_Out_Of_Memory; length = ff->get_glyph(ff, a_index, buffer, length); - if (length == 65535) { - gs_free((gs_memory_t *) a_info->fapi_font->memory, buffer, 0, 0, + if (length == gs_fapi_glyph_invalid_format) { + gs_free((gs_memory_t *) mem, buffer, 0, 0, "get_fapi_glyph_data"); return FT_Err_Invalid_Glyph_Index; } @@ -368,21 +397,25 @@ length = ff->get_glyph(ff, a_index, a_info->glyph_data, (ushort) a_info->glyph_data_length); - if (length == -1) { + if (length == gs_fapi_glyph_invalid_format) { ff->char_data = saved_char_data; return FT_Err_Unknown_File_Format; } + if (length == gs_fapi_glyph_invalid_index) { + ff->char_data = saved_char_data; + return FT_Err_Invalid_Glyph_Index; + } + /* If the buffer was too small enlarge it and try again. */ if (length > a_info->glyph_data_length) { if (a_info->glyph_data) { - gs_free((gs_memory_t *) a_info->fapi_font->memory, + gs_free((gs_memory_t *) mem, a_info->glyph_data, 0, 0, "get_fapi_glyph_data"); } a_info->glyph_data = - gs_malloc((gs_memory_t *) a_info->fapi_font->memory, length, - 1, "get_fapi_glyph_data"); + gs_malloc(mem, length, 1, "get_fapi_glyph_data"); if (!a_info->glyph_data) { a_info->glyph_data_length = 0; @@ -391,8 +424,10 @@ a_info->glyph_data_length = length; ff->char_data = saved_char_data; length = ff->get_glyph(ff, a_index, a_info->glyph_data, length); - if (length == -1) + if (length == gs_fapi_glyph_invalid_format) return FT_Err_Unknown_File_Format; + if (length == gs_fapi_glyph_invalid_index) + return FT_Err_Invalid_Glyph_Index; } /* Set the returned pointer and length. */ @@ -408,11 +443,14 @@ static void free_fapi_glyph_data(FT_Incremental a_info, FT_Data * a_data) { + gs_fapi_font *ff = a_info->fapi_font; + ff_face *face = (ff_face *) ff->server_font_data; + gs_memory_t *mem = (gs_memory_t *) face->server->mem; + if (a_data->pointer == (const FT_Byte *)a_info->glyph_data) a_info->glyph_data_in_use = false; else - gs_free((gs_memory_t *) a_info->fapi_font->memory, - (FT_Byte *) a_data->pointer, 0, 0, "free_fapi_glyph_data"); + gs_free(mem, (FT_Byte *) a_data->pointer, 0, 0, "free_fapi_glyph_data"); } static FT_Error @@ -464,12 +502,13 @@ sizeof (FT_Incremental_InterfaceRec)); if (i) { - i->object = (FT_Incremental) new_inc_int_info(a_server, a_fapi_font); i->funcs = &TheFAPIIncrementalInterfaceFuncs; - } - if (!i->object) { - FF_free(s->ftmemory, i); - i = NULL; + i->object = (FT_Incremental) new_inc_int_info(a_server, a_fapi_font); + + if (!i->object) { + FF_free(s->ftmemory, i); + i = NULL; + } } return i; } @@ -494,9 +533,9 @@ { if (a_error) { if (a_error == FT_Err_Out_Of_Memory) - return gs_error_VMerror; + return_error(gs_error_VMerror); else - return gs_error_unknownerror; + return_error(gs_error_unknownerror); } return 0; } @@ -519,6 +558,7 @@ FT_Long h; FT_Long fflags; FT_Int32 load_flags = 0; + FT_Vector delta = {0,0}; /* Save a_fapi_font->char_data, which is set to null by FAPI_FF_get_glyph as part of a hack to * make the deprecated Type 2 endchar ('seac') work, so that it can be restored @@ -538,6 +578,29 @@ s->outline_glyph = NULL; } +#if 0 + if (a_fapi_font->is_type1) { + FT_Fixed coords[16] = {0}; + int i; + gs_font_type1 *pfont1 = (gs_font_type1 *) a_fapi_font->client_font_data; + FT_Multi_Master amaster; + T1_Face *face = (T1_Face *)ft_face; + + ft_error = FT_Get_Multi_Master(ft_face, &amaster); + + if (pfont1->data.WeightVector.count > 0) { + for (i = 0; i < pfont1->data.WeightVector.count; i++) { + coords[i] = (FT_Fixed)(pfont1->data.WeightVector.values[i] * 65536); + } + coords[0] = coords[1]; + coords[1] = coords[2]; + ft_error = FT_Set_MM_Blend_Coordinates (ft_face, pfont1->data.WeightVector.count / 2, coords); + } + else + ft_error = FT_Set_MM_Blend_Coordinates (ft_face, 0, coords); + } +#endif + if (!a_char_ref->is_glyph_index) { if (ft_face->num_charmaps) index = FT_Get_Char_Index(ft_face, index); @@ -583,6 +646,7 @@ /* Store the overriding metrics if they have been supplied. */ if (face->ft_inc_int && a_char_ref->metrics_type != gs_fapi_metrics_notdef) { + FT_Incremental_MetricsRec *m = &face->ft_inc_int->object->glyph_metrics; m->bearing_x = a_char_ref->sb_x >> 16; @@ -590,6 +654,13 @@ m->advance = a_char_ref->aw_x >> 16; face->ft_inc_int->object->glyph_metrics_index = index; face->ft_inc_int->object->metrics_type = a_char_ref->metrics_type; + + /* we only want this for fonts with TT outlines */ + if (!a_fapi_font->is_type1) { + delta.y = 0; + delta.x = FT_MulFix(a_char_ref->sb_x, ft_face->size->metrics.x_scale); + FT_Vector_Transform( &delta, &face->ft_transform); + } } else if (face->ft_inc_int) /* Make sure we don't leave this set to the last value, as we may then use inappropriate metrics values */ @@ -602,6 +673,16 @@ /* maintain consistency better. (FT_LOAD_NO_BITMAP) */ a_fapi_font->char_data = saved_char_data; if (!a_fapi_font->is_mtx_skipped && !a_fapi_font->is_type1) { + /* grid_fit == 1 is the default - use font's native hints + * with freetype, 1 & 3 are, in practice, the same. + */ + + if (a_server->grid_fit == 0) { + load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT; + } + else if (a_server->grid_fit == 2) { + load_flags = FT_LOAD_FORCE_AUTOHINT; + } load_flags |= FT_LOAD_MONOCHROME | FT_LOAD_NO_BITMAP | FT_LOAD_LINEAR_DESIGN; } else { @@ -660,6 +741,10 @@ a_fapi_font->char_data_len = saved_char_data_len; } + if ((!ft_error || !ft_error_fb) && (delta.x != 0 || delta.y != 0)) { + FT_Outline_Translate( &ft_face->glyph->outline, delta.x >> 16, delta.y >> 16 ); + } + /* Previously we interpreted the glyph unscaled, and derived the metrics from that. Now we only interpret it * once, and work out the metrics from the scaled/hinted outline. */ @@ -710,7 +795,7 @@ a_metrics->em_y = ft_face->units_per_EM; } - if ((!ft_error || !ft_error_fb) && a_bitmap == true) { + if ((!ft_error || !ft_error_fb)) { FT_BBox cbox; @@ -729,7 +814,7 @@ w = (FT_UInt) ((cbox.xMax - cbox.xMin) >> 6); h = (FT_UInt) ((cbox.yMax - cbox.yMin) >> 6); - if (ft_face->glyph->format != FT_GLYPH_FORMAT_BITMAP + if (!a_fapi_font->metrics_only && a_bitmap == true && ft_face->glyph->format != FT_GLYPH_FORMAT_BITMAP && ft_face->glyph->format != FT_GLYPH_FORMAT_COMPOSITE) { if ((bitmap_raster(w) * h) < max_bitmap) { FT_Render_Mode mode = FT_RENDER_MODE_MONO; @@ -743,26 +828,34 @@ } } - if ((!ft_error || !ft_error_fb) && a_glyph) { - ft_error = FT_Get_Glyph(ft_face->glyph, a_glyph); - } - else { - if (ft_face->glyph->format == FT_GLYPH_FORMAT_BITMAP) { - FT_BitmapGlyph bmg; - - ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *) & bmg); - if (!ft_error) { - FT_Bitmap_Done(s->freetype_library, &bmg->bitmap); - FF_free(s->ftmemory, bmg); - } + if (!a_fapi_font->metrics_only) { + /* The following works around the fact that at the scales we deal with + * these values may not fit in a 16.16 fixed point value, and thus cause + * freetype to error due to overflow - but we don't use these values + * and neither does freetype, we can set them to zero and avoid the error + */ + ft_face->glyph->advance.x = ft_face->glyph->advance.y = 0; + if ((!ft_error || !ft_error_fb) && a_glyph) { + ft_error = FT_Get_Glyph(ft_face->glyph, a_glyph); } else { - FT_OutlineGlyph olg; + if (ft_face->glyph->format == FT_GLYPH_FORMAT_BITMAP) { + FT_BitmapGlyph bmg; + + ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *) & bmg); + if (!ft_error) { + FT_Bitmap_Done(s->freetype_library, &bmg->bitmap); + FF_free(s->ftmemory, bmg); + } + } + else { + FT_OutlineGlyph olg; - ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *) & olg); - if (!ft_error) { - FT_Outline_Done(s->freetype_library, &olg->outline); - FF_free(s->ftmemory, olg); + ft_error = FT_Get_Glyph(ft_face->glyph, (FT_Glyph *) & olg); + if (!ft_error) { + FT_Outline_Done(s->freetype_library, &olg->outline); + FF_free(s->ftmemory, olg); + } } } } @@ -770,12 +863,12 @@ if (ft_error == FT_Err_Too_Many_Hints) { #ifdef DEBUG if (gs_debug_c('1')) { - emprintf1(a_fapi_font->memory, + ft_emprintf1(a_fapi_font->memory, "TrueType glyph %"PRId64" uses more instructions than the declared maximum in the font.", a_char_ref->char_codes[0]); if (!ft_error_fb) { - emprintf(a_fapi_font->memory, + ft_emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n"); } } @@ -786,12 +879,12 @@ if (ft_error == FT_Err_Invalid_Argument) { #ifdef DEBUG if (gs_debug_c('1')) { - emprintf1(a_fapi_font->memory, + ft_emprintf1(a_fapi_font->memory, "TrueType parsing error in glyph %"PRId64" in the font.", a_char_ref->char_codes[0]); if (!ft_error_fb) { - emprintf(a_fapi_font->memory, + ft_emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n"); } } @@ -802,12 +895,12 @@ if (ft_error == FT_Err_Too_Many_Function_Defs) { #ifdef DEBUG if (gs_debug_c('1')) { - emprintf1(a_fapi_font->memory, + ft_emprintf1(a_fapi_font->memory, "TrueType instruction error in glyph %"PRId64" in the font.", a_char_ref->char_codes[0]); if (!ft_error_fb) { - emprintf(a_fapi_font->memory, + ft_emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n"); } } @@ -818,12 +911,12 @@ if (ft_error == FT_Err_Invalid_Glyph_Index) { #ifdef DEBUG if (gs_debug_c('1')) { - emprintf1(a_fapi_font->memory, + ft_emprintf1(a_fapi_font->memory, "FreeType is unable to find the glyph %"PRId64" in the font.", a_char_ref->char_codes[0]); if (!ft_error_fb) { - emprintf(a_fapi_font->memory, + ft_emprintf(a_fapi_font->memory, " Continuing, falling back to notdef\n\n"); } } @@ -841,32 +934,30 @@ */ static gs_fapi_retcode gs_fapi_ft_ensure_open(gs_fapi_server * a_server, const char * server_param, - int server_param_size) + int server_param_size) { ff_server *s = (ff_server *) a_server; + FT_UInt tt_ins_version = TT_INTERPRETER_VERSION_35; + FT_Error ft_error; - if (!s->freetype_library) { - FT_Error ft_error; + if (s->freetype_library) + return 0; - /* As we want FT to use our memory management, we cannot use the convenience of - * FT_Init_FreeType(), we have to do each stage "manually" - */ - s->ftmemory->user = s->mem; - s->ftmemory->alloc = FF_alloc; - s->ftmemory->free = FF_free; - s->ftmemory->realloc = FF_realloc; + /* As we want FT to use our memory management, we cannot use the convenience of + * FT_Init_FreeType(), we have to do each stage "manually" + */ + s->ftmemory->user = s->mem; + s->ftmemory->alloc = FF_alloc; + s->ftmemory->free = FF_free; + s->ftmemory->realloc = FF_realloc; + + ft_error = FT_New_Library(s->ftmemory, &s->freetype_library); + if (ft_error) + return ft_to_gs_error(ft_error); - ft_error = FT_New_Library(s->ftmemory, &s->freetype_library); - if (ft_error) { - gs_free(s->mem, s->ftmemory, 0, 0, "gs_fapi_ft_ensure_open"); - } - else { - FT_Add_Default_Modules(s->freetype_library); - } + FT_Add_Default_Modules(s->freetype_library); + FT_Property_Set( s->freetype_library, "truetype", "interpreter-version", &tt_ins_version); - if (ft_error) - return ft_to_gs_error(ft_error); - } return 0; } @@ -913,11 +1004,26 @@ FT_Matrix ftscale_mat; FT_UInt xres; FT_UInt yres; - bool indep_scale; scalex = hypot((double)a_transform->xx, (double)a_transform->xy); scaley = hypot((double)a_transform->yx, (double)a_transform->yy); + /* In addition to all the wrangling below, we have to make sure that + * that the contents of a_transform can also be understood by Freetype. + */ + if (scalex < 64.0 || scaley < 64.0) { + factx = 64.0/scalex; + facty = 64.0/scaley; + + ftscale_mat.xx = (FT_Fixed)(a_transform->xx * factx); + ftscale_mat.xy = (FT_Fixed)(a_transform->xy * facty); + ftscale_mat.yx = (FT_Fixed)(a_transform->yx * factx); + ftscale_mat.yy = (FT_Fixed)(a_transform->yy * facty); + memcpy(a_transform, &ftscale_mat, sizeof(ftscale_mat)); + scalex = hypot((double)a_transform->xx, (double)a_transform->xy); + scaley = hypot((double)a_transform->yx, (double)a_transform->yy); + } + if (*xresp != *yresp) { /* To get good results, we have to pull the implicit scaling from * non-square resolutions, and apply it in the matrix. This means @@ -942,26 +1048,25 @@ FT_Matrix_Multiply(&ftscale_mat, a_transform); xres = yres = (use_x ? (*xresp) : (*yresp)); + xres = (FT_UInt)(xres / factx); + yres = (FT_UInt)(yres / facty); } else { /* Life is considerably easier when square resolutions are in use! */ - xres = *xresp; - yres = *yresp; + xres = (FT_UInt)(*xresp / factx); + yres = (FT_UInt)(*yresp / facty); } - /* - * If the x and y scales differ by more than a factor of 512, we - * manipulate them independently. As the difference between magnitudes - * of the x and y scales tends towards 1000 we start to run out of - * accuracy and magnitude in the FT fixed point representation. - * As these are scaled fixed point values, we should be safe forcing - * them into integer operations. - */ - indep_scale = (((((int)scalex) / ((int)scaley)) > 512) - || ((((int)scaley) / ((int)scalex)) > 512)); - scalex *= 1.0 / 65536.0; scaley *= 1.0 / 65536.0; + + if (scalex < scaley) { + scaley = scalex; + } + else if (scalex > scaley) { + scalex = scaley; + } + /* FT clamps the width and height to a lower limit of 1.0 units * (note: as FT stores it in 64ths of a unit, that is 64) * So if either the width or the height are <1.0 here, we scale @@ -971,154 +1076,39 @@ /* We use 1 1/64th to calculate the scale, so that we *guarantee* the * scalex/y we calculate will be >64 after rounding. */ - /* It turns out that pdfwrite uses a unit matrix for some/many/all of - * its nefarious needs, this causes small values to round to zero in - * some of Freetype's code, which can result in glyph metrics (height, - * width etc) being falsely recorded as zero. - * Raise the scale factor of what we consider a "small" glyph by an - * order of magnitude to keep pdfwrite happy - note this doesn't - * affect the ultimate size of the glyph since we recalculate the - * final scale matrix to suit below. - */ - if (indep_scale) { - if (scaley < 10.0) { - facty = 10.016 / scaley; - scaley = scaley * facty; - } - - /* These seemingly arbitrary numbers are derived from a) using 64ths - of a unit and b) the calculations done in FT_Request_Metrics() to - derive the ppem. This is necessary due to FT's need for them ppem - to be an in larger than 1 - see tt_size_reset(). - - The calculation has been rearranged to reduce (in particular) the - number of floating point divisions. - */ - if (scaley * yres < 2268.0 / 64.0) { - facty = (2400.0 / 64.0) / (yres * scaley); - scaley *= facty; - } - - /* We also have to watch for variable overflow in Freetype. - * We fiddle with whichever of the resolution or the scale - * is larger for the current iteration, but change the scale - * by a smaller multiple, firstly because it is a floating point - * value, so we can, but also because varying the scale by larger - * amounts is more prone to causing rounding errors. - */ - facty = 1.0; - while (scaley * yres > 512.0 * 72 && yres > 0 && scaley > 0.0) { - if (scaley < yres) { - yres >>= 1; - facty *= 2.0; - } - else { - scaley /= 1.25; - } - } - - if (scalex < 10.0) { - factx = 10.016 / scalex; - scalex = scalex * factx; - } - - /* see above */ - if (scalex * xres < 2268.0 / 64.0) { - factx = (2400.0 / 64.0) / (xres * scalex); - scalex *= factx; - } - - /* see above */ - factx = 1.0; - while (scalex * xres > 512.0 * 72.0 && xres > 0 && scalex > 0.0) { - if (scalex < xres) { - xres >>= 1; - factx *= 2.0; - } - else { - scalex /= 1.25; - } - } - } - else { - /* - * But we prefer to scale both axes together, as the results are - * more accurate. - */ - if (scalex > scaley) { - if (scaley < 10.0) { - fact = 10.016 / scaley; - scaley = scaley * fact; - scalex = scalex * fact; - } - - /* These seemingly arbitrary numbers are derived from a) using 64ths - of a unit and b) the calculations done in FT_Request_Metrics() to - derive the ppem. This is necessary due to FT's need for them ppem - to be an in larger than 1 - see tt_size_reset(). - The calculation has been rearranged to reduce (in particular) the - number of floating point divisions. - */ - if (scaley * yres < 2268.0 / 64.0) { - fact = (2400.0 / 64.0) / (yres * scaley); - scaley *= fact; - scalex *= fact; - } - - /* We also have to watch for variable overflow in Freetype. - * We fiddle with whichever of the resolution or the scale - * is larger for the current iteration. - */ - fact = 1.0; - while (scalex * xres > 512.0 * 72 && xres > 0 && yres > 0 - && (scalex > 0.0 && scaley > 0.0)) { - if (scalex < xres) { - xres >>= 1; - yres >>= 1; - fact *= 2.0; - } - else { - scalex /= 1.25; - scaley /= 1.25; - } - } + if (scalex < 10.0) { + fact = 10.016 / scalex; + scalex = scalex * fact; + scaley = scaley * fact; + } + + /* see above */ + if (scalex * xres < 2268.0 / 64.0) { + fact = (2400.0 / 64.0) / (xres * scalex); + scaley *= fact; + scalex *= fact; + } + + /* see above */ + fact = 1.0; + while (scaley * yres > 512.0 * 72.0 && (xres > 0 && yres > 0) + && (scalex > 0.0 && scaley > 0.0)) { + if (scaley < yres) { + xres >>= 1; + yres >>= 1; + fact *= 2.0; } else { - if (scalex < 10.0) { - fact = 10.016 / scalex; - scalex = scalex * fact; - scaley = scaley * fact; - } - - /* see above */ - if (scalex * xres < 2268.0 / 64.0) { - fact = (2400.0 / 64.0) / (xres * scalex); - scaley *= fact; - scalex *= fact; - } - - /* see above */ - fact = 1.0; - while (scaley * yres > 512.0 * 72.0 && (xres > 0 && yres > 0) - && (scalex > 0.0 && scaley > 0.0)) { - if (scaley < yres) { - xres >>= 1; - yres >>= 1; - fact *= 2.0; - } - else { - scalex /= 1.25; - scaley /= 1.25; - } - } + scalex /= 1.25; + scaley /= 1.25; } - factx = facty = fact; } - ftscale_mat.xx = (FT_Fixed) ((65536.0 / scalex) * factx); + + ftscale_mat.xx = (FT_Fixed) ((65536.0 / scalex) * fact); ftscale_mat.xy = 0; ftscale_mat.yx = 0; - ftscale_mat.yy = (FT_Fixed) ((65536.0 / scaley) * facty); + ftscale_mat.yy = (FT_Fixed) ((65536.0 / scaley) * fact); FT_Matrix_Multiply(a_transform, &ftscale_mat); memcpy(a_transform, &ftscale_mat, sizeof(FT_Matrix)); @@ -1143,6 +1133,7 @@ FT_Error ft_error = 0; int i, j; FT_CharMap cmap = NULL; + bool data_owned = true; if (s->bitmap_glyph) { FT_Bitmap_Done(s->freetype_library, &s->bitmap_glyph->bitmap); @@ -1200,9 +1191,11 @@ own_font_data_len, a_font->subfont, &ft_face); - if (!ft_error && ft_face) - ft_error = FT_Select_Charmap(ft_face, ft_encoding_unicode); - + if (ft_error) { + gs_memory_t * mem = (gs_memory_t *) s->ftmemory->user; + gs_free(mem, own_font_data, 0, 0, "FF_open_read_stream"); + return ft_to_gs_error(ft_error); + } } /* Load a typeface from a file. */ else if (a_font->font_file_path) { @@ -1224,9 +1217,10 @@ ft_error = FT_Open_Face(s->freetype_library, &args, a_font->subfont, &ft_face); - - if (!ft_error && ft_face) - ft_error = FT_Select_Charmap(ft_face, ft_encoding_unicode); + if (ft_error) { + /* in the event of an error, Freetype should cleanup the stream */ + return ft_to_gs_error(ft_error); + } } /* Load a typeface from a representation in GhostScript's memory. */ @@ -1234,6 +1228,7 @@ FT_Open_Args open_args; open_args.flags = FT_OPEN_MEMORY; + open_args.stream = NULL; if (a_font->is_type1) { long length; @@ -1255,7 +1250,7 @@ open_args.memory_base = own_font_data = FF_alloc(s->ftmemory, length); if (!open_args.memory_base) - return gs_error_VMerror; + return_error(gs_error_VMerror); own_font_data_len = length; if (type == 1) open_args.memory_size = @@ -1270,7 +1265,7 @@ ft_inc_int = new_inc_int(a_server, a_font); if (!ft_inc_int) { FF_free(s->ftmemory, own_font_data); - return gs_error_VMerror; + return_error(gs_error_VMerror); } } @@ -1280,26 +1275,26 @@ open_args.memory_size = a_font->get_long(a_font, gs_fapi_font_feature_TT_size, 0); if (open_args.memory_size == 0) - return gs_error_invalidfont; + return_error(gs_error_invalidfont); /* Load the TrueType data into a single buffer. */ open_args.memory_base = own_font_data = FF_alloc(s->ftmemory, open_args.memory_size); if (!own_font_data) - return gs_error_VMerror; + return_error(gs_error_VMerror); own_font_data_len = open_args.memory_size; if (a_font-> serialize_tt_font(a_font, own_font_data, open_args.memory_size)) - return gs_error_invalidfont; + return_error(gs_error_invalidfont); /* We always load incrementally. */ ft_inc_int = new_inc_int(a_server, a_font); if (!ft_inc_int) { FF_free(s->ftmemory, own_font_data); - return gs_error_VMerror; + return_error(gs_error_VMerror); } } @@ -1314,17 +1309,22 @@ ft_error = FT_Open_Face(s->freetype_library, &open_args, a_font->subfont, &ft_face); + if (ft_error) { + delete_inc_int (a_server, ft_inc_int); + FF_free(s->ftmemory, own_font_data); + return ft_to_gs_error(ft_error); + } } if (ft_face) { face = new_face(a_server, ft_face, ft_inc_int, ft_strm, - own_font_data, own_font_data_len); + own_font_data, own_font_data_len, data_owned); if (!face) { FF_free(s->ftmemory, own_font_data); FT_Done_Face(ft_face); delete_inc_int(a_server, ft_inc_int); - return gs_error_VMerror; + return_error(gs_error_VMerror); } a_font->server_font_data = face; } @@ -1375,23 +1375,32 @@ FT_Set_Transform(face->ft_face, &face->ft_transform, NULL); - for (i = 0; i < GS_FAPI_NUM_TTF_CMAP_REQ && !cmap; i++) { - if (a_font->ttf_cmap_req[i].platform_id > 0) { - for (j = 0; j < face->ft_face->num_charmaps; j++) { - if (face->ft_face->charmaps[j]->platform_id == a_font->ttf_cmap_req[i].platform_id - && face->ft_face->charmaps[j]->encoding_id == a_font->ttf_cmap_req[i].encoding_id) { - - cmap = face->ft_face->charmaps[j]; - break; + if (!a_font->is_type1) { + for (i = 0; i < GS_FAPI_NUM_TTF_CMAP_REQ && !cmap; i++) { + if (a_font->ttf_cmap_req[i].platform_id > 0) { + for (j = 0; j < face->ft_face->num_charmaps; j++) { + if (face->ft_face->charmaps[j]->platform_id == a_font->ttf_cmap_req[i].platform_id + && face->ft_face->charmaps[j]->encoding_id == a_font->ttf_cmap_req[i].encoding_id) { + + cmap = face->ft_face->charmaps[j]; + break; + } } } + else { + break; + } } - else { - break; + if (cmap) { + (void)FT_Set_Charmap(face->ft_face, cmap); + } + else if (a_font->full_font_buf != NULL || a_font->font_file_path != NULL) { + /* If we've passed a complete TTF to Freetype, but *haven't* requested a + * specific cmap table above, try to use a Unicode one + * If that doesn't work, just leave the default in place. + */ + (void)FT_Select_Charmap(face->ft_face, ft_encoding_unicode); } - } - if (cmap) { - (void)FT_Set_Charmap(face->ft_face, cmap); } } @@ -1417,7 +1426,7 @@ * Get the font bounding box in font units. */ static gs_fapi_retcode -gs_fapi_ft_get_font_bbox(gs_fapi_server * a_server, gs_fapi_font * a_font, int a_box[4]) +gs_fapi_ft_get_font_bbox(gs_fapi_server * a_server, gs_fapi_font * a_font, int a_box[4], int unitsPerEm[2]) { ff_face *face = (ff_face *) a_font->server_font_data; @@ -1425,6 +1434,9 @@ a_box[1] = face->ft_face->bbox.yMin; a_box[2] = face->ft_face->bbox.xMax; a_box[3] = face->ft_face->bbox.yMax; + + unitsPerEm[0] = unitsPerEm[1] = face->ft_face->units_per_EM; + return 0; } @@ -1566,13 +1578,25 @@ gs_fapi_path *path; int64_t x; int64_t y; + FT_Vector currentp; } FF_path_info; +static inline int +FF_points_equal(const FT_Vector *p1, const FT_Vector *p2) +{ + if (p1->x == p2->x && p1->y == p2->y) + return 1; + else + return 0; +} + static int move_to(const FT_Vector * aTo, void *aObject) { FF_path_info *p = (FF_path_info *) aObject; + p->currentp = *aTo; + /* FAPI expects that co-ordinates will be as implied by frac_shift * in our case 16.16 fixed precision. True for 'low level' FT * routines (apparently), it isn't true for these routines where @@ -1591,55 +1615,67 @@ { FF_path_info *p = (FF_path_info *) aObject; - /* See move_to() above */ - p->x = ((int64_t) aTo->x) << 26; - p->y = ((int64_t) aTo->y) << 26; + if (!FF_points_equal(&p->currentp, aTo)) { + p->currentp = *aTo; + + /* See move_to() above */ + p->x = ((int64_t) aTo->x) << 26; + p->y = ((int64_t) aTo->y) << 26; - return p->path->lineto(p->path, p->x, p->y) ? -1 : 0; + return p->path->lineto(p->path, p->x, p->y) ? -1 : 0; + } + return 0; } static int conic_to(const FT_Vector * aControl, const FT_Vector * aTo, void *aObject) { FF_path_info *p = (FF_path_info *) aObject; - floatp x, y, Controlx, Controly; + double x, y, Controlx, Controly; int64_t Control1x, Control1y, Control2x, Control2y; - floatp sx, sy; + double sx, sy; - /* More complicated than above, we need to do arithmetic on the - * co-ordinates, so we want them as floats and we will convert the - * result into 16.16 fixed precision for FAPI - * - * NB this code is funcitonally the same as the original, but I don't believe - * the comment (below) to be what the code is actually doing.... - * - * NB2: the comment below was wrong, even though the code was correct(!!) - * The comment has now been amended. - * - * Convert a quadratic spline to a cubic. Do this by changing the three points - * A, B and C to A, 2/3(B,A), 2/3(B,C), C - that is, the two cubic control points are - * a third of the way from the single quadratic control point to the end points. This - * gives the same curve as the original quadratic. - */ + if (!FF_points_equal(&p->currentp, aControl) || + !FF_points_equal(&p->currentp, aTo) || + !FF_points_equal(aControl, aTo)) { + p->currentp = *aTo; + + /* More complicated than above, we need to do arithmetic on the + * co-ordinates, so we want them as floats and we will convert the + * result into 16.16 fixed precision for FAPI + * + * NB this code is funcitonally the same as the original, but I don't believe + * the comment (below) to be what the code is actually doing.... + * + * NB2: the comment below was wrong, even though the code was correct(!!) + * The comment has now been amended. + * + * Convert a quadratic spline to a cubic. Do this by changing the three points + * A, B and C to A, 2/3(B,A), 2/3(B,C), C - that is, the two cubic control points are + * a third of the way from the single quadratic control point to the end points. This + * gives the same curve as the original quadratic. + */ - sx = (floatp) (p->x >> 32); - sy = (floatp) (p->y >> 32); + sx = (double) (p->x >> 32); + sy = (double) (p->y >> 32); - x = aTo->x / 64.0; - p->x = ((int64_t) float2fixed(x)) << 24; - y = aTo->y / 64.0; - p->y = ((int64_t) float2fixed(y)) << 24; - Controlx = aControl->x / 64.0; - Controly = aControl->y / 64.0; - - Control1x = ((int64_t) float2fixed((sx + Controlx * 2) / 3)) << 24; - Control1y = ((int64_t) float2fixed((sy + Controly * 2) / 3)) << 24; - Control2x = ((int64_t) float2fixed((x + Controlx * 2) / 3)) << 24; - Control2y = ((int64_t) float2fixed((y + Controly * 2) / 3)) << 24; - - return p->path->curveto(p->path, Control1x, - Control1y, - Control2x, Control2y, p->x, p->y) ? -1 : 0; + x = aTo->x / 64.0; + p->x = ((int64_t) float2fixed(x)) << 24; + y = aTo->y / 64.0; + p->y = ((int64_t) float2fixed(y)) << 24; + Controlx = aControl->x / 64.0; + Controly = aControl->y / 64.0; + + Control1x = ((int64_t) float2fixed((sx + Controlx * 2) / 3)) << 24; + Control1y = ((int64_t) float2fixed((sy + Controly * 2) / 3)) << 24; + Control2x = ((int64_t) float2fixed((x + Controlx * 2) / 3)) << 24; + Control2y = ((int64_t) float2fixed((y + Controly * 2) / 3)) << 24; + + return p->path->curveto(p->path, Control1x, + Control1y, + Control2x, Control2y, p->x, p->y) ? -1 : 0; + } + return 0; } static int @@ -1649,21 +1685,26 @@ FF_path_info *p = (FF_path_info *) aObject; int64_t Control1x, Control1y, Control2x, Control2y; - /* See move_to() above */ - p->x = ((int64_t) aTo->x) << 26; - p->y = ((int64_t) aTo->y) << 26; - - Control1x = ((int64_t) aControl1->x) << 26; - Control1y = ((int64_t) aControl1->y) << 26; - Control2x = ((int64_t) aControl2->x) << 26; - Control2y = ((int64_t) aControl2->y) << 26; - return p->path->curveto(p->path, Control1x, Control1y, Control2x, - Control2y, p->x, p->y) ? -1 : 0; - - p->x = aTo->x; - p->y = aTo->y; - return p->path->curveto(p->path, aControl1->x, aControl1->y, aControl2->x, - aControl2->y, aTo->x, aTo->y) ? -1 : 0; + if (!FF_points_equal(&p->currentp, aControl1) || + !FF_points_equal(&p->currentp, aControl2) || + !FF_points_equal(&p->currentp, aTo) || + !FF_points_equal(aControl1, aControl2) || + !FF_points_equal(aControl1, aTo) || + !FF_points_equal(aControl2, aTo)) { + p->currentp = *aTo; + + /* See move_to() above */ + p->x = ((int64_t) aTo->x) << 26; + p->y = ((int64_t) aTo->y) << 26; + + Control1x = ((int64_t) aControl1->x) << 26; + Control1y = ((int64_t) aControl1->y) << 26; + Control2x = ((int64_t) aControl2->x) << 26; + Control2y = ((int64_t) aControl2->y) << 26; + return p->path->curveto(p->path, Control1x, Control1y, Control2x, + Control2y, p->x, p->y) ? -1 : 0; + } + return 0; } static const FT_Outline_Funcs TheFtOutlineFuncs = { @@ -1744,6 +1785,17 @@ return 0; } +static gs_fapi_retcode +gs_fapi_ft_set_mm_weight_vector(gs_fapi_server *server, gs_fapi_font *ff, float *wvector, int length) +{ + (void)server; + (void)ff; + (void)wvector; + (void)length; + + return gs_error_invalidaccess; +} + static void gs_fapi_freetype_destroy(gs_fapi_server ** serv); static const gs_fapi_server_descriptor freetypedescriptor = { @@ -1760,6 +1812,7 @@ {0}, 0, false, + 1, {1, 0, 0, 1, 0, 0}, gs_fapi_ft_ensure_open, gs_fapi_ft_get_scaled_font, @@ -1778,7 +1831,8 @@ gs_fapi_ft_release_char_data, gs_fapi_ft_release_typeface, gs_fapi_ft_check_cmap_for_GID, - NULL /* get_font_info */ + NULL, /* get_font_info */ + gs_fapi_ft_set_mm_weight_vector, }; int gs_fapi_ft_init(gs_memory_t * mem, gs_fapi_server ** server); @@ -1788,7 +1842,7 @@ { ff_server *serv; int code = 0; - gs_memory_t *cmem = NULL; + gs_memory_t *cmem = mem->non_gc_memory; code = gs_memory_chunk_wrap(&(cmem), mem); if (code != 0) { @@ -1796,10 +1850,9 @@ } - serv = - (ff_server *) gs_alloc_bytes_immovable(cmem, sizeof(ff_server), - "gs_fapi_ft_init"); + serv = (ff_server *) gs_alloc_bytes_immovable(cmem, sizeof(ff_server), "gs_fapi_ft_init"); if (!serv) { + gs_memory_chunk_release(cmem); return_error(gs_error_VMerror); } memset(serv, 0, sizeof(*serv)); diff -Nru ghostscript-9.10~dfsg/base/fapiufst.c ghostscript-9.25~dfsg+1/base/fapiufst.c --- ghostscript-9.10~dfsg/base/fapiufst.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/fapiufst.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -18,6 +18,7 @@ /* GS includes : */ #include "stdio_.h" +#include "string_.h" #include "stream.h" /* for files.h */ #include "strmio.h" @@ -82,6 +83,9 @@ #include "t1itype1.h" #endif +#define ufst_emprintf(m,s) { outflush(m); emprintf(m, s); outflush(m); } +#define ufst_emprintf1(m,s,d) { outflush(m); emprintf1(m, s, d); outflush(m); } + #if UFST_VERSION_MAJOR >= 6 && UFST_VERSION_MINOR >= 2 #undef true #undef false @@ -117,7 +121,12 @@ static fapi_ufst_server *static_server_ptr_for_ufst_callback = 0; #endif +#if PCLEO_RDR && BYTEORDER==LOHI GLOBAL UW16 PCLswapHdr(FSP LPUB8 p, UW16 gifct); /* UFST header doesn't define it. */ +#define UFST_PCLswapHdr(p, gifct) PCLswapHdr(FSP p, gifct) +#else +#define UFST_PCLswapHdr(p, gifct) +#endif typedef struct pcleo_glyph_list_elem_s pcleo_glyph_list_elem; struct pcleo_glyph_list_elem_s @@ -291,13 +300,13 @@ bPlugIn = TRUE; } else if (gs_debug_c('1')) - emprintf(r->mem, "Warning: Unknown UFST parameter ignored.\n"); + ufst_emprintf(r->mem, "Warning: Unknown UFST parameter ignored.\n"); } #if !NO_SYMSET_MAPPING if (!bSSdir) { strcpy(ufst_root_dir, "."); if (gs_debug_c('1')) - emprintf(r->mem, + ufst_emprintf(r->mem, "Warning: UFST_SSdir is not specified, will search *.ss files in the curent directory.\n"); } #endif @@ -314,7 +323,7 @@ } else { #ifdef FCO_RDR - emprintf(r->mem, + ufst_emprintf(r->mem, "Warning: UFST_PlugIn is not specified, some characters may be missing.\n"); #endif } @@ -335,7 +344,7 @@ { code = open_UFST(r, (byte *)server_param, server_param_size); if (code < 0) { - emprintf(r->mem, "Error opening the UFST font server.\n"); + ufst_emprintf(r->mem, "Error opening the UFST font server.\n"); return code; } } @@ -852,7 +861,7 @@ "fco_list_elem"); if (e == 0) { CGIFfco_Close(FSA fcHandle); - return gs_error_VMerror; + return_error(gs_error_VMerror); } e->open_count = 0; e->fcHandle = fcHandle; @@ -860,7 +869,7 @@ if (e->file_path == 0) { CGIFfco_Close(FSA fcHandle); gs_free(r->mem, e, 0, 0, "fco_list_elem"); - return gs_error_VMerror; + return_error(gs_error_VMerror); } e->next = r->fco_list; r->fco_list = e; @@ -890,7 +899,7 @@ return (gs_error_invalidaccess); #else /* If we have the Freetype server available, always use it for non-FCO fonts */ - if (gs_fapi_available(r->mem, (char *)"Freetype")) { + if (gs_fapi_available(r->mem, (char *)"FreeType")) { return (gs_error_invalidaccess); } @@ -911,35 +920,23 @@ else { tt_size = ff->get_long(ff, gs_fapi_font_feature_TT_size, 0); if (tt_size == 0) - return gs_error_invalidfont; + return_error(gs_error_invalidfont); /* area_length += tt_size + (use_XL_format ? 6 : 4) + 4 + 2;*/ area_length += tt_size + 6 + 4 + 2; } #endif } else { - int sind = strlen(font_file_path) - 1; + int sind = strlen(font_file_path); - if ((font_file_path[sind] != 'o' || font_file_path[sind] != 'O') && - (font_file_path[sind - 1] != 'c' - || font_file_path[sind - 1] != 'C') - && (font_file_path[sind - 2] != 'f' - || font_file_path[sind - 2] != 'F') - && font_file_path[sind - 3] != '.') { -#if UFST_VERSION_MAJOR < 6 + if (strncasecmp(font_file_path + sind - 4, ".fco", 4) != 0) { return (gs_error_invalidaccess); -#else - /* If we have the Freetype server available, always use it for non-FCO fonts */ - if (gs_fapi_available(r->mem, (char *)"Freetype")) { - return (gs_error_invalidaccess); - } -#endif } area_length += strlen(font_file_path) + 1; } buf = gs_malloc(r->mem, area_length, 1, "ufst font data"); if (buf == 0) - return gs_error_VMerror; + return_error(gs_error_VMerror); memset(buf, 0x00, area_length); @@ -962,12 +959,12 @@ d->font_type = FC_FCO_TYPE; } else { - stream *f = sfopen(font_file_path, "rb", r->mem); + stream *f = sfopen(font_file_path, "r", r->mem); if (f == NULL) { - emprintf1(r->mem, + ufst_emprintf1(r->mem, "fapiufst: Can't open %s\n", font_file_path); - return gs_error_undefinedfilename; + return_error(gs_error_undefinedfilename); } memcpy(d + 1, font_file_path, strlen(font_file_path) + 1); d->font_type = get_font_type(f); @@ -988,9 +985,7 @@ d->font_id = assign_font_id(); } h = (PCLETTO_FHDR *) (buf + sizeof(ufst_common_font_data)); - /* For some reason the bytes of fontDescriptorSize need swapped here - (PCLswapHdr() doesn't do it as needed), but only for TTF fonts - duh!?!? - */ + if (ff->is_type1) { h->fontDescriptorSize = PCLETTOFONTHDRSIZE; } @@ -1047,7 +1042,8 @@ /* fixme : This code assumes 1-byte alignment for PCLETTO_FHDR structure. Use PACK_* macros to improve. */ - PCLswapHdr(FSA(UB8 *) h, 0); + UFST_PCLswapHdr((UB8 *) h, 0); + if (ff->is_type1) { LPUB8 fontdata = (LPUB8) h + PCLETTOFONTHDRSIZE; @@ -1065,7 +1061,7 @@ d->tt_font_body_offset = (LPUB8) fontdata - (LPUB8) d; if (ff->serialize_tt_font(ff, fontdata, tt_size)) - return gs_error_invalidfont; + return_error(gs_error_invalidfont); *(fontdata + tt_size) = 255; *(fontdata + tt_size + 1) = 255; *(fontdata + tt_size + 2) = 0; @@ -1158,9 +1154,9 @@ hy *= 256; while (hx < 1.5 || hy < 1.5) { - world_scale += 8; - hx *= 256; - hy *= 256; + world_scale += 1; + hx *= 10; + hy *= 10; } } fc->s.m2.world_scale = world_scale; @@ -1330,7 +1326,7 @@ } static gs_fapi_retcode -gs_fapi_ufst_get_font_bbox(gs_fapi_server * server, gs_fapi_font * ff, int BBox[4]) +gs_fapi_ufst_get_font_bbox(gs_fapi_server * server, gs_fapi_font * ff, int BBox[4], int unitsPerEm[2]) { fapi_ufst_server *r = If_to_I(server); SW16 VLCPower = 0; @@ -1352,6 +1348,9 @@ BBox[1] >>= VLCPower; BBox[2] >>= VLCPower; BBox[3] >>= VLCPower; + + unitsPerEm[0] = unitsPerEm[1] = 1; + return 0; } @@ -1538,7 +1537,7 @@ } else if (*segment == 0x02) { points += 2; - return gs_error_invalidfont; /* This must not happen */ + return_error(gs_error_invalidfont); /* This must not happen */ } else if (*segment == 0x03) { if ((p->gs_error = @@ -1552,7 +1551,7 @@ points += 3; } else - return gs_error_invalidfont; /* This must not happen */ + return_error(gs_error_invalidfont); /* This must not happen */ segment++; } } @@ -1576,9 +1575,10 @@ } static gs_fapi_retcode -get_char(fapi_ufst_server * r, gs_fapi_font * ff, gs_fapi_char_ref * c, - gs_fapi_path * p, gs_fapi_metrics * metrics, UW16 format) +get_char(gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, + gs_fapi_path *p, gs_fapi_metrics *metrics, UW16 format) { + fapi_ufst_server *r = If_to_I(server); UW16 code = 0, code2 = 0; UL32 cc = (UL32) c->char_codes[0]; SL32 design_bbox[4]; @@ -1602,6 +1602,15 @@ design_escapement[0] = design_escapement[1] = 0; + /* NAFF! UFST requires that we recreate the MT font "object" + * each call (although, it should not!). So we want to defeat + * the optimisation that normally prevents that in gs_fapi_do_char() + * by blanking out the cached scale. + */ + if(d->font_type == FC_FCO_TYPE) { + memset(&(server->face.ctm), 0x00, sizeof(server->face.ctm)); + } + if (ff->is_type1) { /* If a charstring in a Type 1 has been replaced with a PS procedure * get_glyph will return -1. We can then return char_code + 1 which @@ -1813,8 +1822,14 @@ design_escapement[1] = 0; } - du_emx = pol->du_emx; - du_emy = pol->du_emy; + if (pol->du_emx > 0 && pol->du_emy > 0) { + du_emx = pol->du_emx; + du_emy = pol->du_emy; + } + else { + du_emx = pIFS->cs.du_emx; + du_emy = pIFS->cs.du_emy; + } design_bbox[0] = pol->left; design_bbox[1] = pol->bottom; @@ -1922,13 +1937,13 @@ } static gs_fapi_retcode -gs_fapi_ufst_get_char_outline_metrics(gs_fapi_server * server, gs_fapi_font * ff, +gs_fapi_ufst_get_char_outline_metrics(gs_fapi_server *server, gs_fapi_font * ff, gs_fapi_char_ref * c, gs_fapi_metrics * metrics) { fapi_ufst_server *r = If_to_I(server); gs_fapi_ufst_release_char_data_inline(r); - return get_char(r, ff, c, NULL, metrics, FC_CUBIC_TYPE); + return get_char(server, ff, c, NULL, metrics, FC_CUBIC_TYPE); /* UFST cannot render enough metrics information without generating raster or outline. r->char_data keeps an outline after calling this function. */ @@ -1950,7 +1965,7 @@ int code; gs_fapi_ufst_release_char_data_inline(r); - code = get_char(r, ff, c, NULL, metrics, FC_BITMAP_TYPE); + code = get_char(server, ff, c, NULL, metrics, FC_BITMAP_TYPE); if (code == ERR_bm_buff || code == ERR_bm_too_big) /* Too big character ? */ return (gs_error_VMerror); return code; @@ -1968,7 +1983,7 @@ gs_fapi_ufst_release_char_data_inline(r); code = - get_char(r, ff, c, NULL, metrics, + get_char(server, ff, c, NULL, metrics, server->use_outline ? FC_CUBIC_TYPE : FC_BITMAP_TYPE); if (code == ERR_bm_buff || code == ERR_bm_too_big) /* Too big character ? */ return (gs_error_VMerror); @@ -1985,7 +2000,7 @@ fapi_ufst_server *r = If_to_I(server); if (!r->bRaster) - return gs_error_limitcheck; + return_error(gs_error_unregistered); else if (r->char_data == NULL) { rast->height = rast->width = rast->line_step = 0; rast->p = 0; @@ -2079,6 +2094,17 @@ return 0; } +static gs_fapi_retcode +gs_fapi_ufst_set_mm_weight_vector(gs_fapi_server *server, gs_fapi_font *ff, float *wvector, int length) +{ + (void)server; + (void)ff; + (void)wvector; + (void)length; + + return gs_error_invalidaccess; +} + /* --------------------- The plugin definition : ------------------------- */ static void gs_fapi_ufst_destroy(gs_fapi_server ** server); @@ -2097,6 +2123,7 @@ {0}, 0, false, + 1, {1, 0, 0, 1, 0, 0}, gs_fapi_ufst_ensure_open, gs_fapi_ufst_get_scaled_font, @@ -2115,7 +2142,8 @@ gs_fapi_ufst_release_char_data, gs_fapi_ufst_release_typeface, gs_fapi_ufst_check_cmap_for_GID, - gs_fapi_ufst_get_font_info + gs_fapi_ufst_get_font_info, + gs_fapi_ufst_set_mm_weight_vector }; int gs_fapi_ufst_init(gs_memory_t * mem, gs_fapi_server ** server); @@ -2125,7 +2153,7 @@ { fapi_ufst_server *serv; int code = 0; - gs_memory_t *cmem = NULL; + gs_memory_t *cmem = mem->non_gc_memory; code = gs_memory_chunk_wrap(&(cmem), mem); if (code != 0) { @@ -2138,7 +2166,7 @@ (fapi_ufst_server), "fapi_ufst_server"); if (serv == 0) - return gs_error_Fatal; + return_error(gs_error_Fatal); memset(serv, 0, sizeof(*serv)); serv->mem = cmem; diff -Nru ghostscript-9.10~dfsg/base/fcntl_.h ghostscript-9.25~dfsg+1/base/fcntl_.h --- ghostscript-9.10~dfsg/base/fcntl_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/fcntl_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Declaration of the O_* flags for open */ diff -Nru ghostscript-9.10~dfsg/base/freetype.mak ghostscript-9.25~dfsg+1/base/freetype.mak --- ghostscript-9.10~dfsg/base/freetype.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/freetype.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # makefile for freetype as part of the monolithic gs build. @@ -33,10 +33,10 @@ # we must define FT2_BUILD_LIBRARY to get internal declarations # If GS is using the system zlib, freetype should also do so, # FT_CONFIG_SYSTEM_ZLIB is set by the top makefile. -FTCC=$(CC_) $(I_)$(FTSRCDIR)$(D)include$(_I) -DFT2_BUILD_LIBRARY -DDARWIN_NO_CARBON $(FT_CONFIG_SYSTEM_ZLIB) +FTCC=$(CC_) $(I_)$(FTSRCDIR)$(D)include$(_I) $(D_)FT2_BUILD_LIBRARY$(_D) $(D_)DARWIN_NO_CARBON$(_D) $(FT_CONFIG_SYSTEM_ZLIB) # Define the name of this makefile. -FT_MAK=$(GLSRC)freetype.mak +FT_MAK=$(GLSRC)freetype.mak $(TOP_MAKEFILES) # file complements for each component ft_autofit=\ @@ -49,7 +49,10 @@ $(FTOBJ)aflatin.$(OBJ) \ $(FTOBJ)afloader.$(OBJ) \ $(FTOBJ)afmodule.$(OBJ) \ - $(FTOBJ)afwarp.$(OBJ) + $(FTOBJ)afwarp.$(OBJ) \ + $(FTOBJ)afblue.$(OBJ) \ + $(FTOBJ)afranges.$(OBJ) \ + $(FTOBJ)afshaper.$(OBJ) ft_base=\ $(FTOBJ)ftadvanc.$(OBJ) \ @@ -80,8 +83,12 @@ $(FTOBJ)ftsystem.$(OBJ) \ $(FTOBJ)fttype1.$(OBJ) \ $(FTOBJ)ftwinfnt.$(OBJ) \ - $(FTOBJ)ftxf86.$(OBJ) \ - $(FTOBJ)ftpatent.$(OBJ) + $(FTOBJ)ftpatent.$(OBJ) \ + $(FTOBJ)ftmd5.$(OBJ) \ + $(FTOBJ)fthash.$(OBJ) \ + $(FTOBJ)ftpsprop.$(OBJ) \ + $(FTOBJ)ftfntfmt.$(OBJ) + ft_bdf=\ $(FTOBJ)bdflib.$(OBJ) \ @@ -98,12 +105,13 @@ $(FTOBJ)ftcsbits.$(OBJ) ft_cff=\ - $(FTOBJ)cffobjs.$(OBJ) \ - $(FTOBJ)cffload.$(OBJ) \ + $(FTOBJ)cffdrivr.$(OBJ) \ + $(FTOBJ)cffcmap.$(OBJ) \ $(FTOBJ)cffgload.$(OBJ) \ + $(FTOBJ)cffload.$(OBJ) \ + $(FTOBJ)cffobjs.$(OBJ) \ $(FTOBJ)cffparse.$(OBJ) \ - $(FTOBJ)cffcmap.$(OBJ) \ - $(FTOBJ)cffdrivr.$(OBJ) + $(FTOBJ)cffpic.$(OBJ) ft_cid=\ $(FTOBJ)cidparse.$(OBJ) \ @@ -135,7 +143,17 @@ $(FTOBJ)t1cmap.$(OBJ) \ $(FTOBJ)afmparse.$(OBJ) \ $(FTOBJ)psconv.$(OBJ) \ - $(FTOBJ)psauxmod.$(OBJ) + $(FTOBJ)psauxmod.$(OBJ) \ + $(FTOBJ)psft.$(OBJ) \ + $(FTOBJ)cffdecode.$(OBJ) \ + $(FTOBJ)psfont.$(OBJ) \ + $(FTOBJ)psblues.$(OBJ) \ + $(FTOBJ)psintrp.$(OBJ) \ + $(FTOBJ)pserror.$(OBJ) \ + $(FTOBJ)psstack.$(OBJ) \ + $(FTOBJ)pshints.$(OBJ) \ + $(FTOBJ)psarrst.$(OBJ) \ + $(FTOBJ)psread.$(OBJ) ft_pshinter=\ $(FTOBJ)pshrec.$(OBJ) \ @@ -167,7 +185,9 @@ $(FTOBJ)ttsbit.$(OBJ) \ $(FTOBJ)ttkern.$(OBJ) \ $(FTOBJ)ttbdf.$(OBJ) \ - $(FTOBJ)sfntpic.$(OBJ) + $(FTOBJ)sfntpic.$(OBJ) \ + $(FTOBJ)pngshim.$(OBJ) + ft_truetype=\ $(FTOBJ)ttdriver.$(OBJ) \ @@ -176,7 +196,8 @@ $(FTOBJ)ttgload.$(OBJ) \ $(FTOBJ)ft2ttinterp.$(OBJ) \ $(FTOBJ)ttgxvar.$(OBJ) \ - $(FTOBJ)ttpic.$(OBJ) + $(FTOBJ)ttpic.$(OBJ) \ + $(FTOBJ)ttsubpix.$(OBJ) ft_type1=\ $(FTOBJ)t1afm.$(OBJ) \ @@ -194,19 +215,19 @@ ft_winfonts=$(FTOBJ)winfnt.$(OBJ) # instantiate the requested build option (shared or compiled in) -$(FTGEN)freetype.dev : $(TOP_MAKEFILES) $(FTGEN)freetype_$(SHARE_FT).dev +$(FTGEN)freetype.dev : $(FT_MAK) $(FTGEN)freetype_$(SHARE_FT).dev $(FT_MAK) $(MAKEDIRS) $(CP_) $(FTGEN)freetype_$(SHARE_FT).dev $(FTGEN)freetype.dev # Define the shared version. -$(FTGEN)freetype_1.dev : $(TOP_MAKEFILES) $(FT_MAK) $(ECHOGS_XE) +$(FTGEN)freetype_1.dev : $(TOP_MAKEFILES) $(FT_MAK) $(ECHOGS_XE) $(FT_MAK) $(MAKEDIRS) $(SETMOD) $(FTGEN)freetype_1 -link $(FT_LIBS) # Define the non-shared version. -$(FTGEN)freetype_0.dev : $(TOP_MAKEFILES) $(FT_MAK) $(ECHOGS_XE) \ +$(FTGEN)freetype_0.dev : $(FT_MAK) $(ECHOGS_XE) \ $(ft_autofit) $(ft_base) $(ft_bdf) $(ft_cache) $(ft_cff) $(ft_cid) \ $(ft_gzip) $(ft_lzw) $(ft_pcf) $(ft_pfr) $(ft_psaux) $(ft_pshinter) \ $(ft_psnames) $(ft_raster) $(ft_smooth) $(ft_sfnt) $(ft_truetype) \ - $(ft_type1) $(ft_type42) $(ft_winfonts) + $(ft_type1) $(ft_type42) $(ft_winfonts) $(MAKEDIRS) $(SETMOD) $(FTGEN)freetype_0 $(ft_autofit) $(ADDMOD) $(FTGEN)freetype_0 $(ft_base) $(ADDMOD) $(FTGEN)freetype_0 $(ft_bdf) @@ -231,354 +252,413 @@ # custom build rules for each source file -$(FTOBJ)afangles.$(OBJ) : $(FTSRC)autofit$(D)afangles.c +$(FTOBJ)afangles.$(OBJ) : $(FTSRC)autofit$(D)afangles.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afangles.$(OBJ) $(C_) $(FTSRC)autofit$(D)afangles.c -$(FTOBJ)afcjk.$(OBJ) : $(FTSRC)autofit$(D)afcjk.c +$(FTOBJ)afcjk.$(OBJ) : $(FTSRC)autofit$(D)afcjk.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afcjk.$(OBJ) $(C_) $(FTSRC)autofit$(D)afcjk.c -$(FTOBJ)afdummy.$(OBJ) : $(FTSRC)autofit$(D)afdummy.c +$(FTOBJ)afdummy.$(OBJ) : $(FTSRC)autofit$(D)afdummy.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afdummy.$(OBJ) $(C_) $(FTSRC)autofit$(D)afdummy.c -$(FTOBJ)afglobal.$(OBJ) : $(FTSRC)autofit$(D)afglobal.c +$(FTOBJ)afglobal.$(OBJ) : $(FTSRC)autofit$(D)afglobal.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afglobal.$(OBJ) $(C_) $(FTSRC)autofit$(D)afglobal.c -$(FTOBJ)afhints.$(OBJ) : $(FTSRC)autofit$(D)afhints.c +$(FTOBJ)afhints.$(OBJ) : $(FTSRC)autofit$(D)afhints.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afhints.$(OBJ) $(C_) $(FTSRC)autofit$(D)afhints.c -$(FTOBJ)afindic.$(OBJ) : $(FTSRC)autofit$(D)afindic.c +$(FTOBJ)afindic.$(OBJ) : $(FTSRC)autofit$(D)afindic.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afindic.$(OBJ) $(C_) $(FTSRC)autofit$(D)afindic.c -$(FTOBJ)aflatin.$(OBJ) : $(FTSRC)autofit$(D)aflatin.c +$(FTOBJ)aflatin.$(OBJ) : $(FTSRC)autofit$(D)aflatin.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)aflatin.$(OBJ) $(C_) $(FTSRC)autofit$(D)aflatin.c -$(FTOBJ)afloader.$(OBJ) : $(FTSRC)autofit$(D)afloader.c +$(FTOBJ)afloader.$(OBJ) : $(FTSRC)autofit$(D)afloader.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afloader.$(OBJ) $(C_) $(FTSRC)autofit$(D)afloader.c -$(FTOBJ)afmodule.$(OBJ) : $(FTSRC)autofit$(D)afmodule.c +$(FTOBJ)afmodule.$(OBJ) : $(FTSRC)autofit$(D)afmodule.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afmodule.$(OBJ) $(C_) $(FTSRC)autofit$(D)afmodule.c -$(FTOBJ)afwarp.$(OBJ) : $(FTSRC)autofit$(D)afwarp.c +$(FTOBJ)afwarp.$(OBJ) : $(FTSRC)autofit$(D)afwarp.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afwarp.$(OBJ) $(C_) $(FTSRC)autofit$(D)afwarp.c +$(FTOBJ)afblue.$(OBJ) : $(FTSRC)autofit$(D)afblue.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)afblue.$(OBJ) $(C_) $(FTSRC)autofit$(D)afblue.c + +$(FTOBJ)afranges.$(OBJ) : $(FTSRC)autofit$(D)afranges.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)afranges.$(OBJ) $(C_) $(FTSRC)autofit$(D)afranges.c + +$(FTOBJ)afshaper.$(OBJ) : $(FTSRC)autofit$(D)afshaper.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)afshaper.$(OBJ) $(C_) $(FTSRC)autofit$(D)afshaper.c -$(FTOBJ)ftadvanc.$(OBJ) : $(FTSRC)base$(D)ftadvanc.c +$(FTOBJ)ftadvanc.$(OBJ) : $(FTSRC)base$(D)ftadvanc.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftadvanc.$(OBJ) $(C_) $(FTSRC)base$(D)ftadvanc.c -$(FTOBJ)ftcalc.$(OBJ) : $(FTSRC)base$(D)ftcalc.c +$(FTOBJ)ftcalc.$(OBJ) : $(FTSRC)base$(D)ftcalc.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftcalc.$(OBJ) $(C_) $(FTSRC)base$(D)ftcalc.c -$(FTOBJ)ftdbgmem.$(OBJ) : $(FTSRC)base$(D)ftdbgmem.c +$(FTOBJ)ftdbgmem.$(OBJ) : $(FTSRC)base$(D)ftdbgmem.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftdbgmem.$(OBJ) $(C_) $(FTSRC)base$(D)ftdbgmem.c -$(FTOBJ)ftgloadr.$(OBJ) : $(FTSRC)base$(D)ftgloadr.c +$(FTOBJ)ftgloadr.$(OBJ) : $(FTSRC)base$(D)ftgloadr.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftgloadr.$(OBJ) $(C_) $(FTSRC)base$(D)ftgloadr.c -$(FTOBJ)ftobjs.$(OBJ) : $(FTSRC)base$(D)ftobjs.c +$(FTOBJ)ftobjs.$(OBJ) : $(FTSRC)base$(D)ftobjs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftobjs.$(OBJ) $(C_) $(FTSRC)base$(D)ftobjs.c -$(FTOBJ)ftoutln.$(OBJ) : $(FTSRC)base$(D)ftoutln.c +$(FTOBJ)ftoutln.$(OBJ) : $(FTSRC)base$(D)ftoutln.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftoutln.$(OBJ) $(C_) $(FTSRC)base$(D)ftoutln.c -$(FTOBJ)ftrfork.$(OBJ) : $(FTSRC)base$(D)ftrfork.c +$(FTOBJ)ftrfork.$(OBJ) : $(FTSRC)base$(D)ftrfork.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftrfork.$(OBJ) $(C_) $(FTSRC)base$(D)ftrfork.c -$(FTOBJ)ftsnames.$(OBJ) : $(FTSRC)base$(D)ftsnames.c +$(FTOBJ)ftsnames.$(OBJ) : $(FTSRC)base$(D)ftsnames.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftsnames.$(OBJ) $(C_) $(FTSRC)base$(D)ftsnames.c -$(FTOBJ)ftstream.$(OBJ) : $(FTSRC)base$(D)ftstream.c +$(FTOBJ)ftstream.$(OBJ) : $(FTSRC)base$(D)ftstream.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftstream.$(OBJ) $(C_) $(FTSRC)base$(D)ftstream.c -$(FTOBJ)fttrigon.$(OBJ) : $(FTSRC)base$(D)fttrigon.c +$(FTOBJ)fttrigon.$(OBJ) : $(FTSRC)base$(D)fttrigon.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)fttrigon.$(OBJ) $(C_) $(FTSRC)base$(D)fttrigon.c -$(FTOBJ)ftutil.$(OBJ) : $(FTSRC)base$(D)ftutil.c +$(FTOBJ)ftutil.$(OBJ) : $(FTSRC)base$(D)ftutil.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftutil.$(OBJ) $(C_) $(FTSRC)base$(D)ftutil.c -$(FTOBJ)ftbbox.$(OBJ) : $(FTSRC)base$(D)ftbbox.c +$(FTOBJ)ftbbox.$(OBJ) : $(FTSRC)base$(D)ftbbox.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftbbox.$(OBJ) $(C_) $(FTSRC)base$(D)ftbbox.c -$(FTOBJ)ftbdf.$(OBJ) : $(FTSRC)base$(D)ftbdf.c +$(FTOBJ)ftbdf.$(OBJ) : $(FTSRC)base$(D)ftbdf.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftbdf.$(OBJ) $(C_) $(FTSRC)base$(D)ftbdf.c -$(FTOBJ)ftbitmap.$(OBJ) : $(FTSRC)base$(D)ftbitmap.c +$(FTOBJ)ftbitmap.$(OBJ) : $(FTSRC)base$(D)ftbitmap.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftbitmap.$(OBJ) $(C_) $(FTSRC)base$(D)ftbitmap.c -$(FTOBJ)ftdebug.$(OBJ) : $(FTSRC)base$(D)ftdebug.c +$(FTOBJ)ftdebug.$(OBJ) : $(FTSRC)base$(D)ftdebug.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftdebug.$(OBJ) $(C_) $(FTSRC)base$(D)ftdebug.c -$(FTOBJ)ftgasp.$(OBJ) : $(FTSRC)base$(D)ftgasp.c +$(FTOBJ)ftgasp.$(OBJ) : $(FTSRC)base$(D)ftgasp.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftgasp.$(OBJ) $(C_) $(FTSRC)base$(D)ftgasp.c -$(FTOBJ)ftglyph.$(OBJ) : $(FTSRC)base$(D)ftglyph.c +$(FTOBJ)ftglyph.$(OBJ) : $(FTSRC)base$(D)ftglyph.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftglyph.$(OBJ) $(C_) $(FTSRC)base$(D)ftglyph.c -$(FTOBJ)ftgxval.$(OBJ) : $(FTSRC)base$(D)ftgxval.c +$(FTOBJ)ftgxval.$(OBJ) : $(FTSRC)base$(D)ftgxval.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftgxval.$(OBJ) $(C_) $(FTSRC)base$(D)ftgxval.c -$(FTOBJ)ftinit.$(OBJ) : $(FTSRC)base$(D)ftinit.c +$(FTOBJ)ftinit.$(OBJ) : $(FTSRC)base$(D)ftinit.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftinit.$(OBJ) $(C_) $(FTSRC)base$(D)ftinit.c -$(FTOBJ)ftlcdfil.$(OBJ) : $(FTSRC)base$(D)ftlcdfil.c +$(FTOBJ)ftlcdfil.$(OBJ) : $(FTSRC)base$(D)ftlcdfil.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftlcdfil.$(OBJ) $(C_) $(FTSRC)base$(D)ftlcdfil.c -$(FTOBJ)ftmm.$(OBJ) : $(FTSRC)base$(D)ftmm.c +$(FTOBJ)ftmm.$(OBJ) : $(FTSRC)base$(D)ftmm.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftmm.$(OBJ) $(C_) $(FTSRC)base$(D)ftmm.c -$(FTOBJ)ftotval.$(OBJ) : $(FTSRC)base$(D)ftotval.c +$(FTOBJ)ftotval.$(OBJ) : $(FTSRC)base$(D)ftotval.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftotval.$(OBJ) $(C_) $(FTSRC)base$(D)ftotval.c -$(FTOBJ)ftpfr.$(OBJ) : $(FTSRC)base$(D)ftpfr.c +$(FTOBJ)ftpfr.$(OBJ) : $(FTSRC)base$(D)ftpfr.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftpfr.$(OBJ) $(C_) $(FTSRC)base$(D)ftpfr.c -$(FTOBJ)ftstroke.$(OBJ) : $(FTSRC)base$(D)ftstroke.c +$(FTOBJ)ftstroke.$(OBJ) : $(FTSRC)base$(D)ftstroke.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftstroke.$(OBJ) $(C_) $(FTSRC)base$(D)ftstroke.c -$(FTOBJ)ftsynth.$(OBJ) : $(FTSRC)base$(D)ftsynth.c +$(FTOBJ)ftsynth.$(OBJ) : $(FTSRC)base$(D)ftsynth.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftsynth.$(OBJ) $(C_) $(FTSRC)base$(D)ftsynth.c -$(FTOBJ)ftsystem.$(OBJ) : $(FTSRC)base$(D)ftsystem.c +$(FTOBJ)ftsystem.$(OBJ) : $(FTSRC)base$(D)ftsystem.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftsystem.$(OBJ) $(C_) $(FTSRC)base$(D)ftsystem.c -$(FTOBJ)fttype1.$(OBJ) : $(FTSRC)base$(D)fttype1.c +$(FTOBJ)fttype1.$(OBJ) : $(FTSRC)base$(D)fttype1.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)fttype1.$(OBJ) $(C_) $(FTSRC)base$(D)fttype1.c -$(FTOBJ)ftwinfnt.$(OBJ) : $(FTSRC)base$(D)ftwinfnt.c +$(FTOBJ)ftwinfnt.$(OBJ) : $(FTSRC)base$(D)ftwinfnt.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftwinfnt.$(OBJ) $(C_) $(FTSRC)base$(D)ftwinfnt.c -$(FTOBJ)ftxf86.$(OBJ) : $(FTSRC)base$(D)ftxf86.c - $(FTCC) $(FTO_)ftxf86.$(OBJ) $(C_) $(FTSRC)base$(D)ftxf86.c - -$(FTOBJ)ftpatent.$(OBJ) : $(FTSRC)base$(D)ftpatent.c +$(FTOBJ)ftpatent.$(OBJ) : $(FTSRC)base$(D)ftpatent.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftpatent.$(OBJ) $(C_) $(FTSRC)base$(D)ftpatent.c -$(FTOBJ)bdflib.$(OBJ) : $(FTSRC)bdf$(D)bdflib.c +$(FTOBJ)ftmd5.$(OBJ) : $(FTSRC)base$(D)md5.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)ftmd5.$(OBJ) $(C_) $(FTSRC)base$(D)md5.c + +$(FTOBJ)fthash.$(OBJ) : $(FTSRC)base$(D)fthash.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)fthash.$(OBJ) $(C_) $(FTSRC)base$(D)fthash.c + +$(FTOBJ)ftpsprop.$(OBJ) : $(FTSRC)base$(D)ftpsprop.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)ftpsprop.$(OBJ) $(C_) $(FTSRC)base$(D)ftpsprop.c + +$(FTOBJ)ftfntfmt.$(OBJ) : $(FTSRC)base$(D)ftfntfmt.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)ftfntfmt.$(OBJ) $(C_) $(FTSRC)base$(D)ftfntfmt.c + +$(FTOBJ)bdflib.$(OBJ) : $(FTSRC)bdf$(D)bdflib.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)bdflib.$(OBJ) $(C_) $(FTSRC)bdf$(D)bdflib.c -$(FTOBJ)bdfdrivr.$(OBJ) : $(FTSRC)bdf$(D)bdfdrivr.c +$(FTOBJ)bdfdrivr.$(OBJ) : $(FTSRC)bdf$(D)bdfdrivr.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)bdfdrivr.$(OBJ) $(C_) $(FTSRC)bdf$(D)bdfdrivr.c -$(FTOBJ)ftcbasic.$(OBJ) : $(FTSRC)cache$(D)ftcbasic.c +$(FTOBJ)ftcbasic.$(OBJ) : $(FTSRC)cache$(D)ftcbasic.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftcbasic.$(OBJ) $(C_) $(FTSRC)cache$(D)ftcbasic.c -$(FTOBJ)ft2ccache.$(OBJ) : $(FTSRC)cache$(D)ftccache.c +$(FTOBJ)ft2ccache.$(OBJ) : $(FTSRC)cache$(D)ftccache.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ft2ccache.$(OBJ) $(C_) $(FTSRC)cache$(D)ftccache.c -$(FTOBJ)ftccmap.$(OBJ) : $(FTSRC)cache$(D)ftccmap.c +$(FTOBJ)ftccmap.$(OBJ) : $(FTSRC)cache$(D)ftccmap.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftccmap.$(OBJ) $(C_) $(FTSRC)cache$(D)ftccmap.c -$(FTOBJ)ftcglyph.$(OBJ) : $(FTSRC)cache$(D)ftcglyph.c +$(FTOBJ)ftcglyph.$(OBJ) : $(FTSRC)cache$(D)ftcglyph.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftcglyph.$(OBJ) $(C_) $(FTSRC)cache$(D)ftcglyph.c -$(FTOBJ)ftcimage.$(OBJ) : $(FTSRC)cache$(D)ftcimage.c +$(FTOBJ)ftcimage.$(OBJ) : $(FTSRC)cache$(D)ftcimage.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftcimage.$(OBJ) $(C_) $(FTSRC)cache$(D)ftcimage.c -$(FTOBJ)ftcmanag.$(OBJ) : $(FTSRC)cache$(D)ftcmanag.c +$(FTOBJ)ftcmanag.$(OBJ) : $(FTSRC)cache$(D)ftcmanag.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftcmanag.$(OBJ) $(C_) $(FTSRC)cache$(D)ftcmanag.c -$(FTOBJ)ftcmru.$(OBJ) : $(FTSRC)cache$(D)ftcmru.c +$(FTOBJ)ftcmru.$(OBJ) : $(FTSRC)cache$(D)ftcmru.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftcmru.$(OBJ) $(C_) $(FTSRC)cache$(D)ftcmru.c -$(FTOBJ)ftcsbits.$(OBJ) : $(FTSRC)cache$(D)ftcsbits.c +$(FTOBJ)ftcsbits.$(OBJ) : $(FTSRC)cache$(D)ftcsbits.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftcsbits.$(OBJ) $(C_) $(FTSRC)cache$(D)ftcsbits.c -$(FTOBJ)cffobjs.$(OBJ) : $(FTSRC)cff$(D)cffobjs.c - $(FTCC) $(FTO_)cffobjs.$(OBJ) $(C_) $(FTSRC)cff$(D)cffobjs.c +$(FTOBJ)cff.$(OBJ) : $(FTSRC)cff$(D)cff.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cff.$(OBJ) $(C_) $(FTSRC)cff$(D)cff.c -$(FTOBJ)cffload.$(OBJ) : $(FTSRC)cff$(D)cffload.c - $(FTCC) $(FTO_)cffload.$(OBJ) $(C_) $(FTSRC)cff$(D)cffload.c +$(FTOBJ)cffcmap.$(OBJ) : $(FTSRC)cff$(D)cffcmap.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cffcmap.$(OBJ) $(C_) $(FTSRC)cff$(D)cffcmap.c + +$(FTOBJ)cffdrivr.$(OBJ) : $(FTSRC)cff$(D)cffdrivr.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cffdrivr.$(OBJ) $(C_) $(FTSRC)cff$(D)cffdrivr.c -$(FTOBJ)cffgload.$(OBJ) : $(FTSRC)cff$(D)cffgload.c +$(FTOBJ)cffgload.$(OBJ) : $(FTSRC)cff$(D)cffgload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)cffgload.$(OBJ) $(C_) $(FTSRC)cff$(D)cffgload.c -$(FTOBJ)cffparse.$(OBJ) : $(FTSRC)cff$(D)cffparse.c - $(FTCC) $(FTO_)cffparse.$(OBJ) $(C_) $(FTSRC)cff$(D)cffparse.c +$(FTOBJ)cffload.$(OBJ) : $(FTSRC)cff$(D)cffload.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cffload.$(OBJ) $(C_) $(FTSRC)cff$(D)cffload.c -$(FTOBJ)cffcmap.$(OBJ) : $(FTSRC)cff$(D)cffcmap.c - $(FTCC) $(FTO_)cffcmap.$(OBJ) $(C_) $(FTSRC)cff$(D)cffcmap.c +$(FTOBJ)cffobjs.$(OBJ) : $(FTSRC)cff$(D)cffobjs.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cffobjs.$(OBJ) $(C_) $(FTSRC)cff$(D)cffobjs.c -$(FTOBJ)cffdrivr.$(OBJ) : $(FTSRC)cff$(D)cffdrivr.c - $(FTCC) $(FTO_)cffdrivr.$(OBJ) $(C_) $(FTSRC)cff$(D)cffdrivr.c +$(FTOBJ)cffparse.$(OBJ) : $(FTSRC)cff$(D)cffparse.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cffparse.$(OBJ) $(C_) $(FTSRC)cff$(D)cffparse.c + +$(FTOBJ)cffpic.$(OBJ) : $(FTSRC)cff$(D)cffpic.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cffpic.$(OBJ) $(C_) $(FTSRC)cff$(D)cffpic.c -$(FTOBJ)cidparse.$(OBJ) : $(FTSRC)cid$(D)cidparse.c +$(FTOBJ)cidparse.$(OBJ) : $(FTSRC)cid$(D)cidparse.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)cidparse.$(OBJ) $(C_) $(FTSRC)cid$(D)cidparse.c -$(FTOBJ)cidload.$(OBJ) : $(FTSRC)cid$(D)cidload.c +$(FTOBJ)cidload.$(OBJ) : $(FTSRC)cid$(D)cidload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)cidload.$(OBJ) $(C_) $(FTSRC)cid$(D)cidload.c -$(FTOBJ)cidriver.$(OBJ) : $(FTSRC)cid$(D)cidriver.c +$(FTOBJ)cidriver.$(OBJ) : $(FTSRC)cid$(D)cidriver.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)cidriver.$(OBJ) $(C_) $(FTSRC)cid$(D)cidriver.c -$(FTOBJ)cidgload.$(OBJ) : $(FTSRC)cid$(D)cidgload.c +$(FTOBJ)cidgload.$(OBJ) : $(FTSRC)cid$(D)cidgload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)cidgload.$(OBJ) $(C_) $(FTSRC)cid$(D)cidgload.c -$(FTOBJ)cidobjs.$(OBJ) : $(FTSRC)cid$(D)cidobjs.c +$(FTOBJ)cidobjs.$(OBJ) : $(FTSRC)cid$(D)cidobjs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)cidobjs.$(OBJ) $(C_) $(FTSRC)cid$(D)cidobjs.c -$(FTOBJ)ftgzip.$(OBJ) : $(FTSRC)gzip$(D)ftgzip.c +$(FTOBJ)ftgzip.$(OBJ) : $(FTSRC)gzip$(D)ftgzip.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftgzip.$(OBJ) $(C_) $(FTSRC)gzip$(D)ftgzip.c -$(FTOBJ)ftlzw.$(OBJ) : $(FTSRC)lzw$(D)ftlzw.c +$(FTOBJ)ftlzw.$(OBJ) : $(FTSRC)lzw$(D)ftlzw.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftlzw.$(OBJ) $(C_) $(FTSRC)lzw$(D)ftlzw.c -$(FTOBJ)pcfdrivr.$(OBJ) : $(FTSRC)pcf$(D)pcfdrivr.c +$(FTOBJ)pcfdrivr.$(OBJ) : $(FTSRC)pcf$(D)pcfdrivr.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pcfdrivr.$(OBJ) $(C_) $(FTSRC)pcf$(D)pcfdrivr.c -$(FTOBJ)pcfread.$(OBJ) : $(FTSRC)pcf$(D)pcfread.c +$(FTOBJ)pcfread.$(OBJ) : $(FTSRC)pcf$(D)pcfread.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pcfread.$(OBJ) $(C_) $(FTSRC)pcf$(D)pcfread.c -$(FTOBJ)pcfutil.$(OBJ) : $(FTSRC)pcf$(D)pcfutil.c +$(FTOBJ)pcfutil.$(OBJ) : $(FTSRC)pcf$(D)pcfutil.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pcfutil.$(OBJ) $(C_) $(FTSRC)pcf$(D)pcfutil.c -$(FTOBJ)pfrload.$(OBJ) : $(FTSRC)pfr$(D)pfrload.c +$(FTOBJ)pfrload.$(OBJ) : $(FTSRC)pfr$(D)pfrload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pfrload.$(OBJ) $(C_) $(FTSRC)pfr$(D)pfrload.c -$(FTOBJ)pfrgload.$(OBJ) : $(FTSRC)pfr$(D)pfrgload.c +$(FTOBJ)pfrgload.$(OBJ) : $(FTSRC)pfr$(D)pfrgload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pfrgload.$(OBJ) $(C_) $(FTSRC)pfr$(D)pfrgload.c -$(FTOBJ)pfrcmap.$(OBJ) : $(FTSRC)pfr$(D)pfrcmap.c +$(FTOBJ)pfrcmap.$(OBJ) : $(FTSRC)pfr$(D)pfrcmap.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pfrcmap.$(OBJ) $(C_) $(FTSRC)pfr$(D)pfrcmap.c -$(FTOBJ)pfrdrivr.$(OBJ) : $(FTSRC)pfr$(D)pfrdrivr.c +$(FTOBJ)pfrdrivr.$(OBJ) : $(FTSRC)pfr$(D)pfrdrivr.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pfrdrivr.$(OBJ) $(C_) $(FTSRC)pfr$(D)pfrdrivr.c -$(FTOBJ)pfrsbit.$(OBJ) : $(FTSRC)pfr$(D)pfrsbit.c +$(FTOBJ)pfrsbit.$(OBJ) : $(FTSRC)pfr$(D)pfrsbit.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pfrsbit.$(OBJ) $(C_) $(FTSRC)pfr$(D)pfrsbit.c -$(FTOBJ)pfrobjs.$(OBJ) : $(FTSRC)pfr$(D)pfrobjs.c +$(FTOBJ)pfrobjs.$(OBJ) : $(FTSRC)pfr$(D)pfrobjs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pfrobjs.$(OBJ) $(C_) $(FTSRC)pfr$(D)pfrobjs.c -$(FTOBJ)psobjs.$(OBJ) : $(FTSRC)psaux$(D)psobjs.c +$(FTOBJ)psobjs.$(OBJ) : $(FTSRC)psaux$(D)psobjs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)psobjs.$(OBJ) $(C_) $(FTSRC)psaux$(D)psobjs.c -$(FTOBJ)t1decode.$(OBJ) : $(FTSRC)psaux$(D)t1decode.c +$(FTOBJ)t1decode.$(OBJ) : $(FTSRC)psaux$(D)t1decode.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1decode.$(OBJ) $(C_) $(FTSRC)psaux$(D)t1decode.c -$(FTOBJ)t1cmap.$(OBJ) : $(FTSRC)psaux$(D)t1cmap.c +$(FTOBJ)t1cmap.$(OBJ) : $(FTSRC)psaux$(D)t1cmap.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1cmap.$(OBJ) $(C_) $(FTSRC)psaux$(D)t1cmap.c -$(FTOBJ)afmparse.$(OBJ) : $(FTSRC)psaux$(D)afmparse.c +$(FTOBJ)afmparse.$(OBJ) : $(FTSRC)psaux$(D)afmparse.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)afmparse.$(OBJ) $(C_) $(FTSRC)psaux$(D)afmparse.c -$(FTOBJ)psconv.$(OBJ) : $(FTSRC)psaux$(D)psconv.c +$(FTOBJ)psconv.$(OBJ) : $(FTSRC)psaux$(D)psconv.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)psconv.$(OBJ) $(C_) $(FTSRC)psaux$(D)psconv.c -$(FTOBJ)psauxmod.$(OBJ) : $(FTSRC)psaux$(D)psauxmod.c +$(FTOBJ)psauxmod.$(OBJ) : $(FTSRC)psaux$(D)psauxmod.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)psauxmod.$(OBJ) $(C_) $(FTSRC)psaux$(D)psauxmod.c -$(FTOBJ)pshrec.$(OBJ) : $(FTSRC)pshinter$(D)pshrec.c +$(FTOBJ)psft.$(OBJ) : $(FTSRC)psaux$(D)psft.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)psft.$(OBJ) $(C_) $(FTSRC)psaux$(D)psft.c + +$(FTOBJ)cffdecode.$(OBJ) : $(FTSRC)psaux$(D)cffdecode.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)cffdecode.$(OBJ) $(C_) $(FTSRC)psaux$(D)cffdecode.c + +$(FTOBJ)psfont.$(OBJ) : $(FTSRC)psaux$(D)psfont.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)psfont.$(OBJ) $(C_) $(FTSRC)psaux$(D)psfont.c + +$(FTOBJ)psblues.$(OBJ) : $(FTSRC)psaux$(D)psblues.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)psblues.$(OBJ) $(C_) $(FTSRC)psaux$(D)psblues.c + +$(FTOBJ)psintrp.$(OBJ) : $(FTSRC)psaux$(D)psintrp.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)psintrp.$(OBJ) $(C_) $(FTSRC)psaux$(D)psintrp.c + +$(FTOBJ)pserror.$(OBJ) : $(FTSRC)psaux$(D)pserror.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)pserror.$(OBJ) $(C_) $(FTSRC)psaux$(D)pserror.c + +$(FTOBJ)psstack.$(OBJ) : $(FTSRC)psaux$(D)psstack.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)psstack.$(OBJ) $(C_) $(FTSRC)psaux$(D)psstack.c + +$(FTOBJ)pshints.$(OBJ) : $(FTSRC)psaux$(D)pshints.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)pshints.$(OBJ) $(C_) $(FTSRC)psaux$(D)pshints.c + +$(FTOBJ)psarrst.$(OBJ) : $(FTSRC)psaux$(D)psarrst.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)psarrst.$(OBJ) $(C_) $(FTSRC)psaux$(D)psarrst.c + +$(FTOBJ)psread.$(OBJ) : $(FTSRC)psaux$(D)psread.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)psread.$(OBJ) $(C_) $(FTSRC)psaux$(D)psread.c + +$(FTOBJ)pshrec.$(OBJ) : $(FTSRC)pshinter$(D)pshrec.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pshrec.$(OBJ) $(C_) $(FTSRC)pshinter$(D)pshrec.c -$(FTOBJ)pshglob.$(OBJ) : $(FTSRC)pshinter$(D)pshglob.c +$(FTOBJ)pshglob.$(OBJ) : $(FTSRC)pshinter$(D)pshglob.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pshglob.$(OBJ) $(C_) $(FTSRC)pshinter$(D)pshglob.c -$(FTOBJ)pshmod.$(OBJ) : $(FTSRC)pshinter$(D)pshmod.c +$(FTOBJ)pshmod.$(OBJ) : $(FTSRC)pshinter$(D)pshmod.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pshmod.$(OBJ) $(C_) $(FTSRC)pshinter$(D)pshmod.c -$(FTOBJ)pshalgo.$(OBJ) : $(FTSRC)pshinter$(D)pshalgo.c +$(FTOBJ)pshalgo.$(OBJ) : $(FTSRC)pshinter$(D)pshalgo.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pshalgo.$(OBJ) $(C_) $(FTSRC)pshinter$(D)pshalgo.c -$(FTOBJ)psmodule.$(OBJ) : $(FTSRC)psnames$(D)psmodule.c +$(FTOBJ)psmodule.$(OBJ) : $(FTSRC)psnames$(D)psmodule.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)psmodule.$(OBJ) $(C_) $(FTSRC)psnames$(D)psmodule.c -$(FTOBJ)pspic.$(OBJ) : $(FTSRC)psnames$(D)pspic.c +$(FTOBJ)pspic.$(OBJ) : $(FTSRC)psnames$(D)pspic.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)pspic.$(OBJ) $(C_) $(FTSRC)psnames$(D)pspic.c -$(FTOBJ)ftraster.$(OBJ) : $(FTSRC)raster$(D)ftraster.c +$(FTOBJ)ftraster.$(OBJ) : $(FTSRC)raster$(D)ftraster.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftraster.$(OBJ) $(C_) $(FTSRC)raster$(D)ftraster.c -$(FTOBJ)ftrend1.$(OBJ) : $(FTSRC)raster$(D)ftrend1.c +$(FTOBJ)ftrend1.$(OBJ) : $(FTSRC)raster$(D)ftrend1.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftrend1.$(OBJ) $(C_) $(FTSRC)raster$(D)ftrend1.c -$(FTOBJ)rastpic.$(OBJ) : $(FTSRC)raster$(D)rastpic.c +$(FTOBJ)rastpic.$(OBJ) : $(FTSRC)raster$(D)rastpic.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)rastpic.$(OBJ) $(C_) $(FTSRC)raster$(D)rastpic.c -$(FTOBJ)ftgrays.$(OBJ) : $(FTSRC)smooth$(D)ftgrays.c +$(FTOBJ)ftgrays.$(OBJ) : $(FTSRC)smooth$(D)ftgrays.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftgrays.$(OBJ) $(C_) $(FTSRC)smooth$(D)ftgrays.c -$(FTOBJ)ftsmooth.$(OBJ) : $(FTSRC)smooth$(D)ftsmooth.c +$(FTOBJ)ftsmooth.$(OBJ) : $(FTSRC)smooth$(D)ftsmooth.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftsmooth.$(OBJ) $(C_) $(FTSRC)smooth$(D)ftsmooth.c -$(FTOBJ)ftspic.$(OBJ) : $(FTSRC)smooth$(D)ftspic.c +$(FTOBJ)ftspic.$(OBJ) : $(FTSRC)smooth$(D)ftspic.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ftspic.$(OBJ) $(C_) $(FTSRC)smooth$(D)ftspic.c -$(FTOBJ)sfobjs.$(OBJ) : $(FTSRC)sfnt$(D)sfobjs.c +$(FTOBJ)sfobjs.$(OBJ) : $(FTSRC)sfnt$(D)sfobjs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)sfobjs.$(OBJ) $(C_) $(FTSRC)sfnt$(D)sfobjs.c -$(FTOBJ)sfdriver.$(OBJ) : $(FTSRC)sfnt$(D)sfdriver.c +$(FTOBJ)sfdriver.$(OBJ) : $(FTSRC)sfnt$(D)sfdriver.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)sfdriver.$(OBJ) $(C_) $(FTSRC)sfnt$(D)sfdriver.c -$(FTOBJ)ttcmap.$(OBJ) : $(FTSRC)sfnt$(D)ttcmap.c +$(FTOBJ)ttcmap.$(OBJ) : $(FTSRC)sfnt$(D)ttcmap.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttcmap.$(OBJ) $(C_) $(FTSRC)sfnt$(D)ttcmap.c -$(FTOBJ)ttmtx.$(OBJ) : $(FTSRC)sfnt$(D)ttmtx.c +$(FTOBJ)ttmtx.$(OBJ) : $(FTSRC)sfnt$(D)ttmtx.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttmtx.$(OBJ) $(C_) $(FTSRC)sfnt$(D)ttmtx.c -$(FTOBJ)ttpost.$(OBJ) : $(FTSRC)sfnt$(D)ttpost.c +$(FTOBJ)ttpost.$(OBJ) : $(FTSRC)sfnt$(D)ttpost.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttpost.$(OBJ) $(C_) $(FTSRC)sfnt$(D)ttpost.c -$(FTOBJ)ft2ttload.$(OBJ) : $(FTSRC)sfnt$(D)ttload.c +$(FTOBJ)ft2ttload.$(OBJ) : $(FTSRC)sfnt$(D)ttload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ft2ttload.$(OBJ) $(C_) $(FTSRC)sfnt$(D)ttload.c -$(FTOBJ)ttsbit.$(OBJ) : $(FTSRC)sfnt$(D)ttsbit.c +$(FTOBJ)ttsbit.$(OBJ) : $(FTSRC)sfnt$(D)ttsbit.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttsbit.$(OBJ) $(C_) $(FTSRC)sfnt$(D)ttsbit.c -$(FTOBJ)ttkern.$(OBJ) : $(FTSRC)sfnt$(D)ttkern.c +$(FTOBJ)ttkern.$(OBJ) : $(FTSRC)sfnt$(D)ttkern.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttkern.$(OBJ) $(C_) $(FTSRC)sfnt$(D)ttkern.c -$(FTOBJ)ttbdf.$(OBJ) : $(FTSRC)sfnt$(D)ttbdf.c +$(FTOBJ)ttbdf.$(OBJ) : $(FTSRC)sfnt$(D)ttbdf.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttbdf.$(OBJ) $(C_) $(FTSRC)sfnt$(D)ttbdf.c -$(FTOBJ)sfntpic.$(OBJ) : $(FTSRC)sfnt$(D)sfntpic.c +$(FTOBJ)sfntpic.$(OBJ) : $(FTSRC)sfnt$(D)sfntpic.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)sfntpic.$(OBJ) $(C_) $(FTSRC)sfnt$(D)sfntpic.c -$(FTOBJ)ttdriver.$(OBJ) : $(FTSRC)truetype$(D)ttdriver.c +$(FTOBJ)pngshim.$(OBJ) : $(FTSRC)sfnt$(D)pngshim.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)pngshim.$(OBJ) $(C_) $(FTSRC)sfnt$(D)pngshim.c + +$(FTOBJ)ttdriver.$(OBJ) : $(FTSRC)truetype$(D)ttdriver.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttdriver.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttdriver.c -$(FTOBJ)ft2ttobjs.$(OBJ) : $(FTSRC)truetype$(D)ttobjs.c +$(FTOBJ)ft2ttobjs.$(OBJ) : $(FTSRC)truetype$(D)ttobjs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ft2ttobjs.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttobjs.c -$(FTOBJ)ttpload.$(OBJ) : $(FTSRC)truetype$(D)ttpload.c +$(FTOBJ)ttpload.$(OBJ) : $(FTSRC)truetype$(D)ttpload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttpload.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttpload.c -$(FTOBJ)ttgload.$(OBJ) : $(FTSRC)truetype$(D)ttgload.c +$(FTOBJ)ttgload.$(OBJ) : $(FTSRC)truetype$(D)ttgload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttgload.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttgload.c -$(FTOBJ)ft2ttinterp.$(OBJ) : $(FTSRC)truetype$(D)ttinterp.c +$(FTOBJ)ft2ttinterp.$(OBJ) : $(FTSRC)truetype$(D)ttinterp.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ft2ttinterp.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttinterp.c -$(FTOBJ)ttgxvar.$(OBJ) : $(FTSRC)truetype$(D)ttgxvar.c +$(FTOBJ)ttgxvar.$(OBJ) : $(FTSRC)truetype$(D)ttgxvar.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttgxvar.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttgxvar.c -$(FTOBJ)ttpic.$(OBJ) : $(FTSRC)truetype$(D)ttpic.c +$(FTOBJ)ttpic.$(OBJ) : $(FTSRC)truetype$(D)ttpic.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)ttpic.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttpic.c -$(FTOBJ)t1afm.$(OBJ) : $(FTSRC)type1$(D)t1afm.c +$(FTOBJ)ttsubpix.$(OBJ) : $(FTSRC)truetype$(D)ttsubpix.c $(FT_MAK) $(MAKEDIRS) + $(FTCC) $(FTO_)ttsubpix.$(OBJ) $(C_) $(FTSRC)truetype$(D)ttsubpix.c + +$(FTOBJ)t1afm.$(OBJ) : $(FTSRC)type1$(D)t1afm.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1afm.$(OBJ) $(C_) $(FTSRC)type1$(D)t1afm.c -$(FTOBJ)t1driver.$(OBJ) : $(FTSRC)type1$(D)t1driver.c +$(FTOBJ)t1driver.$(OBJ) : $(FTSRC)type1$(D)t1driver.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1driver.$(OBJ) $(C_) $(FTSRC)type1$(D)t1driver.c -$(FTOBJ)t1objs.$(OBJ) : $(FTSRC)type1$(D)t1objs.c +$(FTOBJ)t1objs.$(OBJ) : $(FTSRC)type1$(D)t1objs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1objs.$(OBJ) $(C_) $(FTSRC)type1$(D)t1objs.c -$(FTOBJ)t1load.$(OBJ) : $(FTSRC)type1$(D)t1load.c +$(FTOBJ)t1load.$(OBJ) : $(FTSRC)type1$(D)t1load.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1load.$(OBJ) $(C_) $(FTSRC)type1$(D)t1load.c -$(FTOBJ)t1gload.$(OBJ) : $(FTSRC)type1$(D)t1gload.c +$(FTOBJ)t1gload.$(OBJ) : $(FTSRC)type1$(D)t1gload.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1gload.$(OBJ) $(C_) $(FTSRC)type1$(D)t1gload.c -$(FTOBJ)t1parse.$(OBJ) : $(FTSRC)type1$(D)t1parse.c +$(FTOBJ)t1parse.$(OBJ) : $(FTSRC)type1$(D)t1parse.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t1parse.$(OBJ) $(C_) $(FTSRC)type1$(D)t1parse.c -$(FTOBJ)t42objs.$(OBJ) : $(FTSRC)type42$(D)t42objs.c +$(FTOBJ)t42objs.$(OBJ) : $(FTSRC)type42$(D)t42objs.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t42objs.$(OBJ) $(C_) $(FTSRC)type42$(D)t42objs.c -$(FTOBJ)t42parse.$(OBJ) : $(FTSRC)type42$(D)t42parse.c +$(FTOBJ)t42parse.$(OBJ) : $(FTSRC)type42$(D)t42parse.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t42parse.$(OBJ) $(C_) $(FTSRC)type42$(D)t42parse.c -$(FTOBJ)t42drivr.$(OBJ) : $(FTSRC)type42$(D)t42drivr.c +$(FTOBJ)t42drivr.$(OBJ) : $(FTSRC)type42$(D)t42drivr.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)t42drivr.$(OBJ) $(C_) $(FTSRC)type42$(D)t42drivr.c -$(FTOBJ)winfnt.$(OBJ) : $(FTSRC)winfonts$(D)winfnt.c +$(FTOBJ)winfnt.$(OBJ) : $(FTSRC)winfonts$(D)winfnt.c $(FT_MAK) $(MAKEDIRS) $(FTCC) $(FTO_)winfnt.$(OBJ) $(C_) $(FTSRC)winfonts$(D)winfnt.c diff -Nru ghostscript-9.10~dfsg/base/gconf.c ghostscript-9.25~dfsg+1/base/gconf.c --- ghostscript-9.10~dfsg/base/gconf.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gconf.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Configuration tables */ diff -Nru ghostscript-9.10~dfsg/base/gconf.h ghostscript-9.25~dfsg+1/base/gconf.h --- ghostscript-9.10~dfsg/base/gconf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gconf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Wrapper for gconfig.h or a substitute. */ diff -Nru ghostscript-9.10~dfsg/base/gdbflags.h ghostscript-9.25~dfsg+1/base/gdbflags.h --- ghostscript-9.10~dfsg/base/gdbflags.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdbflags.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Debugging flag definitions */ @@ -23,11 +23,11 @@ UNUSED(0) /* Never use 0, as lots of things 'imply' 0. */ FLAG(icc, 1, 'c', "ICC profile"), -FLAG(validate_chunks, 2, 0, "Validate chunks during interpretation"), +FLAG(validate_clumps, 2, 0, "Validate clumps during interpretation"), FLAG(gc_disable, 3, 0, "Disable Garbage Collection (completely)"), -UNUSED(4) -UNUSED(5) -UNUSED(6) +FLAG(epo_disable, 4, 0, "Disable Erasepage Optimization (completely)"), +FLAG(epo_details, 5, 0, "Erasepage Optimization tracing"), +FLAG(epo_install_only, 6, 0, "Erasepage Optimization install only (for debugging subclass)"), UNUSED(7) UNUSED(8) UNUSED(9) @@ -75,7 +75,7 @@ FLAG(curve_detail, '3', 0, "Curve subdivider/rasterizer (detail)"), FLAG(gc_strings, '4', 0, "Garbage collector (strings)"), FLAG(gc_strings_detail, '5', 0, "Garbage collector (strings, detail)"), -FLAG(gc_chunks, '6', 0, "Garbage collector (chunks, roots)"), +FLAG(gc_clumps, '6', 0, "Garbage collector (clumps, roots)"), FLAG(gc_objects, '7', 0, "Garbage collector (objects)"), FLAG(gc_refs, '8', 0, "Garbage collector (refs)"), FLAG(gc_pointers, '9', 0, "Garbage collector (pointers)"), diff -Nru ghostscript-9.10~dfsg/base/gdebug.h ghostscript-9.25~dfsg+1/base/gdebug.h --- ghostscript-9.10~dfsg/base/gdebug.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdebug.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Debugging machinery definitions */ diff -Nru ghostscript-9.10~dfsg/base/gdevabuf.c ghostscript-9.25~dfsg+1/base/gdevabuf.c --- ghostscript-9.10~dfsg/base/gdevabuf.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevabuf.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Alpha-buffering memory devices */ @@ -65,7 +65,7 @@ gx_color_index color = gx_forward_map_rgb_color(dev, cv); return (color == 0 || color == gx_no_color_index ? color : - (gx_color_index) ((1 << mdev->log2_alpha_bits) - 1)); + (((gx_color_index)1 << mdev->log2_alpha_bits) - 1)); } static int mem_alpha_map_color_rgb(gx_device * dev, gx_color_index color, @@ -97,6 +97,28 @@ int raster, gx_bitmap_id id, int x, int y, int width, int height, gx_color_index color, int depth) { /* Just use copy_color. */ + if (depth == 8) { + /* We don't support depth=8 in this function, but this doesn't + * matter, because: + * 1) This code is only called for dTextAlphaBits > 0, when + * DisableFAPI=true. And we don't support DisableFAPI. + * 2) Even if we did support DisableFAPI, this can never actually + * be called because gx_compute_text_oversampling arranges that + * log2_scale.{x,y} sum to <= alpha_bits, and this code is only + * called if it sums to MORE than alpha_bits. + * 3) Even if copy_alpha DID somehow manage to be called, the + * only place that uses depth==8 is the imagemask interpolation + * code, and that can never hit this code. (Type 3 fonts might + * include Imagemasks, but those don't go through FAPI). + * + * If in the future we ever rearrange the conditions under which + * this code is called (so that it CAN be called with depth == 8) + * then this will probably be best implemented by decimating the + * input alpha values to either 2 or 4 bits as appropriate and + * then recursively calling us back. + */ + return_error(gs_error_unknownerror); + } return (color == 0 ? (*dev_proc(dev, fill_rectangle)) (dev, x, y, width, height, color) : @@ -410,7 +432,7 @@ /* Fill a rectangle. */ static int mem_abuf_fill_rectangle_hl_color(gx_device * dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { @@ -420,6 +442,7 @@ int y = fixed2int(rect->p.y); int w = fixed2int(rect->q.x) - x; int h = fixed2int(rect->q.y) - y; + (void)pgs; x -= mdev->mapped_x; fit_fill_xy(dev, x, y, w, h); @@ -458,7 +481,7 @@ * We should do alpha buffering iff this value is >1. */ int -alpha_buffer_bits(gs_state * pgs) +alpha_buffer_bits(gs_gstate * pgs) { gx_device *dev; diff -Nru ghostscript-9.10~dfsg/base/gdevbbox.c ghostscript-9.25~dfsg+1/base/gdevbbox.c --- ghostscript-9.10~dfsg/base/gdevbbox.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevbbox.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Device for tracking bounding box */ @@ -24,11 +24,13 @@ #include "gdevbbox.h" #include "gxdcolor.h" /* for gx_device_black/white */ #include "gxiparam.h" /* for image source size */ -#include "gxistate.h" +#include "gxgstate.h" #include "gxpaint.h" #include "gxpath.h" #include "gxcpath.h" +#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and object filter */ + /* GC descriptor */ public_st_device_bbox(); @@ -354,12 +356,17 @@ static int bbox_open_device(gx_device * dev) { - gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device_bbox *bdev = (gx_device_bbox *) dev; + int code; if (bdev->free_standing) { gx_device_forward_fill_in_procs((gx_device_forward *) dev); bdev->box_procs = box_procs_default; bdev->box_proc_data = bdev; + + code = install_internal_subclass_devices((gx_device **)&bdev, NULL); + if (code < 0) + return code; } if (bdev->box_procs.init_box == box_procs_default.init_box) BBOX_INIT_BOX(bdev); @@ -604,6 +611,7 @@ default: ecode = code; e:param_signal_error(plist, param_name, ecode); + /* fall through */ case 1: bba.data = 0; } @@ -795,7 +803,7 @@ (pbox)->q.x += (adj).x, (pbox)->q.y += (adj).y) static int -bbox_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath, +bbox_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { @@ -805,6 +813,7 @@ (tdev == 0 ? dev_proc(&gs_null_device, fill_path) : dev_proc(tdev, fill_path)); int code; + gx_drawing_color devc; if (ppath == NULL) { /* A special handling of shfill with no path. */ @@ -831,41 +840,38 @@ * on the target. */ if (BBOX_IN_RECT(bdev, &ibox)) - return fill_path(tdev, pis, ppath, params, pdevc, pcpath); + return fill_path(tdev, pgs, ppath, params, pdevc, pcpath); /* * If the target uses the default algorithm, just draw on the * bbox device. */ if (tdev != 0 && fill_path == gx_default_fill_path) - return fill_path(dev, pis, ppath, params, pdevc, pcpath); + return fill_path(dev, pgs, ppath, params, pdevc, pcpath); /* Draw on the target now. */ - code = fill_path(tdev, pis, ppath, params, pdevc, pcpath); + code = fill_path(tdev, pgs, ppath, params, pdevc, pcpath); if (code < 0) return code; - if (pcpath != NULL && - !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y, - ibox.q.x, ibox.q.y) - ) { - /* - * Let the target do the drawing, but break down the - * fill path into pieces for computing the bounding box. - */ - gx_drawing_color devc; + /* Previously we would use the path bbox above usually, but that bbox is + * inaccurate for curves, because it considers the control points of the + * curves to be included whcih of course they are not. Now we scan-convert + * the path to get an accurate result, just as we do for strokes. + */ + /* + * Draw the path, but break down the + * fill path into pieces for computing the bounding box accurately. + */ - set_nonclient_dev_color(&devc, bdev->black); /* any non-white color will do */ - bdev->target = NULL; - code = gx_default_fill_path(dev, pis, ppath, params, &devc, pcpath); - bdev->target = tdev; - } else { /* Just use the path bounding box. */ - BBOX_ADD_RECT(bdev, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y); - } + set_nonclient_dev_color(&devc, bdev->black); /* any non-white color will do */ + bdev->target = NULL; + code = gx_default_fill_path(dev, pgs, ppath, params, &devc, pcpath); + bdev->target = tdev; return code; } else - return fill_path(tdev, pis, ppath, params, pdevc, pcpath); + return fill_path(tdev, pgs, ppath, params, pdevc, pcpath); } static int -bbox_stroke_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath, +bbox_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_stroke_params * params, const gx_drawing_color * pdevc, const gx_clip_path * pcpath) { @@ -874,41 +880,24 @@ /* Skip the call if there is no target. */ int code = (tdev == 0 ? 0 : - dev_proc(tdev, stroke_path)(tdev, pis, ppath, params, pdevc, pcpath)); + dev_proc(tdev, stroke_path)(tdev, pgs, ppath, params, pdevc, pcpath)); if (!GX_DC_IS_TRANSPARENT(pdevc, bdev)) { gs_fixed_rect ibox; gs_fixed_point expand; + int ibox_valid = 0; - if (gx_stroke_path_expansion(pis, ppath, &expand) == 0 && + if (gx_stroke_path_expansion(pgs, ppath, &expand) == 0 && gx_path_bbox(ppath, &ibox) >= 0 ) { /* The fast result is exact. */ adjust_box(&ibox, expand); - } else { - /* - * The result is not exact. Compute an exact result using - * strokepath. - */ - gx_path *spath = gx_path_alloc(pis->memory, "bbox_stroke_path"); - int code = 0; - - if (spath) - code = gx_imager_stroke_add(ppath, spath, dev, pis); - else - code = -1; - if (code >= 0) - code = gx_path_bbox(spath, &ibox); - if (code < 0) { - ibox.p.x = ibox.p.y = min_fixed; - ibox.q.x = ibox.q.y = max_fixed; - } - if (spath) - gx_path_free(spath, "bbox_stroke_path"); + ibox_valid = 1; } - if (pcpath != NULL && - !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y, - ibox.q.x, ibox.q.y) + if (!ibox_valid || + (pcpath != NULL && + !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y, + ibox.q.x, ibox.q.y)) ) { /* Let the target do the drawing, but break down the */ /* fill path into pieces for computing the bounding box. */ @@ -916,7 +905,7 @@ set_nonclient_dev_color(&devc, bdev->black); /* any non-white color will do */ bdev->target = NULL; - gx_default_stroke_path(dev, pis, ppath, params, &devc, pcpath); + gx_default_stroke_path(dev, pgs, ppath, params, &devc, pcpath); bdev->target = tdev; } else { /* Just use the path bounding box. */ @@ -986,7 +975,7 @@ }; static int -bbox_image_begin(const gs_imager_state * pis, const gs_matrix * pmat, +bbox_image_begin(const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_clip_path * pcpath, gs_memory_t * memory, bbox_image_enum ** ppbe) @@ -996,7 +985,7 @@ bbox_image_enum *pbe; if (pmat == 0) - pmat = &ctm_only(pis); + pmat = &ctm_only(pgs); if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 || (code = gs_matrix_multiply(&mat, pmat, &mat)) < 0 ) @@ -1015,7 +1004,7 @@ pbe->y = prect->p.y, pbe->height = prect->q.y - prect->p.y; } else { gs_int_point size; - int code = (*pic->type->source_size) (pis, pic, &size); + int code = (*pic->type->source_size) (pgs, pic, &size); if (code < 0) { gs_free_object(memory, pbe, "bbox_image_begin"); @@ -1042,7 +1031,7 @@ static int bbox_begin_typed_image(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, @@ -1050,7 +1039,7 @@ { bbox_image_enum *pbe; int code = - bbox_image_begin(pis, pmat, pic, prect, pcpath, memory, &pbe); + bbox_image_begin(pgs, pmat, pic, prect, pcpath, memory, &pbe); if (code < 0) return code; @@ -1071,7 +1060,7 @@ begin_typed_image = dev_proc(tdev, begin_typed_image); } code = (*begin_typed_image) - (tdev, pis, pmat, pic, prect, pdcolor, pcpath, memory, + (tdev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, &pbe->target_info); if (code) { bbox_image_end_image((gx_image_enum_common_t *)pbe, false); @@ -1224,7 +1213,7 @@ static int bbox_create_compositor(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, - gs_imager_state * pis, gs_memory_t * memory, gx_device *cindev) + gs_gstate * pgs, gs_memory_t * memory, gx_device *cindev) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; gx_device *target = bdev->target; @@ -1246,7 +1235,7 @@ gx_device *temp_cdev; gx_device_bbox *bbcdev; int code = (*dev_proc(target, create_compositor)) - (target, &temp_cdev, pcte, pis, memory, cindev); + (target, &temp_cdev, pcte, pgs, memory, cindev); /* If the target did not create a new compositor then we are done. */ if (code < 0 || target == temp_cdev) { @@ -1272,17 +1261,17 @@ /* ------ Text imaging ------ */ static int -bbox_text_begin(gx_device * dev, gs_imager_state * pis, +bbox_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, gs_text_enum_t ** ppenum) { gx_device_bbox *const bdev = (gx_device_bbox *) dev; - int code = gx_default_text_begin(dev, pis, text, font, path, pdcolor, + int code = gx_default_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppenum); - if (bdev->target != NULL) { + if (code >=0 && bdev->target != NULL) { /* See note on imaging_dev in gxtext.h */ rc_assign((*ppenum)->imaging_dev, dev, "bbox_text_begin"); } @@ -1292,7 +1281,7 @@ /* --------------- fillpage ------------------- */ -int bbox_fillpage(gx_device *dev, gs_imager_state * pis, gx_device_color *pdevc) +int bbox_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) { /* Call the target's proc, but don't account the size. */ gx_device_bbox *const bdev = (gx_device_bbox *) dev; @@ -1301,5 +1290,5 @@ BBOX_INIT_BOX(bdev); if (tdev == NULL) return 0; - return dev_proc(tdev, fillpage)(tdev, pis, pdevc); + return dev_proc(tdev, fillpage)(tdev, pgs, pdevc); } diff -Nru ghostscript-9.10~dfsg/base/gdevbbox.h ghostscript-9.25~dfsg+1/base/gdevbbox.h --- ghostscript-9.10~dfsg/base/gdevbbox.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevbbox.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Definitions and interface for bbox (bounding box accumulator) device */ diff -Nru ghostscript-9.10~dfsg/base/gdevdbit.c ghostscript-9.25~dfsg+1/base/gdevdbit.c --- ghostscript-9.10~dfsg/base/gdevdbit.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdbit.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Default device bitmap copying implementation */ @@ -171,7 +171,6 @@ AND it supports devn colors AND is 8 or 16 bit. For example tiffsep and psdcmyk may make use of this if AA is enabled. It is basically designed for devices that need more than 64 bits for color support - without compressed color encoding. So that I can follow things and make it readable for future generations, I am not using the macro nightmare that default_copy_alpha uses. */ @@ -183,14 +182,14 @@ const byte *row_alpha; gs_memory_t *mem = dev->memory; int bpp = dev->color_info.depth; - int ncomps = dev->color_info.num_components; + uchar ncomps = dev->color_info.num_components; uint out_raster; int code = 0; gx_color_value src_cv[GS_CLIENT_COLOR_MAX_COMPONENTS]; gx_color_value curr_cv[GS_CLIENT_COLOR_MAX_COMPONENTS]; gx_color_value blend_cv[GS_CLIENT_COLOR_MAX_COMPONENTS]; int ry; - int k, j; + uchar k, j; gs_get_bits_params_t gb_params; byte *src_planes[GS_CLIENT_COLOR_MAX_COMPONENTS]; gs_int_rect gb_rect; @@ -200,7 +199,6 @@ gx_color_value *composite; byte *gb_buff; int x_curr, w_curr, gb_buff_start; - byte *end_ptr; byte_depth = bpp / ncomps; mask = ((gx_color_index)1 << byte_depth) - 1; @@ -211,7 +209,6 @@ row_alpha = data; out_raster = bitmap_raster(width * byte_depth); gb_buff = gs_alloc_bytes(mem, out_raster * ncomps, "copy_alpha_hl_color(gb_buff)"); - end_ptr = gb_buff + out_raster * ncomps; if (gb_buff == 0) { code = gs_note_error(gs_error_VMerror); return code; @@ -263,14 +260,24 @@ int alpha2, alpha; w_curr += 1; - if (depth == 2) /* map 0 - 3 to 0 - 15 */ - alpha = ((row_alpha[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5; - else - alpha2 = row_alpha[sx >> 1], - alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4); + switch (depth) + { + case 2: + alpha = ((row_alpha[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85; + break; + case 4: + alpha2 = row_alpha[sx >> 1]; + alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4) * 17; + break; + case 8: + alpha = row_alpha[sx]; + break; + default: + return_error(gs_error_rangecheck); + } if (alpha == 0) { - /* With alpha 0 we want to avoid writting out this value. + /* With alpha 0 we want to avoid writing out this value. * While it is true that writting it out leaves the color * unchanged, any device that's watching what pixels are * written (such as the pattern tile devices) may have problems. @@ -280,16 +287,21 @@ code = dev_proc(dev, copy_planes)(dev, &(gb_buff[gb_buff_start]), 0, out_raster, gs_no_bitmap_id, x_curr, ry, w_curr-1, 1, 1); + if (code < 0) { + gs_free_object(mem, gb_buff, "copy_alpha_hl_color"); + return code; + } /* reset ourselves */ gb_buff_start = gb_buff_start + w_curr; w_curr = 0; x_curr = rx + 1; } else { - if (alpha == 15) { + if (alpha == 255) { /* Just use the new color. */ composite = &(src_cv[0]); } else { /* We need to do the weighting by the alpha value */ + alpha += (alpha>>7); /* Expand from 0..255->0..256 */ /* First get the old color */ for (k = 0; k < ncomps; k++) { /* We only have 8 and 16 bit depth to worry about. @@ -308,8 +320,8 @@ } /* Now compute the new color which is a blend of the old and the new */ - blend_cv[k] = curr_cv[k] + - (((long) src_cv[k] - (long) curr_cv[k]) * alpha / 15); + blend_cv[k] = ((curr_cv[k]<<8) + + (((long) src_cv[k] - (long) curr_cv[k]) * alpha))>>8; composite = &(blend_cv[0]); } } @@ -352,8 +364,8 @@ const byte *row; gs_memory_t *mem = dev->memory; int bpp = dev->color_info.depth; - int ncomps = dev->color_info.num_components; - uint in_size = gx_device_raster(dev, false); + uchar ncomps = dev->color_info.num_components; + uint in_size = gx_device_raster_chunky(dev, false); byte *lin; uint out_size; byte *lout; @@ -375,7 +387,10 @@ byte *line; int sx, rx; - DECLARE_LINE_ACCUM_COPY(lout, bpp, x); + byte *l_dptr = lout; + int l_dbit = 0; + byte l_dbyte = ((l_dbit) ? (byte)(*(l_dptr) & (0xff00 >> (l_dbit))) : 0); + int l_xprev = x; code = (*dev_proc(dev, get_bits)) (dev, ry, lin, &line); if (code < 0) @@ -386,11 +401,22 @@ gx_color_index composite; int alpha2, alpha; - if (depth == 2) /* map 0 - 3 to 0 - 15 */ - alpha = ((row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5; - else + switch(depth) + { + case 2: + /* map 0 - 3 to 0 - 15 */ + alpha = ((row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85; + break; + case 4: alpha2 = row[sx >> 1], - alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4); + alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4) * 17; + break; + case 8: + alpha = row[sx]; + break; + default: + return_error(gs_error_rangecheck); + } blend: if (alpha == 0) { /* Previously the code used to just write out the previous @@ -401,14 +427,26 @@ * tile devices). The right thing to do is to write out * the buffered accumulator, and skip over any pixels that * are completely clear. */ - LINE_ACCUM_FLUSH_AND_RESTART(dev, lout, bpp, lx, rx, out_size, ry); + if (rx > l_xprev ) { + sample_store_flush(l_dptr, l_dbit, l_dbyte); + code = (*dev_proc(dev, copy_color)) + (dev, lout, l_xprev - (lx), out_size, + gx_no_bitmap_id, l_xprev, ry, (rx) - l_xprev, 1); + if ( code < 0 ) + return code; + } + l_dptr = lout; + l_dbit = 0; + l_dbyte = (l_dbit ? (byte)(*l_dptr & (0xff00 >> l_dbit)) : 0); + l_xprev = rx+1; lx = rx+1; } else { - if (alpha == 15) { /* Just write the new color. */ + if (alpha == 255) { /* Just write the new color. */ composite = color; } else { gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int i; + uchar i; + int alpha2 = alpha + (alpha>>7); if (previous == gx_no_color_index) { /* Extract the old color. */ if (bpp < 8) { @@ -425,16 +463,16 @@ switch (bpp >> 3) { case 8: previous += (gx_color_index) * src++ - << sample_bound_shift(previous, 56); + << SAMPLE_BOUND_SHIFT(previous, 56); case 7: previous += (gx_color_index) * src++ - << sample_bound_shift(previous, 48); + << SAMPLE_BOUND_SHIFT(previous, 48); case 6: previous += (gx_color_index) * src++ - << sample_bound_shift(previous, 40); + << SAMPLE_BOUND_SHIFT(previous, 40); case 5: previous += (gx_color_index) * src++ - << sample_bound_shift(previous, 32); + << SAMPLE_BOUND_SHIFT(previous, 32); case 4: previous += (gx_color_index) * src++ << 24; case 3: @@ -452,26 +490,40 @@ #else # define b_int int #endif -#define make_shade(old, clr, alpha, amax) \ - (old) + (((b_int)(clr) - (b_int)(old)) * (alpha) / (amax)) +#define make_shade(old, clr, alpha) \ + (((((b_int)(old))<<8) + (((b_int)(clr) - (b_int)(old)) * (alpha)))>>8) for (i=0; i> 1); + alpha = (alpha & 128) | (alpha >> 1); goto blend; } } - LINE_ACCUM(composite, bpp); + if (sizeof(composite) > 4) { + if (sample_store_next64(composite, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(composite, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } } } - LINE_ACCUM_COPY(dev, lout, bpp, lx, rx, out_size, ry); + if ( rx > l_xprev ) { + sample_store_flush(l_dptr, l_dbit, l_dbyte); + code = (*dev_proc(dev, copy_color)) + (dev, lout, l_xprev - lx, out_size, + gx_no_bitmap_id, l_xprev, ry, rx - l_xprev, 1); + if (code < 0) + return code; + } } out:gs_free_object(mem, lout, "copy_alpha(lout)"); gs_free_object(mem, lin, "copy_alpha(lin)"); @@ -603,7 +655,7 @@ */ dev_proc_tile_rectangle((*tile_proc)) = dev_proc(dev, tile_rectangle); - int code; + int code = 0; set_dev_proc(dev, tile_rectangle, gx_default_tile_rectangle); code = (*tile_proc) @@ -634,7 +686,7 @@ dev_proc_copy_mono((*proc_mono)); dev_proc_copy_color((*proc_color)); dev_proc_copy_planes((*proc_planes)); - int code; + int code = 0; if (color0 == gx_no_color_index && color1 == gx_no_color_index) { if (tiles->num_planes > 1) { @@ -652,37 +704,40 @@ proc_mono = dev_proc(dev, copy_mono); } -#define real_copy_tile(dev, srcx, tx, ty, tw, th, id)\ - code =\ - (tiles->num_planes > 1 ?\ - (*proc_planes)(dev, row, srcx, raster, id, tx, ty, tw, th, height) :\ - (proc_color != 0 ?\ - (*proc_color)(dev, row, srcx, raster, id, tx, ty, tw, th) :\ - (*proc_mono)(dev, row, srcx, raster, id, tx, ty, tw, th, color0, color1)));\ - if (code < 0) return_error(code);\ - return_if_interrupt(dev->memory) -#define copy_tile(dev, srcx, tx, ty, tw, th, tid)\ - if_debug6m('t', (dev)->memory, " copy id=%lu sx=%d => x=%d y=%d w=%d h=%d\n",\ - tid, srcx, tx, ty, tw, th);\ - real_copy_tile(dev, srcx, tx, ty, tw, th, tid) +#define GX_DEFAULT_COPY_TILE(dev, srcx, tx, ty, tw, th, tid) do {\ + if_debug6m('t', (dev)->memory, " copy id=%lu sx=%d => x=%d y=%d w=%d h=%d\n", tid, srcx, tx, ty, tw, th);\ + if (tiles->num_planes > 1) {\ + if (proc_planes)\ + code = (*proc_planes)(dev, row, srcx, raster, tid, tx, ty, tw, th, height);\ + } else {\ + if (proc_color != 0) {\ + code = (*proc_color)(dev, row, srcx, raster, tid, tx, ty, tw, th);\ + } else {\ + if (proc_mono)\ + code = (*proc_mono)(dev, row, srcx, raster, tid, tx, ty, tw, th, color0, color1);\ + else code = 0;\ + }\ + }\ + if (code < 0) return_error(code);\ + } while (0); + + if (ch >= h) { /* Shallow operation */ if (icw >= w) { /* Just one (partial) tile to transfer. */ - copy_tile(dev, irx, x, y, w, h, - (w == width && h == height ? tile_id : - gs_no_bitmap_id)); + GX_DEFAULT_COPY_TILE(dev, irx, x, y, w, h, (w == width && h == height ? tile_id : gs_no_bitmap_id)); } else { int ex = x + w; int fex = ex - width; int cx = x + icw; ulong id = (h == height ? tile_id : gs_no_bitmap_id); - copy_tile(dev, irx, x, y, icw, h, gs_no_bitmap_id); + GX_DEFAULT_COPY_TILE(dev, irx, x, y, icw, h, gs_no_bitmap_id); while (cx <= fex) { - copy_tile(dev, 0, cx, y, width, h, id); + GX_DEFAULT_COPY_TILE(dev, 0, cx, y, width, h, id); cx += width; } if (cx < ex) { - copy_tile(dev, 0, cx, y, ex - cx, h, gs_no_bitmap_id); + GX_DEFAULT_COPY_TILE(dev, 0, cx, y, ex - cx, h, gs_no_bitmap_id); } } } else if (icw >= w && shift == 0) { @@ -692,11 +747,11 @@ int cy = y + ch; ulong id = (w == width ? tile_id : gs_no_bitmap_id); - copy_tile(dev, irx, x, y, w, ch, (ch == height ? id : gs_no_bitmap_id)); + GX_DEFAULT_COPY_TILE(dev, irx, x, y, w, ch, (ch == height ? id : gs_no_bitmap_id)); row = tiles->data; do { ch = (cy > fey ? ey - cy : height); - copy_tile(dev, irx, x, cy, w, ch, + GX_DEFAULT_COPY_TILE(dev, irx, x, cy, w, ch, (ch == height ? id : gs_no_bitmap_id)); } while ((cy += ch) < ey); @@ -713,17 +768,17 @@ ulong id = (ch == height ? tile_id : gs_no_bitmap_id); if (icw >= w) { - copy_tile(dev, irx, x, cy, w, ch, + GX_DEFAULT_COPY_TILE(dev, irx, x, cy, w, ch, (w == width ? id : gs_no_bitmap_id)); } else { - copy_tile(dev, irx, x, cy, icw, ch, gs_no_bitmap_id); + GX_DEFAULT_COPY_TILE(dev, irx, x, cy, icw, ch, gs_no_bitmap_id); cx = x + icw; while (cx <= fex) { - copy_tile(dev, 0, cx, cy, width, ch, id); + GX_DEFAULT_COPY_TILE(dev, 0, cx, cy, width, ch, id); cx += width; } if (cx < ex) { - copy_tile(dev, 0, cx, cy, ex - cx, ch, gs_no_bitmap_id); + GX_DEFAULT_COPY_TILE(dev, 0, cx, cy, ex - cx, ch, gs_no_bitmap_id); } } if ((cy += ch) >= ey) @@ -735,8 +790,7 @@ row = tiles->data; } } -#undef copy_tile -#undef real_copy_tile +#undef GX_DEFAULT_COPY_TILE } return 0; } diff -Nru ghostscript-9.10~dfsg/base/gdevdcrd.c ghostscript-9.25~dfsg+1/base/gdevdcrd.c --- ghostscript-9.10~dfsg/base/gdevdcrd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdcrd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Create a sample device CRD */ @@ -38,7 +38,7 @@ }; static const float dent_PQR = 1.0; static int -bit_TransformPQR_proc(int index, floatp in, const gs_cie_wbsd * pwbsd, +bit_TransformPQR_proc(int index, double in, const gs_cie_wbsd * pwbsd, gs_cie_render * pcrd, float *out) { *out = DENT(in, dent_PQR); @@ -49,7 +49,7 @@ }; static const float dent_LMN = 1.0; static float -bit_EncodeLMN_proc(floatp in, const gs_cie_render * pcrd) +bit_EncodeLMN_proc(double in, const gs_cie_render * pcrd) { return DENT(in, dent_LMN); } @@ -65,7 +65,7 @@ {(float)-0.49863, (float) 0.04152, (float) 1.05700} }; static float -bit_EncodeABC_proc(floatp in, const gs_cie_render * pcrd) +bit_EncodeABC_proc(double in, const gs_cie_render * pcrd) { return pow(max(in, 0.0), 0.45); } diff -Nru ghostscript-9.10~dfsg/base/gdevdcrd.h ghostscript-9.25~dfsg+1/base/gdevdcrd.h --- ghostscript-9.10~dfsg/base/gdevdcrd.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdcrd.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Interface for creating a sample device CRD */ diff -Nru ghostscript-9.10~dfsg/base/gdevddrw.c ghostscript-9.25~dfsg+1/base/gdevddrw.c --- ghostscript-9.10~dfsg/base/gdevddrw.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevddrw.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Default polygon and image drawing device procedures */ @@ -26,17 +26,14 @@ #include "gxdcolor.h" #include "gxdevice.h" #include "gxiparam.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxhldevc.h" #include "gdevddrw.h" -#include "vdtrace.h" /* #include "gxdtfill.h" - Do not remove this comment. "gxdtfill.h" is included below. */ -#define VD_RECT_COLOR RGB(0, 0, 255) - #define SWAP(a, b, t)\ (t = a, a = b, b = t) @@ -221,8 +218,7 @@ } static inline bool -check_gradient_overflow(const gs_linear_color_edge *le, const gs_linear_color_edge *re, - int num_components) +check_gradient_overflow(const gs_linear_color_edge *le, const gs_linear_color_edge *re) { if (le->c1 == NULL || re->c1 == NULL) { /* A wedge doesn't use a gradient by X. */ @@ -438,16 +434,6 @@ } } -static inline void -middle_frac31_color(frac31 *c, const frac31 *c0, const frac31 *c2, int num_components) -{ - /* Assuming non-negative values. */ - int i; - - for (i = 0; i < num_components; i++) - c[i] = (int32_t)(((uint32_t)c0[i] + (uint32_t)c2[i]) >> 1); -} - static inline int fill_linear_color_trapezoid_nocheck(gx_device *dev, const gs_fill_attributes *fa, const gs_linear_color_edge *le, const gs_linear_color_edge *re) @@ -486,7 +472,6 @@ const frac31 *c2, const frac31 *c3) { gs_linear_color_edge le, re; - int num_components = dev->color_info.num_components; le.start = *p0; le.end = *p1; @@ -498,7 +483,7 @@ re.c0 = c2; re.c1 = c3; re.clip_x = fa->clip->q.x; - if (check_gradient_overflow(&le, &re, num_components)) + if (check_gradient_overflow(&le, &re)) return 0; return fill_linear_color_trapezoid_nocheck(dev, fa, &le, &re); } @@ -511,7 +496,6 @@ { /* p0 must be the lowest vertex. */ int code; gs_linear_color_edge e0, e1, e2; - int num_components = dev->color_info.num_components; if (p0->y == p1->y) return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p2, p1, p2, c0, c2, c1, c2); @@ -533,9 +517,9 @@ e2.c0 = c1; e2.c1 = c2; e2.clip_x = fa->clip->q.x; - if (check_gradient_overflow(&e0, &e1, num_components)) + if (check_gradient_overflow(&e0, &e1)) return 0; - if (check_gradient_overflow(&e0, &e2, num_components)) + if (check_gradient_overflow(&e0, &e2)) return 0; code = fill_linear_color_trapezoid_nocheck(dev, fa, &e0, &e1); if (code <= 0) /* Sic! */ @@ -547,9 +531,9 @@ e2.c0 = c2; e2.c1 = c1; e2.clip_x = fa->clip->q.x; - if (check_gradient_overflow(&e0, &e1, num_components)) + if (check_gradient_overflow(&e0, &e1)) return 0; - if (check_gradient_overflow(&e2, &e1, num_components)) + if (check_gradient_overflow(&e2, &e1)) return 0; code = fill_linear_color_trapezoid_nocheck(dev, fa, &e0, &e1); if (code <= 0) /* Sic! */ @@ -604,8 +588,6 @@ gs_int_rect r; INT_RECT_FROM_PARALLELOGRAM(&r, px, py, ax, ay, bx, by); - vd_rect(int2fixed(r.p.x), int2fixed(r.p.y), int2fixed(r.q.x), int2fixed(r.q.y), - 1, (int)pdevc->colors.pure); return gx_fill_rectangle_device_rop(r.p.x, r.p.y, r.q.x - r.p.x, r.q.y - r.p.y, pdevc, dev, lop); } @@ -1005,7 +987,7 @@ */ static int gx_no_begin_image(gx_device * dev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, gx_image_enum_common_t ** pinfo) @@ -1014,7 +996,7 @@ } int gx_default_begin_image(gx_device * dev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, gx_image_enum_common_t ** pinfo) @@ -1028,9 +1010,6 @@ const gs_image_t *ptim; int code; - /* Processing an image object operation */ - dev_proc(dev, set_graphics_type_tag)(dev, GS_IMAGE_TAG); - set_dev_proc(dev, begin_image, gx_no_begin_image); if (pim->format == format) ptim = pim; @@ -1040,7 +1019,7 @@ ptim = ℑ } code = (*dev_proc(dev, begin_typed_image)) - (dev, pis, NULL, (const gs_image_common_t *)ptim, prect, pdcolor, + (dev, pgs, NULL, (const gs_image_common_t *)ptim, prect, pdcolor, pcpath, memory, pinfo); set_dev_proc(dev, begin_image, save_begin_image); return code; @@ -1048,26 +1027,22 @@ int gx_default_begin_typed_image(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, gx_image_enum_common_t ** pinfo) { - /* Processing an image object operation */ - if (pis != NULL) /* Null can happen when generating image3 mask */ - dev_proc(dev, set_graphics_type_tag)(dev, GS_IMAGE_TAG); - - /* If this is an ImageType 1 image using the imager's CTM, + /* If this is an ImageType 1 image using the gs_gstate's CTM, * defer to begin_image. */ if (pic->type->begin_typed_image == gx_begin_image1) { const gs_image_t *pim = (const gs_image_t *)pic; if (pmat == 0 || - (pis != 0 && !gs_matrix_compare(pmat, &ctm_only(pis))) + (pgs != 0 && !gs_matrix_compare(pmat, &ctm_only(pgs))) ) { int code = (*dev_proc(dev, begin_image)) - (dev, pis, pim, pim->format, prect, pdcolor, + (dev, pgs, pim, pim->format, prect, pdcolor, pcpath, memory, pinfo); if (code >= 0) @@ -1075,7 +1050,7 @@ } } return (*pic->type->begin_typed_image) - (dev, pis, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); + (dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); } /* Backward compatibility for obsolete driver procedures. */ @@ -1085,16 +1060,7 @@ const byte ** plane_data, int data_x, uint raster, int height) { - int code; - - vd_get_dc('i'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - /* vd_erase(RGB(192, 192, 192)); */ - code = gx_image_data(info, plane_data, data_x, raster, height); - vd_release_dc; - return code; + return gx_image_data(info, plane_data, data_x, raster, height); } int @@ -1105,9 +1071,9 @@ } int -gx_default_fillpage(gx_device *dev, gs_imager_state * pis, gx_device_color *pdevc) +gx_default_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) { - bool hl_color_available = gx_hld_is_hl_color_available(pis, pdevc); + bool hl_color_available = gx_hld_is_hl_color_available(pgs, pdevc); int code = 0; /* Fill the page directly, ignoring clipping. */ @@ -1119,7 +1085,7 @@ rect.q.x = int2fixed(dev->width); rect.q.y = int2fixed(dev->height); code = dev_proc(dev, fill_rectangle_hl_color)(dev, - &rect, (const gs_imager_state *)pis, pdevc, NULL); + &rect, (const gs_gstate *)pgs, pdevc, NULL); } if (!hl_color_available || code == gs_error_rangecheck) code = gx_fill_rectangle_device_rop(0, 0, dev->width, dev->height, pdevc, dev, lop_default); diff -Nru ghostscript-9.10~dfsg/base/gdevddrw.h ghostscript-9.25~dfsg+1/base/gdevddrw.h --- ghostscript-9.10~dfsg/base/gdevddrw.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevddrw.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Prototypes of some polygon and image drawing procedures */ @@ -20,8 +20,7 @@ enum fill_trap_flags { ftf_peak0 = 1, - ftf_peak1 = 2, - ftf_pseudo_rasterization = 4 + ftf_peak1 = 2 }; int gx_fill_trapezoid_cf_fd(gx_device * dev, const gs_fixed_edge * left, diff -Nru ghostscript-9.10~dfsg/base/gdevdevn.c ghostscript-9.25~dfsg+1/base/gdevdevn.c --- ghostscript-9.10~dfsg/base/gdevdevn.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdevn.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Example DeviceN process color model devices. */ @@ -29,6 +29,7 @@ #include "gsequivc.h" #include "gxblend.h" #include "gdevp14.h" +#include "gdevdevnprn.h" /* * Utility routines for common DeviceN related parameters: @@ -50,14 +51,14 @@ /* Convert an RGB color space to DeviceN colorants. */ void rgb_cs_to_devn_cm(gx_device * dev, int * map, - const gs_imager_state *pis, frac r, frac g, frac b, frac out[]) + const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { int i = dev->color_info.num_components - 1; frac cmyk[4]; for(; i >= 0; i--) /* Clear colors */ out[i] = frac_0; - color_rgb_to_cmyk(r, g, b, pis, cmyk, dev->memory); + color_rgb_to_cmyk(r, g, b, pgs, cmyk, dev->memory); if ((i = map[0]) != GX_DEVICE_COLOR_MAX_COMPONENTS) out[i] = cmyk[0]; if ((i = map[1]) != GX_DEVICE_COLOR_MAX_COMPONENTS) @@ -87,6 +88,50 @@ out[i] = k; } +/* Some devices need to create composite mappings of the spot colorants. + This code was originally in the tiffsep device but was moved here to be + sharable across multiple separation devices that need this capability */ + + +/* +* Build the map to be used to create a CMYK equivalent to the current +* device components. +*/ +void build_cmyk_map(gx_device *pdev, int num_comp, + equivalent_cmyk_color_params *equiv_cmyk_colors, + cmyk_composite_map * cmyk_map) +{ + int comp_num; + gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev); + + if (devn_params == NULL) + return; + + for (comp_num = 0; comp_num < num_comp; comp_num++) { + int sep_num = devn_params->separation_order_map[comp_num]; + + cmyk_map[comp_num].c = cmyk_map[comp_num].m = + cmyk_map[comp_num].y = cmyk_map[comp_num].k = frac_0; + /* The tiffsep device has 4 standard colors: CMYK */ + if (sep_num < devn_params->num_std_colorant_names) { + switch (sep_num) { + case 0: cmyk_map[comp_num].c = frac_1; break; + case 1: cmyk_map[comp_num].m = frac_1; break; + case 2: cmyk_map[comp_num].y = frac_1; break; + case 3: cmyk_map[comp_num].k = frac_1; break; + } + } else { + sep_num -= devn_params->num_std_colorant_names; + if (equiv_cmyk_colors->color[sep_num].color_info_valid) { + cmyk_map[comp_num].c = equiv_cmyk_colors->color[sep_num].c; + cmyk_map[comp_num].m = equiv_cmyk_colors->color[sep_num].m; + cmyk_map[comp_num].y = equiv_cmyk_colors->color[sep_num].y; + cmyk_map[comp_num].k = equiv_cmyk_colors->color[sep_num].k; + } + } + } +} + /* * This utility routine calculates the number of bits required to store * color information. In general the values are rounded up to an even @@ -101,7 +146,7 @@ * Input values are not tested for validity. */ int -bpc_to_depth(int ncomp, int bpc) +bpc_to_depth(uchar ncomp, int bpc) { static const byte depths[4][8] = { {1, 2, 0, 4, 8, 0, 0, 8}, @@ -141,6 +186,26 @@ return false; } +/* Check only the separation names */ +int +check_separation_names(const gx_device * dev, const gs_devn_params * pparams, + const char * pname, int name_size, int component_type, int number) +{ + const gs_separations * separations = &pparams->separations; + int num_spot = separations->num_separations; + int color_component_number = number; + int i; + + for (i = 0; inames[i].data, + separations->names[i].size, pname, name_size)) { + return color_component_number; + } + color_component_number++; + } + return -1; +} + /* * This routine will check to see if the color component name match those * of either the process color model colorants or the names on the @@ -161,7 +226,6 @@ { fixed_colorant_name * pcolor = pparams->std_colorant_names; int color_component_number = 0; - int i; /* Check if the component is in the process color model list. */ if (pcolor) { @@ -172,22 +236,8 @@ color_component_number++; } } - - /* Check if the component is in the separation names list. */ - { - const gs_separations * separations = &pparams->separations; - int num_spot = separations->num_separations; - - for (i=0; inames[i].data, - separations->names[i].size, pname, name_size)) { - return color_component_number; - } - color_component_number++; - } - } - - return -1; + return check_separation_names(dev, pparams, pname, name_size, + component_type, color_component_number); } /* @@ -257,7 +307,7 @@ pdevn_params->num_separation_order_names != 0) return -1; /* Do not add --> indicate colorant unknown. */ - /* Make sure the name is not "None" this is sometimes + /* Make sure the name is not "None" this is sometimes within a DeviceN list and should not be added as one of the separations. */ if (strncmp(pname, "None", name_size) == 0) { @@ -275,8 +325,8 @@ gs_separations * separations = &pdevn_params->separations; int sep_num = separations->num_separations++; /* We have a new spot colorant - put in stable memory to avoid "restore" */ - sep_name = gs_alloc_bytes(dev->memory->stable_memory, - name_size, "devn_get_color_comp_index"); + sep_name = gs_alloc_bytes(dev->memory->stable_memory, name_size, "devn_get_color_comp_index"); + memcpy(sep_name, pname, name_size); separations->names[sep_num].size = name_size; separations->names[sep_num].data = sep_name; @@ -333,8 +383,11 @@ if ( (code = sample_device_crd_get_params(pdev, plist, "CRDDefault")) < 0 || (code = param_write_name_array(plist, "SeparationColorNames", &scna)) < 0 || (code = param_write_name_array(plist, "SeparationOrder", &sona)) < 0 || - (code = param_write_bool(plist, "Separations", &seprs)) < 0 || - (code = param_write_int(plist, "PageSpotColors", &(pdevn_params->page_spot_colors))) < 0) + (code = param_write_bool(plist, "Separations", &seprs)) < 0) + return code; + + if (pdev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && + (code = param_write_int(plist, "PageSpotColors", &(pdevn_params->page_spot_colors))) < 0) return code; if (pdevn_params->separations.num_separations > 0) @@ -391,8 +444,10 @@ { break; } END_ARRAY_PARAM(sona, sone); - if (sona.data != 0 && sona.size > GX_DEVICE_COLOR_MAX_COMPONENTS) + if (sona.data != 0 && sona.size > GX_DEVICE_COLOR_MAX_COMPONENTS) { + param_signal_error(plist, "SeparationOrder", gs_error_rangecheck); return_error(gs_error_rangecheck); + } /* Get the SeparationColorNames */ BEGIN_ARRAY_PARAM(param_read_name_array, "SeparationColorNames", @@ -400,8 +455,10 @@ { break; } END_ARRAY_PARAM(scna, scne); - if (scna.data != 0 && scna.size > GX_DEVICE_MAX_SEPARATIONS) + if (scna.data != 0 && scna.size > GX_DEVICE_MAX_SEPARATIONS) { + param_signal_error(plist, "SeparationColorNames", gs_error_rangecheck); return_error(gs_error_rangecheck); + } /* Get the equivalent_cmyk_color_params -- array is N * 5 elements */ BEGIN_ARRAY_PARAM(param_read_int_array, ".EquivCMYKColors", equiv_cmyk, equiv_cmyk.size, equiv_cmyk_e) @@ -442,12 +499,12 @@ } num_spot_changed = true; for (i = pdevn_params->separations.num_separations; i < num_spot; i++) - pdevn_params->separation_order_map[i + pdevn_params->num_std_colorant_names] = + pdevn_params->separation_order_map[i + pdevn_params->num_std_colorant_names] = i + pdevn_params->num_std_colorant_names; pdevn_params->separations.num_separations = num_spot; } /* Process any .EquivCMYKColors info */ - if (equiv_cmyk.data != 0) { + if (equiv_cmyk.data != 0 && pequiv_colors != 0) { int spot_num = 0; for (i=0; i < equiv_cmyk.size; i += 5) { /* valid, C, M, Y, K for each equiv_color */ @@ -480,9 +537,16 @@ if ((comp_num = (*dev_proc(pdev, get_color_comp_index)) (pdev, (const char *)sona.data[i].data, sona.data[i].size, SEPARATION_NAME)) < 0) { + param_signal_error(plist, "SeparationOrder", gs_error_rangecheck); return_error(gs_error_rangecheck); } pdevn_params->separation_order_map[i] = comp_num; + /* If the device enabled AUTO_SPOT_COLORS some separations may */ + /* have been added. Adjust num_spots if so. */ + if (num_spot != pdevn_params->separations.num_separations) { + num_spot = pdevn_params->separations.num_separations; + num_spot_changed = true; + } } } /* @@ -500,8 +564,10 @@ case 1: break; case 0: - if (max_sep < 1 || max_sep > GX_DEVICE_COLOR_MAX_COMPONENTS) + if (max_sep < 1 || max_sep > GX_DEVICE_COLOR_MAX_COMPONENTS) { + param_signal_error(plist, "MaxSeparations", gs_error_rangecheck); return_error(gs_error_rangecheck); + } } /* * The PDF interpreter scans the resources for pages to try to @@ -521,8 +587,10 @@ case 1: break; case 0: - if (page_spot_colors < -1) + if (page_spot_colors < -1) { + param_signal_error(plist, "PageSpotColors", gs_error_rangecheck); return_error(gs_error_rangecheck); + } if (page_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS - MAX_DEVICE_PROCESS_COLORS) page_spot_colors = GX_DEVICE_COLOR_MAX_COMPONENTS - MAX_DEVICE_PROCESS_COLORS; /* Need to leave room for the process colors in GX_DEVICE_COLOR_MAX_COMPONENTS */ @@ -565,51 +633,18 @@ pdev->color_info.max_components) pdev->color_info.num_components = pdev->color_info.max_components; -#if !USE_COMPRESSED_ENCODING + /* * See earlier comment about the depth and non compressed * pixel encoding. */ pdev->color_info.depth = bpc_to_depth(pdev->color_info.num_components, pdevn_params->bitspercomponent); -#endif } } return code; } -/* A self referencing function to copy the color list */ -static int -copy_color_list(compressed_color_list_t *src_color_list, - compressed_color_list_t *des_color_list, gs_memory_t *memory) -{ - int k; - int num_sub_levels = src_color_list->num_sub_level_ptrs; - - if (num_sub_levels > 0) { - for (k = 0; k < num_sub_levels; k++) { - des_color_list->u.sub_level_ptrs[k] = - alloc_compressed_color_list_elem(src_color_list->mem, - des_color_list->level_num_comp - 1); - if (des_color_list->u.sub_level_ptrs[k] == NULL) { - return gs_rethrow(-1, "copy_color_list allocation error"); - } - des_color_list->u.sub_level_ptrs[k]->first_bit_map = - src_color_list->u.sub_level_ptrs[k]->first_bit_map; - des_color_list->u.sub_level_ptrs[k]->num_sub_level_ptrs = - src_color_list->u.sub_level_ptrs[k]->num_sub_level_ptrs; - copy_color_list(src_color_list->u.sub_level_ptrs[k], - des_color_list->u.sub_level_ptrs[k], memory); - } - } else { - /* Allocate and copy the data */ - memcpy(&(des_color_list->u.comp_data[0]), - &(src_color_list->u.comp_data[0]), - size_of(comp_bit_map_list_t)*NUM_ENCODE_LIST_ITEMS); - } - return 0; -} - /* Free the copied deviceN parameters */ void devn_free_params(gx_device *thread_cdev) @@ -626,8 +661,6 @@ "devn_free_params"); devn_params->separations.names[k].data = NULL; } - free_compressed_color_list(devn_params->compressed_color_list); - devn_params->compressed_color_list = NULL; for (k = 0; k < devn_params->pdf14_separations.num_separations; k++) { gs_free_object(thread_cdev->memory, @@ -635,8 +668,6 @@ "devn_free_params"); devn_params->pdf14_separations.names[k].data = NULL; } - free_compressed_color_list(devn_params->pdf14_compressed_color_list); - devn_params->pdf14_compressed_color_list = NULL; } /* This is used to copy the deviceN parameters from the parent clist device to the @@ -647,7 +678,6 @@ gs_devn_params *src_devn_params, *des_devn_params; int code = 0; int k; - compressed_color_list_t *src_color_list, *des_color_list; /* Get pointers to the parameters */ src_devn_params = dev_proc(psrcdev, ret_devn_params)(psrcdev); @@ -677,20 +707,7 @@ /* Order map */ memcpy(des_devn_params->separation_order_map, src_devn_params->separation_order_map, sizeof(gs_separation_map)); - /* Compressed color list. A messy structure that has a union that - includes a linked list item */ - src_color_list = src_devn_params->compressed_color_list; - if (src_color_list != NULL) { - /* Take care of the initial one. Others are done recursively */ - des_color_list = alloc_compressed_color_list_elem(src_color_list->mem, - TOP_ENCODED_LEVEL); - des_color_list->first_bit_map = src_color_list->first_bit_map; - des_color_list->num_sub_level_ptrs = src_color_list->num_sub_level_ptrs; - code = copy_color_list(src_color_list, des_color_list, pdesdev->memory); - des_devn_params->compressed_color_list = des_color_list; - } else { - des_devn_params->compressed_color_list = NULL; - } + /* Handle the PDF14 items if they are there */ des_devn_params->pdf14_separations.num_separations = src_devn_params->pdf14_separations.num_separations; @@ -704,18 +721,6 @@ des_devn_params->pdf14_separations.names[k].size = name_size; des_devn_params->pdf14_separations.names[k].data = sep_name; } - src_color_list = src_devn_params->pdf14_compressed_color_list; - if (src_color_list != NULL) { - /* Take care of the initial one. Others are done recursively */ - des_color_list = alloc_compressed_color_list_elem(src_color_list->mem, - TOP_ENCODED_LEVEL); - des_color_list->first_bit_map = src_color_list->first_bit_map; - des_color_list->num_sub_level_ptrs = src_color_list->num_sub_level_ptrs; - code = copy_color_list(src_color_list, des_color_list, pdesdev->memory); - des_devn_params->pdf14_compressed_color_list = des_color_list; - } else { - des_devn_params->pdf14_compressed_color_list = NULL; - } return code; } @@ -740,6 +745,45 @@ return(0); } +static bool separations_equal(const gs_separations *p1, const gs_separations *p2) +{ + int k; + + if (p1->num_separations != p2->num_separations) + return false; + for (k = 0; k < p1->num_separations; k++) { + if (p1->names[k].size != p2->names[k].size) + return false; + else if (p1->names[k].size > 0) { + if (memcmp(p1->names[k].data, p2->names[k].data, p1->names[k].size) != 0) + return false; + } + } + return true; +} + +static bool devn_params_equal(const gs_devn_params *p1, const gs_devn_params *p2) +{ + if (p1->bitspercomponent != p2->bitspercomponent) + return false; + if (p1->max_separations != p2->max_separations) + return false; + if (p1->num_separation_order_names != p2->num_separation_order_names) + return false; + if (p1->num_std_colorant_names != p2->num_std_colorant_names) + return false; + if (p1->page_spot_colors != p2->page_spot_colors) + return false; + if (!separations_equal(&p1->pdf14_separations, &p2->pdf14_separations)) + return false; + if (!separations_equal(&p1->separations, &p2->separations)) + return false; + if (memcmp(p1->separation_order_map, p2->separation_order_map, sizeof(gs_separation_map)) != 0) + return false; + if (p1->std_colorant_names != p2->std_colorant_names) + return false; + return true; +} /* * Utility routine for handling DeviceN related parameters in a @@ -775,9 +819,8 @@ } /* If anything changed, then close the device, etc. */ - if (memcmp(&pdev->color_info, &save_info, sizeof(gx_device_color_info)) || - memcmp(pdevn_params, &saved_devn_params, - sizeof(gs_devn_params)) || + if (!gx_color_info_equal(&pdev->color_info, &save_info) || + !devn_params_equal(pdevn_params, &saved_devn_params) || (pequiv_colors != NULL && compare_equivalent_cmyk_color_params(pequiv_colors, &saved_equiv_colors))) { gs_closedevice(pdev); @@ -797,134 +840,6 @@ } /* - * The following routines are for compressing colorant values into a 64 bit - * gx_color_index value. This is needed since Ghostscript uses an integer type - * (usually 64 bit long long) as the representation for a pixel. This is a - * problem for handling output devices which support spot colors. Ideally these - * devices should be able to handle any number of colorants. This would require - * an arbitrarily large number of bits to represent a pixel. - * - * See comments before devn_encode_compressed_color for more information. - */ - -/* GC procedures */ -static -ENUM_PTRS_WITH(compressed_color_list_enum_ptrs, compressed_color_list_t *plist) -{ - if (index < plist->num_sub_level_ptrs) - ENUM_RETURN(plist->u.sub_level_ptrs[index]); - return 0; -} -ENUM_PTRS_END - -static RELOC_PTRS_WITH(compressed_color_list_reloc_ptrs, compressed_color_list_t *plist) -{ - int i; - - for (i = 0; i < plist->num_sub_level_ptrs; i++) { - RELOC_PTR(compressed_color_list_t, u.sub_level_ptrs[i]); - } -} -RELOC_PTRS_END - -gs_private_st_composite(st_compressed_color_list, compressed_color_list_t, - "encode color list", compressed_color_list_enum_ptrs, - compressed_color_list_reloc_ptrs); -/* - * A routine for debugging the encoded color colorant list. This routine - * dumps the contents of the list. - */ -void -print_compressed_color_list(const gs_memory_t *mem, compressed_color_list_t * pcomp_list, int num_comp) -{ - int i, j, comp_num, comp; - comp_bit_map_list_t * pcomp_bit_map; - - if (pcomp_list == NULL) - return; - - /* Indent our print out for sub levels */ - for (i = TOP_ENCODED_LEVEL - pcomp_list->level_num_comp; i > 0; i--) - dmlprintf(mem, " "); - dmlprintf1(mem, "List level = %d\n", pcomp_list->level_num_comp); - /* - * Print the colorant bit maps for this level. - */ - for (i = NUM_ENCODE_LIST_ITEMS - 1; i >= pcomp_list->first_bit_map; i--) { - pcomp_bit_map = &(pcomp_list->u.comp_data[i]); - /* Indent our print out for sub levels */ - for (j = TOP_ENCODED_LEVEL - pcomp_list->level_num_comp; j > 0; j--) - dmlprintf(mem, " "); - dmlprintf4(mem,"%3d%4d%4d %d ", i, pcomp_bit_map->num_comp, - pcomp_bit_map->num_non_solid_comp, - pcomp_bit_map->solid_not_100); - for (comp_num = num_comp - 1; comp_num >= 0; comp_num--) { - comp = colorant_present(pcomp_bit_map, colorants, comp_num); - dmlprintf1(mem, "%d", comp); - if ((comp_num & 7) == 0) /* Separate into groups of 8 bits */ - dmlprintf(mem, " "); - } - dmlprintf(mem, " "); - for (comp_num = num_comp - 1; comp_num >= 0; comp_num--) { - comp = colorant_present(pcomp_bit_map, solid_colorants, comp_num); - dmlprintf1(mem, "%d", comp); - if ((comp_num & 7) == 0) /* Separate into groups of 8 bits */ - dmlprintf(mem, " "); - } - dmlprintf(mem, "\n"); - } - - /* - * Print the sub levels. - */ - for (i = 0; i < pcomp_list->num_sub_level_ptrs; i++) - print_compressed_color_list(mem, pcomp_list->u.sub_level_ptrs[i], num_comp); - - return; -} - -/* - * Allocate an list level element for our encode color list. - */ -compressed_color_list_t * -alloc_compressed_color_list_elem(gs_memory_t * mem, int num_comps) -{ - compressed_color_list_t * plist = - gs_alloc_struct(mem->stable_memory, compressed_color_list_t, - &st_compressed_color_list, "alloc_compressed_color_list"); - if (plist != NULL) { - /* Initialize the data in the element. */ - memset(plist, 0, size_of(*plist)); - plist->mem = mem->stable_memory; - plist->level_num_comp = num_comps; - plist->first_bit_map = NUM_ENCODE_LIST_ITEMS; - } - return plist; -} - -/* - * Free the elements of a compressed color list. - */ -void -free_compressed_color_list(compressed_color_list_t * pcomp_list) -{ - int i; - - if (pcomp_list == NULL) - return; - - /* Discard the sub levels. */ - /* Allocation for this object is done in stable memory. Make sure - that is done here too */ - for (i = 0; i < pcomp_list->num_sub_level_ptrs; i++) { - free_compressed_color_list(pcomp_list->u.sub_level_ptrs[i]); - pcomp_list->u.sub_level_ptrs[i] = NULL; - } - gs_free_object(pcomp_list->mem->stable_memory, pcomp_list, "free_compressed_color_list"); - return; -} - -/* * Free a set of separation names */ void @@ -944,699 +859,6 @@ return; } -/* - * Add a new set of bit mapped colorant lists to our list of encoded color - * colorants. - */ -static bool -sub_level_add_compressed_color_list(gs_memory_t * mem, - comp_bit_map_list_t * pnew_comp_bit_map, - compressed_color_list_t * pcomp_list, gx_color_index * plist_index) -{ - int i, entry_num; - int num_non_solid_comp = pnew_comp_bit_map->num_non_solid_comp; - bool status; - - /* - * Check if this is the level for the specified number of entries. If so - * then add the bit map to this level (if we have room). - */ - if (num_non_solid_comp >= pcomp_list->level_num_comp) { - entry_num = pcomp_list->first_bit_map - 1; - - if (entry_num > pcomp_list->num_sub_level_ptrs) { - memcpy(&(pcomp_list->u.comp_data[entry_num]), pnew_comp_bit_map, - size_of(comp_bit_map_list_t)); - pcomp_list->first_bit_map = entry_num; - *plist_index = - ((gx_color_index) entry_num) << (NUM_GX_COLOR_INDEX_BITS - 8); - return true; - } - return false; - } - /* - * Try to insert the bit map into the sub levels. - */ - for (i = 0; i < pcomp_list->num_sub_level_ptrs; i++) { - status = sub_level_add_compressed_color_list(mem, pnew_comp_bit_map, - pcomp_list->u.sub_level_ptrs[i], plist_index); - if (status) { - *plist_index = (((gx_color_index) i) << (NUM_GX_COLOR_INDEX_BITS - 8)) - + (*plist_index >> 8); - return true; - } - } - /* - * If we did not add this bit map into a sub level then create a new sub - * level and insert it there. - */ - entry_num = pcomp_list->num_sub_level_ptrs; - if (entry_num < pcomp_list->first_bit_map) { - pcomp_list->u.sub_level_ptrs[entry_num] = - alloc_compressed_color_list_elem(pcomp_list->mem, pcomp_list->level_num_comp - 1); - if (pcomp_list->u.sub_level_ptrs[entry_num] != NULL) { - pcomp_list->num_sub_level_ptrs++; - status = sub_level_add_compressed_color_list(mem, pnew_comp_bit_map, - pcomp_list->u.sub_level_ptrs[entry_num], plist_index); - if (status) { - *plist_index = (((gx_color_index) i) << (NUM_GX_COLOR_INDEX_BITS - 8)) - + (*plist_index >> 8); - return true; - } - } - } - /* - * If we get to here then there was no space available in this list element. - */ - return false; -} - -/* - * Add a new bit mapped colorant list to our list of encoded color colorants. - * - * Our simple linear search for entries gets very inefficient if we have many - * entries. So we are doing two things to minimize the number of entries. - * We need separate entries for each combination of solid colorants. if we - * do not have many non solid colorants, we use non solid colorants even for - * solid colorants. For small numbers of colorants, we add more colorants - * to try to create an entry that can be used for more situations. We add extra - * process color colorants since these are the ones most likely to be mixed - * with spot colors. - */ -static bool -add_compressed_color_list(gs_memory_t * mem, - comp_bit_map_list_t * pnew_comp_bit_map, - compressed_color_list_t * pcomp_list, gx_color_index * plist_index) -{ - int num_comp = pnew_comp_bit_map->num_comp; - int num_non_solid = pnew_comp_bit_map->num_non_solid_comp; - int num_solid = num_comp - num_non_solid; - int comp_num = 0; - - /* - * If we have room for more 'non solid' colorants then convert some of - * the solid colorants to using the non solid encodings. - */ - while (num_non_solid < MIN_ENCODED_COMPONENTS && num_solid > 0) { - if (colorant_present(pnew_comp_bit_map, solid_colorants, comp_num)) { - clear_colorant_present(pnew_comp_bit_map, - solid_colorants, comp_num); - num_solid--; - num_non_solid++; - } - comp_num++; - } - if (num_non_solid < MIN_ENCODED_COMPONENTS) { - /* - * For small numbers of colorants, we add more colorants to try to - * create an entry that can be used for more situations. - */ - for (comp_num = 0; num_comp < MIN_ENCODED_COMPONENTS; comp_num++) { - if ((colorant_present(pnew_comp_bit_map, colorants, comp_num)) == 0) { - set_colorant_present(pnew_comp_bit_map, colorants, comp_num); - num_non_solid++; - num_comp++; - } - } - } - pnew_comp_bit_map->num_comp = num_comp; - pnew_comp_bit_map->num_non_solid_comp = num_non_solid; - return sub_level_add_compressed_color_list(mem, pnew_comp_bit_map, - pcomp_list, plist_index); -} - -/* - * Initialize our encode color list. When we initialize the list, we add two - * initial colorant maps. The first one is good for any image that uses zeven - * or fewer colorants. The second is good for any image which uses seven spot - * colors (or less) and no process colors. These are placed at the start of - * the list to minimize the add and search times for these common situations. - */ -static compressed_color_list_t * -init_compressed_color_list(gs_memory_t *mem) -{ - /* - * Create our first list element. - */ - compressed_color_list_t * plist = - alloc_compressed_color_list_elem(mem, TOP_ENCODED_LEVEL); - - /* - * Add a first colorant bit map to the list. This bit map covers the first - * TOP_ENCODED_LEVEL colorants. Typically this covers CMYK plus the - * first three spot colors. This bit map should handle many situations. - */ - if (plist != NULL) { - int comp_num; - comp_bit_map_list_t comp_bit_map; - gx_color_index temp; - - /* - * Add a first colorant bit map to the list. This bit map covers the - * first TOP_ENCODED_LEVEL colorants. Typically this covers CMYK plus - * the first three spot colors. This bit map should handle many - * situations. - */ - memset(&comp_bit_map, 0, size_of(comp_bit_map)); - for (comp_num = 0; comp_num < TOP_ENCODED_LEVEL; comp_num++) - set_colorant_present(&comp_bit_map, colorants, comp_num); - comp_bit_map.num_comp = - comp_bit_map.num_non_solid_comp = TOP_ENCODED_LEVEL; - add_compressed_color_list(mem, &comp_bit_map, plist, &temp); - /* - * Add a second colorant bit map to the list. This bit map covers the - * first TOP_ENCODED_LEVEL colorants after the first four colorants. - * Typically this covers the first seven spot colors. This bit map is - * being placed to cover images that use only spot colors. - */ - memset(&comp_bit_map, 0, size_of(comp_bit_map)); - for (comp_num = 4; comp_num < TOP_ENCODED_LEVEL + 4; comp_num++) - set_colorant_present(&comp_bit_map, colorants, comp_num); - comp_bit_map.num_comp = - comp_bit_map.num_non_solid_comp = TOP_ENCODED_LEVEL; - add_compressed_color_list(mem, &comp_bit_map, plist, &temp); - } - return plist; -} - -/* - * For most combinations of colorants we use 8 bits for saving the colorant - * value. However if we get above 7 colorants (in a pixel, not total) we use - * fewer bits. The constraint is that the size of the index value plus the - * the number of colorants being used times size of the colorant value saved - * must fit into a gx_color_index value. - */ -int num_comp_bits[MAX_ENCODED_COMPONENTS + 1] = { - 8, /* 0 colorants - not used */ - 8, /* 1 colorants */ - 8, /* 2 colorants */ - 8, /* 3 colorants */ - 8, /* 4 colorants */ - 8, /* 5 colorants */ - 8, /* 6 colorants */ - 8, /* 7 colorants */ - 7, /* 8 colorants */ - 6, /* 9 colorants */ - 5, /* 10 colorants */ - 5, /* 11 colorants */ - 4, /* 12 colorants */ - 4, /* 13 colorants */ - 4 /* 14 colorants */ -}; - -/* - * Values used to decompressed the colorants in our encoded values back into - * a gx_color value. The color value will be (comp_bits * entry) >> 8 - * The number of bits in comp_bits are defined in the num_comp_bits table. - * These values are chosen to expand these bit combinations back to 16 bit values - * (after shifting right 8 bits). - */ -#define gx_color_value_factor(num_bits) \ - ((gx_max_color_value << 8) + 0xff) / ((1 << num_bits) - 1) - -int comp_bit_factor[MAX_ENCODED_COMPONENTS + 1] = { - gx_color_value_factor(8), /* 0 colorants (8 bits) */ - gx_color_value_factor(8), /* 1 colorants (8 bits) */ - gx_color_value_factor(8), /* 2 colorants (8 bits) */ - gx_color_value_factor(8), /* 3 colorants (8 bits) */ - gx_color_value_factor(8), /* 4 colorants (8 bits) */ - gx_color_value_factor(8), /* 5 colorants (8 bits) */ - gx_color_value_factor(8), /* 6 colorants (8 bits) */ - gx_color_value_factor(8), /* 7 colorants (8 bits) */ - gx_color_value_factor(7), /* 8 colorants (7 bits) */ - gx_color_value_factor(6), /* 9 colorants (6 bits) */ - gx_color_value_factor(5), /* 10 colorants (5 bits) */ - gx_color_value_factor(5), /* 11 colorants (5 bits) */ - gx_color_value_factor(4), /* 12 colorants (4 bits) */ - gx_color_value_factor(4), /* 13 colorants (4 bits) */ - gx_color_value_factor(4) /* 14 colorants (4 bits) */ -}; -#undef gx_color_value_factor - -/* - * Find a given colorant bit map is the list of encoded colorant bit map. - * - * Note: This routine is called recursively to search sub levels of the - * list. - * - * The parameters are: - * num_comp - The number of colorants for the device. - * pcomp_list - The current list of encoded colorants. - * pnew_comp_bit_map - Pointer to the bit map found to be encoded. - * plist_index - Pointer to 'encode bits' (return value) - * pcomp_bit_map - Pointer to pointer to the actual bit map found - * (return value). - * returns true if the bit map is found. - */ -static bool -search_compressed_color_list(int num_comp, compressed_color_list_t * pcomp_list, - comp_bit_map_list_t * pnew_comp_bit_map, gx_color_index * plist_index, - comp_bit_map_list_t * * pcomp_bit_map) -{ - int i; -#if DEVN_ENCODE_COLOR_USING_BIT_MAP_ARRAY - int j, num_bit_map_elem; -#endif - bool found; - - /* - * Search the colorant bit maps for this level of the map. - */ -#if DEVN_ENCODE_COLOR_USING_BIT_MAP_ARRAY - num_bit_map_elem = (num_comp + BITS_PER_COMP_BIT_MAP_ELEM - 1) / - BITS_PER_COMP_BIT_MAP_ELEM; -#endif - for (i = NUM_ENCODE_LIST_ITEMS - 1; i >= pcomp_list->first_bit_map; i--) { - *pcomp_bit_map = &(pcomp_list->u.comp_data[i]); - /* - * Do not try to match if one entry uses a 'solid' set of colorants - * that is not really solid (i.e. not 100%) and the other is. It is - * possible to work if different but it would make some of the logic - * more difficult. - */ - if (pnew_comp_bit_map->solid_not_100 != - (*pcomp_bit_map)->solid_not_100) - continue; - /* - * It is a match if the new colorant bit map is a subset of the one - * in the list and the solid colorants for new map is a super set of - * the solid colorants for the one in the list. I.e. we can use - * the non solid part of the entry for either zero or solid colorants. - */ -#if DEVN_ENCODE_COLOR_USING_BIT_MAP_ARRAY - for (j = 0; j < num_bit_map_elem; j++) { - if ((pnew_comp_bit_map->colorants[j] & - (*pcomp_bit_map)->colorants[j]) != - pnew_comp_bit_map->colorants[j]) - break; /* No match if a colorant is missing. */ - if ((pnew_comp_bit_map->solid_colorants[j] & - (*pcomp_bit_map)->solid_colorants[j]) != - (*pcomp_bit_map)->solid_colorants[j]) - break; /* No match if extra solid colorants */ - } - if (j == num_bit_map_elem) { -#else - if (((pnew_comp_bit_map->colorants & - (*pcomp_bit_map)->colorants) == - pnew_comp_bit_map->colorants) && - ((pnew_comp_bit_map->solid_colorants & - (*pcomp_bit_map)->solid_colorants) == - (*pcomp_bit_map)->solid_colorants)) { -#endif - /* - * To prevent possible loss of accuracy, ignore matches in which the - * packing will use fewer bits in the encoded colorant values than - * is possible for the given number of colorants. - */ - if (num_comp_bits[pnew_comp_bit_map->num_comp] > - num_comp_bits[(*pcomp_bit_map)->num_comp]) - break; - /* - * We have a match. Put our object number into the top eight - * bits of the encoded gx_color_index and exit. - */ - *plist_index = ((gx_color_index) i) << (NUM_GX_COLOR_INDEX_BITS - 8); - return true; - } - } - - /* - * Search the lower levels (i.e. with fewer colorants to see if we - * can find a match. - */ - if (pcomp_list->level_num_comp <= pnew_comp_bit_map->num_non_solid_comp) - return false; /* Exit if not enough colorants in the sub levels */ - - for (i = 0; i < pcomp_list->num_sub_level_ptrs; i++) { - found = search_compressed_color_list(num_comp, - pcomp_list->u.sub_level_ptrs[i], - pnew_comp_bit_map, plist_index, pcomp_bit_map); - if (found) { - /* - * We have a match. Combine the encode index for the sub level - * with our index for this level. - */ - *plist_index = (((gx_color_index) i) << (NUM_GX_COLOR_INDEX_BITS - 8)) - + (*plist_index >> 8); - return true; - } - } - return false; -} - -/* - * Encode a list of colorant values into a gx_color_index_value. - * - * This routine is designed to pack more than eight 8 bit colorant values into - * a 64 bit gx_color_index value. It does this piece of magic by keeping a list - * of which colorant combinations are actualy used (i.e. which colorants are non - * zero). The non zero colorant values and and an 'index' value are packed into - * the output gx_color_index value. - * - * The the different combinations of used colorants are saved into a table - * defined by the comp_bit_map_list_t structure type. This table is kept as - * a list with 256 elements. Each element can be either a pair of bit maps which - * indicates the combination of colorants being used or a pointer to a sub list - * for the next lower level of combinations. There are two bit maps to indicate - * which colorants are specified by the 'index' value. One bit map indicates - * which colorants are used. The second bit map is used to indicate a group of - * colorants with the same value. Normally this second bit map is used to - * indicate which colorants are 'solid' (i.e. 100% and the 'solid_not_100 flag - * is set to false). However if there is a larger group of colorants with the - * same value (and not solid) then the 'solid_not_100' flag is set to true and - * second bit map is used to indicate the colorants in this group. In this - * case, the value of the colorant group is stored in the first colorant entry - * in the gx_color_index. - * - * The number of bits allocated to storing the 'index' and the number of bits - * allocated to storing colorant values depends upon the number of colorant - * being used. - * - * Number of non zero colorant Index bits Bits per colorant - * 0 to 5 24 8 - * 6 16 8 - * 7 8 8 - * 8 8 7 - * 9 8 6 - * 10 8 5 - * 11 8 5 - * 12 8 4 - * 13 8 4 - * 14 8 4 - * More than 14 Not encodeable - * - * The 'index' bits can be logically divided into groups of 8 bits. The - * first (upper) group of 8 bits is used to select either one of 256 - * combinations of 7 or more colorant or to select a pointer to a sub - * level. If a sub level pointer is specified, then the next group of 8 - * index bits is used to select either one of 256 combinations of 6 colorants - * of a sub level pointer. A sub level pointer points to one of 256 - * combinations of 5 colorants. If we have fewer than 5 colorants being - * used, we add extra componnents to bring the total up to 5 colorants. - * This is done to prevent having a bunch of 1 or two colorant combinations. - */ -gx_color_index -devn_encode_compressed_color(gx_device *pdev, const gx_color_value colors[], - gs_devn_params * pdevn_params) -{ - int num_comp = pdev->color_info.num_components; - int comp_num, comp_count = 0, solid_comp_count = 0, bit_pos = 0; - int bit_count, group = 0; - int color_resolution = gx_max_color_value / STD_ENCODED_VALUE; - bool found, added; - comp_bit_map_list_t new_comp_bit_map = {0}; - comp_bit_map_list_t * pbit_map; - gx_color_index color = 0, list_index; - COLROUND_VARS; - - /* - * Determine what colorants are being used (non zero). We bit pack - * this info. Note: We treat any colorant value which is less than - * 256 as zero. Color values are 16 bits and we only keep the top - * eight bits. Likewise for solid (100%) colors. - */ - for (comp_num = 0; comp_num < num_comp; comp_num++) { - if (colors[comp_num] > color_resolution) { - set_colorant_present(&new_comp_bit_map, colorants, comp_num); - comp_count++; - /* Check if the color is solid */ - if (colors[comp_num] > (gx_max_color_value - color_resolution)) { - set_colorant_present(&new_comp_bit_map, - solid_colorants, comp_num); - solid_comp_count++; - } - } - } - new_comp_bit_map.num_comp = comp_count; - new_comp_bit_map.num_non_solid_comp = comp_count - solid_comp_count; - /* - * We may get less loss of accuracy if instead of checking for zero and - * 100% colorant values, we look for a group of colorants with the same - * colorant value. - */ - if (new_comp_bit_map.num_non_solid_comp > TOP_ENCODED_LEVEL && - solid_comp_count < (comp_count / 2)) { - short group_size[(gx_max_color_value / STD_ENCODED_VALUE) + 1] = {0}; - int value, largest_group_size = 0; - - /* Scan to determine the size of the largest group */ - for (comp_num = 0; comp_num < num_comp; comp_num++) { - value = colors[comp_num] / STD_ENCODED_VALUE; - group_size[value]++; - if (group_size[value] > largest_group_size) { - largest_group_size = group_size[value]; - group = value; - } - } - /* - * If using this group instead of the solid colorants will improve - * our situation, then switch to using this group. - */ - if (largest_group_size > (solid_comp_count + 1) && - (comp_count - largest_group_size) < MAX_ENCODED_COMPONENTS) { - /* Setup the colorant description to use this group */ - memset(&(new_comp_bit_map.solid_colorants), 0, - size_of(comp_bit_map_t)); - for (comp_num = 0; comp_num < num_comp; comp_num++) { - value = colors[comp_num] / STD_ENCODED_VALUE; - if (value == group) { - set_colorant_present(&new_comp_bit_map, - solid_colorants, comp_num); - } - } - new_comp_bit_map.solid_not_100 = true; - new_comp_bit_map.num_non_solid_comp = - comp_count - largest_group_size + 1; - } - } - - /* Our encoding scheme cannot handle too many non solid colorants. */ - if (new_comp_bit_map.num_non_solid_comp > MAX_ENCODED_COMPONENTS) - return NON_ENCODEABLE_COLOR; - - /* - * We keep a list of which colorant combinations we have used. Make - * sure that this list has been initialized. Alloc in stable_memory - * to make it immune to restore. - */ - if (pdevn_params->compressed_color_list == NULL) { - pdevn_params->compressed_color_list = - init_compressed_color_list(pdev->memory->stable_memory); - if (pdevn_params->compressed_color_list == NULL) - return NON_ENCODEABLE_COLOR; /* Unable to initialize list */ - } - - /* - * Check our list of colorant combinations to see if we already have a - * combination that is useable. I.e. a combination that includes all of our - * non zero colorants. - */ - found = search_compressed_color_list(num_comp, - pdevn_params->compressed_color_list, - &new_comp_bit_map, &list_index, &pbit_map); - - /* - * If our new colorant list was not found then add it to our encode color - * list. This needs to be in stable_memory to be immune to 'restore'. - */ - if (!found) { - added = add_compressed_color_list(pdev->memory->stable_memory, - &new_comp_bit_map, - pdevn_params->compressed_color_list, - &list_index); - if (!added) - return NON_ENCODEABLE_COLOR; - pbit_map = &new_comp_bit_map; - } - - /* - * Form the encoded color gx_color_index value. This is a combination - * of the bits that encode which colorants are used (non zero) and the - * colorant values. - */ - bit_count = num_comp_bits[pbit_map->num_non_solid_comp]; - if (pbit_map->solid_not_100) { - color = group >> (8 - bit_count); - bit_pos += bit_count; - } - COLROUND_SETUP(bit_count); - for (comp_num = 0; comp_num < num_comp; comp_num++) { - if (colorant_present(pbit_map, colorants, comp_num) && - !colorant_present(pbit_map, solid_colorants, comp_num)) { - color |= COLROUND_ROUND(colors[comp_num]) << bit_pos; - bit_pos += bit_count; - } - } - color |= list_index; - /* - * Make sure that our color index does not match one of the reserved - * values. - */ - if (color == NON_ENCODEABLE_COLOR) - color -= 1; - else if (color == gx_no_color_index) - color -= 2; - return color; -} - -/* - * Find the bit map for given bit map index. - */ -comp_bit_map_list_t * -find_bit_map(gx_color_index index, compressed_color_list_t * pcomp_list) -{ - int loc = (int)(index >> (NUM_GX_COLOR_INDEX_BITS - 8)); - - /* - * Search for the level which contains the bit map. If our index - * for this level is less than the number of sub level pointers for - * this level then we need to go down another level. - */ - while (loc < pcomp_list->num_sub_level_ptrs) { - pcomp_list = pcomp_list->u.sub_level_ptrs[loc]; - index <<= 8; - loc = (int)(index >> (NUM_GX_COLOR_INDEX_BITS - 8)); - } - return &(pcomp_list->u.comp_data[loc]); -} - -/* - * Decode a gx_color_index value back to a list of colorant values. This - * routine assumes that the gx_color_index value is 'encoded' as described - * for devn_encode_compressed_color. - * - * See comments preceding devn_encode_compressed_color for more information - * about the way that we are compressing colorant values in a gx_color_index. - */ -int -devn_decode_compressed_color(gx_device * dev, gx_color_index color, - gx_color_value * out, gs_devn_params * pdevn_params) -{ - int comp_num = 0; - int factor, bit_count, bit_mask; - int ncomp = dev->color_info.num_components; - comp_bit_map_list_t * pbitmap; - gx_color_value solid_color = gx_max_color_value; - - /* - * Set all colorants to max if we get a non encodeable color. We set the - * values to a max since this will represent another non encodeable color. - * Thus if we have a non decodable color, it will continue to propogate. - */ - if (color == NON_ENCODEABLE_COLOR) { - for (; comp_num < ncomp; comp_num++) - out[comp_num] = gx_max_color_value; - return 0; - } - pbitmap = find_bit_map(color, pdevn_params->compressed_color_list); - bit_count = num_comp_bits[pbitmap->num_non_solid_comp]; - bit_mask = (1 << bit_count) - 1; - factor = comp_bit_factor[pbitmap->num_non_solid_comp]; - if (pbitmap->solid_not_100) { - solid_color = (factor * ((int)color & bit_mask)) >> 8; - color >>= bit_count; - } - for (; comp_num < ncomp; comp_num++) { - if (colorant_present(pbitmap, colorants, comp_num)) { - if (colorant_present(pbitmap, solid_colorants, comp_num)) - out[comp_num] = solid_color; - else { - out[comp_num] = (factor * ((int)color & bit_mask)) >> 8; - color >>= bit_count; - } - } - else - out[comp_num] = 0; - } - return 0; -} - -/* - * Unpack a row of 'compressed color' values. These values are encoded as - * described for the devn_encode_compressed_color routine. - * - * The routine takes a raster line of data and expands each pixel into a buffer - * of 8 bit values for each colorant. - * - * See comments preceding devn_encode_compressed_color for more information - * about the way that we are encoding colorant values in a gx_color_index. - * - * Note: For simplicity of coding the calling routines, this routine will also - * handle 'uncompressed' bit maps. - */ -int -devn_unpack_row(gx_device * dev, int num_comp, gs_devn_params * pdevn_params, - int width, byte * in, byte * out) -{ - int i, comp_num, pixel_num; - - if (pdevn_params->compressed_color_list == NULL) { - int bytes_pp = dev->color_info.depth >> 3; - - /* - * For 'uncompressed' data, the number of bytes per pixel in the input - * raster line is defined by the device depth. This may be more than - * the number of actual device components. - */ - for (pixel_num = 0; pixel_num < width; pixel_num++) { - for (i = 0; i < num_comp; i++) - *out++ = *in++; - in += bytes_pp - num_comp; - } - return 0; - } - else { - int non_encodeable_count = 0; - int factor, bit_count, bit_mask; - comp_bit_map_list_t * pbitmap; - gx_color_index color; - - for (pixel_num = 0; pixel_num < width; pixel_num++) { - gx_color_value solid_color = gx_max_color_value; - - /* - * Get the encoded color value. - */ - color = ((gx_color_index)(*in++)) << (NUM_GX_COLOR_INDEX_BITS - 8); - for (i = NUM_GX_COLOR_INDEX_BITS - 16; i >= 0; i -= 8) - color |= ((gx_color_index)(*in++)) << i; - /* - * Set all colorants to zero if we get a non encodeable color. - */ - if (color == NON_ENCODEABLE_COLOR) { - for (comp_num = 0; comp_num < num_comp; comp_num++) - *out++ = 0; - non_encodeable_count++; - } - else { - pbitmap = find_bit_map(color, - pdevn_params->compressed_color_list); - bit_count = num_comp_bits[pbitmap->num_non_solid_comp]; - bit_mask = (1 << bit_count) - 1; - factor = comp_bit_factor[pbitmap->num_non_solid_comp]; - if (pbitmap->solid_not_100) { - solid_color = (factor * ((int)color & bit_mask)) >> 8; - color >>= bit_count; - } - for (comp_num = 0; comp_num < num_comp; comp_num++) { - if (colorant_present(pbitmap, colorants, comp_num)) { - if (colorant_present(pbitmap, - solid_colorants, comp_num)) - *out++ = solid_color >> 8; - else { - *out++ = (factor * ((int)color & bit_mask)) >> 16; - color >>= bit_count; - } - } - else - *out++ = 0; - } - } - } - return non_encodeable_count; - } -} - /* ***************** The spotcmyk and devicen devices ***************** */ /* Define the device parameters. */ @@ -1649,28 +871,12 @@ /* The device descriptor */ static dev_proc_open_device(spotcmyk_prn_open); -static dev_proc_get_params(spotcmyk_get_params); -static dev_proc_put_params(spotcmyk_put_params); static dev_proc_print_page(spotcmyk_print_page); -static dev_proc_get_color_mapping_procs(get_spotcmyk_color_mapping_procs); -static dev_proc_get_color_mapping_procs(get_devicen_color_mapping_procs); -static dev_proc_get_color_comp_index(spotcmyk_get_color_comp_index); -static dev_proc_encode_color(spotcmyk_encode_color); -static dev_proc_decode_color(spotcmyk_decode_color); - -/* - * A structure definition for a DeviceN type device - */ -typedef struct spotcmyk_device_s { - gx_device_common; - gx_prn_device_common; - gs_devn_params devn_params; -} spotcmyk_device; /* GC procedures */ static -ENUM_PTRS_WITH(spotcmyk_device_enum_ptrs, spotcmyk_device *pdev) +ENUM_PTRS_WITH(gx_devn_prn_device_enum_ptrs, gx_devn_prn_device *pdev) { if (index < pdev->devn_params.separations.num_separations) ENUM_RETURN(pdev->devn_params.separations.names[index].data); @@ -1679,36 +885,43 @@ } ENUM_PTRS_END -static RELOC_PTRS_WITH(spotcmyk_device_reloc_ptrs, spotcmyk_device *pdev) +static RELOC_PTRS_WITH(gx_devn_prn_device_reloc_ptrs, gx_devn_prn_device *pdev) { RELOC_PREFIX(st_device_printer); { int i; for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) { - RELOC_PTR(spotcmyk_device, devn_params.separations.names[i].data); + RELOC_PTR(gx_devn_prn_device, devn_params.separations.names[i].data); } } } RELOC_PTRS_END -/* Even though spotcmyk_device_finalize is the same as gx_device_finalize, */ +void +gx_devn_prn_device_finalize(const gs_memory_t *cmem, void *vpdev) +{ + devn_free_params((gx_device*) vpdev); + gx_device_finalize(cmem, vpdev); +} + +/* Even though gx_devn_prn_device_finalize is the same as gx_device_finalize, */ /* we need to implement it separately because st_composite_final */ /* declares all 3 procedures as private. */ static void -spotcmyk_device_finalize(const gs_memory_t *cmem, void *vpdev) +static_gx_devn_prn_device_finalize(const gs_memory_t *cmem, void *vpdev) { - gx_device_finalize(cmem, vpdev); + gx_devn_prn_device_finalize(cmem, vpdev); } -gs_private_st_composite_final(st_spotcmyk_device, spotcmyk_device, - "spotcmyk_device", spotcmyk_device_enum_ptrs, spotcmyk_device_reloc_ptrs, - spotcmyk_device_finalize); +gs_public_st_composite_final(st_gx_devn_prn_device, gx_devn_prn_device, + "gx_devn_prn_device", gx_devn_prn_device_enum_ptrs, gx_devn_prn_device_reloc_ptrs, + static_gx_devn_prn_device_finalize); /* * Macro definition for DeviceN procedures */ -#define device_procs(get_color_mapping_procs)\ +#define device_procs()\ { spotcmyk_prn_open,\ gx_default_get_initial_matrix,\ NULL, /* sync_output */\ @@ -1722,8 +935,8 @@ NULL, /* copy_color */\ NULL, /* draw_line */\ NULL, /* get_bits */\ - spotcmyk_get_params, /* get_params */\ - spotcmyk_put_params, /* put_params */\ + gx_devn_prn_get_params, /* get_params */\ + gx_devn_prn_put_params, /* put_params */\ NULL, /* map_cmyk_color - not used */\ NULL, /* get_xfont_procs */\ NULL, /* get_xfont_device */\ @@ -1758,12 +971,18 @@ NULL, /* begin_transparency_mask */\ NULL, /* end_transparency_mask */\ NULL, /* discard_transparency_layer */\ - get_color_mapping_procs, /* get_color_mapping_procs */\ - spotcmyk_get_color_comp_index, /* get_color_comp_index */\ - spotcmyk_encode_color, /* encode_color */\ - spotcmyk_decode_color, /* decode_color */\ + gx_devn_prn_get_color_mapping_procs,/* get_color_mapping_procs */\ + gx_devn_prn_get_color_comp_index,/* get_color_comp_index */\ + gx_devn_prn_encode_color, /* encode_color */\ + gx_devn_prn_decode_color, /* decode_color */\ NULL, /* pattern_manage */\ - NULL /* fill_rectangle_hl_color */\ + NULL, /* fill_rectangle_hl_color */\ + NULL, /* include_color_space */\ + NULL, /* fill_linear_color_scanline */\ + NULL, /* fill_linear_color_trapezoid */\ + NULL, /* fill_linear_color_triangle */\ + gx_devn_prn_update_spot_equivalent_colors,/* update_spot_equivalent_colors */\ + gx_devn_prn_ret_devn_params /* ret_devn_params */\ } fixed_colorant_name DeviceCMYKComponents[] = { @@ -1774,9 +993,9 @@ 0 /* List terminator */ }; -#define spotcmyk_device_body(procs, dname, ncomp, pol, depth, mg, mc, cn)\ - std_device_full_body_type_extended(spotcmyk_device, &procs, dname,\ - &st_spotcmyk_device,\ +#define gx_devn_prn_device_body(procs, dname, ncomp, pol, depth, mg, mc, cn)\ + std_device_full_body_type_extended(gx_devn_prn_device, &procs, dname,\ + &st_gx_devn_prn_device,\ (int)((long)(DEFAULT_WIDTH_10THS) * (X_DPI) / 10),\ (int)((long)(DEFAULT_HEIGHT_10THS) * (Y_DPI) / 10),\ X_DPI, Y_DPI,\ @@ -1796,11 +1015,11 @@ /* * Example device with CMYK and spot color support */ -static const gx_device_procs spot_cmyk_procs = device_procs(get_spotcmyk_color_mapping_procs); +static const gx_device_procs spot_cmyk_procs = device_procs(); -const spotcmyk_device gs_spotcmyk_device = +const gx_devn_prn_device gs_spotcmyk_device = { - spotcmyk_device_body(spot_cmyk_procs, "spotcmyk", 4, GX_CINFO_POLARITY_SUBTRACTIVE, 4, 1, 1, "DeviceCMYK"), + gx_devn_prn_device_body(spot_cmyk_procs, "spotcmyk", 4, GX_CINFO_POLARITY_SUBTRACTIVE, 4, 1, 1, "DeviceCMYK"), /* DeviceN device specific parameters */ { 1, /* Bits per color - must match ncomp, depth, etc. above */ DeviceCMYKComponents, /* Names of color model colorants */ @@ -1816,11 +1035,11 @@ /* * Example DeviceN color device */ -static const gx_device_procs devicen_procs = device_procs(get_devicen_color_mapping_procs); +static const gx_device_procs devicen_procs = device_procs(); -const spotcmyk_device gs_devicen_device = +const gx_devn_prn_device gs_devicen_device = { - spotcmyk_device_body(devicen_procs, "devicen", 4, GX_CINFO_POLARITY_SUBTRACTIVE, 32, 255, 255, "DeviceCMYK"), + gx_devn_prn_device_body(devicen_procs, "devicen", 4, GX_CINFO_POLARITY_SUBTRACTIVE, 32, 255, 255, "DeviceCMYK"), /* DeviceN device specific parameters */ { 8, /* Bits per color - must match ncomp, depth, etc. above */ NULL, /* No names for standard DeviceN color model */ @@ -1839,6 +1058,9 @@ { int code = gdev_prn_open(pdev); + while (pdev->child) + pdev = pdev->child; + set_linear_color_bits_mask_shift(pdev); pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN; return code; @@ -1849,24 +1071,24 @@ static void gray_cs_to_spotcmyk_cm(gx_device * dev, frac gray, frac out[]) { - int * map = ((spotcmyk_device *) dev)->devn_params.separation_order_map; + int * map = ((gx_devn_prn_device *) dev)->devn_params.separation_order_map; gray_cs_to_devn_cm(dev, map, gray, out); } static void -rgb_cs_to_spotcmyk_cm(gx_device * dev, const gs_imager_state *pis, +rgb_cs_to_spotcmyk_cm(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { - int * map = ((spotcmyk_device *) dev)->devn_params.separation_order_map; + int * map = ((gx_devn_prn_device *) dev)->devn_params.separation_order_map; - rgb_cs_to_devn_cm(dev, map, pis, r, g, b, out); + rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out); } static void cmyk_cs_to_spotcmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { - int * map = ((spotcmyk_device *) dev)->devn_params.separation_order_map; + int * map = ((gx_devn_prn_device *) dev)->devn_params.separation_order_map; cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out); } @@ -1875,16 +1097,8 @@ gray_cs_to_spotcmyk_cm, rgb_cs_to_spotcmyk_cm, cmyk_cs_to_spotcmyk_cm }; -static const gx_cm_color_map_procs * -get_spotcmyk_color_mapping_procs(const gx_device * dev) -{ - return &spotCMYK_procs; -} - -/* Also use the spotcmyk procs for the devicen device. */ - -static const gx_cm_color_map_procs * -get_devicen_color_mapping_procs(const gx_device * dev) +const gx_cm_color_map_procs * +gx_devn_prn_get_color_mapping_procs(const gx_device * dev) { return &spotCMYK_procs; } @@ -1892,13 +1106,13 @@ /* * Encode a list of colorant values into a gx_color_index_value. */ -static gx_color_index -spotcmyk_encode_color(gx_device *dev, const gx_color_value colors[]) +gx_color_index +gx_devn_prn_encode_color(gx_device *dev, const gx_color_value colors[]) { - int bpc = ((spotcmyk_device *)dev)->devn_params.bitspercomponent; + int bpc = ((gx_devn_prn_device *)dev)->devn_params.bitspercomponent; gx_color_index color = 0; int i = 0; - int ncomp = dev->color_info.num_components; + uchar ncomp = dev->color_info.num_components; COLROUND_VARS; COLROUND_SETUP(bpc); @@ -1912,13 +1126,13 @@ /* * Decode a gx_color_index value back to a list of colorant values. */ -static int -spotcmyk_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out) +int +gx_devn_prn_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out) { - int bpc = ((spotcmyk_device *)dev)->devn_params.bitspercomponent; + int bpc = ((gx_devn_prn_device *)dev)->devn_params.bitspercomponent; int mask = (1 << bpc) - 1; int i = 0; - int ncomp = dev->color_info.num_components; + uchar ncomp = dev->color_info.num_components; COLDUP_VARS; COLDUP_SETUP(bpc); @@ -1930,23 +1144,49 @@ } /* Get parameters. */ -static int -spotcmyk_get_params(gx_device * pdev, gs_param_list * plist) +int +gx_devn_prn_get_params(gx_device *dev, gs_param_list *plist) { - int code = gdev_prn_get_params(pdev, plist); + gx_devn_prn_device *pdev = (gx_devn_prn_device *)dev; + int code = gdev_prn_get_params(dev, plist); if (code < 0) return code; - return devn_get_params(pdev, plist, - &(((spotcmyk_device *)pdev)->devn_params), NULL); + return devn_get_params(dev, plist, &pdev->devn_params, + &pdev->equiv_cmyk_colors); } /* Set parameters. */ -static int -spotcmyk_put_params(gx_device * pdev, gs_param_list * plist) +int +gx_devn_prn_put_params(gx_device *dev, gs_param_list *plist) { - return devn_printer_put_params(pdev, plist, - &(((spotcmyk_device *)pdev)->devn_params), NULL); + gx_devn_prn_device *pdev = (gx_devn_prn_device *)dev; + + return devn_printer_put_params(dev, plist, &pdev->devn_params, + &pdev->equiv_cmyk_colors); +} + +/* + * Device proc for returning a pointer to DeviceN parameter structure + */ +gs_devn_params * +gx_devn_prn_ret_devn_params(gx_device * dev) +{ + gx_devn_prn_device *pdev = (gx_devn_prn_device *)dev; + + return &pdev->devn_params; +} + +/* + * Device proc for updating the equivalent CMYK color for spot colors. + */ +int +gx_devn_prn_update_spot_equivalent_colors(gx_device *dev, const gs_gstate * pgs) +{ + gx_devn_prn_device *pdev = (gx_devn_prn_device *)dev; + + return update_spot_equivalent_cmyk_colors(dev, pgs, &pdev->devn_params, + &pdev->equiv_cmyk_colors); } /* @@ -1963,13 +1203,19 @@ * the colorant is not being used due to a SeparationOrder device parameter. * It returns a negative value if not found. */ -static int -spotcmyk_get_color_comp_index(gx_device * dev, const char * pname, +int +gx_devn_prn_get_color_comp_index(gx_device * dev, const char * pname, int name_size, int component_type) { + gx_devn_prn_device *pdev = (gx_devn_prn_device *)dev; + return devn_get_color_comp_index(dev, - &(((spotcmyk_device *)dev)->devn_params), NULL, - pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS); + &pdev->devn_params, + &pdev->equiv_cmyk_colors, + pname, + name_size, + component_type, + ENABLE_AUTO_SPOT_COLORS); } /* @@ -2087,24 +1333,25 @@ int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev); byte *in = gs_alloc_bytes(pdev->memory, line_size, "spotcmyk_print_page(in)"); byte *buf = gs_alloc_bytes(pdev->memory, line_size + 3, "spotcmyk_print_page(buf)"); - const spotcmyk_device * pdevn = (spotcmyk_device *) pdev; - int npcmcolors = pdevn->devn_params.num_std_colorant_names; - int ncomp = pdevn->color_info.num_components; + const gx_devn_prn_device * pdevn = (gx_devn_prn_device *) pdev; + uint npcmcolors = pdevn->devn_params.num_std_colorant_names; + uchar ncomp = pdevn->color_info.num_components; int depth = pdevn->color_info.depth; int nspot = pdevn->devn_params.separations.num_separations; int bpc = pdevn->devn_params.bitspercomponent; int lnum = 0, bottom = pdev->height; int width = pdev->width; FILE * spot_file[GX_DEVICE_COLOR_MAX_COMPONENTS] = {0}; - int i, code = 0; + uint i; + int code = 0; int first_bit; int pcmlinelength = 0; /* Initialize against indeterminizm in case of pdev->height == 0. */ int linelength[GX_DEVICE_COLOR_MAX_COMPONENTS]; byte *data; - char spotname[gp_file_name_sizeof]; + char *spotname = (char *)gs_alloc_bytes(pdev->memory, gp_file_name_sizeof, "spotcmyk_print_page(spotname)"); - if (in == NULL || buf == NULL) { - code = gs_error_VMerror; + if (in == NULL || buf == NULL || spotname == NULL) { + code = gs_note_error(gs_error_VMerror); goto prn_done; } /* @@ -2125,7 +1372,7 @@ gs_sprintf(spotname, "%ss%d", pdevn->fname, i); spot_file[i] = gp_fopen(spotname, "wb"); if (spot_file[i] == NULL) { - code = gs_error_VMerror; + code = gs_note_error(gs_error_VMerror); goto prn_done; } } @@ -2158,13 +1405,13 @@ code = devn_write_pcx_file(pdev, (char *) &pdevn->fname, npcmcolors, bpc, pcmlinelength); if (code < 0) - return code; + goto prn_done; } for(i = 0; i < nspot; i++) { gs_sprintf(spotname, "%ss%d", pdevn->fname, i); code = devn_write_pcx_file(pdev, spotname, 1, bpc, linelength[i]); if (code < 0) - return code; + goto prn_done; } /* Clean up and exit */ @@ -2177,6 +1424,8 @@ gs_free_object(pdev->memory, in, "spotcmyk_print_page(in)"); if (buf != NULL) gs_free_object(pdev->memory, buf, "spotcmyk_print_page(buf)"); + if (spotname != NULL) + gs_free_object(pdev->memory, spotname, "spotcmyk_print_page(spotname)"); return code; } @@ -2188,7 +1437,7 @@ /* ------ Private definitions ------ */ /* All two-byte quantities are stored LSB-first! */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define assign_ushort(a,v) a = ((v) >> 8) + ((v) << 8) #else # define assign_ushort(a,v) a = (v) @@ -2487,19 +1736,26 @@ pcx_header header; int code; bool planar; - char outname[gp_file_name_sizeof]; - FILE * in; - FILE * out; + char *outname = (char *)gs_alloc_bytes(pdev->memory, gp_file_name_sizeof, "devn_write_pcx_file(outname)"); + FILE * in = NULL; + FILE * out = NULL; int depth = bpc_to_depth(ncomp, bpc); + if (outname == NULL) { + code = gs_note_error(gs_error_VMerror); + goto done; + } + in = gp_fopen(filename, "rb"); - if (!in) - return_error(gs_error_invalidfileaccess); + if (!in) { + code = gs_note_error(gs_error_invalidfileaccess); + goto done; + } gs_sprintf(outname, "%s.pcx", filename); out = gp_fopen(outname, "wb"); if (!out) { - fclose(in); - return_error(gs_error_invalidfileaccess); + code = gs_note_error(gs_error_invalidfileaccess); + goto done; } planar = devn_setup_pcx_header(pdev, &header, ncomp, bpc); @@ -2507,8 +1763,15 @@ if (code >= 0) code = devn_finish_pcx_file(pdev, out, &header, ncomp, bpc); - fclose(in); - fclose(out); +done: + if (in) + fclose(in); + if (out) + fclose(out); + + if (outname) + gs_free_object(pdev->memory, outname, "spotcmyk_print_page(outname)"); + return code; } diff -Nru ghostscript-9.10~dfsg/base/gdevdevn.h ghostscript-9.25~dfsg+1/base/gdevdevn.h --- ghostscript-9.10~dfsg/base/gdevdevn.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdevn.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Include file for common DeviceN process color model devices. */ @@ -34,24 +34,6 @@ * device. (This value does not include spot colors. See previous value.) */ #define MAX_DEVICE_PROCESS_COLORS 6 -/* - * This value enable the use of a compression scheme for representing - * the colorant values in a device pixel. Ghostscript represents device - * pixel using an integer type value. This limits the maximum number of - * bits that can be used for a pixel to the largest integer size provided - * by the compiler. For most compilers this is 64 bits (a 'long long' or - * _int64 type). For devices with 4 or fewer colorantss like DeviceGray, - * DeviceRGB, and DeviceCMYK, this will easily represent 16 bits per colorant. - * However if the output device supports spot colorants, this limits us in - * what we can do. To allow support for more than 8 colorants at 8 bits - * per colorant, we use a scheme to compress the colorant values into our - * 64 bit pixels. For more information see the header before - * devn_encode_compressed_color in src/gdevdevn.c. - * - * To disable compression of encoded colorant values, change this definition. - */ -#define USE_COMPRESSED_ENCODING 0 -/* #define USE_COMPRESSED_ENCODING (ARCH_SIZEOF_GX_COLOR_INDEX >= 8) */ /* * Type definitions associated with the fixed color model names. @@ -128,17 +110,6 @@ /* * Pointer to our list of which colorant combinations are being used. */ - struct compressed_color_list_s * compressed_color_list; - /* - * If the file is using PDF 1.4 transparency compositing and we are using - * the clist then we need to pass the compressed color list from the PDF - * 1.4 clist writer device to the PDF 1.4 reader device. However that - * device is not created until the clist is read and being processed. - * We need to temporary hold that data in the output device until after - * clist reader PDF 1.4 compositing device is created. The PDF 1.4 - * compositor may also have a different list of separations. - */ - struct compressed_color_list_s * pdf14_compressed_color_list; gs_separations pdf14_separations; } gs_devn_params_t; @@ -163,7 +134,7 @@ void gray_cs_to_devn_cm(gx_device * dev, int * map, frac gray, frac out[]); void rgb_cs_to_devn_cm(gx_device * dev, int * map, - const gs_imager_state *pis, frac r, frac g, frac b, frac out[]); + const gs_gstate *pgs, frac r, frac g, frac b, frac out[]); void cmyk_cs_to_devn_cm(gx_device * dev, const int * map, frac c, frac m, frac y, frac k, frac out[]); @@ -247,6 +218,24 @@ equivalent_cmyk_color_params * pequiv_colors); /* +* This routine will check to see if the color component name match those +* of the SeparationColorNames list. Needed for case where we have RGB +* blending color spaces in transparency and need to maintain the spot colorants +* +* Parameters: +* dev - pointer to device data structure. +* pname - pointer to name (zero termination not required) +* nlength - length of the name +* index into colorants offset of device +* +* This routine returns a positive value (0 to n) which is the device colorant +* number if the name is found. It returns a negative value if not found. +*/ +int check_separation_names(const gx_device * dev, const gs_devn_params * pparams, + const char * pname, int name_size, int component_type, int number); + + +/* * This routine will check to see if the color component name match those * of either the process color model colorants or the names on the * SeparationColorNames list. @@ -317,23 +306,9 @@ * and 8. * Input values are not tested for validity. */ -int bpc_to_depth(int ncomp, int bpc); +int bpc_to_depth(uchar ncomp, int bpc); /* - * We are encoding color values into a gx_color_index value. This is being - * done to allow more than eight 8 bit colorant values to be stored inside - * of a 64 bit gx_color_index value. - * - * This is done by only keeping track of non zero colorant values. We - * keep a record of which combinations of colorants are used inside of the - * device and encode an index for the colorant combinations into the - * gx_color_index value. - * - * See comments preceding devn_encode_compressed_color in gdevdevn.c for - * more information about how we encode the color information into a - * gx_color_index value. - */ -/* * We are using bytes to pack both which colorants are non zero and the values * of the colorants. Thus do not change this value without recoding the * methods used for encoding our colorants. (This definition is really here @@ -431,6 +406,13 @@ #endif /* +* Element for a map to convert colorants to a CMYK color. +*/ +typedef struct cmyk_composite_map_s { + frac c, m, y, k; +} cmyk_composite_map; + +/* * The colorant bit map list struct. */ typedef struct comp_bit_map_list_s { @@ -442,72 +424,6 @@ } comp_bit_map_list_t; /* - * Encoded colorant list level element definition. - * - * Each list level contains a list of objects. An object can be either a - * colorant bit map or a pointer to a sub list. We start our sub level - * pointer at zero and work up. Component bit maps are started at the top and - * go down. When they meet in the middle, then this list level element is full. - * Note: We start with the bit maps in the upper positions to ensure that - * gx_no_color_index and NON_ENCODEABLE_COLOR values correspond to 7 colorant - * cases. This is less likely to occur and less likely to cause a problem - * when we tweak the outputs to keep actual gx_color_index values from - * being one of these two special cases. - * - * See comments preceding devn_encode_compressed_color in gdevdevn.c for - * more information about how we encode the color information into a - * gx_color_index value. - */ -typedef struct compressed_color_list_s { - gs_memory_t * mem; /* the allocator used for this structure */ - /* - * The number of colorants for this level of the encoded color list. - * Note: Each sub level encodes one fewer colorants. - */ - int level_num_comp; - /* The number of sub level list pointers */ - int num_sub_level_ptrs; - /* The current lower limit for the colorant bit maps */ - int first_bit_map; - /* - * Use a union since an object is either a sub level pointer or a colorant - * bit map but not both. - */ - union { - struct compressed_color_list_s * sub_level_ptrs[NUM_ENCODE_LIST_ITEMS]; - comp_bit_map_list_t comp_data[NUM_ENCODE_LIST_ITEMS]; - } u; -} compressed_color_list_t; - -/* - * Encode a list of colorant values into a gx_color_index_value. - * - * This routine is designed to pack more than eight 8 bit colorant values into - * a 64 bit gx_color_index value. It does this piece of magic by keeping a list - * of which colorant combinations are actualy used (i.e. which colorants are non - * zero). The non zero colorant values and and an 'index' value are packed into - * the output gx_color_index value. - * - * See comments preceding devn_encode_compressed_color in gdevdevn.c for more - * information about how we encode the color information into a gx_color_index - * value. - */ -gx_color_index devn_encode_compressed_color(gx_device *pdev, - const gx_color_value colors[], gs_devn_params * pdevn_params); - -/* - * Decode a gx_color_index value back to a list of colorant values. This - * routine assumes that the gx_color_index value is 'encoded' as described - * for devn_encode_compressed_color. - * - * See comments preceding devn_encode_compressed_color in gdevdevn.c for more - * information about how we encode the color information into a gx_color_index - * value. - */ -int devn_decode_compressed_color(gx_device * dev, gx_color_index color, - gx_color_value * out, gs_devn_params * pdevn_params); - -/* * Unpack a row of 'encoded color' values. These values are encoded as * described for the devn_encode_color routine. * @@ -521,18 +437,6 @@ int width, byte * in, byte * out); /* - * Find the bit map for given bit map index. - */ -comp_bit_map_list_t * find_bit_map(gx_color_index index, - compressed_color_list_t * pcomp_list); - -/* - * Allocate an list level element for our encode color list. - */ -compressed_color_list_t * alloc_compressed_color_list_elem(gs_memory_t * mem, - int num_comps); - -/* * The elements of this array contain the number of bits used to encode a color * value in a 'compressed' gx_color_index value. The index into the array is * the number of compressed components. @@ -540,13 +444,6 @@ extern int num_comp_bits[]; /* - * Values used to decompressed the colorants in our encoded values back into - * a gx_color value. The color value will be (comp_bits * entry) >> 8 - * The number of bits in comp_bits are defined in the num_comp_bits table. - * These values are chosen to expand these bit combinations back to 16 bit values - * (after shifting right 8 bits). - */ -/* * The elements of this array contain factors used to convert compressed color * values to gx_color_values. The index into the array is the number of * compressed components. @@ -554,19 +451,13 @@ extern int comp_bit_factor[]; /* - * A routine for debugging the encoded color colorant list. This routine - * dumps the contents of the list. - */ -void print_compressed_color_list(const gs_memory_t *mem, compressed_color_list_t * pcomp_list, int num_comp); - -/* - * Free the elements of a compressed color list. - */ -void free_compressed_color_list(compressed_color_list_t * pcomp_list); - -/* * Free a set of separation names */ void free_separation_names(gs_memory_t *mem, gs_separations * pseparation); +/* Build a map for use by devices that are building composite views */ +void build_cmyk_map(gx_device *pdev, int num_comp, + equivalent_cmyk_color_params *equiv_cmyk_colors, + cmyk_composite_map * cmyk_map); + #endif /* ifndef gdevdevn_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevdevnprn.h ghostscript-9.25~dfsg+1/base/gdevdevnprn.h --- ghostscript-9.10~dfsg/base/gdevdevnprn.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdevnprn.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,56 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Include file for common DeviceN printer devices. */ + +#ifndef gdevdevnprn_INCLUDED +# define gdevdevnprn_INCLUDED + +/* + * DevN based printer devices all start with the same device fields. + */ +#define gx_devn_prn_device_common\ + gx_device_common;\ + gx_prn_device_common;\ + gs_devn_params devn_params;\ + equivalent_cmyk_color_params equiv_cmyk_colors + +/* + * A structure definition for a DeviceN printer type device + */ +typedef struct gx_devn_prn_device_s { + gx_devn_prn_device_common; +} gx_devn_prn_device; + +/* + * Garbage collection structure descriptor and finalizer. + */ +extern_st(st_gx_devn_prn_device); +struct_proc_finalize(gx_devn_prn_device_finalize); + +/* + * Basic device procedures for instances of the above device. + */ +dev_proc_get_params(gx_devn_prn_get_params); +dev_proc_put_params(gx_devn_prn_put_params); +dev_proc_get_color_comp_index(gx_devn_prn_get_color_comp_index); +dev_proc_get_color_mapping_procs(gx_devn_prn_get_color_mapping_procs); +dev_proc_encode_color(gx_devn_prn_encode_color); +dev_proc_decode_color(gx_devn_prn_decode_color); +dev_proc_update_spot_equivalent_colors(gx_devn_prn_update_spot_equivalent_colors); +dev_proc_ret_devn_params(gx_devn_prn_ret_devn_params); + + +#endif /* ifndef gdevdevnprn_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevdflt.c ghostscript-9.25~dfsg+1/base/gdevdflt.c --- ghostscript-9.10~dfsg/base/gdevdflt.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdflt.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,18 +9,28 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Default device implementation */ #include "math_.h" +#include "memory_.h" #include "gx.h" +#include "gsstruct.h" +#include "gxobj.h" #include "gserrors.h" #include "gsropt.h" #include "gxcomp.h" #include "gxdevice.h" #include "gxdevsop.h" +#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ +#include "gstrans.h" /* For gs_pdf14trans_t */ +#include "gxgstate.h" /* for gs_image_state_s */ + + +/* defined in gsdpram.c */ +int gx_default_get_param(gx_device *dev, char *Param, void *list); /* ---------------- Default device procedures ---------------- */ @@ -86,7 +96,7 @@ else encode_proc = gx_default_gray_encode; dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN; - } else if (dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN) { + } else if (colors_are_separable_and_linear(&dev->color_info)) { gx_color_value max_gray = dev->color_info.max_gray; gx_color_value max_color = dev->color_info.max_color; @@ -117,24 +127,18 @@ static bool is_like_DeviceRGB(gx_device * dev) { - const gx_cm_color_map_procs * cm_procs; + subclass_color_mappings scm; frac cm_comp_fracs[3]; int i; if ( dev->color_info.num_components != 3 || dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE ) return false; - cm_procs = dev_proc(dev, get_color_mapping_procs)(dev); - if (cm_procs == 0 || cm_procs->map_rgb == 0) - return false; + + scm = get_color_mapping_procs_subclass(dev); /* check the values 1/4, 1/3, and 3/4 */ - cm_procs->map_rgb( dev, - 0, - frac_1 / 4, - frac_1 / 3, - 3 * frac_1 / 4, - cm_comp_fracs ); + map_rgb_subclass(scm, 0, frac_1 / 4, frac_1 / 3, 3 * frac_1 / 4,cm_comp_fracs); /* verify results to .01 */ cm_comp_fracs[0] -= frac_1 / 4; @@ -155,19 +159,18 @@ static bool is_like_DeviceCMYK(gx_device * dev) { - const gx_cm_color_map_procs * cm_procs; + subclass_color_mappings scm; frac cm_comp_fracs[4]; int i; if ( dev->color_info.num_components != 4 || dev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE ) return false; - cm_procs = dev_proc(dev, get_color_mapping_procs)(dev); - if (cm_procs == 0 || cm_procs->map_cmyk == 0) - return false; + scm = get_color_mapping_procs_subclass(dev); /* check the values 1/4, 1/3, 3/4, and 1/8 */ - cm_procs->map_cmyk( dev, + + map_cmyk_subclass( scm, frac_1 / 4, frac_1 / 3, 3 * frac_1 / 4, @@ -236,7 +239,7 @@ gx_color_value cv[4] ) { /* The device may have been determined to be 'separable'. */ - if (dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN) + if (colors_are_separable_and_linear(&dev->color_info)) return gx_default_decode_color(dev, color, cv); else { int i, code = dev_proc(dev, map_color_rgb)(dev, color, cv); @@ -291,7 +294,7 @@ return dev_proc(dev, map_color_rgb); /* If separable ande linear then use default */ - if ( dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ) + if (colors_are_separable_and_linear(&dev->color_info)) return &gx_default_decode_color; /* gray devices can be handled based on their polarity */ @@ -327,7 +330,7 @@ * code in gx_device_fill_in_procs, so at this point we can only hope * the device doesn't use the decode_color method. */ - if (dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ) + if (colors_are_separable_and_linear(&dev->color_info)) return &gx_default_decode_color; else return &gx_error_decode_color; @@ -498,6 +501,85 @@ } #undef is_power_of_two +/* + * This routine attempts to determine if a device's encode_color procedure + * produces values that are in keeping with "the standard encoding". + * i.e. that given by pdf14_encode_color. + * + * It works by first checking to see if we are separable_and_linear. If not + * we cannot hope to be the standard encoding. + * + * Then, we check to see if we are a dev device - if so, we must be + * compatible. + * + * Failing that it checks to see if the encoding uses the appropriate + * bit ranges for each individual color. + * + * If those (quick) tests pass, then we try the slower test of checking + * the encodings. We can do this far faster than an exhaustive check, by + * relying on the separability and linearity - we only need to check 256 + * possible values. + * + * The one tricky section there is to avoid the special case for + * gx_no_color_index_value (which can occur when we have a 32bit + * gx_color_index type, and a 4 component device, such as cmyk). + * We allow the encoding to be off in the lower bits for that case. + */ +void check_device_compatible_encoding(gx_device *dev) +{ + gx_device_color_info * pinfo = &(dev->color_info); + int num_components = pinfo->num_components; + gx_color_index mul, color_index; + int i, j; + gx_color_value colorants[GX_DEVICE_COLOR_MAX_COMPONENTS]; + + if (pinfo->separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN) + check_device_separable(dev); + if (pinfo->separable_and_linear != GX_CINFO_SEP_LIN) + return; + + if (dev_proc(dev, ret_devn_params)(dev) != NULL) { + /* We know all devn devices are compatible. */ + pinfo->separable_and_linear = GX_CINFO_SEP_LIN_STANDARD; + return; + } + + /* Do the superficial quick checks */ + for (i = 0; i < num_components; i++) { + int shift = (num_components-1-i)*8; + if (pinfo->comp_shift[i] != shift) + goto bad; + if (pinfo->comp_bits[i] != 8) + goto bad; + if (pinfo->comp_mask[i] != ((gx_color_index)255)<separable_and_linear = GX_CINFO_SEP_LIN_STANDARD; + return; +bad: + pinfo->separable_and_linear = GX_CINFO_SEP_LIN_NON_STANDARD; +} + +int gx_default_no_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, const gx_drawing_color *pdcolor, int depth); + /* Fill in NULL procedures in a device procedure record. */ void gx_device_fill_in_procs(register gx_device * dev) @@ -578,7 +660,7 @@ if (dev->color_info.num_components == 4) set_dev_proc(dev, map_cmyk_color, dev_proc(dev, encode_color)); - if ( dev->color_info.separable_and_linear == GX_CINFO_SEP_LIN ) { + if (colors_are_separable_and_linear(&dev->color_info)) { fill_dev_proc(dev, encode_color, gx_default_encode_color); fill_dev_proc(dev, map_cmyk_color, gx_default_encode_color); fill_dev_proc(dev, map_rgb_color, gx_default_encode_color); @@ -599,36 +681,32 @@ */ switch (dev->color_info.num_components) { case 1: /* DeviceGray or DeviceInvertGray */ - if (dev_proc(dev, get_color_mapping_procs) == NULL) { - /* - * If not gray then the device must provide the color - * mapping procs. - */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { - fill_dev_proc( dev, - get_color_mapping_procs, - gx_default_DevGray_get_color_mapping_procs ); - } else - fill_dev_proc(dev, get_color_mapping_procs, gx_error_get_color_mapping_procs); - } + /* + * If not gray then the device must provide the color + * mapping procs. + */ + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { + fill_dev_proc( dev, + get_color_mapping_procs, + gx_default_DevGray_get_color_mapping_procs ); + } else + fill_dev_proc(dev, get_color_mapping_procs, gx_error_get_color_mapping_procs); fill_dev_proc( dev, get_color_comp_index, gx_default_DevGray_get_color_comp_index ); break; case 3: - if (dev_proc(dev, get_color_mapping_procs) == NULL) { - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { - fill_dev_proc( dev, - get_color_mapping_procs, - gx_default_DevRGB_get_color_mapping_procs ); - fill_dev_proc( dev, - get_color_comp_index, - gx_default_DevRGB_get_color_comp_index ); - } else { - fill_dev_proc(dev, get_color_mapping_procs, gx_error_get_color_mapping_procs); - fill_dev_proc(dev, get_color_comp_index, gx_error_get_color_comp_index); - } + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { + fill_dev_proc( dev, + get_color_mapping_procs, + gx_default_DevRGB_get_color_mapping_procs ); + fill_dev_proc( dev, + get_color_comp_index, + gx_default_DevRGB_get_color_comp_index ); + } else { + fill_dev_proc(dev, get_color_mapping_procs, gx_error_get_color_mapping_procs); + fill_dev_proc(dev, get_color_comp_index, gx_error_get_color_comp_index); } break; @@ -644,7 +722,6 @@ } set_dev_proc(dev, decode_color, get_decode_color(dev)); - fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb); fill_dev_proc(dev, get_profile, gx_default_get_profile); fill_dev_proc(dev, set_graphics_type_tag, gx_default_set_graphics_type_tag); @@ -669,15 +746,27 @@ fill_dev_proc(dev, update_spot_equivalent_colors, gx_default_update_spot_equivalent_colors); fill_dev_proc(dev, ret_devn_params, gx_default_ret_devn_params); fill_dev_proc(dev, fillpage, gx_default_fillpage); - fill_dev_proc(dev, copy_alpha_hl_color, gx_default_copy_alpha_hl_color); + fill_dev_proc(dev, copy_alpha_hl_color, gx_default_no_copy_alpha_hl_color); + + fill_dev_proc(dev, begin_transparency_group, gx_default_begin_transparency_group); + fill_dev_proc(dev, end_transparency_group, gx_default_end_transparency_group); + + fill_dev_proc(dev, begin_transparency_mask, gx_default_begin_transparency_mask); + fill_dev_proc(dev, end_transparency_mask, gx_default_end_transparency_mask); + fill_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer); + + fill_dev_proc(dev, pattern_manage, gx_default_pattern_manage); + fill_dev_proc(dev, push_transparency_state, gx_default_push_transparency_state); + fill_dev_proc(dev, pop_transparency_state, gx_default_pop_transparency_state); + + fill_dev_proc(dev, put_image, gx_default_put_image); - /* NOT push_transparency_state */ - /* NOT pop_transparency_state */ - /* NOT put_image */ fill_dev_proc(dev, dev_spec_op, gx_default_dev_spec_op); - /* NOT copy_planes */ + fill_dev_proc(dev, copy_planes, gx_default_copy_planes); + fill_dev_proc(dev, process_page, gx_default_process_page); } + int gx_default_open_device(gx_device * dev) { @@ -693,8 +782,8 @@ gx_default_get_initial_matrix(gx_device * dev, register gs_matrix * pmat) { /* NB this device has no paper margins */ - floatp fs_res = dev->HWResolution[0] / 72.0; - floatp ss_res = dev->HWResolution[1] / 72.0; + double fs_res = dev->HWResolution[0] / 72.0; + double ss_res = dev->HWResolution[1] / 72.0; switch(dev->LeadingEdge & LEADINGEDGE_MASK) { case 1: /* 90 degrees */ @@ -827,7 +916,7 @@ int gx_no_create_compositor(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, - gs_imager_state * pis, gs_memory_t * memory, + gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) { return_error(gs_error_unknownerror); /* not implemented */ @@ -835,16 +924,16 @@ int gx_default_create_compositor(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, - gs_imager_state * pis, gs_memory_t * memory, + gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) { return pcte->type->procs.create_default_compositor - (pcte, pcdev, dev, pis, memory); + (pcte, pcdev, dev, pgs, memory); } int gx_null_create_compositor(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, - gs_imager_state * pis, gs_memory_t * memory, + gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) { *pcdev = dev; @@ -855,7 +944,7 @@ * Default handler for creating a compositor device when writing the clist. */ int gx_default_composite_clist_write_update(const gs_composite_t *pcte, gx_device * dev, - gx_device ** pcdev, gs_imager_state * pis, gs_memory_t * mem) + gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem) { *pcdev = dev; /* Do nothing -> return the same device */ return 0; @@ -863,7 +952,7 @@ /* Default handler for adjusting a compositor's CTM. */ int -gx_default_composite_adjust_ctm(gs_composite_t *pcte, int x0, int y0, gs_imager_state *pis) +gx_default_composite_adjust_ctm(gs_composite_t *pcte, int x0, int y0, gs_gstate *pgs) { return 0; } @@ -871,10 +960,10 @@ /* * Default check for closing compositor. */ -int +gs_compositor_closing_state gx_default_composite_is_closing(const gs_composite_t *this, gs_composite_t **pcte, gx_device *dev) { - return false; + return COMP_ENQUEUE; } /* @@ -892,7 +981,7 @@ */ int gx_default_composite_clist_read_update(gs_composite_t *pxcte, gx_device * cdev, - gx_device * tdev, gs_imager_state * pis, gs_memory_t * mem) + gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem) { return 0; /* Do nothing */ } @@ -918,6 +1007,8 @@ gx_default_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) { switch(dev_spec_op) { + case gxdso_form_begin: + case gxdso_form_end: case gxdso_pattern_can_accum: case gxdso_pattern_start_accum: case gxdso_pattern_finish_accum: @@ -926,25 +1017,18 @@ case gxdso_pattern_is_cpath_accum: case gxdso_pattern_handles_clip_path: case gxdso_is_pdf14_device: - case gxdso_is_native_planar: case gxdso_supports_devn: case gxdso_supports_hlcolor: + case gxdso_supports_saved_pages: case gxdso_needs_invariant_palette: + case gxdso_supports_iccpostrender: return 0; case gxdso_pattern_shfill_doesnt_need_path: - return (pdev->procs.fill_path == gx_default_fill_path); + return (dev_proc(pdev, fill_path) == gx_default_fill_path); case gxdso_is_std_cmyk_1bit: - return (pdev->procs.map_cmyk_color == cmyk_1bit_map_cmyk_color); + return (dev_proc(pdev, map_cmyk_color) == cmyk_1bit_map_cmyk_color); case gxdso_interpolate_antidropout: - if ((pdev->color_info.num_components == 1 && - pdev->color_info.max_gray < 15) || - (pdev->color_info.num_components > 1 && - pdev->color_info.max_color < 15)) { - /* If we are are limited color device (i.e. we are halftoning) - * then use the antidropout interpolators. */ - return 1; - } - return 0; + return pdev->color_info.use_antidropout_downscaler; case gxdso_interpolate_threshold: if ((pdev->color_info.num_components == 1 && pdev->color_info.max_gray < 15) || @@ -955,17 +1039,22 @@ return 4; } return 0; /* Otherwise no change */ + case gxdso_get_dev_param: + { + dev_param_req_t *request = (dev_param_req_t *)data; + return gx_default_get_param(pdev, request->Param, request->list); + } } - return gs_error_undefined; + return_error(gs_error_undefined); } int gx_default_fill_rectangle_hl_color(gx_device *pdev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } int @@ -981,7 +1070,7 @@ * src/gsequivc.c. */ int -gx_default_update_spot_equivalent_colors(gx_device *pdev, const gs_state * pgs) +gx_default_update_spot_equivalent_colors(gx_device *pdev, const gs_gstate * pgs) { return 0; } @@ -996,22 +1085,120 @@ return NULL; } +int +gx_default_process_page(gx_device *dev, gx_process_page_options_t *options) +{ + gs_int_rect rect; + int code = 0; + void *buffer = NULL; + + /* Possible future improvements in here could be given by us dividing the + * page up into n chunks, and spawning a thread per chunk to do the + * process_fn call on. n could be given by NumRenderingThreads. This + * would give us multi-core advantages even without clist. */ + if (options->init_buffer_fn) { + code = options->init_buffer_fn(options->arg, dev, dev->memory, dev->width, dev->height, &buffer); + if (code < 0) + return code; + } + + rect.p.x = 0; + rect.p.y = 0; + rect.q.x = dev->width; + rect.q.y = dev->height; + if (options->process_fn) + code = options->process_fn(options->arg, dev, dev, &rect, buffer); + if (code >= 0 && options->output_fn) + code = options->output_fn(options->arg, dev, buffer); + + if (options->free_buffer_fn) + options->free_buffer_fn(options->arg, dev, dev->memory, buffer); + + return code; +} + +int +gx_default_begin_transparency_group(gx_device *dev, const gs_transparency_group_params_t *ptgp, const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) +{ + return 0; +} + +int +gx_default_end_transparency_group(gx_device *dev, gs_gstate *pgs) +{ + return 0; +} + +int +gx_default_begin_transparency_mask(gx_device *dev, const gx_transparency_mask_params_t *ptgp, const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) +{ + return 0; +} + +int +gx_default_end_transparency_mask(gx_device *dev, gs_gstate *pgs) +{ + return 0; +} + +int +gx_default_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) +{ + return 0; +} + +int +gx_default_pattern_manage(gx_device *pdev, gx_bitmap_id id, gs_pattern1_instance_t *pinst, pattern_manage_t function) +{ + return_error(gs_error_undefined); +} + +int +gx_default_push_transparency_state(gx_device *dev, gs_gstate *pgs) +{ + return 0; +} + +int +gx_default_pop_transparency_state(gx_device *dev, gs_gstate *pgs) +{ + return 0; +} + +int +gx_default_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y, int width, int height, int row_stride, int alpha_plane_index, int tag_plane_index) +{ + return_error(gs_error_undefined); +} + +int +gx_default_no_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, const gx_drawing_color *pdcolor, int depth) +{ + return_error(gs_error_undefined); +} + +int +gx_default_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, int x, int y, int width, int height, int plane_height) +{ + return_error(gs_error_undefined); +} + /* ---------------- Default per-instance procedures ---------------- */ int -gx_default_install(gx_device * dev, gs_state * pgs) +gx_default_install(gx_device * dev, gs_gstate * pgs) { return 0; } int -gx_default_begin_page(gx_device * dev, gs_state * pgs) +gx_default_begin_page(gx_device * dev, gs_gstate * pgs) { return 0; } int -gx_default_end_page(gx_device * dev, int reason, gs_state * pgs) +gx_default_end_page(gx_device * dev, int reason, gs_gstate * pgs) { return (reason != 2 ? 1 : 0); } @@ -1022,3 +1209,467 @@ /* set the tag but carefully preserve GS_DEVICE_ENCODES_TAGS */ dev->graphics_type_tag = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) | graphics_type_tag; } + +/* ---------------- Device subclassing procedures ---------------- */ + +/* Non-obvious code. The 'dest_procs' is the 'procs' memory occupied by the original device that we decided to subclass, + * 'src_procs' is the newly allocated piece of memory, to whch we have already copied the content of the + * original device (including the procs), prototype is the device structure prototype for the subclassing device. + * Here we copy the methods from the prototype to the original device procs memory *but* if the original (src_procs) + * device had a NULL method, we make the new device procs have a NULL method too. + * The reason for ths is ugly, there are some places in the graphics library which explicitly check for + * a device having a NULL method and take different code paths depending on the result. + * Now in general we expect subclassing devices to implement *every* method, so if we didn't copy + * over NULL methods present in the original source device then the code path could be inappropriate for + * that underlying (now subclassed) device. + */ +/* November 10th 2017 Restored the original behaviour of the device methods, they should now never be NULL. + * Howwever, there are still places in the code which take different code paths if the device method is (now) + * the default device method, rather than a device-specific method. + * So instead of checking for NULL, we now need to check against the default implementation, and *NOT* copy the + * prototype (subclass device) method if the original device had the default implementation. + * I suspect a combination of forwarding and subclassing devices will not work properly for this reason. + */ +int gx_copy_device_procs(gx_device *dest, gx_device *src, gx_device *prototype) +{ + set_dev_proc(dest, open_device, dev_proc(prototype, open_device)); + set_dev_proc(dest, get_initial_matrix, dev_proc(prototype, get_initial_matrix)); + set_dev_proc(dest, sync_output, dev_proc(prototype, sync_output)); + set_dev_proc(dest, output_page, dev_proc(prototype, output_page)); + set_dev_proc(dest, close_device, dev_proc(prototype, close_device)); + set_dev_proc(dest, map_rgb_color, dev_proc(prototype, map_rgb_color)); + set_dev_proc(dest, map_color_rgb, dev_proc(prototype, map_color_rgb)); + set_dev_proc(dest, fill_rectangle, dev_proc(prototype, fill_rectangle)); + set_dev_proc(dest, tile_rectangle, dev_proc(prototype, tile_rectangle)); + set_dev_proc(dest, copy_mono, dev_proc(prototype, copy_mono)); + set_dev_proc(dest, copy_color, dev_proc(prototype, copy_color)); + set_dev_proc(dest, obsolete_draw_line, dev_proc(prototype, obsolete_draw_line)); + set_dev_proc(dest, get_bits, dev_proc(prototype, get_bits)); + set_dev_proc(dest, get_params, dev_proc(prototype, get_params)); + set_dev_proc(dest, put_params, dev_proc(prototype, put_params)); + set_dev_proc(dest, map_cmyk_color, dev_proc(prototype, map_cmyk_color)); + set_dev_proc(dest, get_xfont_procs, dev_proc(prototype, get_xfont_procs)); + set_dev_proc(dest, get_xfont_device, dev_proc(prototype, get_xfont_device)); + set_dev_proc(dest, map_rgb_alpha_color, dev_proc(prototype, map_rgb_alpha_color)); + set_dev_proc(dest, get_page_device, dev_proc(prototype, get_page_device)); + set_dev_proc(dest, get_alpha_bits, dev_proc(prototype, get_alpha_bits)); + set_dev_proc(dest, copy_alpha, dev_proc(prototype, copy_alpha)); + set_dev_proc(dest, get_band, dev_proc(prototype, get_band)); + set_dev_proc(dest, copy_rop, dev_proc(prototype, copy_rop)); + set_dev_proc(dest, fill_path, dev_proc(prototype, fill_path)); + set_dev_proc(dest, stroke_path, dev_proc(prototype, stroke_path)); + set_dev_proc(dest, fill_trapezoid, dev_proc(prototype, fill_trapezoid)); + set_dev_proc(dest, fill_parallelogram, dev_proc(prototype, fill_parallelogram)); + set_dev_proc(dest, fill_triangle, dev_proc(prototype, fill_triangle)); + set_dev_proc(dest, draw_thin_line, dev_proc(prototype, draw_thin_line)); + set_dev_proc(dest, begin_image, dev_proc(prototype, begin_image)); + set_dev_proc(dest, image_data, dev_proc(prototype, image_data)); + set_dev_proc(dest, end_image, dev_proc(prototype, end_image)); + set_dev_proc(dest, strip_tile_rectangle, dev_proc(prototype, strip_tile_rectangle)); + set_dev_proc(dest, strip_copy_rop, dev_proc(prototype, strip_copy_rop)); + set_dev_proc(dest, get_clipping_box, dev_proc(prototype, get_clipping_box)); + set_dev_proc(dest, begin_typed_image, dev_proc(prototype, begin_typed_image)); + set_dev_proc(dest, get_bits_rectangle, dev_proc(prototype, get_bits_rectangle)); + set_dev_proc(dest, map_color_rgb_alpha, dev_proc(prototype, map_color_rgb_alpha)); + set_dev_proc(dest, create_compositor, dev_proc(prototype, create_compositor)); + set_dev_proc(dest, get_hardware_params, dev_proc(prototype, get_hardware_params)); + set_dev_proc(dest, text_begin, dev_proc(prototype, text_begin)); + set_dev_proc(dest, finish_copydevice, dev_proc(prototype, finish_copydevice)); + set_dev_proc(dest, discard_transparency_layer, dev_proc(prototype, discard_transparency_layer)); + set_dev_proc(dest, get_color_mapping_procs, dev_proc(prototype, get_color_mapping_procs)); + set_dev_proc(dest, get_color_comp_index, dev_proc(prototype, get_color_comp_index)); + set_dev_proc(dest, encode_color, dev_proc(prototype, encode_color)); + set_dev_proc(dest, decode_color, dev_proc(prototype, decode_color)); + set_dev_proc(dest, pattern_manage, dev_proc(prototype, pattern_manage)); + set_dev_proc(dest, fill_rectangle_hl_color, dev_proc(prototype, fill_rectangle_hl_color)); + set_dev_proc(dest, include_color_space, dev_proc(prototype, include_color_space)); + set_dev_proc(dest, fill_linear_color_scanline, dev_proc(prototype, fill_linear_color_scanline)); + set_dev_proc(dest, fill_linear_color_trapezoid, dev_proc(prototype, fill_linear_color_trapezoid)); + set_dev_proc(dest, fill_linear_color_triangle, dev_proc(prototype, fill_linear_color_triangle)); + set_dev_proc(dest, update_spot_equivalent_colors, dev_proc(prototype, update_spot_equivalent_colors)); + set_dev_proc(dest, ret_devn_params, dev_proc(prototype, ret_devn_params)); + set_dev_proc(dest, fillpage, dev_proc(prototype, fillpage)); + set_dev_proc(dest, push_transparency_state, dev_proc(prototype, push_transparency_state)); + set_dev_proc(dest, pop_transparency_state, dev_proc(prototype, pop_transparency_state)); + set_dev_proc(dest, dev_spec_op, dev_proc(prototype, dev_spec_op)); + set_dev_proc(dest, get_profile, dev_proc(prototype, get_profile)); + set_dev_proc(dest, strip_copy_rop2, dev_proc(prototype, strip_copy_rop2)); + set_dev_proc(dest, strip_tile_rect_devn, dev_proc(prototype, strip_tile_rect_devn)); + set_dev_proc(dest, process_page, dev_proc(prototype, process_page)); + + /* + * We absolutely must set the 'set_graphics_type_tag' to the default subclass one + * even if the subclassed device is using the default. This is because the + * default implementation sets a flag in the device structure, and if we + * copy the default method, we'lll end up setting the flag in the subclassing device + * instead of the subclassed device! + */ + set_dev_proc(dest, set_graphics_type_tag, dev_proc(prototype, set_graphics_type_tag)); + + /* These are the routines whose existence is checked against the default at + * some point in the code. The code path differs when the device implements a + * method other than the default, so the subclassing device needs to ensure that + * if the subclassed device has one of these methods set to the default, we + * do not overwrite the default method. + */ + if (dev_proc(src, fill_mask) != gx_default_fill_mask) + set_dev_proc(dest, fill_mask, dev_proc(prototype, fill_mask)); + if (dev_proc(src, begin_transparency_group) != gx_default_begin_transparency_group) + set_dev_proc(dest, begin_transparency_group, dev_proc(prototype, begin_transparency_group)); + if (dev_proc(src, end_transparency_group) != gx_default_end_transparency_group) + set_dev_proc(dest, end_transparency_group, dev_proc(prototype, end_transparency_group)); + if (dev_proc(src, put_image) != gx_default_put_image) + set_dev_proc(dest, put_image, dev_proc(prototype, put_image)); + if (dev_proc(src, copy_planes) != gx_default_copy_planes) + set_dev_proc(dest, copy_planes, dev_proc(prototype, copy_planes)); + if (dev_proc(src, copy_alpha_hl_color) != gx_default_no_copy_alpha_hl_color) + set_dev_proc(dest, copy_alpha_hl_color, dev_proc(prototype, copy_alpha_hl_color)); + return 0; +} + +int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, unsigned int private_data_size) +{ + gx_device *child_dev; + void *psubclass_data; + gs_memory_struct_type_t *a_std, *b_std = NULL; + int dynamic = dev_to_subclass->stype_is_dynamic; + char *ptr, *ptr1; + + /* If this happens we are stuffed, as there is no way to get hold + * of the original device's stype structure, which means we cannot + * allocate a replacement structure. Abort if so. + * Also abort if the new_prototype device struct is too large. + */ + if (!dev_to_subclass->stype || + dev_to_subclass->stype->ssize < new_prototype->params_size) + return_error(gs_error_VMerror); + + /* We make a 'stype' structure for our new device, and copy the old stype into it + * This means our new device will always have the 'stype_is_dynamic' flag set + */ + a_std = (gs_memory_struct_type_t *) + gs_alloc_bytes_immovable(dev_to_subclass->memory->non_gc_memory, sizeof(*a_std), + "gs_device_subclass(stype)"); + if (!a_std) + return_error(gs_error_VMerror); + *a_std = *dev_to_subclass->stype; + a_std->ssize = dev_to_subclass->params_size; + + if (!dynamic) { + b_std = (gs_memory_struct_type_t *) + gs_alloc_bytes_immovable(dev_to_subclass->memory->non_gc_memory, sizeof(*b_std), + "gs_device_subclass(stype)"); + if (!b_std) + return_error(gs_error_VMerror); + } + + /* Allocate a device structure for the new child device */ + child_dev = gs_alloc_struct_immovable(dev_to_subclass->memory->stable_memory, gx_device, a_std, + "gs_device_subclass(device)"); + if (child_dev == 0) { + gs_free_const_object(dev_to_subclass->memory->non_gc_memory, a_std, "gs_device_subclass(stype)"); + gs_free_const_object(dev_to_subclass->memory->non_gc_memory, b_std, "gs_device_subclass(stype)"); + return_error(gs_error_VMerror); + } + + /* Make sure all methods are filled in, note this won't work for a forwarding device + * so forwarding devices will have to be filled in before being subclassed. This doesn't fill + * in the fill_rectangle proc, that gets done in the ultimate device's open proc. + */ + gx_device_fill_in_procs(dev_to_subclass); + memcpy(child_dev, dev_to_subclass, dev_to_subclass->stype->ssize); + child_dev->stype = a_std; + child_dev->stype_is_dynamic = 1; + + psubclass_data = (void *)gs_alloc_bytes(dev_to_subclass->memory->non_gc_memory, private_data_size, "subclass memory for subclassing device"); + if (psubclass_data == 0){ + gs_free_const_object(dev_to_subclass->memory->non_gc_memory, a_std, "gs_device_subclass(stype)"); + gs_free_const_object(dev_to_subclass->memory->non_gc_memory, b_std, "gs_device_subclass(stype)"); + gs_free_object(dev_to_subclass->memory->stable_memory, child_dev, "free subclass memory for subclassing device"); + return_error(gs_error_VMerror); + } + memset(psubclass_data, 0x00, private_data_size); + + gx_copy_device_procs(dev_to_subclass, child_dev, new_prototype); + set_dev_proc(dev_to_subclass, fill_rectangle, dev_proc(new_prototype, fill_rectangle)); + set_dev_proc(dev_to_subclass, copy_planes, dev_proc(new_prototype, copy_planes)); + dev_to_subclass->finalize = new_prototype->finalize; + dev_to_subclass->dname = new_prototype->dname; + if (dev_to_subclass->icc_struct) + rc_increment(dev_to_subclass->icc_struct); + if (dev_to_subclass->PageList) + rc_increment(dev_to_subclass->PageList); + + /* In case the new device we're creating has already been initialised, copy + * its additional data. + */ + ptr = ((char *)dev_to_subclass) + sizeof(gx_device); + ptr1 = ((char *)new_prototype) + sizeof(gx_device); + memcpy(ptr, ptr1, new_prototype->params_size - sizeof(gx_device)); + + /* If the original device's stype structure was dynamically allocated, we need + * to 'fixup' the contents, it's procs need to point to the new device's procs + * for instance. + */ + if (dynamic) { + if (new_prototype->stype) { + b_std = (gs_memory_struct_type_t *)dev_to_subclass->stype; + *b_std = *new_prototype->stype; + b_std->ssize = a_std->ssize; + dev_to_subclass->stype_is_dynamic = 1; + } else { + gs_free_const_object(child_dev->memory->non_gc_memory, dev_to_subclass->stype, + "unsubclass"); + dev_to_subclass->stype = NULL; + b_std = (gs_memory_struct_type_t *)new_prototype->stype; + dev_to_subclass->stype_is_dynamic = 0; + } + } + else { + *b_std = *new_prototype->stype; + b_std->ssize = a_std->ssize; + dev_to_subclass->stype_is_dynamic = 1; + } + dev_to_subclass->stype = b_std; + /* We have to patch up the "type" parameters that the memory manage/garbage + * collector will use, as well. + */ + gs_set_object_type(child_dev->memory, dev_to_subclass, b_std); + + dev_to_subclass->subclass_data = psubclass_data; + dev_to_subclass->child = child_dev; + if (child_dev->parent) { + dev_to_subclass->parent = child_dev->parent; + child_dev->parent->child = dev_to_subclass; + } + if (child_dev->child) { + child_dev->child->parent = child_dev; + } + child_dev->parent = dev_to_subclass; + + return 0; +} + +int gx_device_unsubclass(gx_device *dev) +{ + generic_subclass_data *psubclass_data; + gx_device *parent, *child; + gs_memory_struct_type_t *a_std = 0, *b_std = 0; + int dynamic, ref_count; + + /* This should not happen... */ + if (!dev) + return 0; + + ref_count = dev->rc.ref_count; + child = dev->child; + psubclass_data = (generic_subclass_data *)dev->subclass_data; + parent = dev->parent; + dynamic = dev->stype_is_dynamic; + + /* We need to account for the fact that we are removing ourselves from + * the device chain after a clist device has been pushed, due to a + * compositor action. Since we patched the clist 'create_compositor' + * method (and target device) when it was pushed. + * A point to note; we *don't* want to change the forwarding device's + * 'target', because when we copy the child up to replace 'this' device + * we do still want the forwarding device to point here. NB its the *child* + * device that goes away. + */ + if (psubclass_data != NULL && psubclass_data->forwarding_dev != NULL && psubclass_data->saved_compositor_method) + psubclass_data->forwarding_dev->procs.create_compositor = psubclass_data->saved_compositor_method; + + /* If ths device's stype is dynamically allocated, keep a copy of it + * in case we might need it. + */ + if (dynamic) { + a_std = (gs_memory_struct_type_t *)dev->stype; + if (child) + *a_std = *child->stype; + } + + /* If ths device has any private storage, free it now */ + if (psubclass_data) + gs_free_object(dev->memory->non_gc_memory, psubclass_data, "subclass memory for first-last page"); + + /* Copy the child device into ths device's memory */ + if (child) { + b_std = (gs_memory_struct_type_t *)dev->stype; + rc_decrement(dev->icc_struct, "unsubclass device"); + rc_increment(child->icc_struct); + memcpy(dev, child, child->stype->ssize); + /* Patch back the 'stype' in the memory manager */ + gs_set_object_type(child->memory, dev, b_std); + + dev->stype = b_std; + /* The reference count of the subclassing device may have been changed + * (eg graphics states pointing to it) after we subclassed the device. We + * need to ensure that we do not overwrite this when we copy back the subclassed + * device. + */ + dev->rc.ref_count = ref_count; + + /* If we have a chain of devices, make sure the chain beond the device we're unsubclassing + * doesn't get broken, we needd to detach the lower chain and reattach it at the new + * highest level + */ + if (child->child) + child->child->parent = dev; + child->parent->child = child->child; + } + + /* How can we have a subclass device with no child ? Simples; when we hit the end of job + * restore, the devices are not freed in device chain order. To make sure we don't end up + * following stale pointers, when a device is freed we remove it from the chain and update + * any danlging poitners to NULL. When we later free the remaining devices its possible that + * their child pointer can then be NULL. + */ + if (child) { + if (child->icc_struct) + rc_decrement(child->icc_struct, "gx_unsubclass_device, icc_struct"); + if (child->PageList) + rc_decrement(child->PageList, "gx_unsubclass_device, PageList"); + /* we cannot afford to free the child device if its stype is not dynamic because + * we can't 'null' the finalise routine, and we cannot permit the device to be finalised + * because we have copied it up one level, not discarded it. + * (this shouldn't happen! Child devices are always created with a dynamic stype) + * If this ever happens garbage collecton will eventually clean up the memory. + */ + if (child->stype_is_dynamic) { + /* Make sure that nothing will tyr to follow the device chain, just security here */ + child->parent = NULL; + child->child = NULL; + /* Make certainthe memory will be freed, zap the reference count */ + child->rc.ref_count = 0; + /* We *don't* want to run the finalize routine. This would free the stype and + * properly handle the icc_struct and PageList, but for devices with a custom + * finalize (eg psdcmyk) it might also free memory it had allocated, and we're + * still pointing at that memory in the parent. + * The indirection through a variable is just to get rid of const warnings. + */ + b_std = (gs_memory_struct_type_t *)child->stype; + b_std->finalize = NULL; + /* Having patched the stype, we need to make sure the memory manager uses it. + * It keeps a copy in its own data structure, and would use that copy, which would + * mean it would call the finalize routine that we just patched out. + */ + gs_set_object_type(dev->memory->stable_memory, child, b_std); + /* Now (finally) free the child memory */ + gs_free_object(dev->memory->stable_memory, child, "gx_unsubclass_device(device)"); + /* And the stype for it */ + gs_free_const_object(dev->memory->non_gc_memory, b_std, "gs_device_unsubclass(stype)"); + child = 0; + } + } + if(child) + child->parent = dev; + dev->parent = parent; + + /* If this device has a dynamic stype, we wnt to keep using it, but we copied + * the stype pointer from the child when we copied the rest of the device. So + * we update the stype pointer with the saved pointer to this device's stype. + */ + if (dynamic) { + dev->stype = a_std; + dev->stype_is_dynamic = 1; + } else { + dev->stype_is_dynamic = 0; + } + + return 0; +} + +int gx_update_from_subclass(gx_device *dev) +{ + if (!dev->child) + return 0; + + memcpy(&dev->color_info, &dev->child->color_info, sizeof(gx_device_color_info)); + memcpy(&dev->cached_colors, &dev->child->cached_colors, sizeof(gx_device_cached_colors_t)); + dev->max_fill_band = dev->child->max_fill_band; + dev->width = dev->child->width; + dev->height = dev->child->height; + dev->pad = dev->child->pad; + dev->log2_align_mod = dev->child->log2_align_mod; + dev->max_fill_band = dev->child->max_fill_band; + dev->is_planar = dev->child->is_planar; + dev->LeadingEdge = dev->child->LeadingEdge; + memcpy(&dev->ImagingBBox, &dev->child->ImagingBBox, sizeof(dev->child->ImagingBBox)); + dev->ImagingBBox_set = dev->child->ImagingBBox_set; + memcpy(&dev->MediaSize, &dev->child->MediaSize, sizeof(dev->child->MediaSize)); + memcpy(&dev->HWResolution, &dev->child->HWResolution, sizeof(dev->child->HWResolution)); + memcpy(&dev->Margins, &dev->child->Margins, sizeof(dev->child->Margins)); + memcpy(&dev->HWMargins, &dev->child->HWMargins, sizeof(dev->child->HWMargins)); + dev->FirstPage = dev->child->FirstPage; + dev->LastPage = dev->child->LastPage; + dev->PageCount = dev->child->PageCount; + dev->ShowpageCount = dev->child->ShowpageCount; + dev->NumCopies = dev->child->NumCopies; + dev->NumCopies_set = dev->child->NumCopies_set; + dev->IgnoreNumCopies = dev->child->IgnoreNumCopies; + dev->UseCIEColor = dev->child->UseCIEColor; + dev->LockSafetyParams= dev->child->LockSafetyParams; + dev->band_offset_x = dev->child->band_offset_y; + dev->sgr = dev->child->sgr; + dev->MaxPatternBitmap = dev->child->MaxPatternBitmap; + dev->page_uses_transparency = dev->child->page_uses_transparency; + memcpy(&dev->space_params, &dev->child->space_params, sizeof(gdev_space_params)); + dev->graphics_type_tag = dev->child->graphics_type_tag; + + return 0; +} + +int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, + gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) +{ + pdf14_clist_device *p14dev; + generic_subclass_data *psubclass_data; + int code = 0; + + p14dev = (pdf14_clist_device *)dev; + psubclass_data = p14dev->target->subclass_data; + + set_dev_proc(dev, create_compositor, psubclass_data->saved_compositor_method); + + if (gs_is_pdf14trans_compositor(pcte) != 0 && strncmp(dev->dname, "pdf14clist", 10) == 0) { + const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte; + + switch (pdf14pct->params.pdf14_op) { + case PDF14_POP_DEVICE: + { + pdf14_clist_device *p14dev = (pdf14_clist_device *)dev; + gx_device *subclass_device; + + p14dev->target->color_info = p14dev->saved_target_color_info; + if (p14dev->target->child) { + p14dev->target->child->color_info = p14dev->saved_target_color_info; + + set_dev_proc(p14dev->target->child, encode_color, p14dev->saved_target_encode_color); + set_dev_proc(p14dev->target->child, decode_color, p14dev->saved_target_decode_color); + set_dev_proc(p14dev->target->child, get_color_mapping_procs, p14dev->saved_target_get_color_mapping_procs); + set_dev_proc(p14dev->target->child, get_color_comp_index, p14dev->saved_target_get_color_comp_index); + } + + pgs->get_cmap_procs = p14dev->save_get_cmap_procs; + gx_set_cmap_procs(pgs, p14dev->target); + + subclass_device = p14dev->target; + p14dev->target = p14dev->target->child; + + code = dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); + + p14dev->target = subclass_device; + + return code; + } + break; + default: + code = dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); + break; + } + } else { + code = dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); + } + set_dev_proc(dev, create_compositor, gx_subclass_create_compositor); + return code; +} diff -Nru ghostscript-9.10~dfsg/base/gdevdgbr.c ghostscript-9.25~dfsg+1/base/gdevdgbr.c --- ghostscript-9.10~dfsg/base/gdevdgbr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdgbr.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Default implementation of device get_bits[_rectangle] */ @@ -82,7 +82,7 @@ dev->color_info.depth : dev->color_info.num_components); if (!(requested->options & GB_SELECT_PLANES) || - !(both & (GB_PACKING_PLANAR || GB_PACKING_BIT_PLANAR)) + !(both & (GB_PACKING_PLANAR | GB_PACKING_BIT_PLANAR)) ) return false; for (i = 0; i < n; ++i) @@ -132,15 +132,7 @@ * the device wants something else, it should implement * get_bits_rectangle itself. */ - uint dev_raster = - (both & GB_PACKING_CHUNKY ? - gx_device_raster(dev, true) : - both & GB_PACKING_PLANAR ? - bitmap_raster(dev->color_info.depth / - dev->color_info.num_components * dev->width) : - both & GB_PACKING_BIT_PLANAR ? - bitmap_raster(dev->width) : - 0 /* not possible */); + uint dev_raster = gx_device_raster(dev, true); uint raster = (options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster : params->raster); @@ -368,11 +360,11 @@ (stored_options & GB_PACKING_CHUNKY) && ((options & stored_options) & GB_COLORS_NATIVE) ) { - int num_planes = dev->color_info.num_components; + uchar num_planes = dev->color_info.num_components; int dest_depth = depth / num_planes; bits_plane_t source, dest; int plane = -1; - int i; + uchar i; /* Make sure only one plane is being requested. */ for (i = 0; i < num_planes; ++i) @@ -381,6 +373,9 @@ return_error(gs_error_rangecheck); /* > 1 plane */ plane = i; } + /* Ensure at least one plane is requested */ + if (plane < 0) + return_error(gs_error_rangecheck); /* No planes */ source.data.read = src_base; source.raster = dev_raster; source.depth = depth; @@ -429,38 +424,43 @@ params->options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE; for (; h > 0; dest_line += raster, src_line += dev_raster, --h) { int i; - - sample_load_declare_setup(src, sbit, src_line, - src_bit_offset & 7, src_depth); - sample_store_declare_setup(dest, dbit, dbyte, dest_line, - dest_bit_offset & 7, depth); + const byte *src = src_line; + int sbit = src_bit_offset & 7; + byte *dest = dest_line; + int dbit = dest_bit_offset & 7; + byte dbyte = (dbit ? (byte)(*dest & (0xff00 >> dbit)) : 0); #define v2frac(value) ((long)(value) * frac_1 / src_max) for (i = 0; i < w; ++i) { int j; + uchar k; frac sc[4], dc[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value v[GX_DEVICE_COLOR_MAX_COMPONENTS], va = alpha_default; + gx_color_value v[GX_DEVICE_COLOR_MAX_COMPONENTS]; + gx_color_value va = alpha_default; gx_color_index pixel; bool do_alpha = false; - const gx_cm_color_map_procs * map_procs; + subclass_color_mappings scm; - map_procs = dev_proc(dev, get_color_mapping_procs)(dev); + scm = get_color_mapping_procs_subclass(dev); /* Fetch the source data. */ if (stored->options & GB_ALPHA_FIRST) { - sample_load_next16(va, src, sbit, src_depth); + if (sample_load_next16(&va, &src, &sbit, src_depth) < 0) + return_error(gs_error_rangecheck); va = v2cv(va); do_alpha = true; } for (j = 0; j < ncolors; ++j) { gx_color_value vj; - sample_load_next16(vj, src, sbit, src_depth); + if (sample_load_next16(&vj, &src, &sbit, src_depth) < 0) + return_error(gs_error_rangecheck); sc[j] = v2frac(vj); } if (stored->options & GB_ALPHA_LAST) { - sample_load_next16(va, src, sbit, src_depth); + if (sample_load_next16(&va, &src, &sbit, src_depth) < 0) + return_error(gs_error_rangecheck); va = v2cv(va); do_alpha = true; } @@ -477,26 +477,33 @@ switch (ncolors) { case 1: - map_procs->map_gray(dev, sc[0], dc); + map_gray_subclass(scm, sc[0], dc); break; case 3: - map_procs->map_rgb(dev, 0, sc[0], sc[1], sc[2], dc); + map_rgb_subclass(scm, 0, sc[0], sc[1], sc[2], dc); break; case 4: - map_procs->map_cmyk(dev, sc[0], sc[1], sc[2], sc[3], dc); + map_cmyk_subclass(scm, sc[0], sc[1], sc[2], sc[3], dc); break; default: return_error(gs_error_rangecheck); } - for (j = 0; j < dev->color_info.num_components; j++) - v[j] = frac2cv(dc[j]); + for (k = 0; k < dev->color_info.num_components; k++) + v[k] = frac2cv(dc[k]); pixel = dev_proc(dev, encode_color)(dev, v); } - sample_store_next_any(pixel, dest, dbit, depth, dbyte); + if (sizeof(pixel) > 4) { + if (sample_store_next64(pixel, &dest, &dbit, depth, &dbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(pixel, &dest, &dbit, depth, &dbyte) < 0) + return_error(gs_error_rangecheck); + } } - sample_store_flush(dest, dbit, depth, dbyte); + sample_store_flush(dest, dbit, dbyte); } return 0; } @@ -568,15 +575,22 @@ for (i = (depth > 4 ? 16 : 1 << depth); --i >= 0; ) mapped[i] = 0; for (; h > 0; dest_line += raster, src_line += dev_raster, --h) { - sample_load_declare_setup(src, bit, src_line, - src_bit_offset & 7, depth); + const byte *src = src_line; + int bit = src_bit_offset & 7; byte *dest = dest_line; for (i = 0; i < w; ++i) { gx_color_index pixel = 0; gx_color_value rgba[4]; - sample_load_next_any(pixel, src, bit, depth); + if (sizeof(pixel) > 4) { + if (sample_load_next64((uint64_t *)&pixel, &src, &bit, depth) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_load_next32((uint32_t *)&pixel, &src, &bit, depth) < 0) + return_error(gs_error_rangecheck); + } if (pixel < 16) { if (mapped[pixel]) { /* Use the value from the cache. */ diff -Nru ghostscript-9.10~dfsg/base/gdevdrop.c ghostscript-9.25~dfsg+1/base/gdevdrop.c --- ghostscript-9.10~dfsg/base/gdevdrop.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdrop.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Default and device-independent RasterOp algorithms */ @@ -159,12 +159,12 @@ pmdev->height = block_height; pmdev->bitmap_memory = mem; pmdev->color_info = dev->color_info; - plane_depth = dev_proc(dev, dev_spec_op)(dev, gxdso_is_native_planar, NULL, 0); - if (plane_depth > 0) + if (dev->is_planar) { gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int num_comp = dev->color_info.num_components; - int i; + uchar num_comp = dev->color_info.num_components; + uchar i; + plane_depth = dev->color_info.depth / num_comp; for (i = 0; i < num_comp; i++) { planes[i].shift = plane_depth * (num_comp - 1 - i); @@ -447,6 +447,7 @@ case 32: *dp++ = (byte)(pixel >> 24); *dp++ = (byte)(pixel >> 16); + /* fall through */ case 16: *dp++ = (byte)(pixel >> 8); *dp++ = (byte)pixel; @@ -472,7 +473,8 @@ int shift = (~bit_x & 7) + 1; byte buf[GX_DEVICE_COLOR_MAX_COMPONENTS]; const byte *sp = src; - int x, plane; + int x; + uchar plane; if (pdepth == 1 && dev->color_info.num_components == 4) { pack_planar_cmyk_1bit_from_standard(dev, y, destx, src, width, @@ -480,7 +482,7 @@ return; } - for (plane = 0; plane < dev->num_planes; plane++) { + for (plane = 0; plane < dev->color_info.num_components; plane++) { byte *dest = scan_line_base(dev, y + plane * dev->height); dp[plane] = dest + (bit_x >> 3); buf[plane] = (shift == 8 ? 0 : *dp[plane] & (0xff00 >> shift)); @@ -550,22 +552,22 @@ /* We have pdepth*num_planes bits in 'pixel'. We need to copy * them (topmost bits first) into the buffer, packing them at * shift position. */ - int pshift = pdepth*(dev->num_planes-1); + int pshift = pdepth*(dev->color_info.num_components-1); #endif /* Can we fit another pdepth bits into our buffer? */ shift -= pdepth; if (shift < 0) { /* No, so flush the buffer to the planes. */ - for (plane = 0; plane < dev->num_planes; plane++) + for (plane = 0; plane < dev->color_info.num_components; plane++) *dp[plane]++ = buf[plane]; shift += 8; } /* Copy the next pdepth bits into each planes buffer */ #ifdef ORIGINAL_CODE_KEPT_FOR_REFERENCE - for (plane = 0; plane < dev->num_planes; pshift+=8,plane++) + for (plane = 0; plane < dev->color_info.num_components; pshift+=8,plane++) buf[plane] += (byte)(((pixel>>pshift) & pmask)<num_planes; pshift-=pdepth,plane++) + for (plane = 0; plane < dev->color_info.num_components; pshift-=pdepth,plane++) buf[plane] += (byte)(((pixel>>pshift) & pmask)< 0 && depth <= 8) { if (shift == 0) - for (plane = 0; plane < dev->num_planes; plane++) + for (plane = 0; plane < dev->color_info.num_components; plane++) *dp[plane] = buf[plane]; else { int mask = (1<num_planes; plane++) + for (plane = 0; plane < dev->color_info.num_components; plane++) *dp[plane] = (*dp[plane] & mask) + buf[plane]; } } @@ -604,7 +606,7 @@ uint planar_height) { dmlprintf(dev->memory, "mem_default_strip_copy_rop2 should never be called!\n"); - return gs_error_Fatal; + return_error(gs_error_Fatal); } int @@ -649,7 +651,7 @@ byte *row = 0; union { long l; void *p; } dest_buffer[16]; byte *source_row = 0; - uint source_row_raster; + uint source_row_raster = 0; /* init to quiet compiler warning */ union { long l; void *p; } source_buffer[16]; byte *texture_row = 0; uint texture_row_raster; @@ -692,7 +694,7 @@ /* We know the device is a memory device, so we can store the * result directly into its scan lines, unless it is planar. */ - if (tdev->num_planes <= 1) { + if (!tdev->is_planar || tdev->color_info.num_components <= 1) { if ((rop_depth == 24) && (dev_proc(dev, dev_spec_op)(dev, gxdso_is_std_cmyk_1bit, NULL, 0) > 0)) { pack = pack_cmyk_1bit_from_standard; @@ -730,7 +732,7 @@ * We don't want to wrap around more than once in Y when * copying the texture to the intermediate buffer. */ - if (textures->size.y < block_height) + if (textures && textures->size.y < block_height) block_height = textures->size.y; } gs_make_mem_device(&mdev, mdproto, mem, -1, NULL); @@ -762,7 +764,7 @@ unpack_colors_to_standard(dev, source_colors, scolors, rop_depth); real_scolors = source_colors; } - if (expand_t) { + if (expand_t && textures) { texture_row_raster = bitmap_raster(textures->rep_width * rop_depth); ALLOC_BUF(texture_row, texture_buffer, texture_row_raster, "copy_rop texture_row"); diff -Nru ghostscript-9.10~dfsg/base/gdevdsha.c ghostscript-9.25~dfsg+1/base/gdevdsha.c --- ghostscript-9.10~dfsg/base/gdevdsha.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevdsha.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Default shading drawing device procedures. */ @@ -19,14 +19,13 @@ #include "gserrors.h" #include "gxdevice.h" #include "gxcindex.h" -#include "vdtrace.h" #include "gxdevsop.h" -static bool -gx_devn_diff(frac31 devn1[], frac31 devn2[], int num) +static bool +gx_devn_diff(frac31 devn1[], frac31 devn2[], int num) { int k; - + for (k = 0; k < num; k++) { if (devn1[k] != devn2[k]) { return true; @@ -37,7 +36,7 @@ int gx_hl_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, - int i0, int j, int w, const frac31 *c0, const int32_t *c0f, + int i0, int j, int w, const frac31 *c0, const int32_t *c0f, const int32_t *cg_num, int32_t cg_den) { frac31 c[GX_DEVICE_COLOR_MAX_COMPONENTS]; @@ -53,7 +52,7 @@ /* Note: All the stepping math is done with frac color values */ devc.type = gx_dc_type_devn; - + if (j < fixed2int(fa->clip->p.y) || j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */ return 0; @@ -110,7 +109,7 @@ rect.q.y = int2fixed(j + 1); } for (k = 0; k < n; k++) { - devc.colors.devn.values[k] = frac2cv(curr[k]); + devc.colors.devn.values[k] = frac312cv(curr[k]); } code = dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL); if (code < 0) @@ -125,7 +124,7 @@ i++; break; } else { - /* Compute a color change pixel analitically. */ + /* Compute a color change pixel analytically. */ di = i1 - i; for (k = 0; k < n; k++) { int32_t a; @@ -173,7 +172,7 @@ rect.q.y = int2fixed(j + 1); } for (k = 0; k < n; k++) { - devc.colors.devn.values[k] = frac2cv(curr[k]); + devc.colors.devn.values[k] = frac312cv(curr[k]); } return dev_proc(dev, fill_rectangle_hl_color) (dev, &rect, NULL, &devc, NULL); } @@ -200,10 +199,15 @@ const gx_device_color_info *cinfo = &dev->color_info; int n = cinfo->num_components; int si, ei, di, code; + /* If the device encodes tags, we expect the comp_shift[num_components] to be valid */ + /* for the tag part of the color (usually the high order bits of the color_index). */ + gx_color_index tag = device_encodes_tags(dev) ? + (gx_color_index)(dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS) << cinfo->comp_shift[n] + : 0; /* Todo: set this up to vector earlier */ - if (devn && cinfo->polarity == GX_CINFO_POLARITY_SUBTRACTIVE) - return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f, + if (devn) /* Note, PDF14 could be additive and doing devn */ + return gx_hl_fill_linear_color_scanline(dev, fa, i0, j, w, c0, c0f, cg_num, cg_den); if (j < fixed2int(fa->clip->p.y) || j > fixed2int_ceiling(fa->clip->q.y)) /* Must be compatible to the clipping logic. */ @@ -263,11 +267,10 @@ si = max(bi, fixed2int(fa->clip->p.x)); /* Must be compatible to the clipping logic. */ ei = min(i, fixed2int_ceiling(fa->clip->q.x)); /* Must be compatible to the clipping logic. */ if (si < ei) { + ci0 |= tag; /* set tag (may be 0 if the device doesn't use tags) */ if (fa->swap_axes) { - vd_rect(int2fixed(j), int2fixed(si), int2fixed(j + 1), int2fixed(ei), 1, (ulong)ci0); code = dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0); } else { - vd_rect(int2fixed(si), int2fixed(j), int2fixed(ei), int2fixed(j + 1), 1, (ulong)ci0); code = dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0); } if (code < 0) @@ -316,11 +319,10 @@ si = max(bi, fixed2int(fa->clip->p.x)); /* Must be compatible to the clipping logic. */ ei = min(i, fixed2int_ceiling(fa->clip->q.x)); /* Must be compatible to the clipping logic. */ if (si < ei) { + ci0 |= tag; /* set tag (may be 0 if the device doesn't use tags) */ if (fa->swap_axes) { - vd_rect(int2fixed(j), int2fixed(si), int2fixed(j + 1), int2fixed(ei), 1, (ulong)ci0); return dev_proc(dev, fill_rectangle)(dev, j, si, 1, ei - si, ci0); } else { - vd_rect(int2fixed(si), int2fixed(j), int2fixed(ei), int2fixed(j + 1), 1, (ulong)ci0); return dev_proc(dev, fill_rectangle)(dev, si, j, ei - si, 1, ci0); } } diff -Nru ghostscript-9.10~dfsg/base/gdevemap.c ghostscript-9.25~dfsg+1/base/gdevemap.c --- ghostscript-9.10~dfsg/base/gdevemap.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevemap.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Mappings between StandardEncoding and ISOLatin1Encoding */ diff -Nru ghostscript-9.10~dfsg/base/gdevepo.c ghostscript-9.25~dfsg+1/base/gdevepo.c --- ghostscript-9.10~dfsg/base/gdevepo.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevepo.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,678 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Device for erasepage optimization subclass device */ + +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gsdevice.h" /* requires gsmatrix.h */ +#include "gxdcolor.h" /* for gx_device_black/white */ +#include "gxiparam.h" /* for image source size */ +#include "gxgstate.h" +#include "gxpaint.h" +#include "gxpath.h" +#include "gxcpath.h" +#include "gxcmap.h" /* color mapping procs */ +#include "gsstype.h" +#include "gdevprn.h" +#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ +#include "gximage.h" /* For gx_image_enum */ +#include "gdevsclass.h" +#include "gsstate.h" +#include "gxdevsop.h" +#include "gdevepo.h" +#include + +/* Shorter macros for sanity's sake */ +#define DPRINTF(m,f) if_debug0m(gs_debug_flag_epo_details, m,f) +#define DPRINTF1(m,f,a1) if_debug1m(gs_debug_flag_epo_details, m,f, a1) + +/* This is only called for debugging */ +extern void epo_disable(int flag); + +/* Device procedures, we need quite a lot of them */ +static dev_proc_output_page(epo_output_page); +static dev_proc_fill_rectangle(epo_fill_rectangle); +static dev_proc_draw_line(epo_draw_line); +static dev_proc_fill_path(epo_fill_path); +static dev_proc_fill_mask(epo_fill_mask); +static dev_proc_fill_trapezoid(epo_fill_trapezoid); +static dev_proc_fill_parallelogram(epo_fill_parallelogram); +static dev_proc_fill_triangle(epo_fill_triangle); +static dev_proc_draw_thin_line(epo_draw_thin_line); +static dev_proc_fill_rectangle_hl_color(epo_fill_rectangle_hl_color); +static dev_proc_fill_linear_color_scanline(epo_fill_linear_color_scanline); +static dev_proc_fill_linear_color_trapezoid(epo_fill_linear_color_trapezoid); +static dev_proc_fill_linear_color_triangle(epo_fill_linear_color_triangle); +static dev_proc_put_image(epo_put_image); +static dev_proc_fillpage(epo_fillpage); +static dev_proc_create_compositor(epo_create_compositor); +static dev_proc_text_begin(epo_text_begin); +static dev_proc_finish_copydevice(epo_finish_copydevice); +static dev_proc_begin_image(epo_begin_image); +static dev_proc_begin_typed_image(epo_begin_typed_image); +static dev_proc_stroke_path(epo_stroke_path); +static dev_proc_tile_rectangle(epo_tile_rectangle); +static dev_proc_copy_mono(epo_copy_mono); +static dev_proc_copy_color(epo_copy_color); +static dev_proc_get_bits(epo_get_bits); +static dev_proc_copy_alpha(epo_copy_alpha); +static dev_proc_copy_rop(epo_copy_rop); +static dev_proc_strip_tile_rectangle(epo_strip_tile_rectangle); +static dev_proc_strip_copy_rop(epo_strip_copy_rop); +static dev_proc_strip_copy_rop2(epo_strip_copy_rop2); +static dev_proc_copy_planes(epo_copy_planes); +static dev_proc_copy_alpha_hl_color(epo_copy_alpha_hl_color); +static dev_proc_process_page(epo_process_page); + +/* The device prototype */ +#define MAX_COORD (max_int_in_fixed - 1000) +#define MAX_RESOLUTION 4000 + +#define public_st_epo_device() /* in gsdevice.c */\ + gs_public_st_complex_only(st_epo_device, gx_device, EPO_DEVICENAME,\ + 0, epo_enum_ptrs, epo_reloc_ptrs, default_subclass_finalize) + +static +ENUM_PTRS_WITH(epo_enum_ptrs, gx_device *dev); +return 0; /* default case */ +case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); +case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); +ENUM_PTRS_END +static RELOC_PTRS_WITH(epo_reloc_ptrs, gx_device *dev) +{ + dev->parent = gx_device_reloc_ptr(dev->parent, gcst); + dev->child = gx_device_reloc_ptr(dev->child, gcst); +}RELOC_PTRS_END + +public_st_epo_device(); + +const +gx_device_epo gs_epo_device = +{ + std_device_dci_type_body(gx_device_epo, 0, EPO_DEVICENAME, &st_epo_device, + MAX_COORD, MAX_COORD, + MAX_RESOLUTION, MAX_RESOLUTION, + 1, 8, 255, 0, 256, 1), + {default_subclass_open_device, + default_subclass_get_initial_matrix, + default_subclass_sync_output, /* sync_output */ + epo_output_page, + default_subclass_close_device, + default_subclass_map_rgb_color, + default_subclass_map_color_rgb, + epo_fill_rectangle, + epo_tile_rectangle, /* tile_rectangle */ + epo_copy_mono, + epo_copy_color, + epo_draw_line, /* draw_line */ + epo_get_bits, /* get_bits */ + default_subclass_get_params, + default_subclass_put_params, + default_subclass_map_cmyk_color, + default_subclass_get_xfont_procs, /* get_xfont_procs */ + default_subclass_get_xfont_device, /* get_xfont_device */ + default_subclass_map_rgb_alpha_color, + default_subclass_get_page_device, + default_subclass_get_alpha_bits, /* get_alpha_bits */ + epo_copy_alpha, + default_subclass_get_band, /* get_band */ + epo_copy_rop, /* copy_rop */ + epo_fill_path, + epo_stroke_path, + epo_fill_mask, + epo_fill_trapezoid, + epo_fill_parallelogram, + epo_fill_triangle, + epo_draw_thin_line, + epo_begin_image, + default_subclass_image_data, /* image_data */ + default_subclass_end_image, /* end_image */ + epo_strip_tile_rectangle, + epo_strip_copy_rop, + default_subclass_get_clipping_box, /* get_clipping_box */ + epo_begin_typed_image, + default_subclass_get_bits_rectangle, /* get_bits_rectangle */ + default_subclass_map_color_rgb_alpha, + epo_create_compositor, + default_subclass_get_hardware_params, /* get_hardware_params */ + epo_text_begin, + epo_finish_copydevice, /* finish_copydevice */ + default_subclass_begin_transparency_group, /* begin_transparency_group */ + default_subclass_end_transparency_group, /* end_transparency_group */ + default_subclass_begin_transparency_mask, /* begin_transparency_mask */ + default_subclass_end_transparency_mask, /* end_transparency_mask */ + default_subclass_discard_transparency_layer, /* discard_transparency_layer */ + default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ + default_subclass_get_color_comp_index, /* get_color_comp_index */ + default_subclass_encode_color, /* encode_color */ + default_subclass_decode_color, /* decode_color */ + default_subclass_pattern_manage, /* pattern_manage */ + epo_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ + default_subclass_include_color_space, /* include_color_space */ + epo_fill_linear_color_scanline, /* fill_linear_color_scanline */ + epo_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ + epo_fill_linear_color_triangle, /* fill_linear_color_triangle */ + default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ + default_subclass_ret_devn_params, /* ret_devn_params */ + epo_fillpage, /* fillpage */ + default_subclass_push_transparency_state, /* push_transparency_state */ + default_subclass_pop_transparency_state, /* pop_transparency_state */ + epo_put_image, /* put_image */ + default_subclass_dev_spec_op, /* dev_spec_op */ + epo_copy_planes, /* copy_planes */ + default_subclass_get_profile, /* get_profile */ + default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ + epo_strip_copy_rop2, + default_subclass_strip_tile_rect_devn, + epo_copy_alpha_hl_color, + epo_process_page + } +}; + +#undef MAX_COORD +#undef MAX_RESOLUTION + +static bool +is_device_installed(gx_device *dev, const char *name) +{ + while (dev) { + if (!strcmp(dev->dname, name)) { + return true; + } + dev = dev->child; + } + return false; +} + +/* See if this is a device we can optimize + * (currently only the ones that use gx_default_fillpage, which + * automatically excludes clist and pdfwrite, etc) + */ +static bool +device_wants_optimization(gx_device *dev) +{ + return (dev_proc(dev, fillpage) == gx_default_fillpage); +} + +/* Use this when debugging to enable/disable epo + * (1 - disable, 0 - enable) + */ +void +epo_disable(int flag) +{ + gs_debug[gs_debug_flag_epo_disable] = flag; +} + +int +epo_check_and_install(gx_device *dev) +{ + int code = 0; + bool is_installed; + bool can_optimize = false; + + /* Debugging mode to totally disable this */ + if (gs_debug_c(gs_debug_flag_epo_disable)) { + return code; + } + + DPRINTF1(dev->memory, "current device is %s\n", dev->dname); + + is_installed = is_device_installed(dev, EPO_DEVICENAME); + + if (is_installed) { + DPRINTF1(dev->memory, "device %s already installed\n", EPO_DEVICENAME); + /* This is looking for the case where the device + * changed into something we can't optimize, after it was already installed + * (could be clist or some other weird thing) + */ + if (dev->child) { + can_optimize = device_wants_optimization(dev->child); + } + if (!can_optimize) { + DPRINTF1(dev->memory, "child %s can't be optimized, uninstalling\n", dev->child->dname); + /* Not doing any pending fillpages because we are about to do + * a fillpage anyway + */ + gx_device_unsubclass(dev); + return code; + } + } else { + can_optimize = device_wants_optimization(dev); + } + + /* Already installed, nothing to do */ + if (is_installed) { + return code; + } + + /* See if we can optimize */ + if (!can_optimize) { + DPRINTF(dev->memory, "device doesn't want optimization, not installing\n"); + return code; + } + + /* Install subclass for optimization */ + code = gx_device_subclass(dev, (gx_device *)&gs_epo_device, sizeof(erasepage_subclass_data)); + if (code < 0) { + DPRINTF1(dev->memory, "ERROR installing device %s\n", EPO_DEVICENAME); + return code; + } + + DPRINTF1(dev->memory, "SUCCESS installed device %s\n", dev->dname); + return code; +} + +static int +epo_handle_erase_page(gx_device *dev) +{ + erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; + int code = 0; + + if (gs_debug_c(gs_debug_flag_epo_install_only)) { + gx_device_unsubclass(dev); + DPRINTF1(dev->memory, "Uninstall erasepage, device=%s\n", dev->dname); + return code; + } + + DPRINTF1(dev->memory, "Do fillpage, Uninstall erasepage, device %s\n", dev->dname); + + /* Just do a fill_rectangle (using saved color) */ + if (dev->child) { + code = dev_proc(dev->child, fill_rectangle)(dev->child, + 0, 0, + dev->child->width, + dev->child->height, + data->last_color); + } + /* Remove the epo device */ + gx_device_unsubclass(dev); + + return code; +} + +int epo_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) +{ + erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; + + if (gs_debug_c(gs_debug_flag_epo_install_only)) { + return default_subclass_fillpage(dev, pgs, pdevc); + } + + /* If color is not pure, don't defer this, uninstall and do it now */ + if (!color_is_pure(pdevc)) { + DPRINTF(dev->memory, "epo_fillpage(), color is not pure, uninstalling\n"); + gx_device_unsubclass(dev); + return dev_proc(dev, fillpage)(dev, pgs, pdevc); + } + + /* Save the color being requested, and swallow the fillpage */ + data->last_color = pdevc->colors.pure; + + DPRINTF(dev->memory, "Swallowing fillpage\n"); + return 0; +} + +int epo_output_page(gx_device *dev, int num_copies, int flush) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, output_page)(dev, num_copies, flush); +} + +int epo_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_rectangle)(dev, x, y, width, height, color); +} + +int epo_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, obsolete_draw_line)(dev, x0, y0, x1, y1, color); +} + +int epo_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_fill_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_path)(dev, pgs, ppath, params, pdcolor, pcpath); +} + +int epo_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, + const gx_drawing_color *pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path *pcpath) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_mask)(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); +} + +int epo_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, + fixed ybot, fixed ytop, bool swap_axes, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_trapezoid)(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); +} + +int epo_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_parallelogram)(dev, px, py, ax, ay, bx, by, pdcolor, lop); +} + +int epo_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_triangle)(dev, px, py, ax, ay, bx, by, pdcolor, lop); +} + +int epo_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop, + fixed adjustx, fixed adjusty) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, draw_thin_line)(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); +} + +int epo_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_rectangle_hl_color)(dev, rect, pgs, pdcolor, pcpath); +} + +int epo_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, + int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, + int32_t cg_den) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_linear_color_scanline)(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); +} + +int epo_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const gs_fixed_point *p3, + const frac31 *c0, const frac31 *c1, + const frac31 *c2, const frac31 *c3) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_linear_color_trapezoid)(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); +} + +int epo_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, fill_linear_color_triangle)(dev, fa, p0, p1, p2, c0, c1, c2); +} + +int epo_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y, + int width, int height, int row_stride, + int alpha_plane_index, int tag_plane_index) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, put_image)(dev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); +} + +int epo_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, + gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, create_compositor)(dev, pcdev, pcte, pgs, memory, cdev); +} + +int epo_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, + gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gs_text_enum_t **ppte) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, text_begin)(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); +} + +int epo_finish_copydevice(gx_device *dev, const gx_device *from_dev) +{ + /* We musn't allow the following pointers to remain shared with the from_dev + because we're about to tell the caller it's only allowed to copy the prototype + and free the attempted copy of a non-prototype. If from_dev is the prototype + these pointers won't be set, anyway. + */ + dev->child = NULL; + dev->parent = NULL; + dev->subclass_data = NULL; + /* Only allow copying the prototype. */ + return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); +} + +int epo_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, + gs_image_format_t format, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, begin_image)(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); +} + +int epo_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, + const gs_image_common_t *pic, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, begin_typed_image)(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); +} + +int epo_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_stroke_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, stroke_path)(dev, pgs, ppath, params, pdcolor, pcpath); +} + +int epo_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, tile_rectangle)(dev, tile, x, y, width, height, color0, color1, phase_x, phase_y); +} + +int epo_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, copy_mono)(dev, data, data_x, raster, id, x, y, width, height, color0, color1); +} + +int epo_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id,\ + int x, int y, int width, int height) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, copy_color)(dev, data, data_x, raster, id, x, y, width, height); +} + +int epo_get_bits(gx_device *dev, int y, byte *data, byte **actual_data) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, get_bits)(dev, y, data, actual_data); +} + +int epo_copy_alpha(gx_device *dev, const byte *data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, copy_alpha)(dev, data, data_x, raster, id, x, y, width, height, color, depth); +} + +int epo_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, + const gx_tile_bitmap *texture, const gx_color_index *tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, copy_rop)(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); +} + +int epo_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, strip_tile_rectangle)(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); +} + +int epo_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, + const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, strip_copy_rop)(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); +} + +int epo_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, strip_copy_rop2)(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height); +} + +int epo_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, int plane_height) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, copy_planes)(dev, data, data_x, raster, id, x, y, width, height, plane_height); +} + +int epo_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + const gx_drawing_color *pdcolor, int depth) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, copy_alpha_hl_color)(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth); +} + +int epo_process_page(gx_device *dev, gx_process_page_options_t *options) +{ + int code = epo_handle_erase_page(dev); + + if (code != 0) + return code; + return dev_proc(dev, process_page)(dev, options); +} diff -Nru ghostscript-9.10~dfsg/base/gdevepo.h ghostscript-9.25~dfsg+1/base/gdevepo.h --- ghostscript-9.10~dfsg/base/gdevepo.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevepo.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,39 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Common definitions for "erasepage optimization" device */ + +#ifndef gdevepo_INCLUDED +# define gdevepo_INCLUDED + +#ifndef gxdevice_INCLUDED +#include "gxdevice.h" +#endif + +#define EPO_DEVICENAME "erasepage_optimization" + +typedef struct gx_device_s gx_device_epo; + +typedef struct { + subclass_common; + gx_color_index last_color; // Pure color only +} erasepage_subclass_data; + +/* Check if epo subclass device installed, and install it if not */ +int epo_check_and_install(gx_device *dev); +void gx_epo_finalize(const gs_memory_t *cmem, void *vptr); + +#endif /* gdevepo_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevflp.c ghostscript-9.25~dfsg+1/base/gdevflp.c --- ghostscript-9.10~dfsg/base/gdevflp.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevflp.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,1213 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Device for first/last page handling device */ +/* This device is the first 'subclassing' device; the intention of subclassing + * is to allow us to develop a 'chain' or 'pipeline' of devices, each of which + * can process some aspect of the graphics methods before passing them on to the + * next device in the chain. + * + * This device's purpose is to implement the 'FirstPage' and 'LastPage' parameters + * in Ghostscript. Initially only implemented in the PDF interpreter this functionality + * has been shifted internally so that it can be implemented in all the interpreters. + * The approach is pretty simple, we modify gdevprn.c and gdevvec.c so that if -dFirstPage + * or -dLastPage is defined the device in question is subclassed and this device inserted. + * This device then 'black hole's any graphics operations until we reach 'FirstPage'. We then + * allow graphics to pass to the device until we reach the end of 'LastPage' at which time we + * discard operations again until we reach the end, and close the device. + */ + +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gsdevice.h" /* requires gsmatrix.h */ +#include "gxdcolor.h" /* for gx_device_black/white */ +#include "gxiparam.h" /* for image source size */ +#include "gxgstate.h" +#include "gxpaint.h" +#include "gxpath.h" +#include "gxcpath.h" +#include "gxcmap.h" /* color mapping procs */ +#include "gsstype.h" +#include "gdevprn.h" +#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ +#include "gximage.h" /* For gx_image_enum */ +#include "gdevsclass.h" +#include "gdevflp.h" +#include + +/* GC descriptor */ +public_st_device_flp(); +/* we need text and image enumerators, because of the crazy way that text and images work */ +private_st_flp_text_enum(); + +/* Device procedures, we need quite a lot of them */ +static dev_proc_output_page(flp_output_page); +static dev_proc_close_device(flp_close_device); +static dev_proc_fill_rectangle(flp_fill_rectangle); +static dev_proc_tile_rectangle(flp_tile_rectangle); +static dev_proc_copy_mono(flp_copy_mono); +static dev_proc_copy_color(flp_copy_color); +static dev_proc_draw_line(flp_draw_line); +static dev_proc_get_bits(flp_get_bits); +static dev_proc_get_params(flp_put_params); +static dev_proc_get_alpha_bits(flp_get_alpha_bits); +static dev_proc_copy_alpha(flp_copy_alpha); +static dev_proc_get_band(flp_get_band); +static dev_proc_copy_rop(flp_copy_rop); +static dev_proc_fill_path(flp_fill_path); +static dev_proc_stroke_path(flp_stroke_path); +static dev_proc_fill_mask(flp_fill_mask); +static dev_proc_fill_trapezoid(flp_fill_trapezoid); +static dev_proc_fill_parallelogram(flp_fill_parallelogram); +static dev_proc_fill_triangle(flp_fill_triangle); +static dev_proc_draw_thin_line(flp_draw_thin_line); +static dev_proc_begin_image(flp_begin_image); +static dev_proc_image_data(flp_image_data); +static dev_proc_end_image(flp_end_image); +static dev_proc_strip_tile_rectangle(flp_strip_tile_rectangle); +static dev_proc_strip_copy_rop(flp_strip_copy_rop); +static dev_proc_begin_typed_image(flp_begin_typed_image); +static dev_proc_get_bits_rectangle(flp_get_bits_rectangle); +static dev_proc_create_compositor(flp_create_compositor); +static dev_proc_text_begin(flp_text_begin); +static dev_proc_begin_transparency_group(flp_begin_transparency_group); +static dev_proc_end_transparency_group(flp_end_transparency_group); +static dev_proc_begin_transparency_mask(flp_begin_transparency_mask); +static dev_proc_end_transparency_mask(flp_end_transparency_mask); +static dev_proc_discard_transparency_layer(flp_discard_transparency_layer); +static dev_proc_pattern_manage(flp_pattern_manage); +static dev_proc_fill_rectangle_hl_color(flp_fill_rectangle_hl_color); +static dev_proc_fill_linear_color_scanline(flp_fill_linear_color_scanline); +static dev_proc_fill_linear_color_trapezoid(flp_fill_linear_color_trapezoid); +static dev_proc_fill_linear_color_triangle(flp_fill_linear_color_triangle); +static dev_proc_fillpage(flp_fillpage); +static dev_proc_push_transparency_state(flp_push_transparency_state); +static dev_proc_pop_transparency_state(flp_pop_transparency_state); +static dev_proc_put_image(flp_put_image); +static dev_proc_copy_planes(flp_copy_planes); +static dev_proc_strip_copy_rop2(flp_strip_copy_rop2); +static dev_proc_strip_tile_rect_devn(flp_strip_tile_rect_devn); +static dev_proc_copy_alpha_hl_color(flp_copy_alpha_hl_color); +static dev_proc_process_page(flp_process_page); + +/* The device prototype */ +#define MAX_COORD (max_int_in_fixed - 1000) +#define MAX_RESOLUTION 4000 + +#define public_st_flp_device() /* in gsdevice.c */\ + gs_public_st_complex_only(st_flp_device, gx_device, "first_lastpage",\ + 0, flp_enum_ptrs, flp_reloc_ptrs, default_subclass_finalize) + +static +ENUM_PTRS_WITH(flp_enum_ptrs, gx_device *dev); +return 0; /* default case */ +case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); +case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); +ENUM_PTRS_END +static RELOC_PTRS_WITH(flp_reloc_ptrs, gx_device *dev) +{ + dev->parent = gx_device_reloc_ptr(dev->parent, gcst); + dev->child = gx_device_reloc_ptr(dev->child, gcst); +}RELOC_PTRS_END + +public_st_flp_device(); + +const +gx_device_flp gs_flp_device = +{ + std_device_dci_type_body(gx_device_flp, 0, "first_lastpage", &st_flp_device, + MAX_COORD, MAX_COORD, + MAX_RESOLUTION, MAX_RESOLUTION, + 1, 8, 255, 0, 256, 1), + {default_subclass_open_device, + default_subclass_get_initial_matrix, + default_subclass_sync_output, /* sync_output */ + flp_output_page, + flp_close_device, + default_subclass_map_rgb_color, + default_subclass_map_color_rgb, + flp_fill_rectangle, + flp_tile_rectangle, /* tile_rectangle */ + flp_copy_mono, + flp_copy_color, + flp_draw_line, /* draw_line */ + flp_get_bits, /* get_bits */ + default_subclass_get_params, + flp_put_params, + default_subclass_map_cmyk_color, + default_subclass_get_xfont_procs, /* get_xfont_procs */ + default_subclass_get_xfont_device, /* get_xfont_device */ + default_subclass_map_rgb_alpha_color, + default_subclass_get_page_device, + flp_get_alpha_bits, /* get_alpha_bits */ + flp_copy_alpha, + flp_get_band, /* get_band */ + flp_copy_rop, /* copy_rop */ + flp_fill_path, + flp_stroke_path, + flp_fill_mask, + flp_fill_trapezoid, + flp_fill_parallelogram, + flp_fill_triangle, + flp_draw_thin_line, + flp_begin_image, + flp_image_data, /* image_data */ + flp_end_image, /* end_image */ + flp_strip_tile_rectangle, + flp_strip_copy_rop, + default_subclass_get_clipping_box, /* get_clipping_box */ + flp_begin_typed_image, + flp_get_bits_rectangle, /* get_bits_rectangle */ + default_subclass_map_color_rgb_alpha, + flp_create_compositor, + default_subclass_get_hardware_params, /* get_hardware_params */ + flp_text_begin, + default_subclass_finish_copydevice, /* finish_copydevice */ + flp_begin_transparency_group, /* begin_transparency_group */ + flp_end_transparency_group, /* end_transparency_group */ + flp_begin_transparency_mask, /* begin_transparency_mask */ + flp_end_transparency_mask, /* end_transparency_mask */ + flp_discard_transparency_layer, /* discard_transparency_layer */ + default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ + default_subclass_get_color_comp_index, /* get_color_comp_index */ + default_subclass_encode_color, /* encode_color */ + default_subclass_decode_color, /* decode_color */ + flp_pattern_manage, /* pattern_manage */ + flp_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ + default_subclass_include_color_space, /* include_color_space */ + flp_fill_linear_color_scanline, /* fill_linear_color_scanline */ + flp_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ + flp_fill_linear_color_triangle, /* fill_linear_color_triangle */ + default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ + default_subclass_ret_devn_params, /* ret_devn_params */ + flp_fillpage, /* fillpage */ + flp_push_transparency_state, /* push_transparency_state */ + flp_pop_transparency_state, /* pop_transparency_state */ + flp_put_image, /* put_image */ + default_subclass_dev_spec_op, /* dev_spec_op */ + flp_copy_planes, /* copy_planes */ + default_subclass_get_profile, /* get_profile */ + default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ + flp_strip_copy_rop2, + flp_strip_tile_rect_devn, + flp_copy_alpha_hl_color, + flp_process_page + } +}; + +#undef MAX_COORD +#undef MAX_RESOLUTION + +static int ParsePageList(gx_device *dev, first_last_subclass_data *psubclass_data, char *PageList) +{ + char *str, *oldstr, *workstr, c, *ArgCopy; + int LastPage, Page, byte, bit, i; + + psubclass_data->ProcessedPageList = true; + if (strcmp(PageList, "even") == 0) { + psubclass_data->EvenOdd = even; + } else { + if (strcmp(PageList, "odd") == 0) { + psubclass_data->EvenOdd = odd; + } else { + psubclass_data->EvenOdd = none; + + /* validation of parameter */ + str = PageList; + do { + /* Must be digit, ',' or - */ + if (*str != ',' && *str != '-' && (*str < 0x30 || *str > 0x39)) { + return (gs_note_error(gs_error_typecheck)); + } + /* Check we don't have 2 special characters (, or -) in a row */ + if ((*str == ',' || *str == '-') && (*(str+1) == ',' || *(str+1) == '-')) + return (gs_note_error(gs_error_typecheck)); + } while(*(++str)); + + str = PageList; + oldstr = str; + do { + str = strchr(oldstr, ','); + /* Check for trailing ',' in parameter, zap it if we find one. */ + if (str) { + if (*(str + 1)) + oldstr = ++str; + else { + *str = 0x00; + break; + } + } + }while (str); + + /* In case last set is a page range */ + str = strchr(oldstr, '-'); + if (!str) + str = oldstr; + else { + /* We permit a trailing '-' to indicate all pages from this one to the end */ + if (*(str + 1)) + str++; + else { + *str = 0x00; + str = oldstr; + psubclass_data->FromToEnd = atoi(str); + } + } + /* str should now point to the last page number (we hope!) */ + psubclass_data->LastListPage = LastPage = atoi(str); + + psubclass_data->PageArraySize = (LastPage + 7) / 8; + psubclass_data->PageArray = gs_alloc_bytes(dev->memory->non_gc_memory, psubclass_data->PageArraySize, "array of pages selected"); + if (!psubclass_data->PageArray) { + psubclass_data->PageArraySize = 0; + return (gs_note_error(gs_error_VMerror)); + } + memset(psubclass_data->PageArray, 0x00, psubclass_data->PageArraySize); + + oldstr = ArgCopy = (char *)gs_alloc_bytes(dev->memory->non_gc_memory, strlen(PageList) + 1, "temp working string"); + if (!ArgCopy) { + gs_free_object(dev->memory->non_gc_memory, psubclass_data->PageArray, "free array of pages selected"); + psubclass_data->PageArray = 0; + psubclass_data->PageArraySize = 0; + return (gs_note_error(gs_error_VMerror)); + } + memcpy(ArgCopy, PageList, strlen(PageList) + 1); + do { + str = strchr(oldstr, ','); + if (str) + *str++ = 0x00; + /* oldstr now points to a null terminated string and is either a number or a number pair */ + workstr = strchr(oldstr, '-'); + if (workstr) { + *workstr++ = 0x00; + /* oldstr points to null terminated string of start, workstr to null terminated string of end */ + Page = atoi(oldstr) - 1; + if (Page < 0) + Page = 0; + + LastPage = atoi(workstr) - 1; + if (LastPage < 0) + LastPage = 0; + + for (i=Page; i<= LastPage;i++) { + if (i > psubclass_data->LastListPage - 1) { + emprintf(dev->memory, "\n**** Error : rangecheck processing PageList\n"); + return_error(gs_error_rangecheck); + } + byte = (int)(i / 8); + bit = i % 8; + c = 0x01 << bit; + ((char *)psubclass_data->PageArray)[byte] |= c; + } + } else { + Page = atoi(oldstr) - 1; + if (Page < 0) + Page = 0; + if (Page > psubclass_data->LastListPage - 1) { + emprintf(dev->memory, "\n**** Error : rangecheck processing PageList\n"); + return_error(gs_error_rangecheck); + } + byte = (int)(Page / 8); + bit = Page % 8; + c = 0x01 << bit; + ((char *)psubclass_data->PageArray)[byte] |= c; + } + oldstr = str; + } while (str); + gs_free_object(dev->memory->non_gc_memory, ArgCopy, "free temp working string"); + } + } + return 0; +} + +static int SkipPage(gx_device *dev) +{ + first_last_subclass_data *psubclass_data = dev->subclass_data; + int code; + + /* If we're disabled, don't skip any pages, and don't bother parsing the PageList */ + if (dev->DisablePageHandler) + return 0; + + /* If we haven't parsed any extant PageList, do it now */ + if (dev->PageList && !psubclass_data->ProcessedPageList) { + code = ParsePageList(dev, psubclass_data, dev->PageList->Pages); + if (code < 0) + return code; + psubclass_data->ProcessedPageList = true; + } + + if (psubclass_data->PageArray) { + if (psubclass_data->FromToEnd != 0 && psubclass_data->PageCount >= psubclass_data->FromToEnd - 1) + return 0; + else { + if (psubclass_data->PageCount > psubclass_data->LastListPage - 1) + return 1; + else { + int byte, bit; + char c; + + byte = (int)((psubclass_data->PageCount) / 8); + bit = (psubclass_data->PageCount) % 8; + c = 0x01 << bit; + if (((char *)psubclass_data->PageArray)[byte] & c) + return 0; + else + return 1; + } + } + } else { + if (psubclass_data->EvenOdd != none) { + /* Page count is 0 based so the even/odd tests are 'upside down' */ + if (psubclass_data->PageCount % 2 == 0) { + if (psubclass_data->EvenOdd == odd) + return 0; + else + return 1; + } else { + if (psubclass_data->EvenOdd == even) + return 0; + else + return 1; + } + } else { + if (psubclass_data->PageCount >= dev->FirstPage - 1) + if (!dev->LastPage || psubclass_data->PageCount <= dev->LastPage - 1) + return 0; + } + } + return 1; +} + +int flp_output_page(gx_device *dev, int num_copies, int flush) +{ + int code = 0; + + first_last_subclass_data *psubclass_data = dev->subclass_data; + + if (!SkipPage(dev)) + code = default_subclass_output_page(dev, num_copies, flush); + + psubclass_data->PageCount++; + + return code; +} + +int flp_close_device(gx_device *dev) +{ + first_last_subclass_data *psubclass_data = dev->subclass_data; + + if (psubclass_data->PageArraySize) + { + gs_free(dev->memory->non_gc_memory, psubclass_data->PageArray, 1, , "array of pages selected"); + psubclass_data->PageArray = 0; + psubclass_data->PageArraySize = 0; + } + + return default_subclass_close_device(dev); +} + +int flp_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_rectangle(dev, x, y, width, height, color); + + return 0; +} + +int flp_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_tile_rectangle(dev, tile, x, y, width, height, color0, color1, phase_x, phase_y); + + return 0; +} + +int flp_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_copy_mono(dev, data, data_x, raster, id, x, y, width, height, color0, color1); + + return 0; +} + +int flp_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id,\ + int x, int y, int width, int height) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_copy_color(dev, data, data_x, raster, id, x, y, width, height); + + return 0; +} + +int flp_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_draw_line(dev, x0, y0, x1, y1, color); + + return 0; +} + +int flp_get_bits(gx_device *dev, int y, byte *data, byte **actual_data) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_get_bits(dev, y, data, actual_data); + + return gx_default_get_bits(dev, y, data, actual_data); +} + +int +flp_put_params(gx_device * dev, gs_param_list * plist) +{ + bool temp_bool = false; + int code; + + code = param_read_bool(plist, "DisablePageHandler", &temp_bool); + if (code < 0) + return code; + if (code == 0) + dev->DisablePageHandler = temp_bool; + + code = default_subclass_put_params(dev, plist); + + if (code < 0) + return code; + + return code; +} + +int flp_get_alpha_bits(gx_device *dev, graphics_object_type type) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_get_alpha_bits(dev, type); + + return 0; +} + +int flp_copy_alpha(gx_device *dev, const byte *data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_copy_alpha(dev, data, data_x, raster, id, x, y, width, height, color, depth); + + return 0; +} + +int flp_get_band(gx_device *dev, int y, int *band_start) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_get_band(dev, y, band_start); + + return gx_default_get_band(dev, y, band_start); +} + +int flp_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, + const gx_tile_bitmap *texture, const gx_color_index *tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_copy_rop(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); + + return 0; +} + +int flp_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_fill_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); + + return 0; +} + +int flp_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_stroke_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); + + return 0; +} + +int flp_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, + const gx_drawing_color *pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path *pcpath) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_mask(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); + + return 0; +} + +int flp_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, + fixed ybot, fixed ytop, bool swap_axes, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); + + return 0; +} + +int flp_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_parallelogram(dev, px, py, ax, ay, bx, by, pdcolor, lop); + + return 0; +} + +int flp_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_triangle(dev, px, py, ax, ay, bx, by, pdcolor, lop); + + return 0; +} + +int flp_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop, + fixed adjustx, fixed adjusty) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); + + return 0; +} + +int flp_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, + gs_image_format_t format, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); + + return 0; +} + +int flp_image_data(gx_device *dev, gx_image_enum_common_t *info, const byte **planes, int data_x, + uint raster, int height) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_image_data(dev, info, planes, data_x, raster, height); + + return 0; +} + +int flp_end_image(gx_device *dev, gx_image_enum_common_t *info, bool draw_last) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_end_image(dev, info, draw_last); + + return 0; +} + +int flp_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); + + return 0; +} + +int flp_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, + const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); + + return 0; +} + +typedef struct flp_image_enum_s { + gx_image_enum_common; + int y; + int height; +} flp_image_enum; +gs_private_st_composite(st_flp_image_enum, flp_image_enum, "flp_image_enum", +flp_image_enum_enum_ptrs, flp_image_enum_reloc_ptrs); + +static ENUM_PTRS_WITH(flp_image_enum_enum_ptrs, flp_image_enum *pie) + (void)pie; /* Silence unused var warning */ + return ENUM_USING_PREFIX(st_gx_image_enum_common, 0); +ENUM_PTRS_END +static RELOC_PTRS_WITH(flp_image_enum_reloc_ptrs, flp_image_enum *pie) +{ + (void)pie; /* Silence unused var warning */ + RELOC_USING(st_gx_image_enum_common, vptr, size); +} +RELOC_PTRS_END + +static int +flp_image_plane_data(gx_image_enum_common_t * info, + const gx_image_plane_t * planes, int height, + int *rows_used) +{ + flp_image_enum *pie = (flp_image_enum *)info; + + pie->y += height; + *rows_used = height; + + if (pie->y < pie->height) + return 0; + return 1; +} + +static int +flp_image_end_image(gx_image_enum_common_t * info, bool draw_last) +{ + return 0; +} + +static const gx_image_enum_procs_t flp_image_enum_procs = { + flp_image_plane_data, + flp_image_end_image +}; + +int flp_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, + const gs_image_common_t *pic, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + flp_image_enum *pie; + const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic; + int num_components; + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); + + if (pic->type->index == 1) { + const gs_image_t *pim1 = (const gs_image_t *)pic; + + if (pim1->ImageMask) + num_components = 1; + else + num_components = gs_color_space_num_components(pim->ColorSpace); + } else { + num_components = gs_color_space_num_components(pim->ColorSpace); + } + + pie = gs_alloc_struct(memory, flp_image_enum, &st_flp_image_enum, + "flp_begin_image"); + if (pie == 0) + return_error(gs_error_VMerror); + memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */ + *pinfo = (gx_image_enum_common_t *) pie; + gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim, &flp_image_enum_procs, + (gx_device *)dev, num_components, pim->format); + pie->memory = memory; + pie->skipping = true; + pie->height = pim->Height; + pie->y = 0; + + return 0; +} + +int flp_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, + gs_get_bits_params_t *params, gs_int_rect **unread) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_get_bits_rectangle(dev, prect, params, unread); + + return gx_default_get_bits_rectangle(dev->child, prect, params, unread); +} + +int flp_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, + gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) +{ + int code = SkipPage(dev); + + /* The returned pointer 'pcdev' is a signal to the caller, if its not the same as the current + * device in the graphics state, then it gets set as the current device (basically if its not the + * same its a signal that we want to push a new compositor device to the head). So here we start + * by making sure that its set to the one in the graphics state. If the child device wants a + * compositor it will overwrite this value. + */ + *pcdev = pgs->device; + + if (code < 0) + return code; + if (!code) + return default_subclass_create_compositor(dev, pcdev, pcte, pgs, memory, cdev); + + return 0; +} + +/* Text processing (like images) works differently to other device + * methods. Instead of the interpreter calling a device method, only + * the 'begin' method is called, this creates a text enumerator which + * it fills in (in part with the routines for processing text) and returns + * to the interpreter. The interpreter then calls the methods defined in + * the text enumerator to process the text. + * Mad as a fish..... + */ + +/* For our purposes if we are handling the text its because we are not + * printing the page, so we cna afford to ignore all the text processing. + * A more complex device might need to define real handlers for these, and + * pass them on to the subclassed device. + */ +static text_enum_proc_process(flp_text_process); +static int +flp_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom) +{ + return 0; +} +int +flp_text_process(gs_text_enum_t *pte) +{ + return 0; +} +static bool +flp_text_is_width_only(const gs_text_enum_t *pte) +{ + return false; +} +static int +flp_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth) +{ + return 0; +} +static int +flp_text_set_cache(gs_text_enum_t *pte, const double *pw, + gs_text_cache_control_t control) +{ + return 0; +} +static int +flp_text_retry(gs_text_enum_t *pte) +{ + return 0; +} +static void +flp_text_release(gs_text_enum_t *pte, client_name_t cname) +{ + gx_default_text_release(pte, cname); +} + +static const gs_text_enum_procs_t flp_text_procs = { + flp_text_resync, flp_text_process, + flp_text_is_width_only, flp_text_current_width, + flp_text_set_cache, flp_text_retry, + flp_text_release +}; + +/* The device method which we do actually need to define. Either we are skipping the page, + * in which case we create a text enumerator with our dummy procedures, or we are leaving it + * up to the device, in which case we simply pass on the 'begin' method to the device. + */ +int flp_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, + gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gs_text_enum_t **ppte) +{ + flp_text_enum_t *penum; + int code; + + /* We don't want to simply ignore stringwidth for 2 reasons; + * firstly because following elelments may be positioned based on the value returned + * secondly because op_show_restore executes an unconditional grestore, assuming + * that a gsave has been done simply *because* its a tringwidth operation ! + */ + if (dev->DisablePageHandler || ((text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH) && pgs->text_rendering_mode != 3)) + /* Note that the high level devices *must* be given the opportunity to 'see' the + * stringwidth operation, or they won;t be able to cache the glyphs properly. + * So always pass stringwidth operations to the child. + */ + return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + + code = SkipPage(dev); + if (code < 0) + return code; + if (!code) + return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + + rc_alloc_struct_1(penum, flp_text_enum_t, &st_flp_text_enum, memory, + return_error(gs_error_VMerror), "gdev_flp_text_begin"); + penum->rc.free = rc_free_text_enum; + code = gs_text_enum_init((gs_text_enum_t *)penum, &flp_text_procs, + dev, pgs, text, font, path, pdcolor, pcpath, memory); + if (code < 0) { + gs_free_object(memory, penum, "gdev_flp_text_begin"); + return code; + } + *ppte = (gs_text_enum_t *)penum; + + return 0; +} + +int flp_begin_transparency_group(gx_device *dev, const gs_transparency_group_params_t *ptgp, + const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_begin_transparency_group(dev, ptgp, pbbox, pgs, mem); + + return 0; +} + +int flp_end_transparency_group(gx_device *dev, gs_gstate *pgs) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_end_transparency_group(dev, pgs); + + return 0; +} + +int flp_begin_transparency_mask(gx_device *dev, const gx_transparency_mask_params_t *ptmp, + const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_begin_transparency_mask(dev, ptmp, pbbox, pgs, mem); + + return 0; +} + +int flp_end_transparency_mask(gx_device *dev, gs_gstate *pgs) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_end_transparency_mask(dev, pgs); + + return 0; +} + +int flp_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_discard_transparency_layer(dev, pgs); + + return 0; +} + +int flp_pattern_manage(gx_device *dev, gx_bitmap_id id, + gs_pattern1_instance_t *pinst, pattern_manage_t function) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_pattern_manage(dev, id, pinst, function); + + return 0; +} + +int flp_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_rectangle_hl_color(dev, rect, pgs, pdcolor, pcpath); + + return 0; +} + +int flp_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, + int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, + int32_t cg_den) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); + + return 0; +} + +int flp_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const gs_fixed_point *p3, + const frac31 *c0, const frac31 *c1, + const frac31 *c2, const frac31 *c3) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); + + return 0; +} + +int flp_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2); + + return 0; +} + +int flp_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_fillpage(dev, pgs, pdevc); + + return 0; +} + +int flp_push_transparency_state(gx_device *dev, gs_gstate *pgs) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_push_transparency_state(dev, pgs); + + return 0; +} + +int flp_pop_transparency_state(gx_device *dev, gs_gstate *pgs) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_pop_transparency_state(dev, pgs); + + return 0; +} + +int flp_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y, + int width, int height, int row_stride, + int alpha_plane_index, int tag_plane_index) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_put_image(dev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); + + return 0; +} + +int flp_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, int plane_height) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_copy_planes(dev, data, data_x, raster, id, x, y, width, height, plane_height); + + return 0; +} + +int flp_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_strip_copy_rop2(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height); + + return 0; +} + +int flp_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, + const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_strip_tile_rect_devn(dev, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); + + return 0; +} + +int flp_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + const gx_drawing_color *pdcolor, int depth) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_copy_alpha_hl_color(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth); + + return 0; +} + +int flp_process_page(gx_device *dev, gx_process_page_options_t *options) +{ + int code = SkipPage(dev); + + if (code < 0) + return code; + if (!code) + return default_subclass_process_page(dev, options); + + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/gdevflp.h ghostscript-9.25~dfsg+1/base/gdevflp.h --- ghostscript-9.10~dfsg/base/gdevflp.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevflp.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,57 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Common definitions for "first/last page" device */ + +#ifndef gdevflp_INCLUDED +# define gdevflp_INCLUDED + +#ifndef gxdevice_INCLUDED +#include "gxdevice.h" +#endif + +typedef struct gx_device_s gx_device_flp; + +/* Initialize a first/last page device. */ +void gx_device_flp_init(gx_device_flp * dev); + +typedef enum {none, even, odd} flp_EOType; + +typedef struct { + subclass_common; + int PageCount; + int ProcessedPageList; + void *PageArray; + int PageArraySize; + int LastListPage; + int FromToEnd; + flp_EOType EvenOdd; +} first_last_subclass_data; + +typedef struct flp_text_enum_s { + gs_text_enum_common; +} flp_text_enum_t; +#define private_st_flp_text_enum()\ + extern_st(st_gs_text_enum);\ + gs_private_st_suffix_add0(st_flp_text_enum, flp_text_enum_t,\ + "flp_text_enum_t", flp_text_enum_enum_ptrs, flp_text_enum_reloc_ptrs,\ + st_gs_text_enum) + +extern_st(st_device_flp); +#define public_st_device_flp() /* in gdevbflp.c */\ + + +#endif /* gdevflp_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevhit.c ghostscript-9.25~dfsg+1/base/gdevhit.c --- ghostscript-9.10~dfsg/base/gdevhit.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevhit.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Hit detection device */ diff -Nru ghostscript-9.10~dfsg/base/gdevkrnlsclass.c ghostscript-9.25~dfsg+1/base/gdevkrnlsclass.c --- ghostscript-9.10~dfsg/base/gdevkrnlsclass.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevkrnlsclass.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,99 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#include "gx.h" +#include "gxdcolor.h" +#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and object filter */ + +/* If set to '1' ths forces all devices to be loaded, even if they won't do anything. + * This is useful for cluster testing that the very presence of a device doesn't + * break anything. + */ +#define FORCE_TESTING_SUBCLASSING 0 + +int install_internal_subclass_devices(gx_device **ppdev, int *devices_loaded) +{ + int code = 0; + gx_device *dev = (gx_device *)*ppdev, *saved; + +#if FORCE_TESTING_SUBCLASSING + if (!dev->PageHandlerPushed) { +#else + if (!dev->PageHandlerPushed && (dev->FirstPage != 0 || dev->LastPage != 0 || dev->PageList != 0)) { +#endif + code = gx_device_subclass(dev, (gx_device *)&gs_flp_device, sizeof(first_last_subclass_data)); + if (code < 0) + return code; + + saved = dev = dev->child; + + /* Open all devices *after* the new current device */ + do { + dev->is_open = true; + dev = dev->child; + }while(dev); + + dev = saved; + + /* Rewind to top device in chain */ + while(dev->parent) + dev = dev->parent; + + /* Note in all devices in chain that we have loaded the PageHandler */ + do { + dev->PageHandlerPushed = true; + dev = dev->child; + }while(dev); + + dev = saved; + if (devices_loaded) + *devices_loaded = true; + } +#if FORCE_TESTING_SUBCLASSING + if (!dev->ObjectHandlerPushed) { +#else + if (!dev->ObjectHandlerPushed && dev->ObjectFilter != 0) { +#endif + code = gx_device_subclass(dev, (gx_device *)&gs_obj_filter_device, sizeof(obj_filter_subclass_data)); + if (code < 0) + return code; + + saved = dev = dev->child; + + /* Open all devices *after* the new current device */ + do { + dev->is_open = true; + dev = dev->child; + }while(dev); + + dev = saved; + + /* Rewind to top device in chain */ + while(dev->parent) + dev = dev->parent; + + /* Note in all devices in chain that we have loaded the ObjectHandler */ + do { + dev->ObjectHandlerPushed = true; + dev = dev->child; + }while(dev); + + dev = saved; + if (devices_loaded) + *devices_loaded = true; + } + *ppdev = dev; + return code; +} diff -Nru ghostscript-9.10~dfsg/base/gdevkrnlsclass.h ghostscript-9.25~dfsg+1/base/gdevkrnlsclass.h --- ghostscript-9.10~dfsg/base/gdevkrnlsclass.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevkrnlsclass.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,31 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Common extern definitions for the "standard" subclass devices */ + +#ifndef gdev_subclass_dev_INCLUDED +# define gdev_subclass_dev_INCLUDED + +#include "gdevflp.h" +#include "gdevoflt.h" + +extern gx_device_obj_filter gs_obj_filter_device; + +extern gx_device_flp gs_flp_device; + +int install_internal_subclass_devices(gx_device **ppdev, int *devices_loaded); + +#endif /* gdev_subclass_dev_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevm16.c ghostscript-9.25~dfsg+1/base/gdevm16.c --- ghostscript-9.10~dfsg/base/gdevm16.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm16.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 16-bit-per-pixel "memory" (stored bitmap) device */ @@ -74,7 +74,7 @@ int x, int y, int w, int h, gx_color_index color) { gx_device_memory * const mdev = (gx_device_memory *)dev; -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN const ushort color16 = (ushort)color; #else const ushort color16 = (ushort)((color << 8) | (color >> 8)); @@ -118,7 +118,7 @@ gx_color_index zero, gx_color_index one) { gx_device_memory * const mdev = (gx_device_memory *)dev; -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN const ushort zero16 = (ushort)zero; const ushort one16 = (ushort)one; #else diff -Nru ghostscript-9.10~dfsg/base/gdevm1.c ghostscript-9.25~dfsg+1/base/gdevm1.c --- ghostscript-9.10~dfsg/base/gdevm1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Monobit "memory" (stored bitmap) device */ @@ -270,42 +270,44 @@ } } else { /* Use Rop run */ - rop_get_run_op(&ropper, rop, 1, 0); - /* Loop over scan lines. */ - for (; line_count-- > 0; drow += draster, srow += sraster) { - rop_set_s_bitmap_subbyte(&ropper, srow, sbit); - rop_run_subbyte(&ropper, drow, dbit, width); + if (rop_get_run_op(&ropper, rop, 1, 0)) { + /* Loop over scan lines. */ + for (; line_count-- > 0; drow += draster, srow += sraster) { + rop_set_s_bitmap_subbyte(&ropper, srow, sbit); + rop_run_subbyte(&ropper, drow, dbit, width); + } + rop_release_run_op(&ropper); } - rop_release_run_op(&ropper); } } else if (textures->rep_width > 32) { /* Use Rop run */ - rop_get_run_op(&ropper, rop, 1, 0); - /* Loop over scan lines. */ - for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { - int sx = sourcex; - int dx = x; - int w = width; - const byte *trow = textures->data + (ty % textures->rep_height) * traster; - int xoff = x_offset(phase_x, ty, textures); - int nw; - int tx = (dx + xoff) % textures->rep_width; - - /* Loop over (horizontal) copies of the tile. */ - for (; w > 0; sx += nw, dx += nw, w -= nw, tx = 0) { - int dbit = dx & 7; - int sbit = sx & 7; - int tbit = tx & 7; - byte *dptr = drow + (dx >> 3); - const byte *sptr = srow + (sx >> 3); - const byte *tptr = trow + (tx >> 3); - nw = min(w, textures->size.x - tx); - rop_set_s_bitmap_subbyte(&ropper, sptr, sbit); - rop_set_t_bitmap_subbyte(&ropper, tptr, tbit); - rop_run_subbyte(&ropper, dptr, dbit, nw); + if (rop_get_run_op(&ropper, rop, 1, 0)) { + /* Loop over scan lines. */ + for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { + int sx = sourcex; + int dx = x; + int w = width; + const byte *trow = textures->data + (ty % textures->rep_height) * traster; + int xoff = x_offset(phase_x, ty, textures); + int nw; + int tx = (dx + xoff) % textures->rep_width; + + /* Loop over (horizontal) copies of the tile. */ + for (; w > 0; sx += nw, dx += nw, w -= nw, tx = 0) { + int dbit = dx & 7; + int sbit = sx & 7; + int tbit = tx & 7; + byte *dptr = drow + (dx >> 3); + const byte *sptr = srow + (sx >> 3); + const byte *tptr = trow + (tx >> 3); + nw = min(w, textures->size.x - tx); + rop_set_s_bitmap_subbyte(&ropper, sptr, sbit); + rop_set_t_bitmap_subbyte(&ropper, tptr, tbit); + rop_run_subbyte(&ropper, dptr, dbit, nw); + } } + rop_release_run_op(&ropper); } - rop_release_run_op(&ropper); } else if (srow == NULL) { /* Do it the old, 'slow' way. rop runs of less than 1 word are * not likely to be a win with rop_run. */ @@ -497,7 +499,7 @@ */ /* cshift = chunk_bits - shift. */ #undef chunk -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define chunk uint # define CFETCH_RIGHT(cptr, shift, cshift)\ (CFETCH_ALIGNED(cptr) >> shift) @@ -699,7 +701,7 @@ #undef CINVERT #define CINVERT(bits) (bits) /* pre-inverted here */ -#if arch_is_big_endian /* no byte swapping */ +#if ARCH_IS_BIG_ENDIAN /* no byte swapping */ # define WRITE_1TO2(wr_op)\ for ( ; ; )\ { register uint bits = CFETCH_ALIGNED(bptr) ^ invert;\ @@ -961,7 +963,7 @@ set_mono_left_mask(mask, dbit); set_mono_right_mask(rmask, wleft); -#if arch_is_big_endian /* no byte swapping */ +#if ARCH_IS_BIG_ENDIAN /* no byte swapping */ #undef CINVERT #define CINVERT(bits) (bits) /* pre-inverted here */ for (;;) { @@ -1077,7 +1079,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ static dev_proc_copy_mono(mem1_word_copy_mono); @@ -1134,4 +1136,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm24.c ghostscript-9.25~dfsg+1/base/gdevm24.c --- ghostscript-9.10~dfsg/base/gdevm24.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm24.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 24-bit-per-pixel "memory" (stored bitmap) device */ @@ -19,7 +19,6 @@ #include "gxdevice.h" #include "gxdevmem.h" /* semi-public definitions */ #include "gdevmem.h" /* private definitions */ -#include "vdtrace.h" #define mem_true24_strip_copy_rop mem_gray8_rgb24_strip_copy_rop @@ -83,7 +82,7 @@ *(bits32 *)(ptr) = (wxyz) /* Load the 3-word 24-bit-color cache. */ /* Free variables: [m]dev, rgbr, gbrg, brgb. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define set_color24_cache(crgb, r, g, b)\ mdev->color24.rgbr = rgbr = ((bits32)(crgb) << 8) | (r),\ mdev->color24.gbrg = gbrg = (rgbr << 8) | (g),\ @@ -374,11 +373,9 @@ if (sbyte & bit) { if (one != gx_no_color_index) { put3(pptr, r1, g1, b1); - vd_pixel(int2fixed((pptr - mdev->line_ptrs[y]) / 3), int2fixed(y), RGB(r1, g1, b1)); } } else { put3(pptr, r0, g0, b0); - vd_pixel(int2fixed((pptr - mdev->line_ptrs[y]) / 3), int2fixed(y), RGB(r0, g0, b0)); } pptr += 3; @@ -508,20 +505,31 @@ for (sx = sourcex; sx < sourcex + w; ++sx, pptr += 3) { int alpha2, alpha; - if (depth == 2) /* map 0 - 3 to 0 - 15 */ + switch(depth) + { + case 2: /* map 0 - 3 to 0 - 255 */ alpha = - ((line[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5; - else - alpha2 = line[sx >> 1], - alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4); - if (alpha == 15) { /* Just write the new color. */ + ((line[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85; + break; + case 4: + alpha2 = line[sx >> 1]; + alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4) * 17; + break; + case 8: + alpha = line[sx]; + break; + default: + return_error(gs_error_rangecheck); + } + if (alpha == 255) { /* Just write the new color. */ put3(pptr, r, g, b); } else if (alpha != 0) { /* Blend RGB values. */ -#define make_shade(old, clr, alpha, amax) \ - (old) + (((int)(clr) - (int)(old)) * (alpha) / (amax)) - pptr[0] = make_shade(pptr[0], r, alpha, 15); - pptr[1] = make_shade(pptr[1], g, alpha, 15); - pptr[2] = make_shade(pptr[2], b, alpha, 15); + alpha += alpha>>7; +#define make_shade(old, clr, alpha) \ + ((((old)<<8) + ((int)(clr) - (int)(old)) * (alpha))>>8) + pptr[0] = make_shade(pptr[0], r, alpha); + pptr[1] = make_shade(pptr[1], g, alpha); + pptr[2] = make_shade(pptr[2], b, alpha); #undef make_shade } } @@ -536,7 +544,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem24_word_copy_mono, mem24_word_copy_color, mem24_word_fill_rectangle); @@ -609,4 +617,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm2.c ghostscript-9.25~dfsg+1/base/gdevm2.c --- ghostscript-9.10~dfsg/base/gdevm2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 2-bit-per-pixel "memory" (stored bitmap) device */ @@ -170,7 +170,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rectangle); @@ -246,4 +246,4 @@ return code; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm32.c ghostscript-9.25~dfsg+1/base/gdevm32.c --- ghostscript-9.10~dfsg/base/gdevm32.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm32.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 32-bit-per-pixel "memory" (stored bitmap) device */ @@ -44,7 +44,7 @@ #define color_swap_bytes(color)\ ((((color) >> 24) & 0xff) + (((color) >> 8) & 0xff00) +\ (((color) & 0xff00) << 8) + ((color) << 24)) -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define arrange_bytes(color) (color) #else # define arrange_bytes(color) color_swap_bytes(color) @@ -241,7 +241,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle); @@ -293,4 +293,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm40.c ghostscript-9.25~dfsg+1/base/gdevm40.c --- ghostscript-9.10~dfsg/base/gdevm40.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm40.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 40-bit-per-pixel "memory" (stored bitmap) device */ @@ -72,7 +72,7 @@ *(bits32 *)(ptr) = (wxyz) /* Load the 5-word 40-bit-color cache. */ /* Free variables: [m]dev, abcd, bcde, cdea, deab, earc. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define set_color40_cache(color, a, b, c, d, e)\ mdev->color40.abcd = abcd = (color) >> 8, \ mdev->color40.bcde = bcde = (abcd << 8) | (e),\ @@ -409,7 +409,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem40_word_copy_mono, mem40_word_copy_color, mem40_word_fill_rectangle); @@ -482,4 +482,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm48.c ghostscript-9.25~dfsg+1/base/gdevm48.c --- ghostscript-9.10~dfsg/base/gdevm48.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm48.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 48-bit-per-pixel "memory" (stored bitmap) device */ @@ -73,7 +73,7 @@ *(bits32 *)(ptr) = (wxyz) /* Load the 3-word 48-bit-color cache. */ /* Free variables: [m]dev, abcd, bcde, cdea, deab, earc. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define set_color48_cache(color, a, b, c, d, e, f)\ mdev->color48.abcd = abcd = (color) >> 16, \ mdev->color48.cdef = cdef = (abcd << 16) | ((e) <<8) | (f),\ @@ -378,7 +378,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem48_word_copy_mono, mem48_word_copy_color, mem48_word_fill_rectangle); @@ -451,4 +451,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm4.c ghostscript-9.25~dfsg+1/base/gdevm4.c --- ghostscript-9.10~dfsg/base/gdevm4.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm4.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 4-bit-per-pixel "memory" (stored bitmap) device */ @@ -229,7 +229,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem4_word_copy_mono, mem4_word_copy_color, mem4_word_fill_rectangle); @@ -303,4 +303,4 @@ return code; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm56.c ghostscript-9.25~dfsg+1/base/gdevm56.c --- ghostscript-9.10~dfsg/base/gdevm56.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm56.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 56-bit-per-pixel "memory" (stored bitmap) device */ @@ -75,7 +75,7 @@ *(bits32 *)(ptr) = (wxyz) /* Load the 7-word 56-bit-color cache. */ /* Free variables: [m]dev, abcd, bcde, cdea, deab, earc. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define set_color56_cache(color, a, b, c, d, e, f, g)\ mdev->color56.abcd = abcd = (color) >> 24, \ mdev->color56.bcde = bcde = (abcd << 8) | (e),\ @@ -433,7 +433,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem56_word_copy_mono, mem56_word_copy_color, mem56_word_fill_rectangle); @@ -506,4 +506,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm64.c ghostscript-9.25~dfsg+1/base/gdevm64.c --- ghostscript-9.10~dfsg/base/gdevm64.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm64.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 64-bit-per-pixel "memory" (stored bitmap) device */ @@ -61,7 +61,7 @@ #define put8(ptr, abcd, efgh)\ (ptr)[0] = abcd, (ptr)[1] = efgh /* Free variables: [m]dev, abcd, degh. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN /* Unpack a color into 32 bit chunks. */ # define declare_unpack_color(abcd, efgh, color)\ bits32 abcd = (bits32)((color) >> 32);\ @@ -336,7 +336,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem64_word_copy_mono, mem64_word_copy_color, mem64_word_fill_rectangle); @@ -409,4 +409,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevm8.c ghostscript-9.25~dfsg+1/base/gdevm8.c --- ghostscript-9.10~dfsg/base/gdevm8.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevm8.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* 8-bit-per-pixel "memory" (stored bitmap) device */ @@ -121,6 +121,7 @@ goto enter7; } do { + sbyte = *sptr++; /* In true gs fashion: Do not be tempted to replace the * following lines with: *pptr++ = (condition ? b1 : b0); * without good reason as gcc on ARM takes 4 cycles to do that @@ -133,11 +134,12 @@ enter5: if (sbyte & 4) *pptr++ = b1; else *pptr++ = b0; enter6: if (sbyte & 2) *pptr++ = b1; else *pptr++ = b0; enter7: if (sbyte & 1) *pptr++ = b1; else *pptr++ = b0; - sbyte = *sptr++; count -= 8; } while (count >= 0); bit = 128; count += 8; + if (count > 0) + sbyte = *sptr++; } else { /* Less than 1 byte to do */ bit = 0x80>>first_bit; @@ -321,7 +323,7 @@ /* Note that on a big-endian machine, this is the same as the */ /* standard byte-oriented-device. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* Procedures */ declare_mem_procs(mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle); @@ -393,4 +395,4 @@ return 0; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ diff -Nru ghostscript-9.10~dfsg/base/gdevmem.c ghostscript-9.25~dfsg+1/base/gdevmem.c --- ghostscript-9.10~dfsg/base/gdevmem.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmem.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Generic "memory" (stored bitmap) device */ @@ -49,8 +49,8 @@ int y; int h = mptr->height; - if (mptr->num_planes > 0) - h *= mptr->num_planes; + if (mptr->is_planar) + h *= mptr->color_info.num_components; RELOC_PTR(gx_device_memory, base); reloc = base_old - mptr->base; @@ -133,6 +133,9 @@ int bits_per_pixel = dev->color_info.depth; const gx_device_memory *mdproto; + if (dev->is_planar) + bits_per_pixel /= dev->color_info.num_components; + mdproto = gdev_mem_device_for_bits(bits_per_pixel); if (mdproto != 0 && dev_proc(dev, draw_thin_line) == dev_proc(mdproto, draw_thin_line)) return true; @@ -173,16 +176,16 @@ /* Forward the color mapping operations to the target. */ gx_device_forward_color_procs((gx_device_forward *) dev); gx_device_copy_color_procs((gx_device *)dev, target); + dev->color_info.separable_and_linear = target->color_info.separable_and_linear; dev->cached_colors = target->cached_colors; dev->graphics_type_tag = target->graphics_type_tag; /* initialize to same as target */ /* Do a copy of put_image since it needs the source buffer */ -#define COPY_PROC(p) set_dev_proc(dev, p, target->procs.p) - COPY_PROC(put_image); -#undef COPY_PROC + set_dev_proc(dev, put_image, target->procs.put_image); + set_dev_proc(dev, dev_spec_op, gx_default_dev_spec_op); } if (dev->color_info.depth == 1) { gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int k; + uchar k; if (target != 0) { for (k = 0; k < target->color_info.num_components; k++) { @@ -278,6 +281,9 @@ set_dev_proc(pdev, get_page_device, gx_default_get_page_device); gx_device_set_target((gx_device_forward *)pdev, target); + /* Should this be forwarding, monochrome profile, or not set? MJV. */ + set_dev_proc(pdev, get_profile, gx_forward_get_profile); + gdev_mem_mono_set_inverted(pdev, true); check_device_separable((gx_device *)pdev); gx_device_fill_in_procs((gx_device *)pdev); @@ -295,12 +301,14 @@ mem, true); set_dev_proc(dev, get_page_device, gx_default_get_page_device); gx_device_set_target((gx_device_forward *)dev, target); + dev->raster = gx_device_raster((gx_device *)dev, 1); gdev_mem_mono_set_inverted(dev, true); check_device_separable((gx_device *)dev); gx_device_fill_in_procs((gx_device *)dev); - /* Should this be forwarding or monochrome profile? */ + /* Should this be forwarding, monochrome profile, or not set? MJV */ set_dev_proc(dev, get_profile, gx_forward_get_profile); set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + set_dev_proc(dev, dev_spec_op, gx_default_dev_spec_op); /* initialize to same tag as target */ dev->graphics_type_tag = target ? target->graphics_type_tag : GS_UNKNOWN_TAG; } @@ -330,7 +338,7 @@ int gdev_mem_bits_size(const gx_device_memory * dev, int width, int height, ulong *psize) { - int num_planes = dev->num_planes; + int num_planes = dev->is_planar ? dev->color_info.num_components : 0; gx_render_plane_t plane1; const gx_render_plane_t *planes; ulong size; @@ -341,17 +349,20 @@ else planes = &plane1, plane1.depth = dev->color_info.depth, num_planes = 1; for (size = 0, pi = 0; pi < num_planes; ++pi) - size += bitmap_raster(width * planes[pi].depth); + size += bitmap_raster_pad_align(width * planes[pi].depth, dev->pad, dev->log2_align_mod); if (height != 0) if (size > (max_ulong - ARCH_ALIGN_PTR_MOD) / (ulong)height) return_error(gs_error_VMerror); - *psize = ROUND_UP(size * height, ARCH_ALIGN_PTR_MOD); + size = ROUND_UP(size * height, ARCH_ALIGN_PTR_MOD); + if (dev->log2_align_mod > log2_align_bitmap_mod) + size += 1<log2_align_mod; + *psize = size; return 0; } ulong gdev_mem_line_ptrs_size(const gx_device_memory * dev, int width, int height) { - return (ulong)height * sizeof(byte *) * max(dev->num_planes, 1); + return (ulong)height * sizeof(byte *) * (dev->is_planar ? dev->color_info.num_components : 1); } int gdev_mem_data_size(const gx_device_memory * dev, int width, int height, ulong *psize) @@ -385,15 +396,15 @@ * is only an estimate, we may exceed our desired buffer space while * processing the file. */ - max_height = size / (bitmap_raster(width - * dev->color_info.depth + ESTIMATED_PDF14_ROW_SPACE(width, dev->color_info.num_components)) - + sizeof(byte *) * max(dev->num_planes, 1)); + max_height = size / (bitmap_raster_pad_align(width + * dev->color_info.depth + ESTIMATED_PDF14_ROW_SPACE(width, dev->color_info.num_components), + dev->pad, dev->log2_align_mod) + sizeof(byte *) * (dev->is_planar ? dev->color_info.num_components : 1)); height = (int)min(max_height, max_int); } else { /* For non PDF 1.4 transparency, we can do an exact calculation */ max_height = size / - (bitmap_raster(width * dev->color_info.depth) + - sizeof(byte *) * max(dev->num_planes, 1)); + (bitmap_raster_pad_align(width * dev->color_info.depth, dev->pad, dev->log2_align_mod) + + sizeof(byte *) * (dev->is_planar ? dev->color_info.num_components : 1)); height = (int)min(max_height, max_int); /* * Because of alignment rounding, the just-computed height might @@ -417,7 +428,7 @@ gx_device_memory *const mdev = (gx_device_memory *)dev; /* Check that we aren't trying to open a planar device as chunky. */ - if (mdev->num_planes) + if (mdev->is_planar) return_error(gs_error_rangecheck); return gdev_mem_open_scan_lines(mdev, dev->height); } @@ -430,6 +441,7 @@ if (setup_height < 0 || setup_height > mdev->height) return_error(gs_error_rangecheck); if (mdev->bitmap_memory != 0) { + int align; /* Allocate the data now. */ if (gdev_mem_bitmap_size(mdev, &size) < 0) return_error(gs_error_VMerror); @@ -440,13 +452,22 @@ "mem_open"); if (mdev->base == 0) return_error(gs_error_VMerror); +#ifdef PACIFY_VALGRIND + /* If we end up writing the bitmap to the clist, we can get valgrind errors + * because we write and read the padding at the end of each raster line. + * Easiest to set the entire block. + */ + memset(mdev->base, 0x00, size); +#endif + align = 1<log2_align_mod; + mdev->base += (-(int)(intptr_t)mdev->base) & (align-1); mdev->foreign_bits = false; } else if (mdev->line_pointer_memory != 0) { /* Allocate the line pointers now. */ mdev->line_ptrs = (byte **) gs_alloc_byte_array(mdev->line_pointer_memory, mdev->height, - sizeof(byte *) * max(mdev->num_planes, 1), + sizeof(byte *) * (mdev->is_planar ? mdev->color_info.num_components : 1), "gdev_mem_open_scan_lines"); if (mdev->line_ptrs == 0) return_error(gs_error_VMerror); @@ -454,10 +475,18 @@ line_pointers_adjacent = false; } if (line_pointers_adjacent) { - gdev_mem_bits_size(mdev, mdev->width, mdev->height, &size); + int code; + + if (mdev->base == 0) + return_error(gs_error_rangecheck); + + code = gdev_mem_bits_size(mdev, mdev->width, mdev->height, &size); + if (code < 0) + return code; + mdev->line_ptrs = (byte **)(mdev->base + size); } - mdev->raster = gdev_mem_raster(mdev); /* RJW: Wrong for planar */ + mdev->raster = gx_device_raster((gx_device *)mdev, 1); return gdev_mem_set_line_ptrs(mdev, NULL, 0, NULL, setup_height); } /* @@ -470,28 +499,46 @@ gdev_mem_set_line_ptrs(gx_device_memory * mdev, byte * base, int raster, byte **line_ptrs, int setup_height) { - int num_planes = mdev->num_planes; - gx_render_plane_t plane1; - const gx_render_plane_t *planes; - byte **pline = - (line_ptrs ? (mdev->line_ptrs = line_ptrs) : mdev->line_ptrs); - byte *data = - (base ? (mdev->raster = raster, mdev->base = base) : - (raster = mdev->raster, mdev->base)); + int num_planes = (mdev->is_planar ? mdev->color_info.num_components : 0); + byte **pline; + byte *data; int pi; + /* If we are supplied with line_ptrs, then assume that we don't have + * any already, and take them on. */ + if (line_ptrs) + mdev->line_ptrs = line_ptrs; + pline = mdev->line_ptrs; + + /* If we are supplied a base, then we are supplied a raster. Assume that + * we don't have any buffer already, and take these on. Assume that the + * base has been allocated with sufficient padding to allow for any + * alignment required. */ + if (base == NULL) { + base = mdev->base; + raster = mdev->raster; + } else { + mdev->base = base; + mdev->raster = raster; + } + + /* Now, pad and align as required. */ + if (mdev->log2_align_mod > log2_align_bitmap_mod) { + int align = 1<log2_align_mod; + align = (-(int)(intptr_t)base) & (align-1); + data = base + align; + } else { + data = mdev->base; + } + if (num_planes) { if (base && !mdev->plane_depth) return_error(gs_error_rangecheck); - planes = mdev->planes; } else { - planes = &plane1; - plane1.depth = mdev->color_info.depth; num_planes = 1; } for (pi = 0; pi < num_planes; ++pi) { - int raster = bitmap_raster(mdev->width * planes[pi].depth); byte **pptr = pline; byte **pend = pptr + setup_height; byte *scan_line = data; @@ -562,6 +609,8 @@ GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE; return_error(gs_error_rangecheck); } + if (mdev->line_ptrs == 0x00) + return_error(gs_error_rangecheck); if ((w <= 0) | (h <= 0)) { if ((w | h) < 0) return_error(gs_error_rangecheck); @@ -591,7 +640,7 @@ } } -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN /* * Swap byte order in a rectangular subset of a bitmap. If store = true, @@ -664,6 +713,10 @@ } bit_x = x * dev->color_info.depth; bit_w = w * dev->color_info.depth; + + if(mdev->line_ptrs == 0x00) + return_error(gs_error_rangecheck); + src = scan_line_base(mdev, y); mem_swap_byte_rect(src, dev_raster, bit_x, bit_w, h, false); code = mem_get_bits_rectangle(dev, prect, params, unread); @@ -671,7 +724,7 @@ return code; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ /* Map a r-g-b color to a color index for a mapped color memory device */ /* (2, 4, or 8 bits per pixel.) */ diff -Nru ghostscript-9.10~dfsg/base/gdevmem.h ghostscript-9.25~dfsg+1/base/gdevmem.h --- ghostscript-9.10~dfsg/base/gdevmem.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmem.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Private definitions for memory devices. */ @@ -91,7 +91,7 @@ dev_proc_open_device(mem_open); dev_proc_get_bits_rectangle(mem_get_bits_rectangle); /* The following are for word-oriented devices. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define mem_word_get_bits_rectangle mem_get_bits_rectangle #else dev_proc_get_bits_rectangle(mem_word_get_bits_rectangle); @@ -248,7 +248,7 @@ dev_proc_strip_copy_rop(mem_gray_strip_copy_rop); dev_proc_strip_copy_rop(mem_gray8_rgb24_strip_copy_rop); -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define mem_mono_word_device mem_mono_device # define mem_mapped2_word_device mem_mapped2_device # define mem_mapped4_word_device mem_mapped4_device diff -Nru ghostscript-9.10~dfsg/base/gdevmpla.c ghostscript-9.25~dfsg+1/base/gdevmpla.c --- ghostscript-9.10~dfsg/base/gdevmpla.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmpla.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Any-depth planar "memory" (stored bitmap) device */ @@ -42,23 +42,16 @@ static dev_proc_fill_rectangle_hl_color(mem_planar_fill_rectangle_hl_color); static dev_proc_put_image(mem_planar_put_image); -/* It's a bit nasty to have to fork the planar dev_spec_op like this, but - * the forwarding nature of the device means that the function pointer test - * for the map_cmyk_color call fails if we let it fall through to the - * default device. */ static int mem_planar_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) { cmm_dev_profile_t *dev_profile; - gx_device_memory *mdev = (gx_device_memory *)pdev; - if (dev_spec_op == gxdso_is_native_planar) - return mdev->plane_depth; if (dev_spec_op == gxdso_supports_devn) { dev_proc(pdev, get_profile)(pdev, &dev_profile); if (dev_profile != NULL && dev_profile->supports_devn && - pdev->procs.fill_rectangle_hl_color == mem_planar_fill_rectangle_hl_color) + dev_proc(pdev, fill_rectangle_hl_color) == mem_planar_fill_rectangle_hl_color) return 1; } return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); @@ -68,10 +61,6 @@ mem_planar_dev_spec_op_cmyk4(gx_device *pdev, int dev_spec_op, void *data, int size) { - gx_device_memory *mdev = (gx_device_memory *)pdev; - - if (dev_spec_op == gxdso_is_native_planar) - return mdev->plane_depth; if (dev_spec_op == gxdso_is_std_cmyk_1bit) return 1; return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); @@ -97,7 +86,7 @@ int pi; const gx_device_memory *mdproto = gdev_mem_device_for_bits(mdev->color_info.depth); - if (num_planes < 1 || num_planes > GX_DEVICE_COLOR_MAX_COMPONENTS) + if (num_planes < 1 || num_planes > GX_DEVICE_COLOR_MAX_COMPONENTS || num_planes != mdev->color_info.num_components) return_error(gs_error_rangecheck); for (pi = 0, total_depth = 0; pi < num_planes; ++pi) { int shift = planes[pi].shift; @@ -121,11 +110,17 @@ } if (total_depth > mdev->color_info.depth) return_error(gs_error_rangecheck); - mdev->num_planes = num_planes; + mdev->is_planar = 1; memcpy(mdev->planes, planes, num_planes * sizeof(planes[0])); mdev->plane_depth = same_depth; /* Change the drawing procedures. */ set_dev_proc(mdev, open_device, mem_planar_open); + /* Regardless of how many planes we are using, always let the + * device know how to handle hl_color. Even if we spot that we + * can get away with a normal device, our callers may want to + * feed us single component devn data. */ + set_dev_proc(mdev, fill_rectangle_hl_color, + mem_planar_fill_rectangle_hl_color); if (num_planes == 1) { /* For 1 plane, just use a normal device */ set_dev_proc(mdev, fill_rectangle, dev_proc(mdproto, fill_rectangle)); @@ -141,9 +136,7 @@ four planes then use the high level color filling procedure. Also make use of the put_image operation to go from the pdf14 device directly to the planar buffer. */ - if (mdev->num_planes >= 4) { - set_dev_proc(mdev, fill_rectangle_hl_color, - mem_planar_fill_rectangle_hl_color); + if (num_planes >= 4) { set_dev_proc(mdev, put_image, mem_planar_put_image); } set_dev_proc(mdev, fill_rectangle, mem_planar_fill_rectangle); @@ -151,13 +144,13 @@ set_dev_proc(mdev, copy_mono, mem_planar_copy_mono); set_dev_proc(mdev, dev_spec_op, mem_planar_dev_spec_op); if ((mdev->color_info.depth == 24) && - (mdev->num_planes == 3) && + (num_planes == 3) && (mdev->planes[0].depth == 8) && (mdev->planes[0].shift == 16) && (mdev->planes[1].depth == 8) && (mdev->planes[1].shift == 8) && (mdev->planes[2].depth == 8) && (mdev->planes[2].shift == 0)) set_dev_proc(mdev, copy_color, mem_planar_copy_color_24to8); else if ((mdev->color_info.depth == 4) && - (mdev->num_planes == 4) && + (num_planes == 4) && (mdev->planes[0].depth == 1) && (mdev->planes[0].shift == 3) && (mdev->planes[1].depth == 1) && (mdev->planes[1].shift == 2) && (mdev->planes[2].depth == 1) && (mdev->planes[2].shift == 1) && @@ -167,13 +160,13 @@ } else set_dev_proc(mdev, copy_color, mem_planar_copy_color); set_dev_proc(mdev, copy_alpha, gx_default_copy_alpha); - set_dev_proc(mdev, copy_planes, mem_planar_copy_planes); set_dev_proc(mdev, strip_tile_rectangle, mem_planar_strip_tile_rectangle); set_dev_proc(mdev, strip_tile_rect_devn, mem_planar_strip_tile_rect_devn); set_dev_proc(mdev, strip_copy_rop, mem_planar_strip_copy_rop); set_dev_proc(mdev, strip_copy_rop2, mem_planar_strip_copy_rop2); set_dev_proc(mdev, get_bits_rectangle, mem_planar_get_bits_rectangle); } + set_dev_proc(mdev, copy_planes, mem_planar_copy_planes); return 0; } @@ -184,7 +177,7 @@ gx_device_memory *const mdev = (gx_device_memory *)dev; /* Check that we aren't trying to open a chunky device as planar. */ - if (mdev->num_planes == 0) + if (!dev->is_planar) return_error(gs_error_rangecheck); return gdev_mem_open_scan_lines(mdev, dev->height); } @@ -210,7 +203,9 @@ * at least 2 line pointers to use. Otherwise, we fall back to the old * method. */ -/* FIXME: Find a nicer way of calculating raster. */ +/* FIXME: Find a nicer way of calculating raster. This is only required if + * we allow the plane_depth to vary per plane, and the rest of the code + * assumes that it never does. This can probably be simplified now. */ #define MEM_SET_PARAMS(mdev, plane_depth)\ (mdev->color_info.depth = plane_depth, /* maybe not needed */\ mdev->base = mdev->line_ptrs[0],\ @@ -220,25 +215,61 @@ mdev->base = msp.base,\ mdev->line_ptrs = msp.line_ptrs) +static int +put_image_copy_planes(gx_device * dev, const byte **base_ptr, int sourcex, + int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + int plane_depth; + mem_save_params_t save; + const gx_device_memory *mdproto; + int code = 0; + uchar plane; + + MEM_SAVE_PARAMS(mdev, save); + for (plane = 0; plane < mdev->color_info.num_components; plane++) + { + const byte *base = base_ptr[plane]; + plane_depth = mdev->planes[plane].depth; + mdproto = gdev_mem_device_for_bits(plane_depth); + if (base == NULL) { + /* Blank the plane */ + code = dev_proc(mdproto, fill_rectangle)(dev, x, y, w, h, + (gx_color_index)(dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ? 0 : -1)); + } else if (plane_depth == 1) + code = dev_proc(mdproto, copy_mono)(dev, base, sourcex, sraster, id, + x, y, w, h, + (gx_color_index)0, + (gx_color_index)1); + else + code = dev_proc(mdproto, copy_color)(dev, base, sourcex, sraster, + id, x, y, w, h); + mdev->line_ptrs += mdev->height; + } + MEM_RESTORE_PARAMS(mdev, save); + return code; +} + /* Put image command for copying the planar image buffers with or without alpha directly to the device buffer */ static int -mem_planar_put_image(gx_device *pdev, const byte *buffer, int num_chan, int xstart, +mem_planar_put_image(gx_device *pdev, const byte **buffers, int num_chan, int xstart, int ystart, int width, int height, int row_stride, - int plane_stride, int alpha_plane_index, int tag_plane_index) + int alpha_plane_index, int tag_plane_index) { gx_device_memory * const mdev = (gx_device_memory *)pdev; /* We don't want alpha, return 0 to ask for the pdf14 device to do the alpha composition. We also do not want chunky data coming in or to deal with planar devices that are not 8 bit per colorant */ - if (alpha_plane_index != 0 || plane_stride == 0 || + if (alpha_plane_index != 0 || mdev->planes[0].depth != 8) return 0; - (*dev_proc(pdev, copy_planes)) (pdev, buffer, 0, row_stride, - gx_no_bitmap_id, xstart, ystart, - width, height, plane_stride/row_stride); + put_image_copy_planes(pdev, buffers, 0, row_stride, + gx_no_bitmap_id, xstart, ystart, + width, height); /* we used all of the data */ return height; } @@ -247,12 +278,12 @@ devices. (e.g. tiffsep, psdcmyk) */ static int mem_planar_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_memory * const mdev = (gx_device_memory *)dev; mem_save_params_t save; - int pi; + uchar pi; int x = fixed2int(rect->p.x); int y = fixed2int(rect->p.y); int w = fixed2int(rect->q.x) - x; @@ -264,7 +295,7 @@ return gx_fill_rectangle_device_rop( x, y, w, h, pdcolor, dev, lop_default); } MEM_SAVE_PARAMS(mdev, save); - for (pi = 0; pi < mdev->num_planes; ++pi) { + for (pi = 0; pi < mdev->color_info.num_components; ++pi) { int plane_depth = mdev->planes[pi].depth; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; int shift = 16 - plane_depth; @@ -286,10 +317,10 @@ { gx_device_memory * const mdev = (gx_device_memory *)dev; mem_save_params_t save; - int pi; + uchar pi; MEM_SAVE_PARAMS(mdev, save); - for (pi = 0; pi < mdev->num_planes; ++pi) { + for (pi = 0; pi < mdev->color_info.num_components; ++pi) { int plane_depth = mdev->planes[pi].depth; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; const gx_device_memory *mdproto = @@ -313,10 +344,10 @@ { gx_device_memory * const mdev = (gx_device_memory *)dev; mem_save_params_t save; - int pi; + uchar pi; MEM_SAVE_PARAMS(mdev, save); - for (pi = 0; pi < mdev->num_planes; ++pi) { + for (pi = 0; pi < mdev->color_info.num_components; ++pi) { int plane_depth = mdev->planes[pi].depth; int shift = mdev->planes[pi].shift; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; @@ -821,11 +852,19 @@ } buf; int source_depth = dev->color_info.depth; mem_save_params_t save; - int pi; + uchar pi; + + /* This routine cannot copy from 3bit chunky data, as 3 bit + * things don't pack nicely into bytes or words. Accordingly + * treat 3 bit things as 4 bit things. This is appropriate as + * 3 bit data will generally have been passed to us as 4bit + * data - such as halftones. */ + if (source_depth == 3) + source_depth = 4; fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); MEM_SAVE_PARAMS(mdev, save); - for (pi = 0; pi < mdev->num_planes; ++pi) { + for (pi = 0; pi < mdev->color_info.num_components; ++pi) { int plane_depth = mdev->planes[pi].depth; int shift = mdev->planes[pi].shift; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; @@ -871,21 +910,29 @@ source_bit = xbit & 7; } for (iy = 0; iy < ch; ++iy) { - sample_load_declare_setup(sptr, sbit, source_base, - source_bit, source_depth); - sample_store_declare_setup(dptr, dbit, dbbyte, - buf.b + br * iy, - 0, plane_depth); + const byte *sptr =source_base; + int sbit = source_bit; + byte *dptr = buf.b + br * iy; + int dbit = 0; + byte dbbyte = (dbit ? (byte)(*dptr & (0xff00 >> dbit)) : 0); for (ix = 0; ix < cw; ++ix) { gx_color_index value; - sample_load_next_any(value, sptr, sbit, source_depth); + if (sizeof(value) > 4){ + if (sample_load_next64((uint64_t *)&value, &sptr, &sbit, source_depth) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_load_next32((uint32_t *)&value, &sptr, &sbit, source_depth) < 0) + return_error(gs_error_rangecheck); + } value = (value >> shift) & mask; - sample_store_next16(value, dptr, dbit, plane_depth, - dbbyte); + if (sample_store_next16(value, &dptr, &dbit, plane_depth, + &dbbyte) < 0) + return_error(gs_error_rangecheck); } - sample_store_flush(dptr, dbit, plane_depth, dbbyte); + sample_store_flush(dptr, dbit, dbbyte); source_base += sraster; } /* @@ -920,10 +967,10 @@ mem_save_params_t save; const gx_device_memory *mdproto; int code = 0; - int plane; + uchar plane; MEM_SAVE_PARAMS(mdev, save); - for (plane = 0; plane < mdev->num_planes; plane++) + for (plane = 0; plane < mdev->color_info.num_components; plane++) { plane_depth = mdev->planes[plane].depth; mdproto = gdev_mem_device_for_bits(plane_depth); @@ -950,10 +997,10 @@ { gx_device_memory * const mdev = (gx_device_memory *)dev; mem_save_params_t save; - int pi; + uchar pi; MEM_SAVE_PARAMS(mdev, save); - for (pi = 0; pi < mdev->num_planes; ++pi) { + for (pi = 0; pi < mdev->color_info.num_components; ++pi) { int plane_depth = mdev->planes[pi].depth; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; int shift = 16 - plane_depth; @@ -1003,14 +1050,14 @@ { gx_device_memory * const mdev = (gx_device_memory *)dev; mem_save_params_t save; - int pi; + uchar pi; /* We can't split up the transfer if the tile is colored. */ if (color0 == gx_no_color_index && color1 == gx_no_color_index) return gx_default_strip_tile_rectangle (dev, tiles, x, y, w, h, color0, color1, px, py); MEM_SAVE_PARAMS(mdev, save); - for (pi = 0; pi < mdev->num_planes; ++pi) { + for (pi = 0; pi < mdev->color_info.num_components; ++pi) { int plane_depth = mdev->planes[pi].depth; int shift = mdev->planes[pi].shift; gx_color_index mask = ((gx_color_index)1 << plane_depth) - 1; @@ -1057,10 +1104,10 @@ int line_count; byte *cdrow, *mdrow, *ydrow, *kdrow; byte lmask, rmask; - rop_proc cproc, mproc, yproc; + rop_proc cproc = NULL, mproc = NULL, yproc = NULL; int dbit; - int cscolor, mscolor, yscolor, kscolor; - int ctcolor, mtcolor, ytcolor, ktcolor; + int cscolor = 0, mscolor = 0, yscolor = 0, kscolor = 0; + int ctcolor = 0, mtcolor = 0, ytcolor = 0, ktcolor = 0; int constant_s = 0; /* Modify the raster operation according to the source palette. */ @@ -1151,7 +1198,9 @@ mdrow = cdrow + mdev->height * draster; ydrow = mdrow + mdev->height * draster; kdrow = ydrow + mdev->height * draster; - traster = (textures ? textures->raster : 0); + if (!textures) + return 0; + traster = textures->raster; ty = y + phase_y; for (; line_count-- > 0; cdrow += draster, mdrow += draster, ydrow += draster, kdrow += draster, srow += sraster, ++ty) { int sx = sourcex; @@ -1694,10 +1743,12 @@ int offset, uint draster, byte *dest, byte **line_ptrs, int plane_height) { - int num_planes = mdev->num_planes; - sample_load_declare(sptr[GX_DEVICE_COLOR_MAX_COMPONENTS], - sbit[GX_DEVICE_COLOR_MAX_COMPONENTS]); - sample_store_declare(dptr, dbit, dbbyte); + int num_planes = mdev->color_info.num_components; + const byte *sptr[GX_DEVICE_COLOR_MAX_COMPONENTS]; + int sbit[GX_DEVICE_COLOR_MAX_COMPONENTS]; + byte *dptr; + int dbit; + byte dbbyte; int ddepth = mdev->color_info.depth; int direct = (mdev->color_info.depth != num_planes * mdev->plane_depth ? 0 : @@ -1725,13 +1776,13 @@ int xbit = x * plane_depth; sptr[pi] = *line_ptr + (xbit >> 3); - sample_load_setup(sbit[pi], xbit & 7, plane_depth); + sbit[pi] = xbit & 7; } { int xbit = offset * ddepth; dptr = dest + (iy - y) * draster + (xbit >> 3); - sample_store_setup(dbit, xbit & 7, ddepth); + dbit = xbit & 7; } if (direct == -8) { /* 1 byte per component, lsb first. */ @@ -1760,20 +1811,29 @@ break; } } - sample_store_preload(dbbyte, dptr, dbit, ddepth); + dbbyte = (dbit ? (byte)(*dptr & (0xff00 >> dbit)) : 0); +/* sample_store_preload(dbbyte, dptr, dbit, ddepth);*/ for (ix = w; ix > 0; --ix) { gx_color_index color = 0; for (pi = 0; pi < num_planes; ++pi) { int plane_depth = mdev->planes[pi].depth; - uint value; + ushort value; - sample_load_next16(value, sptr[pi], sbit[pi], plane_depth); + if (sample_load_next16(&value, &sptr[pi], &sbit[pi], plane_depth) < 0) + return_error(gs_error_rangecheck); color |= (gx_color_index)value << mdev->planes[pi].shift; } - sample_store_next_any(color, dptr, dbit, ddepth, dbbyte); + if (sizeof(color) > 4) { + if (sample_store_next64(color, &dptr, &dbit, ddepth, &dbbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(color, &dptr, &dbit, ddepth, &dbbyte) < 0) + return_error(gs_error_rangecheck); + } } - sample_store_flush(dptr, dbit, ddepth, dbbyte); + sample_store_flush(dptr, dbit, dbbyte); } return 0; } @@ -1836,32 +1896,33 @@ * pointers for the buffer. For now, for the sake of sanity, we * convert whole lines of s, but only as many lines as we have to. */ /* We assume that scolors == NULL here */ - int i, j; + int i; + uchar j; uint chunky_sraster; uint nbytes; byte **line_ptrs; byte *sbuf, *buf; - chunky_sraster = sraster * mdev->num_planes; + chunky_sraster = sraster * mdev->color_info.num_components; nbytes = height * chunky_sraster; buf = gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(buf)"); if (buf == NULL) { return gs_note_error(gs_error_VMerror); } - nbytes = sizeof(byte *) * mdev->num_planes * height; + nbytes = sizeof(byte *) * mdev->color_info.num_components * height; line_ptrs = (byte **)gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(line_ptrs)"); if (line_ptrs == NULL) { gs_free_object(mdev->memory, buf, "mem_planar_strip_copy_rop(buf)"); return gs_note_error(gs_error_VMerror); } - for (j = 0; j < mdev->num_planes; j++) { + for (j = 0; j < mdev->color_info.num_components; j++) { sbuf = (byte *)sdata + j * sraster; for (i = height; i > 0; i--) { *line_ptrs++ = sbuf; sbuf += sraster; } } - line_ptrs -= height * mdev->num_planes; + line_ptrs -= height * mdev->color_info.num_components; planar_to_chunky(mdev, sourcex, 0, width, height, 0, chunky_sraster, buf, line_ptrs, planar_height); gs_free_object(mdev->memory, line_ptrs, "mem_planar_strip_copy_rop(line_ptrs)"); @@ -1906,18 +1967,18 @@ if (buf == NULL) { return gs_note_error(gs_error_VMerror); } - nbytes = sizeof(byte *) * mdev->num_planes * textures->rep_height; + nbytes = sizeof(byte *) * mdev->color_info.num_components * textures->rep_height; line_ptrs = (byte **)gs_alloc_bytes(mdev->memory, nbytes, "mem_planar_strip_copy_rop(line_ptrs)"); if (line_ptrs == NULL) { gs_free_object(mdev->memory, buf, "mem_planar_strip_copy_rop(buf)"); return gs_note_error(gs_error_VMerror); } tbuf = textures->data; - for (i = textures->rep_height * mdev->num_planes; i > 0; i--) { + for (i = textures->rep_height * mdev->color_info.num_components; i > 0; i--) { *line_ptrs++ = tbuf; tbuf += textures->raster; } - line_ptrs -= textures->rep_height * mdev->num_planes; + line_ptrs -= textures->rep_height * mdev->color_info.num_components; planar_to_chunky(mdev, 0, ty, textures->rep_width, chunky_t_height, 0, chunky_t_raster, buf, line_ptrs, textures->rep_height); gs_free_object(mdev->memory, line_ptrs, "mem_planar_strip_copy_rop(line_ptrs)"); @@ -1941,11 +2002,11 @@ if (!lop_uses_T(lop) || (tcolors && (tcolors[0] == tcolors[1]))) { /* No T in use, or constant T. */ if ((!lop_uses_S(lop) || (scolors && (scolors[0] == scolors[1]))) && - ((mdev->num_planes == 1) || (mdev->num_planes == 3))) { - int plane; + ((mdev->color_info.num_components == 1) || (mdev->color_info.num_components == 3))) { + uchar plane; /* No S in use, or constant S. And either greyscale or rgb, * so we can just do the rop on each plane in turn. */ - for (plane=0; plane < mdev->num_planes; plane++) + for (plane=0; plane < mdev->color_info.num_components; plane++) { gx_color_index tcolors2[2], scolors2[2]; int shift = mdev->planes[plane].shift; @@ -1969,7 +2030,7 @@ } return 0; } - if ((mdev->num_planes == 4) && (mdev->plane_depth == 1) && + if ((mdev->color_info.num_components == 4) && (mdev->plane_depth == 1) && ((lop & (lop_S_transparent | lop_T_transparent)) == 0)) { lop = cmykrop[lop & 0xff] | (lop & ~0xff); @@ -1982,7 +2043,7 @@ } } if (!tcolors && !scolors && - (mdev->num_planes == 4) && (mdev->plane_depth == 1) && + (mdev->color_info.num_components == 4) && (mdev->plane_depth == 1) && ((lop & (lop_S_transparent | lop_T_transparent)) == 0)) { lop = cmykrop[lop & 0xff] | (lop & ~0xff); return planar_cmyk4bit_strip_copy_rop(mdev, sdata, sourcex, @@ -2006,11 +2067,11 @@ gs_get_bits_params_t * params, gs_int_rect ** unread) { - /* This duplicates most of mem_get_bits_rectangle. Tant pis. */ + /* This duplicates most of mem_get_bits_rectangle. Tant pgs. */ gx_device_memory * const mdev = (gx_device_memory *)dev; gs_get_bits_options_t options = params->options; int x = prect->p.x, w = prect->q.x - x, y = prect->p.y, h = prect->q.y - y; - int num_planes = mdev->num_planes; + uchar num_planes = mdev->color_info.num_components; gs_get_bits_params_t copy_params; int code; @@ -2036,6 +2097,10 @@ GB_COLORS_NATIVE | GB_ALPHA_NONE; return_error(gs_error_rangecheck); } + + if (mdev->line_ptrs == 0x00) + return_error(gs_error_rangecheck); + if ((w <= 0) | (h <= 0)) { if ((w | h) < 0) return_error(gs_error_rangecheck); @@ -2071,13 +2136,13 @@ */ if (!(~options & (GB_PACKING_PLANAR | GB_SELECT_PLANES))) { /* Check that only a single plane is being requested. */ - int pi; + uchar pi; for (pi = 0; pi < num_planes; ++pi) if (params->data[pi] != 0) break; if (pi < num_planes) { - int plane = pi++; + uchar plane = pi++; for (; pi < num_planes; ++pi) if (params->data[pi] != 0) diff -Nru ghostscript-9.10~dfsg/base/gdevmpla.h ghostscript-9.25~dfsg+1/base/gdevmpla.h --- ghostscript-9.10~dfsg/base/gdevmpla.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmpla.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Interface to planar memory devices. */ diff -Nru ghostscript-9.10~dfsg/base/gdevmplt.c ghostscript-9.25~dfsg+1/base/gdevmplt.c --- ghostscript-9.10~dfsg/base/gdevmplt.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmplt.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,237 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Device to set monochrome mode in PCL */ +/* This device is one of the 'subclassing' devices, part of a chain or pipeline + * of devices, each of which can process some aspect of the graphics methods + * before passing them on to the next device in the chain. + * In this case, the device simply returns monochrome color_mapping procs + * instead of color ones. When we want to go back to color, we just + * remove this device. + */ +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gsdevice.h" /* requires gsmatrix.h */ +#include "gxdcolor.h" /* for gx_device_black/white */ +#include "gxiparam.h" /* for image source size */ +#include "gxgstate.h" +#include "gxpaint.h" +#include "gxpath.h" +#include "gxcpath.h" +#include "gxcmap.h" /* color mapping procs */ +#include "gsstype.h" +#include "gdevprn.h" +#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ +#include "gdevsclass.h" +#include "gdevmplt.h" +#include "gxdcconv.h" /* for color_rgb_to_gray and color_cmyk_to_gray */ + +/* Device procedures, we only need one */ +static dev_proc_get_color_mapping_procs(pcl_mono_palette_get_color_mapping_procs); + +/* The device prototype */ +#define MAX_COORD (max_int_in_fixed - 1000) +#define MAX_RESOLUTION 4000 + +/* GC descriptor */ +#define public_st_pcl_mono_palette_device() /* in gsdevice.c */\ + gs_public_st_complex_only(st_pcl_mono_palette_device, gx_device, "PCL_Mono_Palette",\ + 0, pcl_mono_palette_enum_ptrs, pcl_mono_palette_reloc_ptrs, default_subclass_finalize) + +static +ENUM_PTRS_WITH(pcl_mono_palette_enum_ptrs, gx_device *dev); +return 0; /* default case */ +case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); +case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); +ENUM_PTRS_END +static RELOC_PTRS_WITH(pcl_mono_palette_reloc_ptrs, gx_device *dev) +{ + dev->parent = gx_device_reloc_ptr(dev->parent, gcst); + dev->child = gx_device_reloc_ptr(dev->child, gcst); +} +RELOC_PTRS_END + +public_st_pcl_mono_palette_device(); + +const +gx_device_mplt gs_pcl_mono_palette_device = +{ + /* + * Define the device as 8-bit gray scale to avoid computing halftones. + */ + std_device_dci_type_body(gx_device_mplt, 0, "PCL_Mono_Palette", &st_pcl_mono_palette_device, + MAX_COORD, MAX_COORD, + MAX_RESOLUTION, MAX_RESOLUTION, + 1, 8, 255, 0, 256, 1), + {default_subclass_open_device, + default_subclass_get_initial_matrix, + default_subclass_sync_output, /* sync_output */ + default_subclass_output_page, + default_subclass_close_device, + default_subclass_map_rgb_color, + default_subclass_map_color_rgb, + default_subclass_fill_rectangle, + default_subclass_tile_rectangle, /* tile_rectangle */ + default_subclass_copy_mono, + default_subclass_copy_color, + default_subclass_draw_line, /* draw_line */ + default_subclass_get_bits, /* get_bits */ + default_subclass_get_params, + default_subclass_put_params, + default_subclass_map_cmyk_color, + default_subclass_get_xfont_procs, /* get_xfont_procs */ + default_subclass_get_xfont_device, /* get_xfont_device */ + default_subclass_map_rgb_alpha_color, + default_subclass_get_page_device, + default_subclass_get_alpha_bits, /* get_alpha_bits */ + default_subclass_copy_alpha, + default_subclass_get_band, /* get_band */ + default_subclass_copy_rop, /* copy_rop */ + default_subclass_fill_path, + default_subclass_stroke_path, + default_subclass_fill_mask, + default_subclass_fill_trapezoid, + default_subclass_fill_parallelogram, + default_subclass_fill_triangle, + default_subclass_draw_thin_line, + default_subclass_begin_image, + default_subclass_image_data, /* image_data */ + default_subclass_end_image, /* end_image */ + default_subclass_strip_tile_rectangle, + default_subclass_strip_copy_rop, + default_subclass_get_clipping_box, /* get_clipping_box */ + default_subclass_begin_typed_image, + default_subclass_get_bits_rectangle, /* get_bits_rectangle */ + default_subclass_map_color_rgb_alpha, + default_subclass_create_compositor, + default_subclass_get_hardware_params, /* get_hardware_params */ + default_subclass_text_begin, + default_subclass_finish_copydevice, /* finish_copydevice */ + default_subclass_begin_transparency_group, /* begin_transparency_group */ + default_subclass_end_transparency_group, /* end_transparency_group */ + default_subclass_begin_transparency_mask, /* begin_transparency_mask */ + default_subclass_end_transparency_mask, /* end_transparency_mask */ + default_subclass_discard_transparency_layer, /* discard_transparency_layer */ + pcl_mono_palette_get_color_mapping_procs, /* get_color_mapping_procs */ + default_subclass_get_color_comp_index, /* get_color_comp_index */ + default_subclass_encode_color, /* encode_color */ + default_subclass_decode_color, /* decode_color */ + default_subclass_pattern_manage, /* pattern_manage */ + default_subclass_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ + default_subclass_include_color_space, /* include_color_space */ + default_subclass_fill_linear_color_scanline, /* fill_linear_color_scanline */ + default_subclass_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ + default_subclass_fill_linear_color_triangle, /* fill_linear_color_triangle */ + default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ + default_subclass_ret_devn_params, /* ret_devn_params */ + default_subclass_fillpage, /* fillpage */ + default_subclass_push_transparency_state, /* push_transparency_state */ + default_subclass_pop_transparency_state, /* pop_transparency_state */ + default_subclass_put_image, /* put_image */ + default_subclass_dev_spec_op, /* dev_spec_op */ + default_subclass_copy_planes, /* copy_planes */ + default_subclass_get_profile, /* get_profile */ + default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ + default_subclass_strip_copy_rop2, + default_subclass_strip_tile_rect_devn, + default_subclass_copy_alpha_hl_color, + default_subclass_process_page + } +}; + +#undef MAX_COORD +#undef MAX_RESOLUTION + +/* The justification for this device, these 3 procedures map colour values + * to gray values + */ +static void +pcl_gray_cs_to_cm(gx_device * dev, frac gray, frac out[]) +{ + pcl_mono_palette_subclass_data *psubclass_data; + + while(dev && dev->child) { + if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) + break; + dev = dev->child; + }; + + if (dev && dev->child) { + psubclass_data = dev->subclass_data; + /* just pass it along */ + psubclass_data->device_cm_procs->map_gray(dev, gray, out); + } else + return; +} + +static void +pcl_rgb_cs_to_cm(gx_device * dev, const gs_gstate * pgs, frac r, frac g, + frac b, frac out[]) +{ + pcl_mono_palette_subclass_data *psubclass_data; + frac gray; + + while(dev && dev->child) { + if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) + break; + dev = dev->child; + }; + + if (dev && dev->child) { + psubclass_data = dev->subclass_data; + gray = color_rgb_to_gray(r, g, b, NULL); + + psubclass_data->device_cm_procs->map_rgb(dev, pgs, gray, gray, gray, out); + } else + return; +} + +static void +pcl_cmyk_cs_to_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +{ + pcl_mono_palette_subclass_data *psubclass_data; + frac gray; + + while(dev && dev->child) { + if (strncmp(dev->dname, "PCL_Mono_Palette", 16) == 0) + break; + dev = dev->child; + }; + + if (dev && dev->child) { + psubclass_data = dev->subclass_data; + gray = color_cmyk_to_gray(c, m, y, k, NULL); + + psubclass_data->device_cm_procs->map_cmyk(dev, gray, gray, gray, gray, out); + } else + return; +} + +const gx_cm_color_map_procs *pcl_mono_palette_get_color_mapping_procs(const gx_device *dev) +{ + pcl_mono_palette_subclass_data *psubclass_data = dev->subclass_data; + + if (psubclass_data->device_cm_procs == 0L) { + psubclass_data->pcl_mono_procs.map_gray = pcl_gray_cs_to_cm; + psubclass_data->pcl_mono_procs.map_rgb = pcl_rgb_cs_to_cm; + psubclass_data->pcl_mono_procs.map_cmyk = pcl_cmyk_cs_to_cm; + psubclass_data->device_cm_procs = (gx_cm_color_map_procs *)dev_proc(dev->child, get_color_mapping_procs) (dev->child); + } + return &psubclass_data->pcl_mono_procs; +} diff -Nru ghostscript-9.10~dfsg/base/gdevmplt.h ghostscript-9.25~dfsg+1/base/gdevmplt.h --- ghostscript-9.10~dfsg/base/gdevmplt.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmplt.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,35 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Common definitions for PCL monochrome palette device */ + +#ifndef gdevmplt_INCLUDED +# define gdevmplt_INCLUDED + +typedef struct gx_device_s gx_device_mplt; + +/* Initialize device. */ +void gx_device_pcl_mono_palette_init(gx_device_mplt * dev); + +typedef struct { + subclass_common; + gx_cm_color_map_procs pcl_mono_procs; + gx_cm_color_map_procs *device_cm_procs; +} pcl_mono_palette_subclass_data; + +extern_st(st_device_mplt); + +#endif /* gdevmplt_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevmr1.c ghostscript-9.25~dfsg+1/base/gdevmr1.c --- ghostscript-9.10~dfsg/base/gdevmr1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmr1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* RasterOp implementation for monobit memory devices */ diff -Nru ghostscript-9.10~dfsg/base/gdevmr2n.c ghostscript-9.25~dfsg+1/base/gdevmr2n.c --- ghostscript-9.10~dfsg/base/gdevmr2n.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmr2n.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* RasterOp implementation for 2- and 4-bit memory devices */ @@ -81,7 +81,7 @@ long tdata; int depth = dev->color_info.depth; int log2_depth = depth >> 1; /* works for 2, 4 */ - gx_color_index max_pixel = (1 << depth) - 1; + gx_color_index max_pixel = ((gx_color_index)1 << depth) - 1; int code; #ifdef DEBUG diff -Nru ghostscript-9.10~dfsg/base/gdevmr8n.c ghostscript-9.25~dfsg+1/base/gdevmr8n.c --- ghostscript-9.10~dfsg/base/gdevmr8n.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmr8n.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* RasterOp implementation for 8N-bit memory devices */ @@ -26,13 +26,9 @@ #include "gxdevrop.h" #include "gdevmem.h" #include "gdevmrop.h" -#include "vdtrace.h" -/* Enable the following to use RUN_ROPs. Benefits of this are not proven yet - * so disabled, even though cluster testing shows that the results are the - * same. - */ -#undef USE_RUN_ROP +/* Use the RUN_ROP code. */ +#define USE_RUN_ROP #undef COMPARE_AND_CONTRAST /* @@ -56,10 +52,11 @@ const gx_color_index * scolors, const gx_strip_bitmap * textures, const gx_color_index * tcolors, int x, int y, int width, int height, - int phase_x, int phase_y, gs_logical_operation_t lop) + int phase_x, int phase_y, gs_logical_operation_t dirty_lop) { gx_device_memory *mdev = (gx_device_memory *) dev; - gs_rop3_t rop = lop_rop(lop); + gs_logical_operation_t lop = lop_sanitize(dirty_lop); + gs_rop3_t rop; gx_color_index const_source = gx_no_color_index; gx_color_index const_texture = gx_no_color_index; uint draster = mdev->raster; @@ -68,10 +65,15 @@ int depth = dev->color_info.depth; int bpp = depth >> 3; /* bytes per pixel, 1 or 3 */ gx_color_index all_ones = ((gx_color_index) 1 << depth) - 1; + gx_color_index local_scolors[2]; + gx_color_index local_tcolors[2]; + +#if !defined(USE_RUN_ROP) || defined(COMPARE_AND_CONTRAST) gx_color_index strans = (lop & lop_S_transparent ? all_ones : gx_no_color_index); gx_color_index ttrans = (lop & lop_T_transparent ? all_ones : gx_no_color_index); +#endif #ifdef USE_RUN_ROP rop_run_op ropper; #ifdef COMPARE_AND_CONTRAST @@ -82,29 +84,37 @@ #endif /* Check for constant source. */ - if (!rop3_uses_S(rop)) + if (!rop3_uses_S(lop) && (lop & lop_S_transparent) == 0) { const_source = 0; /* arbitrary */ - else if (scolors != 0 && scolors[0] == scolors[1]) { + } else if (scolors != 0 && scolors[0] == scolors[1]) { /* Constant source */ const_source = scolors[0]; if (const_source == gx_device_black(dev)) - rop = rop3_know_S_0(rop); - else if (const_source == gx_device_white(dev)) - rop = rop3_know_S_1(rop); + lop = lop_know_S_0(lop); + else if (const_source == gx_device_white(dev)) { + if (lop & lop_S_transparent) + return 0; + lop = lop_know_S_1(lop); + } } /* Check for constant texture. */ - if (!rop3_uses_T(rop)) + if (!rop3_uses_T(lop) && (lop & lop_T_transparent) == 0) const_texture = 0; /* arbitrary */ else if (tcolors != 0 && tcolors[0] == tcolors[1]) { /* Constant texture */ const_texture = tcolors[0]; if (const_texture == gx_device_black(dev)) - rop = rop3_know_T_0(rop); - else if (const_texture == gx_device_white(dev)) - rop = rop3_know_T_1(rop); + lop = lop_know_T_0(lop); + else if (const_texture == gx_device_white(dev)) { + if (lop & lop_T_transparent) + return 0; + lop = lop_know_T_1(lop); + } } + rop = lop_rop(lop); + if (bpp == 1 && (gx_device_has_color(dev) || (gx_device_black(dev) != 0 || gx_device_white(dev) != all_ones)) @@ -146,6 +156,8 @@ x, y, width, height, phase_x, phase_y, lop); } + /* Put the updated rop back into the lop */ + lop = rop | (lop & (lop_S_transparent | lop_T_transparent)); } /* Adjust coordinates to be in bounds. */ @@ -161,6 +173,25 @@ base = scan_line_base(mdev, y); drow = base + x * bpp; + /* Allow for colors being passed in with tags in the top bits. + * This confuses transparency code. + */ + { + gx_color_index color_mask = (bpp == 1 ? 0xff : 0xffffff); + if (scolors) + { + local_scolors[0] = scolors[0] & color_mask; + local_scolors[1] = scolors[1] & color_mask; + scolors = local_scolors; + } + if (tcolors) + { + local_tcolors[0] = tcolors[0] & color_mask; + local_tcolors[1] = tcolors[1] & color_mask; + tcolors = local_tcolors; + } + } + /* * There are 18 cases depending on whether each of the source and * texture is constant, 1-bit, or multi-bit, and on whether the @@ -176,12 +207,14 @@ /* 8-bit */ #define cbit8(base, i, colors)\ (dbit(base, i) ? (byte)colors[1] : (byte)colors[0]) +#ifdef COMPARE_AND_CONTRAST #define rop_body_8(s_pixel, t_pixel)\ if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\ (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\ )\ continue;\ *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel) +#endif /* 24-bit */ #define get24(ptr)\ (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2]) @@ -191,6 +224,7 @@ (ptr)[2] = (byte)(pixel) #define cbit24(base, i, colors)\ (dbit(base, i) ? colors[1] : colors[0]) +#ifdef COMPARE_AND_CONTRAST #define rop_body_24(s_pixel, t_pixel)\ if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\ (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\ @@ -200,145 +234,137 @@ d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\ put24(dptr, d_pixel);\ } +#endif if (const_texture != gx_no_color_index) { /**** Constant texture ****/ if (const_source != gx_no_color_index) { /**** Constant source & texture ****/ - rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_constant); rop_set_s_constant(&ropper, const_source); rop_set_t_constant(&ropper, const_texture); - for (; line_count-- > 0; drow += draster) { + if (rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_constant)) { + for (; line_count-- > 0; drow += draster) { #ifdef COMPARE_AND_CONTRAST - byte *dptr = drow; - int left = width; + byte *dptr = drow; + int left = width; - bytelen = left*bpp; start = dptr; - memcpy(testbuffer, dptr, bytelen); - rop_run(&ropper, testbuffer, left); + bytelen = left*bpp; start = dptr; + memcpy(testbuffer, dptr, bytelen); + rop_run(&ropper, testbuffer, left); - if (bpp == 1) + if (bpp == 1) /**** 8-bit destination ****/ - for (; left > 0; ++dptr, --left) { - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), const_texture); - rop_body_8((byte)const_source, (byte)const_texture); - } - else + for (; left > 0; ++dptr, --left) { + rop_body_8((byte)const_source, (byte)const_texture); + } + else /**** 24-bit destination ****/ - for (; left > 0; dptr += 3, --left) { - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), const_texture); - rop_body_24(const_source, const_texture); + for (; left > 0; dptr += 3, --left) { + rop_body_24(const_source, const_texture); + } + if (memcmp(testbuffer, start, bytelen) != 0) { + emprintf(dev->memory, "Failed!\n"); } - if (memcmp(testbuffer, start, bytelen) != 0) { - emprintf(dev->memory, "Failed!\n"); - } #else - rop_run(&ropper, drow, width); + rop_run(&ropper, drow, width); #endif + } + rop_release_run_op(&ropper); } - rop_release_run_op(&ropper); } else { /**** Data source, const texture ****/ if (scolors) { const byte *srow = sdata; - rop_get_run_op(&ropper, lop, depth, rop_t_constant | rop_s_1bit); rop_set_t_constant(&ropper, const_texture); rop_set_s_colors(&ropper, scolors); + if (rop_get_run_op(&ropper, lop, depth, rop_t_constant | rop_s_1bit)) { - for (; line_count-- > 0; drow += draster, srow += sraster) { + for (; line_count-- > 0; drow += draster, srow += sraster) { #ifdef COMPARE_AND_CONTRAST - byte *dptr = drow; - int left = width; + byte *dptr = drow; + int left = width; /**** 1-bit source ****/ - int sx = sourcex; + int sx = sourcex; - rop_set_s_bitmap_subbyte(&ropper, srow, sourcex); - bytelen = left*bpp; start = dptr; - memcpy(testbuffer, dptr, bytelen); - rop_run(&ropper, testbuffer, width); - if (bpp == 1) + rop_set_s_bitmap_subbyte(&ropper, srow, sourcex); + bytelen = left*bpp; start = dptr; + memcpy(testbuffer, dptr, bytelen); + rop_run(&ropper, testbuffer, width); + if (bpp == 1) /**** 8-bit destination ****/ - for (; left > 0; ++dptr, ++sx, --left) { - byte s_pixel = cbit8(srow, sx, scolors); + for (; left > 0; ++dptr, ++sx, --left) { + byte s_pixel = cbit8(srow, sx, scolors); - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), const_texture); - rop_body_8(s_pixel, (byte)const_texture); - } - else + rop_body_8(s_pixel, (byte)const_texture); + } + else /**** 24-bit destination ****/ - for (; left > 0; dptr += 3, ++sx, --left) { - bits32 s_pixel = cbit24(srow, sx, scolors); + for (; left > 0; dptr += 3, ++sx, --left) { + bits32 s_pixel = cbit24(srow, sx, scolors); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), const_texture); - rop_body_24(s_pixel, const_texture); + rop_body_24(s_pixel, const_texture); + } + if (memcmp(testbuffer, start, bytelen) != 0) { + emprintf(dev->memory, "Failed!\n"); } - if (memcmp(testbuffer, start, bytelen) != 0) { - emprintf(dev->memory, "Failed!\n"); - } #else /**** 1-bit source ****/ /**** 8-bit destination ****/ /**** 24-bit destination ****/ - rop_set_s_bitmap_subbyte(&ropper, srow, sourcex); - rop_run(&ropper, drow, width); + rop_set_s_bitmap_subbyte(&ropper, srow, sourcex); + rop_run(&ropper, drow, width); #endif + } + rop_release_run_op(&ropper); } - rop_release_run_op(&ropper); } else { const byte *srow = sdata; - rop_get_run_op(&ropper, lop, depth, rop_t_constant); rop_set_t_constant(&ropper, const_texture); - for (; line_count-- > 0; drow += draster, srow += sraster) { + if (rop_get_run_op(&ropper, lop, depth, rop_t_constant)) { + for (; line_count-- > 0; drow += draster, srow += sraster) { #ifdef COMPARE_AND_CONTRAST - byte *dptr = drow; - int left = width; + byte *dptr = drow; + int left = width; - bytelen = left*bpp; start = dptr; - memcpy(testbuffer, dptr, bytelen); + bytelen = left*bpp; start = dptr; + memcpy(testbuffer, dptr, bytelen); - rop_set_s_bitmap(&ropper, srow + sourcex * bpp); - rop_run(&ropper, testbuffer, left); + rop_set_s_bitmap(&ropper, srow + sourcex * bpp); + rop_run(&ropper, testbuffer, left); /**** 8-bit source & dest ****/ - if (bpp == 1) { - const byte *sptr = srow + sourcex; + if (bpp == 1) { + const byte *sptr = srow + sourcex; - for (; left > 0; ++dptr, ++sptr, --left) { - byte s_pixel = *sptr; + for (; left > 0; ++dptr, ++sptr, --left) { + byte s_pixel = *sptr; - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), const_texture); - rop_body_8(s_pixel, (byte)const_texture); - } - } else { + rop_body_8(s_pixel, (byte)const_texture); + } + } else { /**** 24-bit source & dest ****/ - const byte *sptr = srow + sourcex * 3; + const byte *sptr = srow + sourcex * 3; - bytelen = left*bpp; start = dptr; - memcpy(testbuffer, dptr, bytelen); + bytelen = left*bpp; start = dptr; + memcpy(testbuffer, dptr, bytelen); - for (; left > 0; dptr += 3, sptr += 3, --left) { - bits32 s_pixel = get24(sptr); + for (; left > 0; dptr += 3, sptr += 3, --left) { + bits32 s_pixel = get24(sptr); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), const_texture); - rop_body_24(s_pixel, const_texture); + rop_body_24(s_pixel, const_texture); + } + } + if (memcmp(testbuffer, start, bytelen) != 0) { + emprintf(dev->memory, "Failed!\n"); } - } - if (memcmp(testbuffer, start, bytelen) != 0) { - emprintf(dev->memory, "Failed!\n"); - } #else /**** 8-bit source & dest ****/ /**** 24-bit source & dest ****/ - rop_set_s_bitmap(&ropper, srow + sourcex * bpp); - rop_run(&ropper, drow, width); + rop_set_s_bitmap(&ropper, srow + sourcex * bpp); + rop_run(&ropper, drow, width); #endif + } + rop_release_run_op(&ropper); } - rop_release_run_op(&ropper); } } } else if (const_source != gx_no_color_index) { @@ -347,190 +373,187 @@ uint traster = textures->raster; int ty = y + phase_y; - rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_1bit); rop_set_s_constant(&ropper, const_source); - for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ - int dx = x, w = width, nw; - byte *dptr = drow; - const byte *trow = - textures->data + (ty % textures->size.y) * traster; - int xoff = x_offset(phase_x, ty, textures); - - for (; w > 0; dx += nw, w -= nw) { - int tx = (dx + xoff) % textures->rep_width; - int left = nw = min(w, textures->size.x - tx); - const byte *tptr = trow; + if (rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_1bit)) { + for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ + int dx = x, w = width, nw; + byte *dptr = drow; + const byte *trow = + textures->data + (ty % textures->size.y) * traster; + int xoff = x_offset(phase_x, ty, textures); + + for (; w > 0; dx += nw, w -= nw) { + int tx = (dx + xoff) % textures->rep_width; + int left = nw = min(w, textures->size.x - tx); +#ifdef COMPARE_AND_CONTRAST + const byte *tptr = trow; +#endif - rop_set_t_bitmap_subbyte(&ropper, trow, tx); + rop_set_t_bitmap_subbyte(&ropper, trow, tx); #ifdef COMPARE_AND_CONTRAST - bytelen = left*bpp; start = dptr; - memcpy(testbuffer, dptr, bytelen); - rop_run(&ropper, testbuffer, left); + bytelen = left*bpp; start = dptr; + memcpy(testbuffer, dptr, bytelen); + rop_run(&ropper, testbuffer, left); /**** 1-bit texture ****/ - if (bpp == 1) + if (bpp == 1) /**** 8-bit dest ****/ - for (; left > 0; ++dptr, ++tx, --left) { - byte t_pixel = cbit8(tptr, tx, tcolors); + for (; left > 0; ++dptr, ++tx, --left) { + byte t_pixel = cbit8(tptr, tx, tcolors); - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), t_pixel); - rop_body_8((byte)const_source, t_pixel); - } - else + rop_body_8((byte)const_source, t_pixel); + } + else /**** 24-bit dest ****/ - for (; left > 0; dptr += 3, ++tx, --left) { - bits32 t_pixel = cbit24(tptr, tx, tcolors); + for (; left > 0; dptr += 3, ++tx, --left) { + bits32 t_pixel = cbit24(tptr, tx, tcolors); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), t_pixel); - rop_body_24(const_source, t_pixel); + rop_body_24(const_source, t_pixel); + } + if (memcmp(testbuffer, start, bytelen) != 0) { + emprintf(dev->memory, "Failed!\n"); } - if (memcmp(testbuffer, start, bytelen) != 0) { - emprintf(dev->memory, "Failed!\n"); - } #else - rop_run(&ropper, dptr, left); - dptr += left; + rop_run(&ropper, dptr, left); + dptr += left; #endif + } } } } else { uint traster = textures->raster; int ty = y + phase_y; - rop_get_run_op(&ropper, lop, depth, rop_s_constant); rop_set_s_constant(&ropper, const_source); + if (rop_get_run_op(&ropper, lop, depth, rop_s_constant)) { - for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ - int dx = x, w = width, nw; - byte *dptr = drow; - const byte *trow = - textures->data + (ty % textures->size.y) * traster; - int xoff = x_offset(phase_x, ty, textures); - - for (; w > 0; dx += nw, w -= nw) { - int tx = (dx + xoff) % textures->rep_width; - int left = nw = min(w, textures->size.x - tx); - const byte *tptr = trow + tx*bpp; - rop_set_t_bitmap(&ropper, tptr); + for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ + int dx = x, w = width, nw; + byte *dptr = drow; + const byte *trow = + textures->data + (ty % textures->size.y) * traster; + int xoff = x_offset(phase_x, ty, textures); + + for (; w > 0; dx += nw, w -= nw) { + int tx = (dx + xoff) % textures->rep_width; + int left = nw = min(w, textures->size.x - tx); + const byte *tptr = trow + tx*bpp; + rop_set_t_bitmap(&ropper, tptr); #ifdef COMPARE_AND_CONTRAST - bytelen = left*bpp; start = dptr; - memcpy(testbuffer, dptr, bytelen); - rop_run(&ropper, testbuffer, left); + bytelen = left*bpp; start = dptr; + memcpy(testbuffer, dptr, bytelen); + rop_run(&ropper, testbuffer, left); /**** 8-bit T & D ****/ - if (bpp == 1) { - for (; left > 0; ++dptr, ++tptr, --left) { - byte t_pixel = *tptr; - - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), t_pixel); - rop_body_8((byte)const_source, t_pixel); - } - } else { + if (bpp == 1) { + for (; left > 0; ++dptr, ++tptr, --left) { + byte t_pixel = *tptr; + + rop_body_8((byte)const_source, t_pixel); + } + } else { /**** 24-bit T & D ****/ - for (; left > 0; dptr += 3, tptr += 3, --left) { - bits32 t_pixel = get24(tptr); + for (; left > 0; dptr += 3, tptr += 3, --left) { + bits32 t_pixel = get24(tptr); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), t_pixel); - rop_body_24(const_source, t_pixel); + rop_body_24(const_source, t_pixel); + } + } + if (memcmp(testbuffer, start, bytelen) != 0) { + emprintf(dev->memory, "Failed!\n"); } - } - if (memcmp(testbuffer, start, bytelen) != 0) { - emprintf(dev->memory, "Failed!\n"); - } #else /**** 8-bit T & D ****/ /**** 24-bit T & D ****/ - rop_run(&ropper, dptr, left); - dptr += left * bpp; + rop_run(&ropper, dptr, left); + dptr += left * bpp; #endif + } } + rop_release_run_op(&ropper); } - rop_release_run_op(&ropper); } } else { /**** Data source & texture ****/ - if (scolors != NULL | tcolors != NULL) { + if (scolors != NULL || tcolors != NULL) { uint traster = textures->raster; int ty = y + phase_y; const byte *srow = sdata; - rop_get_run_op(&ropper, lop, depth, - ((scolors == NULL ? 0 : rop_s_1bit) | - (tcolors == NULL ? 0 : rop_t_1bit))); - - /* Loop over scan lines. */ - for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */ - int sx = sourcex; - int dx = x; - int w = width; - int nw; - byte *dptr = drow; - const byte *trow = - textures->data + (ty % textures->size.y) * traster; - int xoff = x_offset(phase_x, ty, textures); - - for (; w > 0; dx += nw, w -= nw) { /* Loop over individual pixels. */ - int tx = (dx + xoff) % textures->rep_width; - int left = nw = min(w, textures->size.x - tx); - const byte *sptr = srow + sx*bpp; - const byte *tptr = trow + tx*bpp; - - /* - * For maximum speed, we should split this loop - * into 7 cases depending on source & texture - * depth: (1,1), (1,8), (1,24), (8,1), (8,8), - * (24,1), (24,24). But since we expect these - * cases to be relatively uncommon, we just - * divide on the destination depth. - */ - if (scolors) - rop_set_s_bitmap_subbyte(&ropper, srow, sx); - else - rop_set_s_bitmap(&ropper, sptr); - if (tcolors) - rop_set_t_bitmap_subbyte(&ropper, trow, tx); - else - rop_set_t_bitmap(&ropper, tptr); + if (scolors) + rop_set_s_colors(&ropper, scolors); + if (tcolors) + rop_set_s_colors(&ropper, tcolors); + if (rop_get_run_op(&ropper, lop, depth, + ((scolors == NULL ? 0 : rop_s_1bit) | + (tcolors == NULL ? 0 : rop_t_1bit)))) { + /* Loop over scan lines. */ + for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */ + int sx = sourcex; + int dx = x; + int w = width; + int nw; + byte *dptr = drow; + const byte *trow = + textures->data + (ty % textures->size.y) * traster; + int xoff = x_offset(phase_x, ty, textures); + + for (; w > 0; dx += nw, w -= nw) { /* Loop over individual pixels. */ + int tx = (dx + xoff) % textures->rep_width; + int left = nw = min(w, textures->size.x - tx); + const byte *sptr = srow + sx*bpp; + const byte *tptr = trow + tx*bpp; + + /* + * For maximum speed, we should split this loop + * into 7 cases depending on source & texture + * depth: (1,1), (1,8), (1,24), (8,1), (8,8), + * (24,1), (24,24). But since we expect these + * cases to be relatively uncommon, we just + * divide on the destination depth. + */ + if (scolors) + rop_set_s_bitmap_subbyte(&ropper, srow, sx); + else + rop_set_s_bitmap(&ropper, sptr); + if (tcolors) + rop_set_t_bitmap_subbyte(&ropper, trow, tx); + else + rop_set_t_bitmap(&ropper, tptr); #ifdef COMPARE_AND_CONTRAST - bytelen = left*bpp; start = dptr; - memcpy(testbuffer, dptr, bytelen); - rop_run(&ropper, testbuffer, left); - if (bpp == 1) { + bytelen = left*bpp; start = dptr; + memcpy(testbuffer, dptr, bytelen); + rop_run(&ropper, testbuffer, left); + if (bpp == 1) { /**** 8-bit destination ****/ - for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) { - byte s_pixel = - (scolors ? cbit8(srow, sx, scolors) : *sptr); - byte t_pixel = - (tcolors ? cbit8(trow, tx, tcolors) : *tptr); - - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), t_pixel); - rop_body_8(s_pixel, t_pixel); - } - } else { + for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) { + byte s_pixel = + (scolors ? cbit8(srow, sx, scolors) : *sptr); + byte t_pixel = + (tcolors ? cbit8(trow, tx, tcolors) : *tptr); + + rop_body_8(s_pixel, t_pixel); + } + } else { /**** 24-bit destination ****/ - for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) { - bits32 s_pixel = - (scolors ? cbit24(srow, sx, scolors) : - get24(sptr)); - bits32 t_pixel = - (tcolors ? cbit24(tptr, tx, tcolors) : - get24(tptr)); - - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), t_pixel); - rop_body_24(s_pixel, t_pixel); + for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) { + bits32 s_pixel = + (scolors ? cbit24(srow, sx, scolors) : + get24(sptr)); + bits32 t_pixel = + (tcolors ? cbit24(tptr, tx, tcolors) : + get24(tptr)); + + rop_body_24(s_pixel, t_pixel); + } + } + if (memcmp(testbuffer, start, bytelen) != 0) { + emprintf(dev->memory, "Failed!\n"); } - } - if (memcmp(testbuffer, start, bytelen) != 0) { - emprintf(dev->memory, "Failed!\n"); - } #else - rop_run(&ropper, dptr, left); + rop_run(&ropper, dptr, left); + dptr += left * bpp; #endif + } } } } else { @@ -539,53 +562,55 @@ const byte *srow = sdata; /* Loop over scan lines. */ - rop_get_run_op(&ropper, rop, depth, 0); - for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */ - int sx = sourcex; - int dx = x; - int w = width; - int nw; - byte *dptr = drow; - const byte *trow = - textures->data + (ty % textures->size.y) * traster; - int xoff = x_offset(phase_x, ty, textures); - - for (; w > 0; dx += nw, w -= nw) { /* Loop over individual pixels. */ - int tx = (dx + xoff) % textures->rep_width; - int left = nw = min(w, textures->size.x - tx); - const byte *tptr = trow + tx * bpp; - const byte *sptr = srow + sx * bpp; + if (rop_get_run_op(&ropper, lop, depth, 0)) { + for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */ + int sx = sourcex; + int dx = x; + int w = width; + int nw; + byte *dptr = drow; + const byte *trow = + textures->data + (ty % textures->size.y) * traster; + int xoff = x_offset(phase_x, ty, textures); + + for (; w > 0; sx += nw, dx += nw, w -= nw) { /* Loop over individual pixels. */ + int tx = (dx + xoff) % textures->rep_width; + int left = nw = min(w, textures->size.x - tx); + const byte *tptr = trow + tx * bpp; + const byte *sptr = srow + sx * bpp; - rop_set_s_bitmap(&ropper, sptr); - rop_set_t_bitmap(&ropper, tptr); + rop_set_s_bitmap(&ropper, sptr); + rop_set_t_bitmap(&ropper, tptr); #ifdef COMPARE_AND_CONTRAST - if (bpp == 1) { - rop_run(&ropper, testbuffer, left); + if (bpp == 1) { + rop_run(&ropper, testbuffer, left); /**** 8-bit destination ****/ - for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) { - rop_body_8(*sptr, *tptr); - } - } else { + for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) { + rop_body_8(*sptr, *tptr); + } + } else { /**** 24-bit destination ****/ - for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) { - bits32 s_pixel = get24(sptr); - bits32 t_pixel = get24(tptr); + for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) { + bits32 s_pixel = get24(sptr); + bits32 t_pixel = get24(tptr); - rop_body_24(s_pixel, t_pixel); + rop_body_24(s_pixel, t_pixel); + } + } + if (memcmp(testbuffer, start, bytelen) != 0) { + emprintf(dev->memory, "Failed!\n"); } - } - if (memcmp(testbuffer, start, bytelen) != 0) { - emprintf(dev->memory, "Failed!\n"); - } #else /**** 8-bit destination ****/ /**** 24-bit destination ****/ - rop_run(&ropper, dptr, left); + rop_run(&ropper, dptr, left); + dptr += left * bpp; #endif + } } + rop_release_run_op(&ropper); } - rop_release_run_op(&ropper); } } #undef rop_body_8 @@ -635,15 +660,11 @@ if (bpp == 1) /**** 8-bit destination ****/ for (; left > 0; ++dptr, --left) { - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), const_texture); rop_body_8((byte)const_source, (byte)const_texture); } else /**** 24-bit destination ****/ for (; left > 0; dptr += 3, --left) { - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(const_source, const_texture); } } @@ -664,8 +685,6 @@ for (; left > 0; ++dptr, ++sx, --left) { byte s_pixel = cbit8(srow, sx, scolors); - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), const_texture); rop_body_8(s_pixel, (byte)const_texture); } else @@ -673,8 +692,6 @@ for (; left > 0; dptr += 3, ++sx, --left) { bits32 s_pixel = cbit24(srow, sx, scolors); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(s_pixel, const_texture); } } else if (bpp == 1) { @@ -684,8 +701,6 @@ for (; left > 0; ++dptr, ++sptr, --left) { byte s_pixel = *sptr; - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), const_texture); rop_body_8(s_pixel, (byte)const_texture); } } else { @@ -695,8 +710,6 @@ for (; left > 0; dptr += 3, sptr += 3, --left) { bits32 s_pixel = get24(sptr); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(s_pixel, const_texture); } } @@ -726,8 +739,6 @@ for (; left > 0; ++dptr, ++tx, --left) { byte t_pixel = cbit8(tptr, tx, tcolors); - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8((byte)const_source, t_pixel); } else @@ -735,8 +746,6 @@ for (; left > 0; dptr += 3, ++tx, --left) { bits32 t_pixel = cbit24(tptr, tx, tcolors); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(const_source, t_pixel); } } else if (bpp == 1) { @@ -745,8 +754,6 @@ for (; left > 0; ++dptr, ++tptr, --left) { byte t_pixel = *tptr; - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8((byte)const_source, t_pixel); } } else { @@ -755,8 +762,6 @@ for (; left > 0; dptr += 3, tptr += 3, --left) { bits32 t_pixel = get24(tptr); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(const_source, t_pixel); } } @@ -803,8 +808,6 @@ byte t_pixel = (tcolors ? cbit8(tptr, tx, tcolors) : *tptr); - vd_pixel(int2fixed((dptr - base) % draster), - int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8(s_pixel, t_pixel); } } else { @@ -820,8 +823,6 @@ (tcolors ? cbit24(tptr, tx, tcolors) : get24(tptr)); - vd_pixel(int2fixed((dptr - base) % draster / 3), - int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(s_pixel, t_pixel); } } diff -Nru ghostscript-9.10~dfsg/base/gdevmrop.h ghostscript-9.25~dfsg+1/base/gdevmrop.h --- ghostscript-9.10~dfsg/base/gdevmrop.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmrop.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Definitions for device RasterOp implementations. */ diff -Nru ghostscript-9.10~dfsg/base/gdevmrun.c ghostscript-9.25~dfsg+1/base/gdevmrun.c --- ghostscript-9.10~dfsg/base/gdevmrun.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmrun.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Run-length encoded memory device */ diff -Nru ghostscript-9.10~dfsg/base/gdevmrun.h ghostscript-9.25~dfsg+1/base/gdevmrun.h --- ghostscript-9.10~dfsg/base/gdevmrun.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmrun.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Definition of run-length encoded memory device */ diff -Nru ghostscript-9.10~dfsg/base/gdevmx.c ghostscript-9.25~dfsg+1/base/gdevmx.c --- ghostscript-9.10~dfsg/base/gdevmx.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevmx.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* x-bit-per-pixel "memory" (stored bitmap) device. */ diff -Nru ghostscript-9.10~dfsg/base/gdevnfwd.c ghostscript-9.25~dfsg+1/base/gdevnfwd.c --- ghostscript-9.10~dfsg/base/gdevnfwd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevnfwd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Null and forwarding device implementation */ @@ -44,7 +44,9 @@ if (target && !fdev->finalize) fdev->finalize = gx_device_forward_finalize; rc_assign(fdev->target, target, "gx_device_set_target"); - fdev->graphics_type_tag = target != NULL ? target->graphics_type_tag : 0; /* initialize to same as target */ + /* try to initialize to same as target, otherwise UNKNOWN */ + fdev->graphics_type_tag = target != NULL ? target->graphics_type_tag : GS_UNKNOWN_TAG; + fdev->interpolate_control = target != NULL ? target->interpolate_control : 1; /* the default */ } /* Fill in NULL procedures in a forwarding device procedure record. */ @@ -416,7 +418,7 @@ } int -gx_forward_fill_path(gx_device * dev, const gs_imager_state * pis, +gx_forward_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) @@ -427,11 +429,11 @@ (tdev == 0 ? (tdev = dev, gx_default_fill_path) : dev_proc(tdev, fill_path)); - return proc(tdev, pis, ppath, params, pdcolor, pcpath); + return proc(tdev, pgs, ppath, params, pdcolor, pcpath); } int -gx_forward_stroke_path(gx_device * dev, const gs_imager_state * pis, +gx_forward_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_stroke_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) @@ -442,7 +444,7 @@ (tdev == 0 ? (tdev = dev, gx_default_stroke_path) : dev_proc(tdev, stroke_path)); - return proc(tdev, pis, ppath, params, pdcolor, pcpath); + return proc(tdev, pgs, ppath, params, pdcolor, pcpath); } int @@ -524,7 +526,7 @@ int gx_forward_begin_image(gx_device * dev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, @@ -536,7 +538,7 @@ (tdev == 0 ? (tdev = dev, gx_default_begin_image) : dev_proc(tdev, begin_image)); - return proc(tdev, pis, pim, format, prect, pdcolor, pcpath, + return proc(tdev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); } @@ -618,7 +620,7 @@ return gx_default_strip_tile_rect_devn(dev, tiles, x, y, w, h, pdcolor0, pdcolor1, px, py); else - return dev_proc(tdev, strip_tile_rect_devn)(dev, tiles, x, y, w, h, + return dev_proc(tdev, strip_tile_rect_devn)(tdev, tiles, x, y, w, h, pdcolor0, pdcolor1, px, py); } @@ -635,7 +637,7 @@ } int -gx_forward_begin_typed_image(gx_device * dev, const gs_imager_state * pis, +gx_forward_begin_typed_image(gx_device * dev, const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pim, const gs_int_rect * prect, @@ -650,7 +652,7 @@ (tdev == 0 ? (tdev = dev, gx_default_begin_typed_image) : dev_proc(tdev, begin_typed_image)); - return proc(tdev, pis, pmat, pim, prect, pdcolor, pcpath, + return proc(tdev, pgs, pmat, pim, prect, pdcolor, pcpath, memory, pinfo); } @@ -689,7 +691,7 @@ } int -gx_forward_text_begin(gx_device * dev, gs_imager_state * pis, +gx_forward_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, @@ -701,7 +703,7 @@ (tdev == 0 ? (tdev = dev, gx_default_text_begin) : dev_proc(tdev, text_begin)); - return proc(tdev, pis, text, font, path, pdcolor, pcpath, + return proc(tdev, pgs, text, font, path, pdcolor, pcpath, memory, ppenum); } @@ -714,38 +716,34 @@ fwd_map_gray_cs(gx_device * dev, frac gray, frac out[]) { gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device * const tdev = fdev->target; - const gx_cm_color_map_procs * pprocs; + gx_device * tdev = fdev->target; + subclass_color_mappings scm; - /* Verify that all of the pointers and procs are set */ - /* If not then use a default routine. This case should be an error */ - if (tdev == 0 || dev_proc(tdev, get_color_mapping_procs) == 0 || - (pprocs = dev_proc(tdev, get_color_mapping_procs(tdev))) == 0 || - pprocs->map_gray == 0) - gray_cs_to_gray_cm(tdev, gray, out); /* if all else fails */ + if (tdev) { + scm = get_color_mapping_procs_subclass(tdev); + map_gray_subclass(scm, gray, out); + } else - pprocs->map_gray(tdev, gray, out); + gray_cs_to_gray_cm(tdev, gray, out); /* if all else fails */ } /* * We need to forward the color mapping to the target device. */ static void -fwd_map_rgb_cs(gx_device * dev, const gs_imager_state *pis, +fwd_map_rgb_cs(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device * const tdev = fdev->target; - const gx_cm_color_map_procs * pprocs; + gx_device * tdev = fdev->target; + subclass_color_mappings scm; - /* Verify that all of the pointers and procs are set */ - /* If not then use a default routine. This case should be an error */ - if (tdev == 0 || dev_proc(tdev, get_color_mapping_procs) == 0 || - (pprocs = dev_proc(tdev, get_color_mapping_procs(tdev))) == 0 || - pprocs->map_rgb == 0) - rgb_cs_to_rgb_cm(tdev, pis, r, g, b, out); /* if all else fails */ + if (tdev) { + scm = get_color_mapping_procs_subclass(tdev); + map_rgb_subclass(scm, pgs, r, g, b, out); + } else - pprocs->map_rgb(tdev, pis, r, g, b, out); + rgb_cs_to_rgb_cm(tdev, pgs, r, g, b, out); /* if all else fails */ } /* @@ -755,17 +753,15 @@ fwd_map_cmyk_cs(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { gx_device_forward * const fdev = (gx_device_forward *)dev; - gx_device * const tdev = fdev->target; - const gx_cm_color_map_procs * pprocs; + gx_device * tdev = fdev->target; + subclass_color_mappings scm; - /* Verify that all of the pointers and procs are set */ - /* If not then use a default routine. This case should be an error */ - if (tdev == 0 || dev_proc(tdev, get_color_mapping_procs) == 0 || - (pprocs = dev_proc(tdev, get_color_mapping_procs(tdev))) == 0 || - pprocs->map_cmyk == 0) - cmyk_cs_to_cmyk_cm(tdev, c, m, y, k, out); /* if all else fails */ + if (tdev) { + scm = get_color_mapping_procs_subclass(tdev); + map_cmyk_subclass(scm, c, m, y, k, out); + } else - pprocs->map_cmyk(tdev, c, m, y, k, out); + cmyk_cs_to_cmyk_cm(tdev, c, m, y, k, out); /* if all else fails */ } static const gx_cm_color_map_procs FwdDevice_cm_map_procs = { @@ -784,8 +780,7 @@ const gx_device_forward * fdev = (const gx_device_forward *)dev; gx_device * tdev = fdev->target; - return (tdev == 0 || dev_proc(tdev, get_color_mapping_procs) == 0 - ? gx_default_DevGray_get_color_mapping_procs(dev) + return (tdev == 0 ? gx_default_DevGray_get_color_mapping_procs(dev) : &FwdDevice_cm_map_procs); } @@ -836,10 +831,11 @@ so this function is unapplicable to clist. */ if (tdev == 0) { if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path) { - return (dev->procs.fill_path == gx_default_fill_path); + return (dev_proc(dev, fill_path) == gx_default_fill_path); } + return_error(gs_error_undefined); } else if (dev_spec_op == gxdso_pattern_handles_clip_path) { - if (dev->procs.fill_path == gx_default_fill_path) + if (dev_proc(dev, fill_path) == gx_default_fill_path) return 0; } else if (dev_spec_op == gxdso_device_child) { gxdso_device_child_request *d = (gxdso_device_child_request *)data; @@ -854,7 +850,7 @@ int gx_forward_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_forward * const fdev = (gx_device_forward *)dev; @@ -866,7 +862,7 @@ return_error(gs_error_rangecheck); else return dev_proc(tdev, fill_rectangle_hl_color)(tdev, rect, - pis, pdcolor, pcpath); + pgs, pdcolor, pcpath); } int @@ -942,7 +938,7 @@ } int -gx_forward_update_spot_equivalent_colors(gx_device *dev, const gs_state * pgs) +gx_forward_update_spot_equivalent_colors(gx_device *dev, const gs_gstate * pgs) { gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device *tdev = fdev->target; @@ -965,20 +961,20 @@ } int -gx_forward_fillpage(gx_device *dev, gs_imager_state * pis, gx_device_color *pdevc) +gx_forward_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) { gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device *tdev = fdev->target; dev_proc_fillpage((*proc)) = (tdev == 0 ? (tdev = dev, gx_default_fillpage) : dev_proc(tdev, fillpage)); - return proc(tdev, pis, pdevc); + return proc(tdev, pgs, pdevc); } int gx_forward_create_compositor(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, - gs_imager_state * pis, gs_memory_t * memory, + gs_gstate * pgs, gs_memory_t * memory, gx_device *cdev) { gx_device_forward * const fdev = (gx_device_forward *)dev; @@ -986,9 +982,9 @@ int code; if (tdev == 0) - return gx_no_create_compositor(dev, pcdev, pcte, pis, memory, cdev); + return gx_no_create_compositor(dev, pcdev, pcte, pgs, memory, cdev); /* else do the compositor action */ - code = dev_proc(tdev, create_compositor)(tdev, pcdev, pcte, pis, memory, cdev); + code = dev_proc(tdev, create_compositor)(tdev, pcdev, pcte, pgs, memory, cdev); /* the compositor may have changed color_info. Pick up the new value */ dev->color_info = tdev->color_info; return code; @@ -1039,6 +1035,7 @@ static dev_proc_strip_copy_rop(null_strip_copy_rop); static dev_proc_strip_copy_rop2(null_strip_copy_rop2); static dev_proc_strip_tile_rect_devn(null_strip_tile_rect_devn); +static dev_proc_fill_rectangle_hl_color(null_fill_rectangle_hl_color); #define null_procs(get_initial_matrix, get_page_device) {\ gx_default_open_device,\ @@ -1095,13 +1092,13 @@ gx_default_gray_fast_encode, /* encode_color */\ null_decode_color, /* decode_color */\ NULL, /* pattern_manage */\ - gx_default_fill_rectangle_hl_color,\ + null_fill_rectangle_hl_color,\ gx_default_include_color_space,\ NULL, /* fill_line_sl */\ NULL, /* fill_line_tr */\ NULL, /* fill_line_tri */\ NULL, /* up_spot_eq_col */\ - NULL, /* ret_devn_params */\ + gx_default_ret_devn_params, /* ret_devn_params */\ NULL, /* fillpage */\ NULL, /* push_transparency_state */\ NULL, /* pop_transparency_state */\ @@ -1206,14 +1203,14 @@ return 0; } static int -null_fill_path(gx_device * dev, const gs_imager_state * pis, +null_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) { return 0; } static int -null_stroke_path(gx_device * dev, const gs_imager_state * pis, +null_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_stroke_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) { @@ -1285,6 +1282,22 @@ return 0; } +/* We use this to erase a pattern background, if pdfwrite has pushed + * the NULL device to dispense with text (because its a strinwidth) + * we don't want to throw an error when erasing the pattern which + * fills the text, because pdfwrite manages the pattern itself and + * we don't need to erase hte background. More generally, since the + * null device is a bit bucket, it shouldn't really throw errors + * when asked to render anything at all. + */ +static int null_fill_rectangle_hl_color(gx_device *pdev, + const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath) +{ + return 0; +} + bool fwd_uses_fwd_cmap_procs(gx_device * dev) { @@ -1324,7 +1337,7 @@ dmlprintf(dev->memory, "NULL\n"); return; } - dmlprintf3(dev->memory, "%x(%d) = '%s'\n", dev, dev->rc.ref_count, dev->dname); + dmlprintf3(dev->memory, "%p(%ld) = '%s'\n", dev, dev->rc.ref_count, dev->dname); data.n = 0; do { diff -Nru ghostscript-9.10~dfsg/base/gdevoflt.c ghostscript-9.25~dfsg+1/base/gdevoflt.c --- ghostscript-9.10~dfsg/base/gdevoflt.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevoflt.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,557 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Derived from gdevflp.c */ +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gsdevice.h" /* requires gsmatrix.h */ +#include "gxdcolor.h" /* for gx_device_black/white */ +#include "gxiparam.h" /* for image source size */ +#include "gxgstate.h" +#include "gxpaint.h" +#include "gxpath.h" +#include "gxcpath.h" +#include "gxcmap.h" /* color mapping procs */ +#include "gsstype.h" +#include "gdevprn.h" +#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ +#include "gximage.h" /* For gx_image_enum */ +#include "gdevsclass.h" +#include "gdevoflt.h" + +int gs_is_pdf14trans_compositor(const gs_composite_t * pct); + +/* GC descriptor */ +public_st_device_obj_filter(); +/* we need text and image enumerators, because of the crazy way that text and images work */ +private_st_obj_filter_text_enum(); + +/* Device procedures, we need to implement all of them */ +static dev_proc_fill_rectangle(obj_filter_fill_rectangle); +static dev_proc_tile_rectangle(obj_filter_tile_rectangle); +static dev_proc_draw_line(obj_filter_draw_line); +static dev_proc_fill_path(obj_filter_fill_path); +static dev_proc_stroke_path(obj_filter_stroke_path); +static dev_proc_fill_mask(obj_filter_fill_mask); +static dev_proc_fill_trapezoid(obj_filter_fill_trapezoid); +static dev_proc_fill_parallelogram(obj_filter_fill_parallelogram); +static dev_proc_fill_triangle(obj_filter_fill_triangle); +static dev_proc_draw_thin_line(obj_filter_draw_thin_line); +static dev_proc_begin_image(obj_filter_begin_image); +static dev_proc_image_data(obj_filter_image_data); +static dev_proc_end_image(obj_filter_end_image); +static dev_proc_strip_tile_rectangle(obj_filter_strip_tile_rectangle); +static dev_proc_strip_copy_rop(obj_filter_strip_copy_rop); +static dev_proc_begin_typed_image(obj_filter_begin_typed_image); +static dev_proc_text_begin(obj_filter_text_begin); +static dev_proc_fill_rectangle_hl_color(obj_filter_fill_rectangle_hl_color); +static dev_proc_fill_linear_color_scanline(obj_filter_fill_linear_color_scanline); +static dev_proc_fill_linear_color_trapezoid(obj_filter_fill_linear_color_trapezoid); +static dev_proc_fill_linear_color_triangle(obj_filter_fill_linear_color_triangle); +static dev_proc_put_image(obj_filter_put_image); +static dev_proc_strip_copy_rop2(obj_filter_strip_copy_rop2); +static dev_proc_strip_tile_rect_devn(obj_filter_strip_tile_rect_devn); + +/* The device prototype */ +#define MAX_COORD (max_int_in_fixed - 1000) +#define MAX_RESOLUTION 4000 + +#define public_st_obj_filter_device() /* in gsdevice.c */\ + gs_public_st_complex_only(st_obj_filter_device, gx_device, "object filter",\ + 0, obj_filter_enum_ptrs, obj_filter_reloc_ptrs, default_subclass_finalize) + +static +ENUM_PTRS_WITH(obj_filter_enum_ptrs, gx_device *dev); +return 0; /* default case */ +case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); +case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); +ENUM_PTRS_END +static RELOC_PTRS_WITH(obj_filter_reloc_ptrs, gx_device *dev) +{ + dev->parent = gx_device_reloc_ptr(dev->parent, gcst); + dev->child = gx_device_reloc_ptr(dev->child, gcst); +} +RELOC_PTRS_END + +public_st_obj_filter_device(); + +const +gx_device_obj_filter gs_obj_filter_device = +{ + /* + * Define the device as 8-bit gray scale to avoid computing halftones. + */ + std_device_dci_type_body(gx_device_obj_filter, 0, "object_filter", &st_obj_filter_device, + MAX_COORD, MAX_COORD, + MAX_RESOLUTION, MAX_RESOLUTION, + 1, 8, 255, 0, 256, 1), + {default_subclass_open_device, + default_subclass_get_initial_matrix, + default_subclass_sync_output, /* sync_output */ + default_subclass_output_page, + default_subclass_close_device, + default_subclass_map_rgb_color, + default_subclass_map_color_rgb, + obj_filter_fill_rectangle, + obj_filter_tile_rectangle, /* tile_rectangle */ + default_subclass_copy_mono, + default_subclass_copy_color, + obj_filter_draw_line, /* draw_line */ + default_subclass_get_bits, /* get_bits */ + default_subclass_get_params, + default_subclass_put_params, + default_subclass_map_cmyk_color, + default_subclass_get_xfont_procs, /* get_xfont_procs */ + default_subclass_get_xfont_device, /* get_xfont_device */ + default_subclass_map_rgb_alpha_color, + default_subclass_get_page_device, + default_subclass_get_alpha_bits, /* get_alpha_bits */ + default_subclass_copy_alpha, + default_subclass_get_band, /* get_band */ + default_subclass_copy_rop, /* copy_rop */ + obj_filter_fill_path, + obj_filter_stroke_path, + obj_filter_fill_mask, + obj_filter_fill_trapezoid, + obj_filter_fill_parallelogram, + obj_filter_fill_triangle, + obj_filter_draw_thin_line, + obj_filter_begin_image, + obj_filter_image_data, /* image_data */ + obj_filter_end_image, /* end_image */ + obj_filter_strip_tile_rectangle, + obj_filter_strip_copy_rop, + default_subclass_get_clipping_box, /* get_clipping_box */ + obj_filter_begin_typed_image, + default_subclass_get_bits_rectangle, /* get_bits_rectangle */ + default_subclass_map_color_rgb_alpha, + default_subclass_create_compositor, + default_subclass_get_hardware_params, /* get_hardware_params */ + obj_filter_text_begin, + default_subclass_finish_copydevice, /* finish_copydevice */ + default_subclass_begin_transparency_group, /* begin_transparency_group */ + default_subclass_end_transparency_group, /* end_transparency_group */ + default_subclass_begin_transparency_mask, /* begin_transparency_mask */ + default_subclass_end_transparency_mask, /* end_transparency_mask */ + default_subclass_discard_transparency_layer, /* discard_transparency_layer */ + default_subclass_get_color_mapping_procs, /* get_color_mapping_procs */ + default_subclass_get_color_comp_index, /* get_color_comp_index */ + default_subclass_encode_color, /* encode_color */ + default_subclass_decode_color, /* decode_color */ + default_subclass_pattern_manage, /* pattern_manage */ + obj_filter_fill_rectangle_hl_color, /* fill_rectangle_hl_color */ + default_subclass_include_color_space, /* include_color_space */ + obj_filter_fill_linear_color_scanline, /* fill_linear_color_scanline */ + obj_filter_fill_linear_color_trapezoid, /* fill_linear_color_trapezoid */ + obj_filter_fill_linear_color_triangle, /* fill_linear_color_triangle */ + default_subclass_update_spot_equivalent_colors, /* update_spot_equivalent_colors */ + default_subclass_ret_devn_params, /* ret_devn_params */ + default_subclass_fillpage, /* fillpage */ + default_subclass_push_transparency_state, /* push_transparency_state */ + default_subclass_pop_transparency_state, /* pop_transparency_state */ + obj_filter_put_image, /* put_image */ + default_subclass_dev_spec_op, /* dev_spec_op */ + default_subclass_copy_planes, /* copy_planes */ + default_subclass_get_profile, /* get_profile */ + default_subclass_set_graphics_type_tag, /* set_graphics_type_tag */ + obj_filter_strip_copy_rop2, + obj_filter_strip_tile_rect_devn, + default_subclass_copy_alpha_hl_color, + default_subclass_process_page + } +}; + +#undef MAX_COORD +#undef MAX_RESOLUTION + +int obj_filter_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_rectangle(dev, x, y, width, height, color); + return 0; +} + +int obj_filter_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_tile_rectangle(dev, tile, x, y, width, height, color0, color1, phase_x, phase_y); + return 0; +} + +int obj_filter_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_draw_line(dev, x0, y0, x1, y1, color); + return 0; +} + +int obj_filter_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_fill_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); + return 0; +} + +int obj_filter_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_stroke_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); + return 0; +} + +int obj_filter_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, + const gx_drawing_color *pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path *pcpath) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_fill_mask(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); + return 0; +} + +int obj_filter_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, + fixed ybot, fixed ytop, bool swap_axes, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); + return 0; +} + +int obj_filter_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_parallelogram(dev, px, py, ax, ay, bx, by, pdcolor, lop); + return 0; +} + +int obj_filter_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_triangle(dev, px, py, ax, ay, bx, by, pdcolor, lop); + return 0; +} + +int obj_filter_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop, + fixed adjustx, fixed adjusty) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); + return 0; +} + +int obj_filter_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, + gs_image_format_t format, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); + return 0; +} + +int obj_filter_image_data(gx_device *dev, gx_image_enum_common_t *info, const byte **planes, int data_x, + uint raster, int height) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_image_data(dev, info, planes, data_x, raster, height); + return 0; +} + +int obj_filter_end_image(gx_device *dev, gx_image_enum_common_t *info, bool draw_last) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_end_image(dev, info, draw_last); + return 0; +} + +int obj_filter_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); + return 0; +} + +int obj_filter_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, + const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); + return 0; +} + +typedef struct obj_filter_image_enum_s { + gx_image_enum_common; + int y; + int height; +} obj_filter_image_enum; +gs_private_st_composite(st_obj_filter_image_enum, obj_filter_image_enum, "obj_filter_image_enum", + obj_filter_image_enum_enum_ptrs, obj_filter_image_enum_reloc_ptrs); + +static ENUM_PTRS_WITH(obj_filter_image_enum_enum_ptrs, obj_filter_image_enum *pie) + (void)pie; /* Silence unused var warning */ + return ENUM_USING_PREFIX(st_gx_image_enum_common, 0); +ENUM_PTRS_END +static RELOC_PTRS_WITH(obj_filter_image_enum_reloc_ptrs, obj_filter_image_enum *pie) +{ + (void)pie; /* Silence unused var warning */ + RELOC_USING(st_gx_image_enum_common, vptr, size); +} +RELOC_PTRS_END + +static int +obj_filter_image_plane_data(gx_image_enum_common_t * info, + const gx_image_plane_t * planes, int height, + int *rows_used) +{ + obj_filter_image_enum *pie = (obj_filter_image_enum *)info; + + pie->y += height; + *rows_used = height; + + if (pie->y < pie->height) + return 0; + return 1; +} + +static int +obj_filter_image_end_image(gx_image_enum_common_t * info, bool draw_last) +{ + return 0; +} + +static const gx_image_enum_procs_t obj_filter_image_enum_procs = { + obj_filter_image_plane_data, + obj_filter_image_end_image +}; + +int obj_filter_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, + const gs_image_common_t *pic, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + obj_filter_image_enum *pie; + const gs_pixel_image_t *pim = (const gs_pixel_image_t *)pic; + int num_components; + + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); + + if (pic->type->index == 1) { + const gs_image_t *pim1 = (const gs_image_t *)pic; + + if (pim1->ImageMask) + num_components = 1; + else + num_components = gs_color_space_num_components(pim->ColorSpace); + } else { + num_components = gs_color_space_num_components(pim->ColorSpace); + } + + pie = gs_alloc_struct(memory, obj_filter_image_enum, &st_obj_filter_image_enum, + "obj_filter_begin_image"); + if (pie == 0) + return_error(gs_error_VMerror); + memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */ + *pinfo = (gx_image_enum_common_t *) pie; + gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim, &obj_filter_image_enum_procs, + (gx_device *)dev, num_components, pim->format); + pie->memory = memory; + pie->skipping = true; + pie->height = pim->Height; + pie->y = 0; + + return 0; +} + +/* Text processing (like images) works differently to other device + * methods. Instead of the interpreter calling a device method, only + * the 'begin' method is called, this creates a text enumerator which + * it fills in (in part with the routines for processing text) and returns + * to the interpreter. The interpreter then calls the methods defined in + * the text enumerator to process the text. + * Mad as a fish..... + */ + +/* For our purposes if we are handling the text its because we are not + * printing the page, so we cna afford to ignore all the text processing. + * A more complex device might need to define real handlers for these, and + * pass them on to the subclassed device. + */ +static text_enum_proc_process(obj_filter_text_process); +static int +obj_filter_text_resync(gs_text_enum_t *pte, const gs_text_enum_t *pfrom) +{ + return 0; +} +int +obj_filter_text_process(gs_text_enum_t *pte) +{ + return 0; +} +static bool +obj_filter_text_is_width_only(const gs_text_enum_t *pte) +{ + return false; +} +static int +obj_filter_text_current_width(const gs_text_enum_t *pte, gs_point *pwidth) +{ + return 0; +} +static int +obj_filter_text_set_cache(gs_text_enum_t *pte, const double *pw, + gs_text_cache_control_t control) +{ + return 0; +} +static int +obj_filter_text_retry(gs_text_enum_t *pte) +{ + return 0; +} +static void +obj_filter_text_release(gs_text_enum_t *pte, client_name_t cname) +{ + gx_default_text_release(pte, cname); +} + +static const gs_text_enum_procs_t obj_filter_text_procs = { + obj_filter_text_resync, obj_filter_text_process, + obj_filter_text_is_width_only, obj_filter_text_current_width, + obj_filter_text_set_cache, obj_filter_text_retry, + obj_filter_text_release +}; + +/* The device method which we do actually need to define. Either we are skipping the page, + * in which case we create a text enumerator with our dummy procedures, or we are leaving it + * up to the device, in which case we simply pass on the 'begin' method to the device. + */ +int obj_filter_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, + gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gs_text_enum_t **ppte) +{ + obj_filter_text_enum_t *penum; + int code = 0; + + /* We don't want to simply ignore stringwidth for 2 reasons; + * firstly because following elelments may be positioned based on the value returned + * secondly because op_show_restore executes an unconditional grestore, assuming + * that a gsave has been done simply *because* its a tringwidth operation ! + */ + if ((text->operation & TEXT_DO_NONE) && (text->operation & TEXT_RETURN_WIDTH) && pgs->text_rendering_mode != 3) + /* Note that the high level devices *must* be given the opportunity to 'see' the + * stringwidth operation, or they won;t be able to cache the glyphs properly. + * So always pass stringwidth operations to the child. + */ + return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + + if ((dev->ObjectFilter & FILTERTEXT) == 0) + return default_subclass_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + + rc_alloc_struct_1(penum, obj_filter_text_enum_t, &st_obj_filter_text_enum, memory, + return_error(gs_error_VMerror), "gdev_obj_filter_text_begin"); + penum->rc.free = rc_free_text_enum; + code = gs_text_enum_init((gs_text_enum_t *)penum, &obj_filter_text_procs, + dev, pgs, text, font, path, pdcolor, pcpath, memory); + if (code < 0) { + gs_free_object(memory, penum, "gdev_obj_filter_text_begin"); + return code; + } + *ppte = (gs_text_enum_t *)penum; + + return 0; +} + +int obj_filter_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_rectangle_hl_color(dev, rect, pgs, pdcolor, pcpath); + return 0; +} + +int obj_filter_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, + int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, + int32_t cg_den) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); + return 0; +} + +int obj_filter_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const gs_fixed_point *p3, + const frac31 *c0, const frac31 *c1, + const frac31 *c2, const frac31 *c3) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); + return 0; +} + +int obj_filter_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) +{ + if ((dev->ObjectFilter & FILTERVECTOR) == 0) + return default_subclass_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2); + return 0; +} + +int obj_filter_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y, + int width, int height, int row_stride, + int alpha_plane_index, int tag_plane_index) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_put_image(dev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); + return 0; +} + +int obj_filter_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_strip_copy_rop2(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height); + return 0; +} + +int obj_filter_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, + const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y) +{ + if ((dev->ObjectFilter & FILTERIMAGE) == 0) + return default_subclass_strip_tile_rect_devn(dev, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/gdevoflt.h ghostscript-9.25~dfsg+1/base/gdevoflt.h --- ghostscript-9.10~dfsg/base/gdevoflt.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevoflt.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,47 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Common definitions for "object filter" device */ + +#ifndef gdev_obj_filter_INCLUDED +# define gdev_obj_filter_INCLUDED + +#ifndef gxdevice_INCLUDED +#include "gxdevice.h" +#endif + +typedef struct gx_device_s gx_device_obj_filter; + +/* Initialize a object filter device. */ +void gx_device_obj_filter_init(gx_device_obj_filter * dev); + +typedef struct { + subclass_common; +} obj_filter_subclass_data; + +typedef struct obj_filter_text_enum_s { + gs_text_enum_common; +} obj_filter_text_enum_t; +#define private_st_obj_filter_text_enum()\ + extern_st(st_gs_text_enum);\ + gs_private_st_suffix_add0(st_obj_filter_text_enum, obj_filter_text_enum_t,\ + "obj_filter_text_enum_t", obj_filter_text_enum_enum_ptrs, obj_filter_text_enum_reloc_ptrs,\ + st_gs_text_enum) + +extern_st(st_device_obj_filter); +#define public_st_device_obj_filter() /* in gdevoflt.c */\ + +#endif /* gdev_obj_filter_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevp14.c ghostscript-9.25~dfsg+1/base/gdevp14.c --- ghostscript-9.10~dfsg/base/gdevp14.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevp14.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Compositing devices for implementing PDF 1.4 imaging model */ @@ -23,19 +23,20 @@ #include "gxdevice.h" #include "gsdevice.h" #include "gsstruct.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdcolor.h" #include "gxiparam.h" #include "gstparam.h" #include "gxblend.h" #include "gxtext.h" -#include "gsdfilt.h" #include "gsimage.h" #include "gsrect.h" #include "gscoord.h" #include "gzstate.h" #include "gdevdevn.h" +#include "gdevmem.h" #include "gdevp14.h" +#include "gdevprn.h" /* for prn_device structures */ #include "gsovrc.h" #include "gxcmap.h" #include "gscolor1.h" @@ -44,8 +45,6 @@ #include "gxcldev.h" #include "gxclpath.h" #include "gxdcconv.h" -#include "vdtrace.h" -#include "gscolorbuffer.h" #include "gsptype2.h" #include "gxpcolor.h" #include "gsptype1.h" @@ -70,33 +69,29 @@ /* Static prototypes */ /* Used for filling rects when we are doing a fill with a pattern that has transparency */ -static int -pdf14_tile_pattern_fill(gx_device * pdev, const gs_imager_state * pis, - gx_path * ppath, const gx_fill_params * params, - const gx_device_color * pdevc, const gx_clip_path * pcpath); +static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs, + gx_path * ppath, const gx_fill_params * params, + const gx_device_color * pdevc, const gx_clip_path * pcpath); static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory); static void pdf14_free_smask_color(pdf14_device * pdev); static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect, - const gs_rect *pbbox, gs_imager_state *pis); + const gs_rect *pbbox, gs_gstate *pgs); static int pdf14_clist_update_params(pdf14_clist_device * pdev, - const gs_imager_state * pis, - bool crop_blend_params, - gs_pdf14trans_params_t *group_params); -static int pdf14_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, - gx_color_index color, const gx_device_color *pdc, - bool devn); -static int pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, - int w, int h, gx_color_index color, - const gx_device_color *pdc, - bool devn); + const gs_gstate * pgs, + bool crop_blend_params, + gs_pdf14trans_params_t *group_params); +static int pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, + int w, int h, gx_color_index color, + const gx_device_color *pdc, + bool devn); static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x, - int aa_raster, gx_bitmap_id id, int x, int y, int w, int h, - gx_color_index color, const gx_device_color *pdc, - int depth, bool devn); + int aa_raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index color, const gx_device_color *pdc, + int depth, bool devn); /* Functions for dealing with soft mask color */ -static int pdf14_decrement_smask_color(gs_imager_state * pis, gx_device * dev); -static int pdf14_increment_smask_color(gs_imager_state * pis, gx_device * dev); +static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev); +static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev); /* * We chose the blending color space based upon the process color model of the @@ -114,10 +109,14 @@ /* Forward prototypes */ void pdf14_cmyk_cs_to_cmyk_cm(gx_device *, frac, frac, frac, frac, frac *); -int gs_pdf14_device_push(gs_memory_t *, gs_imager_state *, gx_device **, - gx_device *, const gs_pdf14trans_t *); +static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, + gx_device ** pdev, gx_device * target, + const gs_pdf14trans_t * pdf14pct); +static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs, + gx_device ** pdev, gx_device * target, + const gs_pdf14trans_t * pdf14pct); static int pdf14_tile_pattern_fill(gx_device * pdev, - const gs_imager_state * pis, gx_path * ppath, + const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath); static pdf14_mask_t * pdf14_mask_element_new(gs_memory_t * memory); @@ -126,9 +125,10 @@ #endif /* Buffer stack data structure */ -gs_private_st_ptrs5(st_pdf14_buf, pdf14_buf, "pdf14_buf", +gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf", pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs, - saved, data, transfer_fn, mask_stack, parent_color_info_procs); + saved, data, backdrop, transfer_fn, mask_stack, + matte, parent_color_info_procs); gs_private_st_ptrs2(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx", pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs, @@ -162,12 +162,14 @@ static int pdf14_output_page(gx_device * pdev, int num_copies, int flush); static dev_proc_put_params(pdf14_put_params); static dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index); +static dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index); +static dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index); static dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs); +static dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs); +static dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs); dev_proc_encode_color(pdf14_encode_color); dev_proc_encode_color(pdf14_encode_color_tag); -dev_proc_encode_color(pdf14_compressed_encode_color); dev_proc_decode_color(pdf14_decode_color); -dev_proc_decode_color(pdf14_compressed_decode_color); static dev_proc_fill_rectangle(pdf14_fill_rectangle); static dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color); static dev_proc_fill_path(pdf14_fill_path); @@ -176,6 +178,7 @@ static dev_proc_stroke_path(pdf14_stroke_path); static dev_proc_begin_typed_image(pdf14_begin_typed_image); static dev_proc_text_begin(pdf14_text_begin); +static dev_proc_finish_copydevice(pdf14_finish_copydevice); static dev_proc_create_compositor(pdf14_create_compositor); static dev_proc_create_compositor(pdf14_forward_create_compositor); static dev_proc_begin_transparency_group(pdf14_begin_transparency_group); @@ -183,18 +186,15 @@ static dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask); static dev_proc_end_transparency_mask(pdf14_end_transparency_mask); static dev_proc_dev_spec_op(pdf14_dev_spec_op); -static int pdf14_clist_get_param_compressed_color_list(pdf14_device * p14dev); static dev_proc_push_transparency_state(pdf14_push_transparency_state); static dev_proc_pop_transparency_state(pdf14_pop_transparency_state); static dev_proc_ret_devn_params(pdf14_ret_devn_params); static dev_proc_copy_alpha(pdf14_copy_alpha); static dev_proc_copy_planes(pdf14_copy_planes); static dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color); - +static dev_proc_discard_transparency_layer(pdf14_discard_trans_layer); static const gx_color_map_procs * - pdf14_get_cmap_procs(const gs_imager_state *, const gx_device *); -static const gx_color_map_procs * - pdf14_get_cmap_procs_group(const gs_imager_state *, const gx_device *); + pdf14_get_cmap_procs(const gs_gstate *, const gx_device *); #define XSIZE (int)(8.5 * X_DPI) /* 8.5 x 11 inch page, by default */ #define YSIZE (int)(11 * Y_DPI) @@ -246,12 +246,12 @@ pdf14_create_compositor, /* create_compositor */\ NULL, /* get_hardware_params */\ pdf14_text_begin, /* text_begin */\ - NULL, /* finish_copydevice */\ + pdf14_finish_copydevice, /* finish_copydevice */\ pdf14_begin_transparency_group,\ pdf14_end_transparency_group,\ pdf14_begin_transparency_mask,\ pdf14_end_transparency_mask,\ - NULL, /* discard_transparency_layer */\ + pdf14_discard_trans_layer,\ get_color_mapping_procs, /* get_color_mapping_procs */\ get_color_comp_index, /* get_color_comp_index */\ encode_color, /* encode_color */\ @@ -271,7 +271,7 @@ pdf14_dev_spec_op, /* dev_spec_op */\ pdf14_copy_planes, /* copy_planes */\ NULL, /* */\ - NULL, /* set_graphics_type_tag */\ + gx_forward_set_graphics_type_tag, /* set_graphics_type_tag */\ NULL, /* strip_copy_rop2 */\ NULL, /* strip_tile_rect_devn */\ pdf14_copy_alpha_hl_color /* copy_alpha_hl_color */\ @@ -292,17 +292,21 @@ gx_default_DevCMYK_get_color_comp_index, pdf14_encode_color, pdf14_decode_color); -#if USE_COMPRESSED_ENCODING -static const gx_device_procs pdf14_CMYKspot_procs = - pdf14_dev_procs(pdf14_cmykspot_get_color_mapping_procs, - pdf14_cmykspot_get_color_comp_index, - pdf14_compressed_encode_color, pdf14_compressed_decode_color); -#else static const gx_device_procs pdf14_CMYKspot_procs = pdf14_dev_procs(pdf14_cmykspot_get_color_mapping_procs, pdf14_cmykspot_get_color_comp_index, pdf14_encode_color, pdf14_decode_color); -#endif + +static const gx_device_procs pdf14_RGBspot_procs = + pdf14_dev_procs(pdf14_rgbspot_get_color_mapping_procs, + pdf14_rgbspot_get_color_comp_index, + pdf14_encode_color, pdf14_decode_color); + +static const gx_device_procs pdf14_Grayspot_procs = +pdf14_dev_procs(pdf14_grayspot_get_color_mapping_procs, + pdf14_grayspot_get_color_comp_index, + pdf14_encode_color, pdf14_decode_color); + static const gx_device_procs pdf14_custom_procs = pdf14_dev_procs(gx_forward_get_color_mapping_procs, @@ -310,34 +314,36 @@ gx_forward_encode_color, gx_forward_decode_color); +struct_proc_finalize(pdf14_device_finalize); + gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device", pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs, - gx_device_finalize); + pdf14_device_finalize); -static int pdf14_put_image(gx_device * dev, gs_imager_state * pis, +static int pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target); -static int pdf14_cmykspot_put_image(gx_device * dev, gs_imager_state * pis, +static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target); -static int pdf14_custom_put_image(gx_device * dev, gs_imager_state * pis, +static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target); /* Used to alter device color mapping procs based upon group or softmask color space */ static int pdf14_update_device_color_procs(gx_device *dev, gs_transparency_color_t group_color, int64_t icc_hashcode, - gs_imager_state *pis, cmm_profile_t *iccprofile); + gs_gstate *pgs, cmm_profile_t *iccprofile, bool is_mask); /* Used to alter device color mapping procs based upon group or softmask color space */ /* Uses color procs stack so that it can be used with clist writer */ static int pdf14_update_device_color_procs_push_c(gx_device *dev, gs_transparency_color_t group_color, int64_t icc_hashcode, - gs_imager_state *pis, cmm_profile_t *iccprofile); + gs_gstate *pgs, cmm_profile_t *iccprofile, bool is_mask); static int -pdf14_update_device_color_procs_pop_c(gx_device *dev,gs_imager_state *pis); +pdf14_update_device_color_procs_pop_c(gx_device *dev,gs_gstate *pgs); -static void pdf14_push_parent_color(gx_device *dev, const gs_imager_state *pis); -static void pdf14_pop_parent_color(gx_device *dev, const gs_imager_state *pis); +static void pdf14_push_parent_color(gx_device *dev, const gs_gstate *pgs); +static void pdf14_pop_parent_color(gx_device *dev, const gs_gstate *pgs); static const pdf14_procs_t gray_pdf14_procs = { pdf14_unpack_additive, @@ -355,7 +361,17 @@ }; static const pdf14_procs_t cmykspot_pdf14_procs = { - pdf14_unpack_compressed, + pdf14_unpack_custom, /* should never be used since we will use devn values */ + pdf14_cmykspot_put_image +}; + +static const pdf14_procs_t rgbspot_pdf14_procs = { + pdf14_unpack_rgb_mix, + pdf14_cmykspot_put_image +}; + +static const pdf14_procs_t grayspot_pdf14_procs = { + pdf14_unpack_gray_mix, pdf14_cmykspot_put_image }; @@ -379,6 +395,16 @@ art_blend_saturation_cmyk_8 }; +static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = { + art_blend_luminosity_rgb_8, + art_blend_saturation_rgb_8 +}; + +static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = { + art_blend_luminosity_custom_8, + art_blend_saturation_custom_8 +}; + static const pdf14_nonseparable_blending_procs_t custom_blending_procs = { art_blend_luminosity_custom_8, art_blend_saturation_custom_8 @@ -441,6 +467,52 @@ &cmyk_blending_procs }; +const pdf14_device gs_pdf14_RGBspot_device = { + std_device_part1_(pdf14_device, &pdf14_RGBspot_procs, "pdf14rgbspot", + &st_pdf14_device, open_init_closed), + dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), + std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), + offset_margin_values(0, 0, 0, 0, 0, 0), + std_device_part3_(), + { 0 }, /* Procs */ + NULL, /* target */ + /* DeviceN parameters */ + { 8, /* Not used - Bits per color */ + 0, /* Names of color model colorants */ + 3, /* Number colorants for RGB */ + 0, /* MaxSeparations has not been specified */ + -1, /* PageSpotColors has not been specified */ + { 0 }, /* SeparationNames */ + 0, /* SeparationOrder names */ + { 0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */ + }, + &rgbspot_pdf14_procs, + &rgbspot_blending_procs +}; + +const pdf14_device gs_pdf14_Grayspot_device = { + std_device_part1_(pdf14_device, &pdf14_Grayspot_procs, "pdf14grayspot", + &st_pdf14_device, open_init_closed), + dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256), + std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI), + offset_margin_values(0, 0, 0, 0, 0, 0), + std_device_part3_(), + { 0 }, /* Procs */ + NULL, /* target */ + /* DeviceN parameters */ + { 8, /* Not used - Bits per color */ + 0, /* Names of color model colorants */ + 3, /* Number colorants for RGB */ + 0, /* MaxSeparations has not been specified */ + -1, /* PageSpotColors has not been specified */ + { 0 }, /* SeparationNames */ + 0, /* SeparationOrder names */ + { 0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */ + }, + &grayspot_pdf14_procs, + &grayspot_blending_procs +}; + /* * The 'custom' PDF 1.4 compositor device is for working with those devices * which support spot colors but do not have a CMYK process color model. @@ -475,11 +547,79 @@ &custom_blending_procs }; +/* Devices used for pdf14-accum-* device, one for each image colorspace, */ +/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following */ +/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap. */ + +static dev_proc_print_page(no_print_page); + +static int +no_print_page(gx_device_printer *pdev, FILE *prn_stream) +{ + return_error(gs_error_unknownerror); +} + +struct gx_device_pdf14_accum_s { + gx_device_common; + gx_prn_device_common; + gx_device *save_p14dev; /* the non-clist pdf14 deivce saved for after accum */ +}; +typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum; + +gs_public_st_suffix_add1_final(st_pdf14_accum, gx_device_pdf14_accum, + "gx_device_pdf14_accum", pdf14_accum_enum_ptrs, pdf14_accum_reloc_ptrs, + gx_device_finalize, st_device_printer, save_p14dev); + +static const gx_device_procs pdf14_accum_Gray_procs = + prn_color_procs(gdev_prn_open, NULL, gdev_prn_close, + gx_default_8bit_map_gray_color, gx_default_8bit_map_color_gray); + +const gx_device_pdf14_accum pdf14_accum_Gray = { + prn_device_stype_body(gx_device_pdf14_accum, pdf14_accum_Gray_procs, "pdf14-accum-Gray", + &st_pdf14_accum, + 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, + 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, + 1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/, + 256/*dither_grays*/, 0/*dither_colors*/, + no_print_page), + 0/*save_p14dev*/ +}; + +static const gx_device_procs pdf14_accum_RGB_procs = + prn_color_procs(gdev_prn_open, NULL, gdev_prn_close, + gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb); + +const gx_device_pdf14_accum pdf14_accum_RGB = { + prn_device_stype_body(gx_device_pdf14_accum, pdf14_accum_RGB_procs, "pdf14-accum-RGB", + &st_pdf14_accum, + 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, + 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, + 3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/, + 1/*dither_grays*/, 256/*dither_colors*/, + no_print_page), + 0/*save_p14dev*/ +}; + +static const gx_device_procs pdf14_accum_CMYK_procs = + prn_color_procs(gdev_prn_open, NULL, gdev_prn_close, + cmyk_8bit_map_cmyk_color, cmyk_8bit_map_color_cmyk); + +const gx_device_pdf14_accum pdf14_accum_CMYK = { + prn_device_stype_body(gx_device_pdf14_accum, pdf14_accum_CMYK_procs, "pdf14-accum-CMYK", + &st_pdf14_accum, + 0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/, + 0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/, + 4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/, + 256/*dither_grays*/, 256/*dither_colors*/, + no_print_page), + 0/*save_p14dev*/ +}; + /* GC procedures */ static ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev) { - index -= 7; + index -= 5; if (index < pdev->devn_params.separations.num_separations) ENUM_RETURN(pdev->devn_params.separations.names[index].data); index -= pdev->devn_params.separations.num_separations; @@ -491,9 +631,7 @@ case 1: return ENUM_OBJ(pdev->trans_group_parent_cmap_procs); case 2: return ENUM_OBJ(pdev->smaskcolor); case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target)); -case 4: ENUM_RETURN(pdev->devn_params.compressed_color_list); -case 5: ENUM_RETURN(pdev->devn_params.pdf14_compressed_color_list); -case 6: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device)); +case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device)); ENUM_PTRS_END static RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev) @@ -505,8 +643,6 @@ RELOC_PTR(pdf14_device, devn_params.separations.names[i].data); } } - RELOC_PTR(pdf14_device, devn_params.compressed_color_list); - RELOC_PTR(pdf14_device, devn_params.pdf14_compressed_color_list); RELOC_VAR(pdev->ctx); RELOC_VAR(pdev->smaskcolor); RELOC_VAR(pdev->trans_group_parent_cmap_procs); @@ -517,6 +653,117 @@ /* ------ Private definitions ------ */ +/* Transform of color data and copy noncolor data. Used in + group pop and during the pdf14 put image calls when the blend color space + is different than the target device color space. The function will try do + in-place conversion if possible. If not, it will do an allocation. The + put_image call needs to know if an allocation was made so that it can adjust + for the fact that we likely don't have a full page any longer and we don't + need to do the offset to our data in the buffer. */ +static pdf14_buf* +pdf14_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev, + pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile, + cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc) +{ + gsicc_rendering_param_t rendering_params; + gsicc_link_t *icc_link; + gsicc_bufferdesc_t src_buff_desc; + gsicc_bufferdesc_t des_buff_desc; + int src_planestride = src_buf->planestride; + int src_rowstride = src_buf->rowstride; + int src_n_planes = src_buf->n_planes; + int src_n_chan = src_buf->n_chan; + int des_planestride = src_planestride; + int des_rowstride = src_rowstride; + int des_n_planes = src_n_planes; + int des_n_chan = src_n_chan; + int diff; + int k, j; + byte *des_data = NULL; + pdf14_buf *output = src_buf; + *did_alloc = false; + + /* Same profile */ + if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile)) + return src_buf; + + /* Define the rendering intent get the link */ + rendering_params.black_point_comp = gsBLACKPTCOMP_ON; + rendering_params.graphics_type_tag = GS_IMAGE_TAG; + rendering_params.override_icc = false; + rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; + rendering_params.rendering_intent = gsPERCEPTUAL; + rendering_params.cmm = gsCMM_DEFAULT; + icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile, + &rendering_params, pgs->memory, false); + if (icc_link == NULL) + return NULL; + + /* If different data sizes, we have to do an allocation */ + diff = des_profile->num_comps - src_profile->num_comps; + if (diff != 0) { + byte *src_ptr; + byte *des_ptr; + + *did_alloc = true; + des_rowstride = (width + 3) & -4; + des_planestride = height * des_rowstride; + des_n_planes = src_n_planes + diff; + des_n_chan = src_n_chan + diff; + des_data = gs_alloc_bytes(ctx->memory, des_planestride * des_n_planes, + "pdf14_transform_color_buffer"); + if (des_data == NULL) + return NULL; + + /* Copy over the noncolor planes. May only be a dirty part, so have + to copy row by row */ + src_ptr = src_data; + des_ptr = des_data; + for (j = 0; j < height; j++) { + for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) { + memcpy(des_ptr + des_planestride * (k + des_profile->num_comps), + src_ptr + src_planestride * (k + src_profile->num_comps), + width); + } + src_ptr += src_rowstride; + des_ptr += des_rowstride; + } + } else + des_data = src_data; + + /* Set up the buffer descriptors. */ + gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1, false, + false, true, src_planestride, src_rowstride, height, width); + gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, + 1, false, false, true, des_planestride, + des_rowstride, height, width); + + /* Transform the data. Since the pdf14 device should be using RGB, CMYK or + Gray buffers, this transform does not need to worry about the cmap procs + of the target device. */ + (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc, + src_data, des_data); + gsicc_release_link(icc_link); + + output->planestride = des_planestride; + output->rowstride = des_rowstride; + output->n_planes = des_n_planes; + output->n_chan = des_n_chan; + /* If not in-place conversion, then release. */ + if (des_data != src_data) { + gs_free_object(ctx->memory, output->data, + "pdf14_transform_color_buffer"); + output->data = des_data; + /* Note, this is needed for case where we did a put image, as the + resulting transformed buffer may not be a full page. */ + output->rect.p.x = x0; + output->rect.p.y = y0; + output->rect.q.x = x0 + width; + output->rect.q.y = y0 + height; + } + return output; +} + /** * pdf14_buf_new: Allocate a new PDF 1.4 buffer. * @n_chan: Number of pixel channels including alpha. @@ -525,13 +772,14 @@ **/ static pdf14_buf * pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g, - bool has_shape, bool idle, int n_chan, gs_memory_t *memory) + bool has_shape, bool idle, int n_chan, int num_spots, + gs_memory_t *memory) { - /* Note that alpha_g is the alpha for the GROUP */ - /* This is distinct from the alpha that may also exist */ - /* for the objects within the group. Hence it can introduce */ - /* yet another plane */ + /* Note that alpha_g is the alpha for the GROUP */ + /* This is distinct from the alpha that may also exist */ + /* for the objects within the group. Hence it can introduce */ + /* yet another plane */ pdf14_buf *result; pdf14_parent_color_t *new_parent_color; @@ -550,6 +798,8 @@ if (result == NULL) return result; + result->memory = memory; + result->backdrop = NULL; result->saved = NULL; result->isolated = false; result->knockout = false; @@ -561,11 +811,19 @@ result->n_planes = n_planes; result->rowstride = rowstride; result->transfer_fn = NULL; + result->matte_num_comps = 0; + result->matte = NULL; result->mask_stack = NULL; result->idle = idle; result->mask_id = 0; + result->num_spots = num_spots; new_parent_color = gs_alloc_struct(memory, pdf14_parent_color_t, &st_pdf14_clr, "pdf14_buf_new"); + if (new_parent_color == NULL) { + gs_free_object(memory, result, "pdf14_buf_new"); + return NULL; + } + result->parent_color_info_procs = new_parent_color; result->parent_color_info_procs->get_cmap_procs = NULL; result->parent_color_info_procs->parent_color_mapping_procs = NULL; @@ -574,7 +832,7 @@ result->parent_color_info_procs->previous = NULL; result->parent_color_info_procs->encode = NULL; result->parent_color_info_procs->decode = NULL; - if (height <= 0) { + if (idle || height <= 0) { /* Empty clipping - will skip all drawings. */ result->planestride = 0; result->data = 0; @@ -584,7 +842,7 @@ result->data = gs_alloc_bytes(memory, planestride * n_planes, "pdf14_buf_new"); if (result->data == NULL) { - gs_free_object(memory, result, "pdf_buf_new"); + gs_free_object(memory, result, "pdf14_buf_new"); return NULL; } if (has_alpha_g) { @@ -608,12 +866,29 @@ } static void -pdf14_buf_free(pdf14_buf *buf, gs_memory_t *memory) +pdf14_buf_free(pdf14_buf *buf) { + pdf14_parent_color_t *old_parent_color_info = buf->parent_color_info_procs; + gs_memory_t *memory = buf->memory; + + if (buf->mask_stack && buf->mask_stack->rc_mask) + rc_decrement(buf->mask_stack->rc_mask, "pdf14_buf_free"); + gs_free_object(memory, buf->mask_stack, "pdf14_buf_free"); gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free"); + gs_free_object(memory, buf->matte, "pdf14_buf_free"); gs_free_object(memory, buf->data, "pdf14_buf_free"); - gs_free_object(memory, buf->parent_color_info_procs, "pdf14_buf_free"); + + while (old_parent_color_info) { + if (old_parent_color_info->icc_profile != NULL) { + gsicc_adjust_profile_rc(old_parent_color_info->icc_profile, -1, "pdf14_buf_free"); + } + buf->parent_color_info_procs = old_parent_color_info->previous; + gs_free_object(memory, old_parent_color_info, "pdf14_buf_free"); + old_parent_color_info = buf->parent_color_info_procs; + } + + gs_free_object(memory, buf->backdrop, "pdf14_buf_free"); gs_free_object(memory, buf, "pdf14_buf_free"); } @@ -624,7 +899,7 @@ pdf14_rcmask_t *rcmask = (pdf14_rcmask_t * ) ptr_in; /* free the pdf14 buffer. */ if ( rcmask->mask_buf != NULL ){ - pdf14_buf_free(rcmask->mask_buf, mem); + pdf14_buf_free(rcmask->mask_buf); } gs_free_object(mem, rcmask, "rc_pdf14_maskbuf_free"); } @@ -649,15 +924,16 @@ { pdf14_ctx *result; pdf14_buf *buf; - gs_memory_t *memory = dev->memory; - bool has_tags = dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS; + gs_memory_t *memory = dev->memory->stable_memory; + bool has_tags = device_encodes_tags(dev); + pdf14_device *pdev = (pdf14_device *)dev; - result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, - "pdf14_ctx_new"); + result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new"); if (result == NULL) return result; /* Note: buffer creation expects alpha to be in number of channels */ - buf = pdf14_buf_new(rect, has_tags, false, false, false, n_chan+1, memory); + buf = pdf14_buf_new(rect, has_tags, false, false, false, n_chan + 1, + pdev->devn_params.page_spot_colors, memory); if (buf == NULL) { gs_free_object(memory, result, "pdf14_ctx_new"); return NULL; @@ -697,7 +973,7 @@ } for (buf = ctx->stack; buf != NULL; buf = next) { next = buf->saved; - pdf14_buf_free(buf, ctx->memory); + pdf14_buf_free(buf); } gs_free_object (ctx->memory, ctx, "pdf14_ctx_free"); } @@ -715,6 +991,15 @@ while (buf != NULL) { if (buf->isolated) return NULL; + if (buf->knockout && !buf->isolated) return buf->saved; + /* If target (NOS) is knockout and isolated then the compositing will happen + at the end */ + if (buf->saved != NULL && buf->saved->knockout && buf->saved->isolated) return NULL; + /* Target (NOS) is not isolated. Next group on stack is a knockout. + We need to compose with the backdrop when we do the pop */ + if (buf->saved != NULL && buf->saved->knockout && !buf->saved->isolated) + return NULL; + /* Not a knockout and not isolated. Initialize backdrop */ if (!buf->knockout) return buf->saved; buf = buf->saved; } @@ -724,11 +1009,13 @@ } static int -pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, - bool isolated, bool knockout, - byte alpha, byte shape, - gs_blend_mode_t blend_mode, bool idle, - uint mask_id, int numcomps) +pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated, + bool knockout, byte alpha, byte shape, + gs_blend_mode_t blend_mode, bool idle, uint mask_id, + int numcomps, bool cm_back_drop, + cmm_profile_t *group_profile, + cmm_profile_t *tos_profile, gs_gstate *pgs, + gx_device *dev) { pdf14_buf *tos = ctx->stack; pdf14_buf *buf, *backdrop; @@ -736,30 +1023,26 @@ if_debug1m('v', ctx->memory, "[v]pdf14_push_transparency_group, idle = %d\n", idle); - /* todo: fix this hack, which makes all knockout groups isolated. - For the vast majority of files, there won't be any visible - effects, but it still isn't correct. The pixel compositing code - for non-isolated knockout groups gets pretty hairy, which is - why this is here. */ - if (knockout) - isolated = true; + + /* We are going to use the shape in the knockout computation. If previous + buffer has a shape or if this is a knockout then we will have a shape here */ has_shape = tos->has_shape || tos->knockout; + // has_shape = false; + /* If previous buffer has tags, then add tags here */ has_tags = tos->has_tags; - /* We need to create this based upon the size of - the color space + an alpha channel. NOT the device size - or the previous ctx size. */ - /* The second parameter in pdf14_buf_new decides if we should - add a GROUP alpha channel to the buffer. If it is NOT isolated, then this - buffer will be added. If it is isolated, then the buffer will not be added. - I question the redundancy here of the alpha and the group alpha channel, - but that will need to be looked at later. */ - buf = pdf14_buf_new(rect, has_tags, !isolated, has_shape, idle, - numcomps+1, ctx->memory); - if_debug4m('v', ctx->memory, - "[v]base buf: %d x %d, %d color channels, %d planes\n", - buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes); + + /* If the group is NOT isolated we add in the alpha_g plane. This enables + recompositing to be performed ala art_pdf_recomposite_group_8 so that + the backdrop is only included one time in the computation. */ + /* Order of buffer data is color data, followed by alpha channel, followed by + shape (if present), then alpha_g (if present), then tags (if present) */ + buf = pdf14_buf_new(rect, has_tags, !isolated, has_shape, idle, numcomps + 1, + tos->num_spots, ctx->memory); if (buf == NULL) return_error(gs_error_VMerror); + if_debug4m('v', ctx->memory, + "[v]base buf: %d x %d, %d color channels, %d planes\n", + buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes); buf->isolated = isolated; buf->knockout = knockout; buf->alpha = alpha; @@ -777,58 +1060,127 @@ if (idle) return 0; backdrop = pdf14_find_backdrop_buf(ctx); - if (backdrop == NULL) + if (backdrop == NULL) { + /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */ memset(buf->data, 0, buf->planestride * (buf->n_chan + - (buf->has_shape ? 1 : 0))); - else - pdf14_preserve_backdrop(buf, tos, has_shape); -#if RAW_DUMP + (buf->has_shape ? 1 : 0) + + (buf->has_alpha_g ? 1 : 0))); + } else { + if (!buf->knockout) { + if (!cm_back_drop) { + pdf14_preserve_backdrop(buf, tos, false); + } else { + /* We must have an non-isolated group with a mismatch in color spaces. + In this case, we can't just copy the buffer but must CM it */ + pdf14_preserve_backdrop_cm(buf, group_profile, tos, tos_profile, + ctx->memory, pgs, dev, false); + } + } + } + /* If knockout, we have to maintain a copy of the backdrop in case we are + drawing nonisolated groups on top of the knockout group. */ + if (buf->knockout) { + buf->backdrop = gs_alloc_bytes(ctx->memory, buf->planestride * buf->n_chan, + "pdf14_push_transparency_group"); + if (buf->backdrop == NULL) { + return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed"); + } + if (buf->isolated) { + /* We will have opaque backdrop for non-isolated compositing */ + memset(buf->backdrop, 0, buf->planestride * buf->n_chan); + } else { + /* Save knockout backdrop for non-isolated compositing */ + /* Note that we need to drill down through the non-isolated groups in our + stack and make sure that we are not embedded in another knockout group */ + pdf14_buf *check = tos; + pdf14_buf *child = NULL; /* Needed so we can get profile */ + cmm_profile_t *prev_knockout_profile; + + while (check != NULL) { + if (check->isolated) + break; + if (check->knockout) { + break; + } + child = check; + check = check->saved; + } + /* Here we need to grab a back drop from a knockout parent group and + potentially worry about color differences. */ + if (check == NULL) { + prev_knockout_profile = tos_profile; + check = tos; + } else { + if (child == NULL) { + prev_knockout_profile = tos_profile; + } else { + prev_knockout_profile = child->parent_color_info_procs->icc_profile; + } + } + if (!cm_back_drop) { + pdf14_preserve_backdrop(buf, check, false); + } else { + /* We must have an non-isolated group with a mismatch in color spaces. + In this case, we can't just copy the buffer but must CM it */ + pdf14_preserve_backdrop_cm(buf, group_profile, check, + prev_knockout_profile, ctx->memory, pgs, + dev, false); + } + memcpy(buf->backdrop, buf->data, buf->planestride * buf->n_chan); + } +#if RAW_DUMP + /* Dump the current buffer to see what we have. */ + dump_raw_buffer(ctx->stack->rect.q.y-ctx->stack->rect.p.y, + ctx->stack->rowstride, buf->n_chan, + ctx->stack->planestride, ctx->stack->rowstride, + "KnockoutBackDrop", buf->backdrop); + global_index++; +#endif + } else { + buf->backdrop = NULL; + } +#if RAW_DUMP /* Dump the current buffer to see what we have. */ - dump_raw_buffer(ctx->stack->rect.q.y-ctx->stack->rect.p.y, ctx->stack->rowstride, ctx->stack->n_planes, ctx->stack->planestride, ctx->stack->rowstride, - "TransGroupPush",ctx->stack->data); - + "TransGroupPush", ctx->stack->data); global_index++; #endif return 0; } static int -pdf14_pop_transparency_group(gs_imager_state *pis, pdf14_ctx *ctx, +pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx, const pdf14_nonseparable_blending_procs_t * pblend_procs, - int curr_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev) + int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev) { pdf14_buf *tos = ctx->stack; pdf14_buf *nos = tos->saved; pdf14_mask_t *mask_stack = tos->mask_stack; pdf14_buf *maskbuf; int x0, x1, y0, y1; - byte *new_data_buf = NULL; - int num_noncolor_planes, new_num_planes; - int num_cols, num_rows, num_newcolor_planes; + int nos_num_color_comp; bool icc_match; - gsicc_rendering_param_t rendering_params; - gsicc_link_t *icc_link; - gsicc_bufferdesc_t input_buff_desc; - gsicc_bufferdesc_t output_buff_desc; pdf14_device *pdev = (pdf14_device *)dev; bool overprint = pdev->overprint; gx_color_index drawn_comps = pdev->drawn_comps; - bool blendspot = pdev->blendspot; + + if (nos == NULL) + return_error(gs_error_unknownerror); /* Unmatched group pop */ + + nos_num_color_comp = nos->parent_color_info_procs->num_components - nos->num_spots; + tos_num_color_comp = tos_num_color_comp - tos->num_spots; #ifdef DEBUG pdf14_debug_mask_stack_state(ctx); #endif - if ( mask_stack == NULL) { + if (mask_stack == NULL) { maskbuf = NULL; } else { maskbuf = mask_stack->rc_mask->mask_buf; } - if (nos == NULL) - return_error(gs_error_rangecheck); /* Sanitise the dirty rectangles, in case some of the drawing routines * have made them overly large. */ rect_intersect(tos->dirty, tos->rect); @@ -859,20 +1211,13 @@ goto exit; if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255) goto exit; - /* We can only do this clipping if we have a soft mask AND if the alpha outside - the soft mask is zero */ - if (maskbuf != NULL && maskbuf->alpha == 0) { - y0 = max(y0, maskbuf->rect.p.y); - y1 = min(y1, maskbuf->rect.q.y); - x0 = max(x0, maskbuf->rect.p.x); - x1 = min(x1, maskbuf->rect.q.x); - } + #if RAW_DUMP /* Dump the current buffer to see what we have. */ dump_raw_buffer(ctx->stack->rect.q.y-ctx->stack->rect.p.y, ctx->stack->rowstride, ctx->stack->n_planes, ctx->stack->planestride, ctx->stack->rowstride, - "aTrans_Group_Pop",ctx->stack->data); + "aaTrans_Group_Pop",ctx->stack->data); #endif /* Note currently if a pattern space has transparency, the ICC profile is not used for blending purposes. Instead we rely upon the gray, rgb, or cmyk parent space. @@ -881,7 +1226,7 @@ operations called in the tile transparency code. Instead we may want to look at pdf14_begin_transparency_group and pdf14_end_transparency group which is where all the ICC information is handled. We will return to look at that later */ - if ( nos->parent_color_info_procs->icc_profile != NULL ) { + if (nos->parent_color_info_procs->icc_profile != NULL) { icc_match = (nos->parent_color_info_procs->icc_profile->hashcode != curr_icc_profile->hashcode); } else { @@ -890,128 +1235,38 @@ } /* If the color spaces are different and we actually did do a swap of the procs for color */ - if ( (nos->parent_color_info_procs->parent_color_mapping_procs != NULL && - nos->parent_color_info_procs->num_components != curr_num_color_comp) - || icc_match ) { + if ((nos->parent_color_info_procs->parent_color_mapping_procs != NULL && + nos_num_color_comp != tos_num_color_comp) || icc_match) { if (x0 < x1 && y0 < y1) { - /* The NOS blending color space is different than that of the - TOS. It is necessary to transform the TOS buffer data to the - color space of the NOS prior to doing the pdf14_compose_group - operation. */ - num_noncolor_planes = tos->n_planes - curr_num_color_comp; - num_newcolor_planes = nos->parent_color_info_procs->num_components; - new_num_planes = num_noncolor_planes + num_newcolor_planes; - /* See if we are doing ICC based conversion */ - if (nos->parent_color_info_procs->icc_profile != NULL && - curr_icc_profile != NULL) { - /* Use the ICC color management for buffer color conversion */ - /* Define the rendering intents */ - rendering_params.black_point_comp = gsBLACKPTCOMP_ON; - rendering_params.graphics_type_tag = GS_IMAGE_TAG; - rendering_params.override_icc = false; - rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = gsPERCEPTUAL; - rendering_params.cmm = gsCMM_DEFAULT; - /* Request the ICC link for the transform that we will need to use */ - /* Note that if pis is NULL we assume the same color space. This - is due to a call to pop the group from fill_mask when filling - with a mask with transparency. In that case, the parent - and the child will have the same color space anyway */ - icc_link = gsicc_get_link_profile(pis, dev, curr_icc_profile, - nos->parent_color_info_procs->icc_profile, - &rendering_params, pis->memory, false); - /* If the link is the identity, then we don't need to do - any color conversions */ - if ( !(icc_link->is_identity) ) { - /* Before we do any allocations check if we can get away with - reusing the existing buffer if it is the same size ( if it is - smaller go ahead and allocate). We could reuse it in this - case too. We need to do a bit of testing to determine what - would be best. */ - /* FIXME: RJW: Could we get away with just color converting - * the area that's actually active (i.e. dirty, not rect)? - */ - if( num_newcolor_planes != curr_num_color_comp ) { - /* Different size. We will need to allocate */ - new_data_buf = gs_alloc_bytes(ctx->memory, - tos->planestride*new_num_planes, - "pdf14_buf_new"); - if (new_data_buf == NULL) - return_error(gs_error_VMerror); - /* Copy over the noncolor planes. */ - memcpy(new_data_buf + tos->planestride * num_newcolor_planes, - tos->data + tos->planestride * curr_num_color_comp, - tos->planestride * num_noncolor_planes); - } else { - /* In place color conversion! */ - new_data_buf = tos->data; - } - /* Set up the buffer descriptors. Note that pdf14 always has - the alpha channels at the back end (last planes). - We will just handle that here and let the CMM know - nothing about it */ - num_rows = tos->rect.q.y - tos->rect.p.y; - num_cols = tos->rect.q.x - tos->rect.p.x; - gsicc_init_buffer(&input_buff_desc, curr_num_color_comp, 1, - false, false, true, - tos->planestride, tos->rowstride, - num_rows, num_cols); - gsicc_init_buffer(&output_buff_desc, - nos->parent_color_info_procs->num_components, - 1, false, false, true, tos->planestride, - tos->rowstride, num_rows, num_cols); - /* Transform the data. Since the pdf14 device should be - using RGB, CMYK or Gray buffers, this transform - does not need to worry about the cmap procs of - the target device. Those are handled when we do - the pdf14 put image operation */ - (icc_link->procs.map_buffer)(dev, icc_link, &input_buff_desc, - &output_buff_desc, tos->data, - new_data_buf); - } - /* Release the link */ - gsicc_release_link(icc_link); - /* free the old object if the color spaces were different sizes */ - if( !(icc_link->is_identity) && - num_newcolor_planes != curr_num_color_comp ) { - gs_free_object(ctx->memory, tos->data, "pdf14_buf_free"); - tos->data = new_data_buf; - } - } else { - /* Non ICC based transform */ - new_data_buf = gs_alloc_bytes(ctx->memory, - tos->planestride*new_num_planes,"pdf14_buf_new"); - if (new_data_buf == NULL) - return_error(gs_error_VMerror); - gs_transform_color_buffer_generic(tos->data, tos->rowstride, - tos->planestride,curr_num_color_comp, tos->rect, - new_data_buf, num_newcolor_planes, num_noncolor_planes); - /* Free the old object */ - gs_free_object(ctx->memory, tos->data, "pdf14_buf_free"); - tos->data = new_data_buf; - } - /* Adjust the plane and channel size now */ - tos->n_chan = nos->n_chan; - tos->n_planes = nos->n_planes; + pdf14_buf *result; + bool did_alloc; /* We don't care here */ + + result = pdf14_transform_color_buffer(pgs, ctx, dev, tos, tos->data, + curr_icc_profile, nos->parent_color_info_procs->icc_profile, + tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x, + tos->rect.q.y - tos->rect.p.y, &did_alloc); + if (result == NULL) + return_error(gs_error_unknownerror); /* transform failed */ + #if RAW_DUMP /* Dump the current buffer to see what we have. */ dump_raw_buffer(ctx->stack->rect.q.y-ctx->stack->rect.p.y, - ctx->stack->rowstride, ctx->stack->n_planes, + ctx->stack->rowstride, ctx->stack->n_chan, ctx->stack->planestride, ctx->stack->rowstride, - "Trans_Group_ColorConv",ctx->stack->data); + "aCMTrans_Group_ColorConv",ctx->stack->data); #endif /* compose. never do overprint in this case */ - pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan, + pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan, nos->parent_color_info_procs->isadditive, nos->parent_color_info_procs->parent_blending_procs, - false, drawn_comps, false, ctx->memory); + false, drawn_comps, ctx->memory, dev); } } else { /* Group color spaces are the same. No color conversions needed */ if (x0 < x1 && y0 < y1) - pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1,nos->n_chan, - ctx->additive, pblend_procs, overprint, - drawn_comps, blendspot, ctx->memory); + pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan, + ctx->additive, pblend_procs, overprint, + drawn_comps, ctx->memory, dev); } exit: ctx->stack = nos; @@ -1024,7 +1279,7 @@ ctx->smask_blend = true; } if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle); - pdf14_buf_free(tos, ctx->memory); + pdf14_buf_free(tos); return 0; } @@ -1039,8 +1294,8 @@ byte *transfer_fn, bool idle, bool replacing, uint mask_id, gs_transparency_mask_subtype_t subtype, int numcomps, int Background_components, - const float Background[], - const float GrayBackground) + const float Background[], int Matte_components, + const float Matte[], const float GrayBackground) { pdf14_buf *buf; unsigned char *curr_ptr, gray; @@ -1057,7 +1312,7 @@ the color space + an alpha channel. NOT the device size or the previous ctx size */ /* A mask doesnt worry about tags */ - buf = pdf14_buf_new(rect, false, false, false, idle, numcomps+1, + buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0, ctx->memory); if (buf == NULL) return_error(gs_error_VMerror); @@ -1068,15 +1323,22 @@ buf->shape = 0xff; buf->blend_mode = BLEND_MODE_Normal; buf->transfer_fn = transfer_fn; + buf->matte_num_comps = Matte_components; + if (Matte_components) { + buf->matte = (byte *)gs_alloc_bytes(ctx->memory, sizeof(float)*Matte_components, + "pdf14_push_transparency_mask"); + if (buf->matte == NULL) + return_error(gs_error_VMerror); + memcpy(buf->matte, Matte, size_of(float)*Matte_components); + } buf->mask_id = mask_id; - { /* If replacing=false, we start the mask for an image with SMask. - In this case the image's SMask temporary replaces the - mask of the containing group. Save the containing droup's mask - in buf->mask_stack */ - buf->mask_stack = ctx->mask_stack; - if (buf->mask_stack){ - rc_increment(buf->mask_stack->rc_mask); - } + /* If replacing=false, we start the mask for an image with SMask. + In this case the image's SMask temporary replaces the + mask of the containing group. Save the containing droup's mask + in buf->mask_stack */ + buf->mask_stack = ctx->mask_stack; + if (buf->mask_stack){ + rc_increment(buf->mask_stack->rc_mask); } #if RAW_DUMP /* Dump the current buffer to see what we have. */ @@ -1117,8 +1379,10 @@ return 0; } -static void pdf14_free_mask_stack(pdf14_mask_t *mask_stack, gs_memory_t *memory) +static void pdf14_free_mask_stack(pdf14_ctx *ctx, gs_memory_t *memory) { + pdf14_mask_t *mask_stack = ctx->mask_stack; + if (mask_stack->rc_mask != NULL) { pdf14_mask_t *curr_mask = mask_stack; pdf14_mask_t *old_mask; @@ -1131,10 +1395,11 @@ } else { gs_free_object(memory, mask_stack, "pdf14_free_mask_stack"); } + ctx->mask_stack = NULL; } static int -pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_imager_state *pis, gx_device *dev) +pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev) { pdf14_buf *tos = ctx->stack; byte *new_data_buf; @@ -1143,11 +1408,10 @@ cmm_profile_t *src_profile; gsicc_rendering_param_t rendering_params; gsicc_link_t *icc_link; - gsicc_rendering_param_t render_cond; - int code; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; - code = dev_proc(dev, get_profile)(dev, &dev_profile); + dev_proc(dev, get_profile)(dev, &dev_profile); gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile, &render_cond); ctx->smask_depth -= 1; @@ -1187,15 +1451,14 @@ to begin with. For now we need to delete the structure that was created. Only delete if the alpha value is 255 */ if (tos->alpha == 255) { - pdf14_buf_free(tos, ctx->memory); + pdf14_buf_free(tos); if (ctx->mask_stack != NULL) { - pdf14_free_mask_stack(ctx->mask_stack, ctx->memory); - ctx->mask_stack = NULL; - } + pdf14_free_mask_stack(ctx, ctx->memory); + } } else { /* Assign as mask buffer */ if (ctx->mask_stack != NULL) { - pdf14_free_mask_stack(ctx->mask_stack, ctx->memory); + pdf14_free_mask_stack(ctx, ctx->memory); } ctx->mask_stack = pdf14_mask_element_new(ctx->memory); ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory); @@ -1210,7 +1473,7 @@ /* Due to the fact that on certain systems we may have issues recovering */ /* the data after a resize */ new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride, - "pdf14_buf_new"); + "pdf14_pop_transparency_mask"); if (new_data_buf == NULL) return_error(gs_error_VMerror); /* Initialize with 0. Need to do this since in Smask_Luminosity_Mapping @@ -1283,8 +1546,8 @@ rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; rendering_params.rendering_intent = gsPERCEPTUAL; rendering_params.cmm = gsCMM_DEFAULT; - icc_link = gsicc_get_link_profile(pis, dev, des_profile, - src_profile, &rendering_params, pis->memory, false); + icc_link = gsicc_get_link_profile(pgs, dev, des_profile, + src_profile, &rendering_params, pgs->memory, false); smask_icc(dev, tos->rect.q.y - tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,tos->n_chan, tos->rowstride, tos->planestride, @@ -1295,18 +1558,18 @@ } } /* Free the old object, NULL test was above */ - gs_free_object(ctx->memory, tos->data, "pdf14_buf_free"); + gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask"); tos->data = new_data_buf; /* Data is single channel now */ tos->n_chan = 1; tos->n_planes = 1; /* Assign as reference counted mask buffer */ if (ctx->mask_stack != NULL) { - /* In this case, the source file is wacky as it already had a + /* In this case, the source file is wacky as it already had a softmask and now is getting a replacement. We need to clean up the softmask stack before doing this free and creating a new stack. Bug 693312 */ - pdf14_free_mask_stack(ctx->mask_stack, ctx->memory); + pdf14_free_mask_stack(ctx, ctx->memory); } ctx->mask_stack = pdf14_mask_element_new(ctx->memory); if (ctx->mask_stack == NULL) @@ -1334,7 +1597,7 @@ } static int -pdf14_push_transparency_state(gx_device *dev, gs_imager_state *pis) +pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs) { /* We need to push the current soft mask. We need to be able to recover it if we draw a new one and @@ -1358,14 +1621,13 @@ } #ifdef DEBUG pdf14_debug_mask_stack_state(pdev->ctx); -#endif +#endif return(0); } static int -pdf14_pop_transparency_state(gx_device *dev, gs_imager_state *pis) +pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs) { - /* Pop the soft mask. It is no longer needed. Likely due to a Q that has occurred. */ pdf14_device *pdev = (pdf14_device *)dev; @@ -1376,7 +1638,7 @@ /* rc decrement the current link after we break it from the list, then free the stack element. Don't do anything if there is no mask present. */ - if ( ctx->mask_stack != NULL ) { + if (ctx->mask_stack != NULL) { old_mask = ctx->mask_stack; ctx->mask_stack = ctx->mask_stack->previous; if (old_mask->rc_mask) { @@ -1394,7 +1656,7 @@ } #ifdef DEBUG pdf14_debug_mask_stack_state(pdev->ctx); -#endif +#endif return 0; } @@ -1410,11 +1672,14 @@ rect.p.y = 0; rect.q.x = dev->width; rect.q.y = dev->height; - pdev->ctx = pdf14_ctx_new(&rect, dev->color_info.num_components, - pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, dev); + /* If we are reenabling the device dont create a new ctx. Bug 697456 */ + if (pdev->ctx == NULL) + pdev->ctx = pdf14_ctx_new(&rect, dev->color_info.num_components, + pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, dev); if (pdev->ctx == NULL) return_error(gs_error_VMerror); pdev->free_devicen = true; + pdev->text_group = PDF14_TEXTGROUP_NO_BT; return 0; } @@ -1422,12 +1687,32 @@ pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm }; +static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = { + pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm +}; + +static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = { + pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm +}; + static const gx_cm_color_map_procs * pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev) { return &pdf14_DeviceCMYKspot_procs; } +static const gx_cm_color_map_procs * +pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev) +{ + return &pdf14_DeviceRGBspot_procs; +} + +static const gx_cm_color_map_procs * +pdf14_grayspot_get_color_mapping_procs(const gx_device * dev) +{ + return &pdf14_DeviceGrayspot_procs; +} + /* Used to pass along information about the buffer created by the pdf14 device. This is used by the pattern accumulator when the pattern contains transparency. Note that if free_device is true then @@ -1459,10 +1744,10 @@ if (width <= 0 || height <= 0 || buf->data == NULL) return 0; transbuff->n_chan = buf->n_chan; + transbuff->has_tags = buf->has_tags; transbuff->has_shape = buf->has_shape; transbuff->width = buf->rect.q.x - buf->rect.p.x; transbuff->height = buf->rect.q.y - buf->rect.p.y; - transbuff->blending_mode = pdev->blend_mode; if (free_device) { transbuff->pdev14 = NULL; @@ -1478,8 +1763,11 @@ transbuff->planestride = planestride; transbuff->rowstride = rowstride; - transbuff->transbytes = gs_alloc_bytes(mem, planestride*buf->n_chan, + transbuff->transbytes = gs_alloc_bytes(mem, planestride*(buf->n_chan + buf->has_tags ? 1 : 0), "pdf14_get_buffer_information"); + if (transbuff->transbytes == NULL) + return gs_error_VMerror; + transbuff->mem = mem; for (j = 0; j < transbuff->n_chan; j++) { buff_ptr_src = buf->data + j * buf->planestride + @@ -1499,7 +1787,7 @@ transbuff->planestride = buf->planestride; transbuff->rowstride = buf->rowstride; transbuff->transbytes = buf->data; - transbuff->mem = dev->memory; + transbuff->mem = buf->memory; buf->data = NULL; /* So that the buffer is not freed */ } /* Go ahead and free up the pdf14 device */ @@ -1518,7 +1806,7 @@ transbuff->planestride = buf->planestride; transbuff->rowstride = buf->rowstride; transbuff->transbytes = buf->data; - transbuff->mem = dev->memory; + transbuff->mem = buf->memory; transbuff->rect = rect; #if RAW_DUMP /* Dump the buffer that should be going into the pattern */; @@ -1545,7 +1833,7 @@ * Return code: negative on error. **/ static int -pdf14_put_image(gx_device * dev, gs_imager_state * pis, gx_device * target) +pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) { const pdf14_device * pdev = (pdf14_device *)dev; int code; @@ -1557,13 +1845,20 @@ int num_comp = buf->n_chan - 1; byte *linebuf; gs_color_space *pcs; - const byte bg = pdev->ctx->additive ? 255 : 0; int x1, y1, width, height; byte *buf_ptr; bool data_blended = false; int num_rows_left; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; + cmm_dev_profile_t *dev_target_profile; + byte bg = pdev->ctx->additive ? 255 : 0; + + /* Make sure that this is the only item on the stack. Fuzzing revealed a + potential problem. Bug 694190 */ + if (buf->saved != NULL) { + return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync"); + } if_debug0m('v', dev->memory, "[v]pdf14_put_image\n"); rect_intersect(rect, buf->dirty); @@ -1577,26 +1872,89 @@ if (width <= 0 || height <= 0 || buf->data == NULL) return 0; buf_ptr = buf->data + rect.p.y * buf->rowstride + rect.p.x; - /* See if the target device has a put_image command. If - yes then see if it can handle the image data directly. - If it cannot, then we will need to use the begin_typed_image - interface, which cannot pass along tag nor alpha data to - the target device */ - if (target->procs.put_image != NULL) { - /* See if the target device can handle the data in its current - form with the alpha component */ - int alpha_offset = num_comp; - int tag_offset = buf->has_tags ? num_comp+1 : 0; - code = dev_proc(target, put_image) (target, buf_ptr, num_comp, + + /* Check that target is OK. From fuzzing results the target could have been + destroyed, for e.g if it were a pattern accumulator that was closed + prematurely (Bug 694154). We should always be able to to get an ICC + profile from the target. */ + code = dev_proc(target, get_profile)(target, &dev_target_profile); + if (code < 0) + return code; + if (dev_target_profile == NULL) + return gs_throw_code(gs_error_Fatal); + + /* See if the target device has a put_image command. If yes then see if it + can handle the image data directly. If it cannot, then we will need to + use the begin_typed_image interface, which cannot pass along tag nor + alpha data to the target device. */ + if (dev_proc(target, put_image) != gx_default_put_image) { + pdf14_buf *cm_result = NULL; + int alpha_offset, tag_offset; + const byte *buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS]; + int i; + + /* If we are using a blending color space, take care of that first */ + if (pdev->using_blend_cs) { + cmm_profile_t *src_profile; + cmm_profile_t *des_profile; + bool did_alloc; + + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) { + return code; + } + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile, + &render_cond); + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile, + &render_cond); + +#if RAW_DUMP + dump_raw_buffer(height, width, buf->n_planes, buf->planestride, + buf->rowstride, "pre_blend_cs", buf_ptr); + global_index++; +#endif + + cm_result = pdf14_transform_color_buffer(pgs, pdev->ctx, dev, buf, + buf_ptr, src_profile, des_profile, rect.p.x, rect.p.y, width, + height, &did_alloc); + + if (cm_result == NULL) + return_error(gs_error_VMerror); + + /* Based upon our transform, do a bit of updating */ + buf = cm_result; + num_comp = buf->n_chan - 1; + + /* Make sure our buf_ptr is pointing to the proper location */ + if (did_alloc) + buf_ptr = cm_result->data; /* Note the lack of offset */ + +#if RAW_DUMP + dump_raw_buffer(height, width, buf->n_planes, buf->planestride, + buf->rowstride, "post_blend_cs", buf_ptr); + global_index++; +#endif + /* May need to adjust background value due to color space change */ + if (des_profile->num_comps == 4) + bg = 0; + else + bg = 255; + } + alpha_offset = num_comp; + tag_offset = buf->has_tags ? buf->n_chan : 0; + + /* See if the target device can handle the data with alpha component */ + for (i = 0; i < buf->n_planes; i++) + buf_ptrs[i] = buf_ptr + i * buf->planestride; + code = dev_proc(target, put_image) (target, buf_ptrs, num_comp, rect.p.x, rect.p.y, width, height, - buf->rowstride, buf->planestride, - num_comp,tag_offset); + buf->rowstride, alpha_offset, + tag_offset); if (code == 0) { - /* Device could not handle the alpha data. Go ahead and - preblend now. Note that if we do this, and we end up in the - default below, we only need to repack in chunky not blend */ + /* Device could not handle the alpha data. Go ahead and preblend + now. Note that if we do this, and we end up in the default below, + we only need to repack in chunky not blend */ #if RAW_DUMP - /* Dump before and after the blend to make sure we are doing that ok */ dump_raw_buffer(height, width, buf->n_planes, pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, "pre_final_blend",buf_ptr); @@ -1605,7 +1963,6 @@ gx_blend_image_buffer(buf_ptr, width, height, buf->rowstride, buf->planestride, num_comp, bg); #if RAW_DUMP - /* Dump before and after the blend to make sure we are doing that ok */ dump_raw_buffer(height, width, buf->n_planes, pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, "post_final_blend",buf_ptr); @@ -1613,21 +1970,21 @@ clist_band_count++; #endif data_blended = true; - /* Try again now */ + + /* Try again now with just the tags */ alpha_offset = 0; - code = dev_proc(target, put_image) (target, buf_ptr, num_comp, + code = dev_proc(target, put_image) (target, buf_ptrs, num_comp, rect.p.x, rect.p.y, width, height, - buf->rowstride, buf->planestride, - alpha_offset, tag_offset); + buf->rowstride, alpha_offset, + tag_offset); } if (code > 0) { /* We processed some or all of the rows. Continue until we are done */ num_rows_left = height - code; while (num_rows_left > 0) { - code = dev_proc(target, put_image) (target, buf_ptr, buf->n_planes, - rect.p.x, rect.p.y+code, width, + code = dev_proc(target, put_image) (target, buf_ptrs, num_comp, + rect.p.x, rect.p.y + code, width, num_rows_left, buf->rowstride, - buf->planestride, alpha_offset, tag_offset); num_rows_left = num_rows_left - code; } @@ -1637,38 +1994,45 @@ /* * Set color space in preparation for sending an image. */ - code = gs_cspace_build_ICC(&pcs, NULL, pis->memory); + code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory); if (pcs == NULL) return_error(gs_error_VMerror); - /* Need to set this to avoid color management during the - image color render operation. Exception is for the special case - when the destination was CIELAB. Then we need to convert from - default RGB to CIELAB in the put image operation. That will happen - here as we should have set the profile for the pdf14 device to RGB - and the target will be CIELAB */ + if (code < 0) + return code; + /* Need to set this to avoid color management during the image color render + operation. Exception is for the special case when the destination was + CIELAB. Then we need to convert from default RGB to CIELAB in the put + image operation. That will happen here as we should have set the profile + for the pdf14 device to RGB and the target will be CIELAB. In addition, + the case when we have a blend color space that is different than the + target device color space */ code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) { + rc_decrement_only_cs(pcs, "pdf14_put_image"); + return code; + } gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, - &(pcs->cmm_icc_profile_data), &render_cond); + &(pcs->cmm_icc_profile_data), &render_cond); /* pcs takes a reference to the profile data it just retrieved. */ - rc_increment(pcs->cmm_icc_profile_data); - gscms_set_icc_range(&(pcs->cmm_icc_profile_data)); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image"); + gsicc_set_icc_range(&(pcs->cmm_icc_profile_data)); gs_image_t_init_adjust(&image, pcs, false); image.ImageMatrix.xx = (float)width; image.ImageMatrix.yy = (float)height; image.Width = width; image.Height = height; image.BitsPerComponent = 8; - ctm_only_writable(pis).xx = (float)width; - ctm_only_writable(pis).xy = 0; - ctm_only_writable(pis).yx = 0; - ctm_only_writable(pis).yy = (float)height; - ctm_only_writable(pis).tx = (float)rect.p.x; - ctm_only_writable(pis).ty = (float)rect.p.y; + ctm_only_writable(pgs).xx = (float)width; + ctm_only_writable(pgs).xy = 0; + ctm_only_writable(pgs).yx = 0; + ctm_only_writable(pgs).yy = (float)height; + ctm_only_writable(pgs).tx = (float)rect.p.x; + ctm_only_writable(pgs).ty = (float)rect.p.y; code = dev_proc(target, begin_typed_image) (target, - pis, NULL, + pgs, NULL, (gs_image_common_t *)&image, NULL, NULL, NULL, - pis->memory, &info); + pgs->memory, &info); if (code < 0) { rc_decrement_only_cs(pcs, "pdf14_put_image"); return code; @@ -1680,7 +2044,7 @@ pdev->ctx->stack->n_planes, pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, "pdF14_putimage",pdev->ctx->stack->data); - dump_raw_buffer(height, width, num_comp+1, + dump_raw_buffer(height, width, buf->n_planes, pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, "PDF14_PUTIMAGE_SMALL",buf_ptr); global_index++; @@ -1700,7 +2064,7 @@ } } } else { - gx_build_blended_image_row(buf_ptr, y, buf->planestride, width, + gx_build_blended_image_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf); } planes.data = linebuf; @@ -1720,7 +2084,7 @@ /** * pdf14_cmykspot_put_image: Put rendered image to target device. * @pdev: The PDF 1.4 rendering device. - * @pis: State for image draw operation. + * @pgs: State for image draw operation. * @target: The target device. * * Puts the rendered image in @pdev's buffer to @target. This is called @@ -1729,7 +2093,7 @@ * Return code: negative on error. **/ static int -pdf14_cmykspot_put_image(gx_device * dev, gs_imager_state * pis, gx_device * target) +pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) { pdf14_device * pdev = (pdf14_device *)dev; pdf14_buf *buf = pdev->ctx->stack; @@ -1739,7 +2103,7 @@ gs_separations * pseparations = &pdevn_params->separations; int planestride = buf->planestride; int rowstride = buf->rowstride; - const byte bg = pdev->ctx->additive ? gx_max_color_value : 0; + const byte bg = pdev->ctx->additive ? 0xff : 0; int num_comp = buf->n_chan - 1; byte *buf_ptr; @@ -1764,14 +2128,14 @@ clist_band_count++; #endif return gx_put_blended_image_cmykspot(target, buf_ptr, planestride, rowstride, - rect.p.x, rect.p.y, width, height, num_comp, bg, + rect.p.x, rect.p.y, width, height, num_comp, bg, buf->has_tags, rect, pseparations); } /** * pdf14_custom_put_image: Put rendered image to target device. * @pdev: The PDF 1.4 rendering device. - * @pis: State for image draw operation. + * @pgs: State for image draw operation. * @target: The target device. * * Puts the rendered image in @pdev's buffer to @target. This is called @@ -1780,7 +2144,7 @@ * Return code: negative on error. **/ static int -pdf14_custom_put_image(gx_device * dev, gs_imager_state * pis, gx_device * target) +pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target) { pdf14_device * pdev = (pdf14_device *)dev; pdf14_buf *buf = pdev->ctx->stack; @@ -1789,7 +2153,7 @@ int planestride = buf->planestride; int rowstride = buf->rowstride; int num_comp = buf->n_chan - 1; - const byte bg = pdev->ctx->additive ? gx_max_color_value : 0; + const byte bg = pdev->ctx->additive ? 0xff : 0; int x1, y1, width, height; byte *buf_ptr; @@ -1808,11 +2172,48 @@ x0, y0, width, height, num_comp, bg); } +/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop + * of one or more groups, we have to cycle through any ICC profile changes since the push + * putting everything back how it was, and cleaning up the reference counts. + */ +static void pdf14_cleanup_parent_color_profiles (pdf14_device *pdev) +{ + if (pdev->ctx) { + pdf14_buf *buf, *next; + + for (buf = pdev->ctx->stack; buf != NULL; buf = next) { + pdf14_parent_color_t *old_parent_color_info = buf->parent_color_info_procs; + next = buf->saved; + while (old_parent_color_info) { + if (old_parent_color_info->icc_profile != NULL) { + cmm_profile_t *group_profile; + gsicc_rendering_param_t render_cond; + cmm_dev_profile_t *dev_profile; + int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev, &dev_profile); + + if (code >= 0) { + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile, + &render_cond); + + gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[0], -1, "pdf14_end_transparency_group"); + pdev->icc_struct->device_profile[0] = old_parent_color_info->icc_profile; + old_parent_color_info->icc_profile = NULL; + } + } + + old_parent_color_info = old_parent_color_info->previous; + } + } + } +} + static int pdf14_close(gx_device *dev) { pdf14_device *pdev = (pdf14_device *)dev; + pdf14_cleanup_parent_color_profiles (pdev); + if (pdev->ctx) { pdf14_ctx_free(pdev->ctx); pdev->ctx = NULL; @@ -1820,6 +2221,67 @@ return 0; } +/* This is called when something has gone wrong and the interpreter received a + stop while in the middle of doing something with the PDF14 device. We need + to clean up and end this in a graceful manner */ +static int +pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs) +{ + pdf14_device *pdev = (pdf14_device *)dev; + /* The things that need to be cleaned up */ + pdf14_ctx *ctx = pdev->ctx; + pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor; + pdf14_parent_color_t *group_procs = pdev->trans_group_parent_cmap_procs; + + /* Free up the smask color */ + if (smaskcolor != NULL) { + smaskcolor->ref_count = 1; + pdf14_decrement_smask_color(pgs, dev); + pdev->smaskcolor = NULL; + } + + /* Free up the nested color procs and decrement the profiles */ + if (group_procs != NULL) { + while (group_procs->previous != NULL) + pdf14_pop_parent_color(dev, pgs); + gs_free_object(dev->memory->stable_memory, group_procs, "pdf14_discard_trans_layer"); + pdev->trans_group_parent_cmap_procs = NULL; + } + + /* Start the contex clean up */ + if (ctx != NULL) { + pdf14_buf *buf, *next; + pdf14_parent_color_t *procs, *prev_procs; + + if (ctx->mask_stack != NULL) { + pdf14_free_mask_stack(ctx, ctx->memory); + } + + /* Now the stack of buffers */ + for (buf = ctx->stack; buf != NULL; buf = next) { + next = buf->saved; + + gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer"); + gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer"); + gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer"); + gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer"); + /* During the soft mask push, the mask_stack was copied (not moved) from + the ctx to the tos mask_stack. We are done with this now so it is safe + to free this one object */ + gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer"); + for (procs = buf->parent_color_info_procs; procs != NULL; procs = prev_procs) { + prev_procs = procs->previous; + gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer"); + } + gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer"); + } + /* Finally the context itself */ + gs_free_object (ctx->memory, ctx, "pdf14_discard_trans_layer"); + pdev->ctx = NULL; + } + return 0; +} + static int pdf14_output_page(gx_device * dev, int num_copies, int flush) { @@ -1842,9 +2304,9 @@ static void gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target) { - int code; cmm_dev_profile_t *profile_targ; cmm_dev_profile_t *profile_dev14; + pdf14_device *pdev = (pdf14_device*) dev; COPY_PARAM(width); COPY_PARAM(height); @@ -1852,33 +2314,45 @@ COPY_ARRAY_PARAM(ImagingBBox); COPY_PARAM(ImagingBBox_set); COPY_ARRAY_PARAM(HWResolution); - COPY_ARRAY_PARAM(MarginsHWResolution); COPY_ARRAY_PARAM(Margins); COPY_ARRAY_PARAM(HWMargins); COPY_PARAM(PageCount); COPY_PARAM(MaxPatternBitmap); + COPY_PARAM(graphics_type_tag); + COPY_PARAM(interpolate_control); + memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params)); /* The PDF14 device copies only the default profile not the text etc. TODO: MJV. It has to make its own device structure but can grab a copy of the profile. This allows swapping of profiles - in the PDF14 device without messing up the target device profile */ + in the PDF14 device without messing up the target device profile. + Also if the device is using a blend color space it will grab that too */ if (dev->icc_struct == NULL) { dev->icc_struct = gsicc_new_device_profile_array(dev->memory); profile_dev14 = dev->icc_struct; - code = - dev_proc((gx_device *) target, get_profile)((gx_device *) target, + dev_proc((gx_device *) target, get_profile)((gx_device *) target, &(profile_targ)); + gsicc_adjust_profile_rc(profile_targ->device_profile[0], 1, "gs_pdf14_device_copy_params"); + if (profile_dev14->device_profile[0] != NULL) { + gsicc_adjust_profile_rc(profile_dev14->device_profile[0], -1, "gs_pdf14_device_copy_params"); + } profile_dev14->device_profile[0] = profile_targ->device_profile[0]; - dev->icc_struct->devicegraytok = profile_targ->devicegraytok; + dev->icc_struct->devicegraytok = profile_targ->devicegraytok; dev->icc_struct->graydetection = profile_targ->graydetection; dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor; dev->icc_struct->supports_devn = profile_targ->supports_devn; - gx_monitor_enter(profile_dev14->device_profile[0]->lock); - rc_increment(profile_dev14->device_profile[0]); - gx_monitor_leave(profile_dev14->device_profile[0]->lock); + dev->icc_struct->usefastcolor = profile_targ->usefastcolor; profile_dev14->rendercond[0] = profile_targ->rendercond[0]; + if (pdev->using_blend_cs) { + /* Swap the device profile and the blend profile. */ + gsicc_adjust_profile_rc(profile_targ->device_profile[0], 1, "gs_pdf14_device_copy_params"); + gsicc_adjust_profile_rc(profile_targ->blend_profile, 1, "gs_pdf14_device_copy_params"); + gsicc_adjust_profile_rc(profile_dev14->device_profile[0], -1, "gs_pdf14_device_copy_params"); + gsicc_adjust_profile_rc(profile_dev14->blend_profile, -1, "gs_pdf14_device_copy_params"); + profile_dev14->blend_profile = profile_targ->device_profile[0]; + profile_dev14->device_profile[0] = profile_targ->blend_profile; + } profile_dev14->sim_overprint = profile_targ->sim_overprint; } - dev->graphics_type_tag = target->graphics_type_tag; /* initialize to same as target */ #undef COPY_ARRAY_PARAM #undef COPY_PARAM } @@ -1910,12 +2384,8 @@ } /* Function prototypes */ -int put_param_compressed_color_list_elem(gx_device * pdev, - gs_param_list * plist, compressed_color_list_t ** pret_comp_list, - char * keyname, int num_comps); int put_param_pdf14_spot_names(gx_device * pdev, gs_separations * pseparations, gs_param_list * plist); -#define PDF14CompressedColorListParamName "PDF14CompressedColorList" #define PDF14NumSpotColorsParamName "PDF14NumSpotColors" /* @@ -1950,24 +2420,24 @@ * by pdf14_fill_rectangle. */ static void -pdf14_set_marking_params(gx_device *dev, const gs_imager_state *pis) +pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs) { pdf14_device * pdev = (pdf14_device *)dev; - pdev->opacity = pis->opacity.alpha; - pdev->shape = pis->shape.alpha; - pdev->alpha = pis->opacity.alpha * pis->shape.alpha; - pdev->blend_mode = pis->blend_mode; - pdev->overprint = pis->overprint; - pdev->overprint_mode = pis->overprint_mode; + pdev->opacity = pgs->opacity.alpha; + pdev->shape = pgs->shape.alpha; + pdev->alpha = pgs->opacity.alpha * pgs->shape.alpha; + pdev->blend_mode = pgs->blend_mode; + pdev->overprint = pgs->overprint; + pdev->overprint_mode = pgs->overprint_mode; if_debug3m('v', dev->memory, "[v]set_marking_params, opacity = %g, shape = %g, bm = %d\n", - pdev->opacity, pdev->shape, pis->blend_mode); + pdev->opacity, pdev->shape, pgs->blend_mode); } static void -update_lop_for_pdf14(gs_imager_state *pis, const gx_drawing_color *pdcolor) +update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor) { bool hastrans = false; @@ -1988,31 +2458,33 @@ } } /* The only idempotent blend modes are Normal, Darken and Lighten */ - if ((pis->alpha != 0xFFFF) || - (pis->blend_mode != BLEND_MODE_Normal && pis->blend_mode != BLEND_MODE_Darken && pis->blend_mode != BLEND_MODE_Lighten) || - (pis->opacity.alpha != 1.0) || - (pis->shape.alpha != 1.0) || + if ((pgs->alpha != 0xFFFF) || + (pgs->blend_mode != BLEND_MODE_Normal && pgs->blend_mode != BLEND_MODE_Darken && pgs->blend_mode != BLEND_MODE_Lighten) || + (pgs->opacity.alpha != 1.0) || + (pgs->shape.alpha != 1.0) || (hastrans)) { /* * The blend operations are not idempotent. Force non-idempotent * filling and stroking operations. */ - pis->log_op |= lop_pdf14; + pgs->log_op |= lop_pdf14; } } static int -pdf14_fill_path(gx_device *dev, const gs_imager_state *pis, +pdf14_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { - gs_imager_state new_is = *pis; + gs_gstate new_pgs = *pgs; int code; gs_pattern2_instance_t *pinst = NULL; - if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)){ + if (pdcolor == NULL) + return_error(gs_error_unknownerror); /* color must be defined */ + if (gx_dc_is_pattern1_color(pdcolor)){ if( gx_pattern1_get_transptr(pdcolor) != NULL || gx_pattern1_clist_has_trans(pdcolor) ){ /* In this case, we need to push a transparency group @@ -2053,14 +2525,14 @@ } } #endif - code = pdf14_tile_pattern_fill(dev, &new_is, ppath, + code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath, params, pdcolor, pcpath); - new_is.trans_device = NULL; - new_is.has_transparency = false; + new_pgs.trans_device = NULL; + new_pgs.has_transparency = false; return code; } } - if (pdcolor != NULL && gx_dc_is_pattern2_color(pdcolor)) { + if (gx_dc_is_pattern2_color(pdcolor)) { pinst = (gs_pattern2_instance_t *)pdcolor->ccolor.pattern; pinst->saved->has_transparency = true; @@ -2068,13 +2540,13 @@ by the pdf14 clist writer device. */ pinst->saved->trans_device = dev; } - update_lop_for_pdf14(&new_is, pdcolor); - pdf14_set_marking_params(dev, pis); - new_is.trans_device = dev; - new_is.has_transparency = true; - code = gx_default_fill_path(dev, &new_is, ppath, params, pdcolor, pcpath); - new_is.trans_device = NULL; - new_is.has_transparency = false; + update_lop_for_pdf14(&new_pgs, pdcolor); + pdf14_set_marking_params(dev, pgs); + new_pgs.trans_device = dev; + new_pgs.has_transparency = true; + code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath); + new_pgs.trans_device = NULL; + new_pgs.has_transparency = false; if (pinst != NULL){ pinst->saved->trans_device = NULL; } @@ -2082,16 +2554,16 @@ } static int -pdf14_stroke_path(gx_device *dev, const gs_imager_state *pis, +pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_stroke_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { - gs_imager_state new_is = *pis; + gs_gstate new_pgs = *pgs; - update_lop_for_pdf14(&new_is, pdcolor); - pdf14_set_marking_params(dev, pis); - return gx_default_stroke_path(dev, &new_is, ppath, params, pdcolor, + update_lop_for_pdf14(&new_pgs, pdcolor); + pdf14_set_marking_params(dev, pgs); + return gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath); } @@ -2100,7 +2572,7 @@ int aa_raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index color, int depth) { - return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h, + return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h, color, NULL, depth, false); } @@ -2109,7 +2581,7 @@ int aa_raster, gx_bitmap_id id, int x, int y, int w, int h, const gx_drawing_color *pdcolor, int depth) { - return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h, + return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h, 0, pdcolor, depth, true); } @@ -2125,7 +2597,7 @@ int i, j, k; byte *line, *dst_ptr; byte src[PDF14_MAX_PLANES]; - byte dst[PDF14_MAX_PLANES]; + byte dst[PDF14_MAX_PLANES] = { 0 }; gs_blend_mode_t blend_mode = pdev->blend_mode; bool additive = pdev->ctx->additive; int rowstride = buf->rowstride; @@ -2141,7 +2613,6 @@ int alpha_g_off = shape_off + (has_shape ? planestride : 0); int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0); bool overprint = pdev->overprint; - bool blendspot = pdev->blendspot; gx_color_index drawn_comps = pdev->drawn_comps; gx_color_index comps; byte shape = 0; /* Quiet compiler. */ @@ -2169,7 +2640,7 @@ src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask); } } - } else + } else pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src); src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5); if (has_shape) @@ -2202,24 +2673,33 @@ for (i = 0; i < w; ++i, ++sx) { /* Complement the components for subtractive color spaces */ if (additive) { - for (k = 0; k < num_chan; ++k) + for (k = 0; k < num_chan; ++k) /* num_chan includes alpha */ dst[k] = dst_ptr[k * planestride]; } else { /* Complement the components for subtractive color spaces */ for (k = 0; k < num_comp; ++k) dst[k] = 255 - dst_ptr[k * planestride]; - dst[num_comp] = dst_ptr[num_comp * planestride]; + dst[num_comp] = dst_ptr[num_comp * planestride]; /* alpha */ } /* Get the aa alpha from the buffer */ - if (depth == 2) { /* map 0 - 3 to 0 - 15 */ - alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5; - } else { - alpha2_aa = aa_row[sx >> 1], - alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4); + switch(depth) + { + case 2: /* map 0 - 3 to 0 - 255 */ + alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85; + break; + case 4: + alpha2_aa = aa_row[sx >> 1]; + alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17; + break; + case 8: + alpha_aa = aa_row[sx]; + break; + default: + return_error(gs_error_rangecheck); } if (alpha_aa != 0) { /* This does happen */ - if (!(alpha_aa == 15)) { + if (alpha_aa != 255) { /* We have an alpha value from aa */ - alpha_aa_act = (255 * alpha_aa) / 15; + alpha_aa_act = alpha_aa; if (src_alpha != 255) { /* Need to combine it with the existing alpha */ int tmp = src_alpha * alpha_aa_act + 0x80; @@ -2233,38 +2713,26 @@ src[num_comp] = src_alpha; } if (knockout) { - if (has_shape) { - art_pdf_composite_knockout_simple_8(dst, - has_shape ? dst_ptr + shape_off : NULL, - has_tags ? dst_ptr + tag_off : NULL, - src, curr_tag, num_comp, 255); - } else { + if (buf->isolated) { art_pdf_knockoutisolated_group_8(dst, src, num_comp); + } else { + art_pdf_composite_knockout_8(dst, src, num_comp, + blend_mode, pdev->blend_procs, pdev); } } else { - art_pdf_composite_pixel_alpha_8(dst, src, num_comp, - blend_mode, pdev->blend_procs); + art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp, + pdev->blend_procs, pdev); } /* Complement the results for subtractive color spaces */ if (additive) { for (k = 0; k < num_chan; ++k) dst_ptr[k * planestride] = dst[k]; } else { - if (overprint) { - if (blendspot) { - /* Overprint simulation of spot colorants */ - for (k = 0; k < num_comp; ++i) { - int temp = - (255 - dst_ptr[k * planestride]) * dst[k]; - temp = temp >> 8; - dst_ptr[k * planestride] = (255 - temp); - } - } else { - for (k = 0, comps = drawn_comps; comps != 0; - ++k, comps >>= 1) { - if ((comps & 0x1) != 0) { - dst_ptr[k * planestride] = 255 - dst[k]; - } + if (overprint && dst_ptr[num_comp * planestride] != 0) { + for (k = 0, comps = drawn_comps; comps != 0; + ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = 255 - dst[k]; } } /* The alpha channel */ @@ -2285,11 +2753,12 @@ dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); } if (has_tags) { - /* If alpha is 100% then set to pure path, else or */ - if (dst[num_comp] == 255) { + /* If alpha is 100% then set to curr_tag, else or */ + /* other than Normal BM, we always OR */ + if (src[num_comp] == 255 && blend_mode == BLEND_MODE_Normal) { dst_ptr[tag_off] = curr_tag; } else { - dst_ptr[tag_off] = ( dst_ptr[tag_off] |curr_tag ) & ~GS_UNTOUCHED_TAG; + dst_ptr[tag_off] |= curr_tag; } } } @@ -2317,9 +2786,11 @@ bool has_pattern_trans = false; cmm_dev_profile_t *dev_profile; + if (pdcolor == NULL) + return_error(gs_error_unknownerror); /* color must be defined */ /* If we are doing a fill with a pattern that has a transparency then go ahead and do a push and a pop of the transparency group */ - if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) { + if (gx_dc_is_pattern1_color(pdcolor)) { if( gx_pattern1_get_transptr(pdcolor) != NULL) { ptile = pdcolor->colors.pattern.p_tile; /* Set up things in the ptile so that we get the proper @@ -2351,8 +2822,10 @@ group_rect.q.y = y + h; if (!(w <= 0 || h <= 0)) { code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, - 1, 0, 255,255, ptile->ttrans->blending_mode, 0, 0, - ptile->ttrans->n_chan-1); + 1, 0, 255,255, ptile->blending_mode, 0, 0, + ptile->ttrans->n_chan-1, false, NULL, NULL, NULL, NULL); + if (code < 0) + return code; /* Set up the output buffer information now that we have pushed the group */ fill_trans_buffer = new_pattern_trans_buff(p14dev->memory); @@ -2380,7 +2853,8 @@ x, y, w, h, dev, lop, false); } if (has_pattern_trans) { - code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code >= 0) + code = dev_proc(dev, get_profile)(dev, &dev_profile); if (code >= 0) code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs, @@ -2397,13 +2871,13 @@ /* Used for filling rects when we are doing a fill with a pattern that has transparency */ static int -pdf14_tile_pattern_fill(gx_device * pdev, const gs_imager_state * pis, +pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { - int code = 0; - gs_imager_state *pis_noconst = (gs_imager_state *)pis; /* Break const. */ + int code; + gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */ gs_fixed_rect clip_box; gs_fixed_rect outer_box; pdf14_device * p14dev = (pdf14_device *)pdev; @@ -2412,27 +2886,28 @@ gx_color_tile *ptile = NULL; int k; gx_pattern_trans_t *fill_trans_buffer = NULL; - int ok; gs_int_point phase; /* Needed during clist rendering for band offset */ int n_chan_tile; gx_clip_path cpath_intersection; gx_path path_ttrans; gs_blend_mode_t blend_mode; + if (ppath == NULL) + return_error(gs_error_unknownerror); /* should not happen */ if (pcpath != NULL) { code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1); - if (code < 0) - return code; } else { (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box); gx_cpath_init_local(&cpath_intersection, ppath->memory); code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box); } - if (ppath != NULL) { - code = gx_cpath_intersect_with_params(&cpath_intersection, ppath, - params->rule, pis_noconst, params); - } - /* One (common) case worth optimising for is where we have a pattern that + if (code < 0) + return code; + code = gx_cpath_intersect_with_params(&cpath_intersection, ppath, + params->rule, pgs_noconst, params); + if (code < 0) + return code; + /* One (common) case worth optimising for is where we have a pattern that * is positioned such that only one repeat of the tile is actually * visible. In this case, we can restrict the size of the blending group * we need to produce to be that of the actual area of the tile that is @@ -2458,18 +2933,23 @@ /* Only the 0th repeat is visible. Restrict the size further to * just the used area of that patch. */ gx_path_init_local(&path_ttrans, ppath->memory); - gx_path_add_rectangle(&path_ttrans, - int2fixed(ptile->ttrans->rect.p.x), - int2fixed(ptile->ttrans->rect.p.y), - int2fixed(ptile->ttrans->rect.q.x), - int2fixed(ptile->ttrans->rect.q.y)); + code = gx_path_add_rectangle(&path_ttrans, + int2fixed(ptile->ttrans->rect.p.x), + int2fixed(ptile->ttrans->rect.p.y), + int2fixed(ptile->ttrans->rect.q.x), + int2fixed(ptile->ttrans->rect.q.y)); + if (code < 0) + return code; code = gx_cpath_intersect(&cpath_intersection, &path_ttrans, - params->rule, pis_noconst); + params->rule, pgs_noconst); + if (code < 0) + return code; } } /* Now let us push a transparency group into which we are * going to tile the pattern. */ if (ppath != NULL && code >= 0) { + pdf14_device save_pdf14_dev; /* save area for p14dev */ gx_cpath_outer_box(&cpath_intersection, &outer_box); rect.p.x = fixed2int(outer_box.p.x); @@ -2483,16 +2963,21 @@ conversion. In this way, we ensure that if the tile has any overlapping occuring it will be blended in the proper manner i.e in the tile underlying color space. */ - ptile = pdevc->colors.pattern.p_tile; if (ptile->cdev == NULL) { + if (ptile->ttrans == NULL) + return_error(gs_error_unknownerror); /* should not happen */ n_chan_tile = ptile->ttrans->n_chan; - blend_mode = ptile->ttrans->blending_mode; - code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, 255,255, - blend_mode, 0, 0, n_chan_tile-1); } else { n_chan_tile = ptile->cdev->common.color_info.num_components+1; - blend_mode = p14dev->blend_mode; } + blend_mode = ptile->blending_mode; + memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device)); + code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, 255,255, + blend_mode, 0, 0, n_chan_tile-1, + false, NULL, NULL, pgs_noconst, + pdev); + if (code < 0) + return code; /* Set the blending procs and the is_additive setting based upon the number of channels */ @@ -2508,9 +2993,8 @@ /* Now lets go through the rect list and fill with the pattern */ /* First get the buffer that we will be filling */ if (ptile->cdev == NULL) { - fill_trans_buffer = new_pattern_trans_buff(pis->memory); + fill_trans_buffer = new_pattern_trans_buff(pgs->memory); pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false); - fill_trans_buffer->blending_mode = blend_mode; /* Based upon if the tiles overlap pick the type of rect fill that we will want to use */ if (ptile->has_overlap) { @@ -2525,20 +3009,20 @@ phase.y = pdevc->phase.y; if (cpath_intersection.rect_list->list.head != NULL){ curr_clip_rect = cpath_intersection.rect_list->list.head->next; - for( k = 0; k< cpath_intersection.rect_list->list.count; k++){ - if_debug5m('v', pis->memory, + for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){ + if_debug5m('v', pgs->memory, "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %d \n", curr_clip_rect->xmin, curr_clip_rect->ymin, curr_clip_rect->xmax-curr_clip_rect->xmin, - curr_clip_rect->ymax-curr_clip_rect->ymin, ptile->id); - ok = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin, - curr_clip_rect->xmax, curr_clip_rect->ymax, ptile, - fill_trans_buffer, phase, pdev, pdevc); + curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id); + code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin, + curr_clip_rect->xmax, curr_clip_rect->ymax, ptile, + fill_trans_buffer, phase, pdev, pdevc); curr_clip_rect = curr_clip_rect->next; } } else if (cpath_intersection.rect_list->list.count == 1) { /* The case when there is just a single rect */ - if_debug5m('v', pis->memory, + if_debug5m('v', pgs->memory, "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %d \n", cpath_intersection.rect_list->list.single.xmin, cpath_intersection.rect_list->list.single.ymin, @@ -2546,12 +3030,12 @@ cpath_intersection.rect_list->list.single.xmin, cpath_intersection.rect_list->list.single.ymax- cpath_intersection.rect_list->list.single.ymin, - ptile->id); - ok = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin, - cpath_intersection.rect_list->list.single.ymin, - cpath_intersection.rect_list->list.single.xmax, - cpath_intersection.rect_list->list.single.ymax, - ptile, fill_trans_buffer, phase, pdev, pdevc); + (int)ptile->id); + code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin, + cpath_intersection.rect_list->list.single.ymin, + cpath_intersection.rect_list->list.single.xmax, + cpath_intersection.rect_list->list.single.ymax, + ptile, fill_trans_buffer, phase, pdev, pdevc); } } else { /* Clist pattern with transparency. Create a clip device from our @@ -2565,31 +3049,49 @@ dev = (gx_device *)&clipdev; phase.x = pdevc->phase.x; phase.y = pdevc->phase.y; - ok = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, - rect.q.x - rect.p.x, - rect.q.y - rect.p.y, - ptile, fill_trans_buffer, phase, - dev, pdevc); + code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y, + ptile, fill_trans_buffer, phase, + dev, pdevc); + } + /* We're done drawing with the pattern, remove the reference to the + * pattern device + */ + p14dev->pclist_device = NULL; + if (code < 0) + return code; + /* free our buffer object */ if (fill_trans_buffer != NULL) { - gs_free_object(pis->memory, fill_trans_buffer, "pdf14_tile_pattern_fill"); + gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill"); ptile->ttrans->fill_trans_buffer = NULL; /* Avoid GC issues */ } - /* pop our transparency group which will force the blending. In clist - case, rendering occurs directly into primary buffer since it includes - the device push etc. This was all needed for Bug 693498 */ - if (ptile->cdev == NULL) { - code = pdf14_pop_transparency_group(pis_noconst, p14dev->ctx, - p14dev->blend_procs, - p14dev->color_info.num_components, - p14dev->icc_struct->device_profile[0], - pdev); - } + /* pop our transparency group which will force the blending. + This was all needed for Bug 693498 */ + code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx, + p14dev->blend_procs, + p14dev->color_info.num_components, + p14dev->icc_struct->device_profile[0], + pdev); + memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device)); + p14dev->pclist_device = NULL; } return code; } +/* Useful function that should probably go elsewhere. + * Call this function to find the topmost pdf14 device in the device chain, + * or NULL if there is not one. + */ +static pdf14_device *find_pdf14_device(gx_device *dev) +{ + pdf14_device *pdev; + + if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0) + return NULL; + return pdev; +} + /* Imager render for pattern transparency filling. This is just here to catch the final flush, at which time we will pop the group and reset a few items */ static int @@ -2597,42 +3099,54 @@ uint w, int h, gx_device * dev) { int code; - pdf14_device * p14dev = (pdf14_device *)dev; - const gs_imager_state * pis = penum->pis; + pdf14_device * p14dev; + const gs_gstate * pgs = penum->pgs; gx_device_color * pdcolor = (penum->icolor1); gx_color_tile *ptile = pdcolor->colors.pattern.p_tile; /* Pass along to the original renderer */ code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev); + if (code < 0) + return code; /* On our final time through here, go ahead and pop the transparency group and reset the procs in the device color. And free the fill trans buffer object */ - if ( h == 0 && ptile->trans_group_popped == false) { - if (pis->is_gstate) { + if (h == 0 && ptile->trans_group_popped == false) { + p14dev = find_pdf14_device(dev); + + if (p14dev->pclist_device == NULL) { /* Used if we are on clist writing phase. Would only occur if we somehow failed in high level clist image writing */ - code = gs_end_transparency_group((gs_state *) pis); + code = gs_end_transparency_group((gs_gstate *) pgs); } else { /* Used if we are on clist reading phase. If we had high level image in clist */ + cmm_dev_profile_t *dev_profile; + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + + if_debug2m('v', p14dev->ctx->memory, + "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n", + ptile->uid.id, ptile->id); code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs, - p14dev->color_info.num_components, - dev->icc_struct->device_profile[0], (gx_device *) p14dev); + p14dev->color_info.num_components, dev_profile->device_profile[0], + (gx_device *) p14dev); } pdcolor->colors.pattern.p_tile->trans_group_popped = true; - gs_free_object(pis->memory, ptile->ttrans->fill_trans_buffer, + gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer, "pdf14_pattern_trans_render"); ptile->ttrans->fill_trans_buffer = NULL; /* Avoid GC issues */ } - return(code); + return code; } /* This function is used to get things in place for filling a mask image with a pattern that has transparency. It is used by pdf14_begin_type_image and pdf14_clist_begin_type_image */ static int -pdf14_patt_trans_image_fill(gx_device * dev, const gs_imager_state * pis, +pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, @@ -2642,7 +3156,7 @@ const gs_image_t *pim = (const gs_image_t *)pic; pdf14_device * p14dev = (pdf14_device *)dev; gx_color_tile *ptile; - int code = 0; + int code; gs_int_rect group_rect; gx_image_enum *penum; gs_rect bbox_in, bbox_out; @@ -2661,8 +3175,8 @@ ptile->ttrans->is_additive = false; } /* Set the blending mode in the ptile based upon the current - setting in the imager state */ - ptile->ttrans->blending_mode = pis->blend_mode; + setting in the gs_gstate */ + ptile->blending_mode = pgs->blend_mode; /* Based upon if the tiles overlap pick the type of rect fill that we will want to use */ if (ptile->has_overlap) { @@ -2675,8 +3189,10 @@ /* Set the procs so that we use the proper filling method. */ gx_set_pattern_procs_trans((gx_device_color*) pdcolor); /* Let the imaging stuff get set up */ - code = gx_default_begin_typed_image(dev, pis, pmat, pic, + code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,pcpath, mem, pinfo); + if (code < 0) + return code; /* Now Push the group */ /* First apply the inverse of the image matrix to our image size to get our bounding box. */ @@ -2686,18 +3202,24 @@ bbox_in.q.y = pim->Height; code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix), &bbox_out); - if (code < 0) return code; - /* That in turn will get hit by the matrix in the imager state */ + if (code < 0) + return code; + /* That in turn will get hit by the matrix in the gs_gstate */ code = compute_group_device_int_rect(p14dev, &group_rect, - &bbox_out, (gs_imager_state *)pis); + &bbox_out, (gs_gstate *)pgs); + if (code < 0) + return code; if (!(pim->Width == 0 || pim->Height == 0)) { - code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, - 1, 0, 255,255, - pis->blend_mode, 0, - 0, ptile->ttrans->n_chan-1); + if_debug2m('v', p14dev->ctx->memory, + "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n", + ptile->uid.id, ptile->id); + code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 255,255, + pgs->blend_mode, 0, 0, + ptile->ttrans->n_chan-1, false, NULL, + NULL, (gs_gstate *)pgs, dev); /* Set up the output buffer information now that we have pushed the group */ - fill_trans_buffer = new_pattern_trans_buff(pis->memory); + fill_trans_buffer = new_pattern_trans_buff(pgs->memory); pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false); /* Store this in the appropriate place in pdcolor. This is released later in pdf14_pattern_trans_render when @@ -2715,7 +3237,7 @@ } static int -pdf14_begin_typed_image(gx_device * dev, const gs_imager_state * pis, +pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, @@ -2739,8 +3261,8 @@ renderer which will end up installed for this case. Detect setting of begin_image to gx_no_begin_image. (final recursive call) */ - if (dev->procs.begin_image != gx_default_begin_image) { - code = pdf14_patt_trans_image_fill(dev, pis, pmat, pic, + if (dev_proc(dev, begin_image) != gx_default_begin_image) { + code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); return code; @@ -2748,33 +3270,29 @@ } } } - pdf14_set_marking_params(dev, pis); - return gx_default_begin_typed_image(dev, pis, pmat, pic, prect, pdcolor, + pdf14_set_marking_params(dev, pgs); + return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); } static void -pdf14_set_params(gs_imager_state * pis, gx_device * dev, +pdf14_set_params(gs_gstate * pgs, gx_device * dev, const gs_pdf14trans_params_t * pparams) { - pdf14_device * p14dev = (pdf14_device *)dev; - if_debug0m('v', dev->memory, "[v]pdf14_set_params\n"); if (pparams->changed & PDF14_SET_BLEND_MODE) - pis->blend_mode = pparams->blend_mode; + pgs->blend_mode = pparams->blend_mode; if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT) - pis->text_knockout = pparams->text_knockout; + pgs->text_knockout = pparams->text_knockout; if (pparams->changed & PDF14_SET_SHAPE_ALPHA) - pis->shape.alpha = pparams->shape.alpha; + pgs->shape.alpha = pparams->shape.alpha; if (pparams->changed & PDF14_SET_OPACITY_ALPHA) - pis->opacity.alpha = pparams->opacity.alpha; + pgs->opacity.alpha = pparams->opacity.alpha; if (pparams->changed & PDF14_SET_OVERPRINT) - pis->overprint = pparams->overprint; + pgs->overprint = pparams->overprint; if (pparams->changed & PDF14_SET_OVERPRINT_MODE) - pis->overprint_mode = pparams->overprint_mode; - if (pparams->changed & PDF14_SET_OVERPRINT_BLEND) - p14dev->blendspot = pparams->blendspot; - pdf14_set_marking_params(dev, pis); + pgs->overprint_mode = pparams->overprint_mode; + pdf14_set_marking_params(dev, pgs); } /* @@ -2792,7 +3310,7 @@ { gx_device_forward * pdev = (gx_device_forward *)dev; gx_device * tdev = pdev->target; - int code = 0; + int code; /* The PDF 1.4 compositing devices must have a target */ if (tdev == 0) @@ -2862,24 +3380,62 @@ * color model of the output device. */ static pdf14_default_colorspace_t -pdf14_determine_default_blend_cs(gx_device * pdev) +pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum, + bool *using_blend_cs) { + /* If a blend color space was specified, then go ahead and use that to + define the default color space for the blend modes. Only Gray, RGB + or CMYK blend color spaces are allowed. Note we do not allow this + setting if we are dealing with a separation device. */ + cmm_dev_profile_t *dev_profile; + int code = dev_proc(pdev, get_profile)(pdev, &dev_profile); + bool valid_blend_cs = false; + *using_blend_cs = false; + + /* Make sure any specified blend color space is valid along with other cond */ + if (code == 0 && dev_profile->blend_profile != NULL && !use_pdf14_accum) { + if (!dev_profile->blend_profile->isdevlink && + !dev_profile->blend_profile->islab && + (dev_profile->blend_profile->data_cs == gsGRAY || + dev_profile->blend_profile->data_cs == gsRGB || + dev_profile->blend_profile->data_cs == gsCMYK)) { + /* Also, do not allow the use of the blend space when we are pushing + a pattern pdf14 device. Those should inherit from the parent */ + if (!(gx_device_is_pattern_clist(pdev) || + gx_device_is_pattern_accum(pdev))) { + valid_blend_cs = true; + } + } + } + /* If num components is one, just go ahead and use gray. This avoids issues with additive/subtractive mono color devices */ if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE || - pdev->color_info.num_components == 1) + pdev->color_info.num_components == 1) { /* - * Note: We do not allow the SeparationOrder device parameter for - * additive devices. Thus we always have 1 colorant for DeviceGray - * and 3 colorants for DeviceRGB. - */ - if (pdev->color_info.num_components == 1) - return PDF14_DeviceGray; - else + * Note: We do not allow the SeparationOrder device parameter for + * additive devices. Thus we always have 1 colorant for DeviceGray + * and 3 colorants for DeviceRGB. + */ + if (valid_blend_cs) { + *using_blend_cs = true; + switch (dev_profile->blend_profile->num_comps) { + case 1: + return PDF14_DeviceGray; + case 3: + return PDF14_DeviceRGB; + case 4: + return PDF14_DeviceCMYK; + } + } + if (pdev->color_info.num_components == 1) + return PDF14_DeviceGray; + else return PDF14_DeviceRGB; - else { + } else { /* - * Check if the device is CMYK only or CMYK plus spot colors. + * Check if the device is CMYK only or CMYK plus spot colors. Note + * the CMYK plus spot colors will not support the blend color space */ int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0; #if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING @@ -2907,8 +3463,20 @@ * the output device device to only select CMYK. */ if (num_cmyk_used == 4 && pdev->color_info.num_components == 4 - && pdev->color_info.max_components == 4) + && pdev->color_info.max_components == 4) { + if (valid_blend_cs) { + *using_blend_cs = true; + switch (dev_profile->blend_profile->num_comps) { + case 1: + return PDF14_DeviceGray; + case 3: + return PDF14_DeviceRGB; + case 4: + return PDF14_DeviceCMYK; + } + } return PDF14_DeviceCMYK; + } /* * Check if we should use the 'custom' PDF 1.4 compositor device. * This device is only needed for those devices which do not support @@ -2933,11 +3501,13 @@ */ static int get_pdf14_device_proto(gx_device * dev, pdf14_device ** pdevproto, - pdf14_device * ptempdevproto, gs_imager_state * pis, - const gs_pdf14trans_t * pdf14pct) + pdf14_device * ptempdevproto, gs_gstate * pgs, + const gs_pdf14trans_t * pdf14pct, bool use_pdf14_accum) { + bool using_blend_cs; pdf14_default_colorspace_t dev_cs = - pdf14_determine_default_blend_cs(dev); + pdf14_determine_default_blend_cs(dev, use_pdf14_accum, + &using_blend_cs); switch (dev_cs) { case PDF14_DeviceGray: @@ -2949,16 +3519,19 @@ ptempdevproto->color_info.max_gray = 255; ptempdevproto->color_info.gray_index = 0; /* Avoid halftoning */ ptempdevproto->color_info.dither_grays = 256; + ptempdevproto->sep_device = false; *pdevproto = ptempdevproto; break; case PDF14_DeviceRGB: *pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; *ptempdevproto = **pdevproto; + ptempdevproto->sep_device = false; *pdevproto = ptempdevproto; break; case PDF14_DeviceCMYK: *pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; *ptempdevproto = **pdevproto; + ptempdevproto->sep_device = false; *pdevproto = ptempdevproto; break; case PDF14_DeviceCMYKspot: @@ -2981,8 +3554,9 @@ GS_CLIENT_COLOR_MAX_COMPONENTS) ptempdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS; - ptempdevproto->color_info.depth = + ptempdevproto->color_info.depth = ptempdevproto->color_info.num_components * 8; + ptempdevproto->sep_device = true; *pdevproto = ptempdevproto; } break; @@ -3007,9 +3581,66 @@ default: /* Should not occur */ return_error(gs_error_rangecheck); } + ptempdevproto->using_blend_cs = using_blend_cs; return 0; } +/* When playing back the clist, we need to know if the buffer device is compatible */ +/* with the pdf14 compositor that was used when writing the clist. Colorspace and */ +/* depth are critical since these must match when reading back colors. */ +bool +pdf14_ok_to_optimize(gx_device *dev) +{ + bool using_blend_cs; + pdf14_default_colorspace_t pdf14_cs = + pdf14_determine_default_blend_cs(dev, false, &using_blend_cs); + gsicc_colorbuffer_t dev_icc_cs; + bool ok = false; + int tag_depth = device_encodes_tags(dev) ? 8 : 0; + cmm_dev_profile_t *dev_profile; + int code = dev_proc(dev, get_profile)(dev, &dev_profile); + + if (code < 0) + return false; + + check_device_compatible_encoding(dev); + + if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD) + return false; + + dev_icc_cs = dev_profile->device_profile[0]->data_cs; + /* If the outputprofile is not "standard" then colors converted to device color */ + /* during clist writing won't match the colors written for the pdf14 clist dev */ + if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK)) + return false; /* can't handle funky output profiles */ + + switch (pdf14_cs) { + case PDF14_DeviceGray: + ok = dev->color_info.max_gray == 255 && dev->color_info.depth == 8 + tag_depth; + break; + case PDF14_DeviceRGB: + ok = dev->color_info.max_color == 255 && dev->color_info.depth == 24 + tag_depth; + break; + case PDF14_DeviceCMYK: + ok = dev->color_info.max_color == 255 && dev->color_info.depth == 32 + tag_depth; + break; + case PDF14_DeviceCMYKspot: + ok = false; /* punt for this case */ + break; + case PDF14_DeviceCustom: + /* + * We are using the output device's process color model. The + * color_info for the PDF 1.4 compositing device needs to match + * the output device, but it may not have been contone. + */ + ok = dev->color_info.depth == dev->color_info.num_components * 8 + tag_depth; + break; + default: /* Should not occur */ + ok = false; + } + return ok; +} + /* * Recreate the PDF 1.4 compositor device. Once created, the PDF 1.4 * compositor device is never removed. (We do not have a remove compositor @@ -3018,13 +3649,14 @@ * again. */ static int -pdf14_recreate_device(gs_memory_t *mem, gs_imager_state * pis, +pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs, gx_device * dev, const gs_pdf14trans_t * pdf14pct) { pdf14_device * pdev = (pdf14_device *)dev; gx_device * target = pdev->target; pdf14_device * dev_proto; pdf14_device temp_dev_proto; + bool has_tags = device_encodes_tags(dev); int code; if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n"); @@ -3033,12 +3665,20 @@ * We will not use the entire prototype device but we will set the * color related info and the device procs to match the prototype. */ - code = get_pdf14_device_proto(target, &dev_proto, - &temp_dev_proto, pis, pdf14pct); + code = get_pdf14_device_proto(target, &dev_proto, &temp_dev_proto, pgs, + pdf14pct, false); if (code < 0) return code; pdev->color_info = dev_proto->color_info; + pdev->pad = target->pad; + pdev->log2_align_mod = target->log2_align_mod; + pdev->is_planar = target->is_planar; pdev->procs = dev_proto->procs; + if (has_tags) { + set_dev_proc(pdev, encode_color, pdf14_encode_color_tag); + pdev->color_info.comp_shift[pdev->color_info.num_components] = pdev->color_info.depth; + pdev->color_info.depth += 8; + } dev->static_procs = dev_proto->static_procs; gx_device_set_procs(dev); gx_device_fill_in_procs(dev); @@ -3051,7 +3691,7 @@ * create compositor request. */ static int -gx_update_pdf14_compositor(gx_device * pdev, gs_imager_state * pis, +gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs, const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem ) { pdf14_device *p14dev = (pdf14_device *)pdev; @@ -3066,63 +3706,81 @@ if (!(params.is_pattern)) { p14dev->blend_mode = 0; p14dev->opacity = p14dev->shape = 0.0; - pdf14_recreate_device(mem, pis, pdev, pdf14pct); + pdf14_recreate_device(mem, pgs, pdev, pdf14pct); + } + break; + case PDF14_ABORT_DEVICE: + /* Something has gone very wrong. Let transparency device clean up + what ever it has allocated and then we are shutting it down */ + code = gx_abort_trans_device(pgs, pdev); + if (p14dev->free_devicen) { + devn_free_params(pdev); } + pdf14_disable_device(pdev); + pdf14_close(pdev); break; case PDF14_POP_DEVICE: if (!(params.is_pattern)) { if_debug0m('v', pdev->memory, "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n"); - pis->get_cmap_procs = p14dev->save_get_cmap_procs; - gx_set_cmap_procs(pis, p14dev->target); + pgs->get_cmap_procs = p14dev->save_get_cmap_procs; + gx_set_cmap_procs(pgs, p14dev->target); /* Send image out raster data to output device */ { /* Make a copy so we can change the ROP */ - gs_imager_state new_is = *pis; + gs_gstate new_pgs = *pgs; - /* We don't use the imager state log_op since this is for the */ + /* We don't use the gs_gstate log_op since this is for the */ /* clist playback. Putting the image (band in the case of the */ /* clist) only needs to use the default ROP to copy the data */ - new_is.log_op = rop3_default; - p14dev->pdf14_procs->put_image(pdev, &new_is, p14dev->target); + new_pgs.log_op = rop3_default; + code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target); + } + /* Before we disable the device release any deviceN structures. + free_devicen is set if the pdf14 device had inherited its + deviceN parameters from the target clist device. In this + case they should not be freed */ + if (p14dev->free_devicen) { + devn_free_params(pdev); } - /* Before we disable the device release any deviceN structures. - free_devicen is set if the pdf14 device had inherited its - deviceN parameters from the target clist device. In this - case they should not be freed */ - if (p14dev->free_devicen) { - devn_free_params(pdev); - } pdf14_disable_device(pdev); pdf14_close(pdev); } break; case PDF14_BEGIN_TRANS_GROUP: - code = gx_begin_transparency_group(pis, pdev, ¶ms); + code = gx_begin_transparency_group(pgs, pdev, ¶ms); break; case PDF14_END_TRANS_GROUP: - code = gx_end_transparency_group(pis, pdev); + code = gx_end_transparency_group(pgs, pdev); + break; + case PDF14_BEGIN_TRANS_TEXT_GROUP: + p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED; + break; + case PDF14_END_TRANS_TEXT_GROUP: + if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) + code = gx_end_transparency_group(pgs, pdev); + p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */ break; case PDF14_BEGIN_TRANS_MASK: - code = gx_begin_transparency_mask(pis, pdev, ¶ms); + code = gx_begin_transparency_mask(pgs, pdev, ¶ms); break; case PDF14_END_TRANS_MASK: - code = gx_end_transparency_mask(pis, pdev, ¶ms); + code = gx_end_transparency_mask(pgs, pdev, ¶ms); break; case PDF14_SET_BLEND_PARAMS: - pdf14_set_params(pis, pdev, &pdf14pct->params); + pdf14_set_params(pgs, pdev, &pdf14pct->params); break; case PDF14_PUSH_TRANS_STATE: - code = gx_push_transparency_state(pis, pdev); + code = gx_push_transparency_state(pgs, pdev); break; case PDF14_POP_TRANS_STATE: - code = gx_pop_transparency_state(pis, pdev); + code = gx_pop_transparency_state(pgs, pdev); break; case PDF14_PUSH_SMASK_COLOR: - code = pdf14_increment_smask_color(pis, pdev); + code = pdf14_increment_smask_color(pgs, pdev); break; case PDF14_POP_SMASK_COLOR: - code = pdf14_decrement_smask_color(pis, pdev); + code = pdf14_decrement_smask_color(pgs, pdev); break; } return code; @@ -3138,23 +3796,23 @@ */ static int pdf14_forward_create_compositor(gx_device * dev, gx_device * * pcdev, - const gs_composite_t * pct, gs_imager_state * pis, + const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { pdf14_device *pdev = (pdf14_device *)dev; gx_device * tdev = pdev->target; gx_device * ndev; - int code = 0; + int code; *pcdev = dev; if (gs_is_pdf14trans_compositor(pct)) { const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct; if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE) - return gx_update_pdf14_compositor(dev, pis, pdf14pct, mem); + return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem); return 0; } - code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pis, mem, cdev); + code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pgs, mem, cdev); if (code < 0) return code; gx_device_set_target((gx_device_forward *)pdev, ndev); @@ -3166,9 +3824,9 @@ * and return. Since the gs_pdf14_device only supports the high-level routines * of the interface, don't bother trying to handle any other compositor. */ -static int +static int pdf14_create_compositor(gx_device * dev, gx_device * * pcdev, - const gs_composite_t * pct, gs_imager_state * pis, + const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { pdf14_device *p14dev = (pdf14_device *)dev; @@ -3180,7 +3838,7 @@ groups. We want this propogated through all the pdf14 functions. Store a pointer to it in the pdf14 device */ p14dev->pclist_device = cdev; - return gx_update_pdf14_compositor(dev, pis, pdf14pct, mem); + return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem); } else if (gs_is_overprint_compositor(pct)) { /* If we had an overprint compositer action, then the color components that were drawn should be updated. @@ -3189,7 +3847,6 @@ values around a fair amount. Hence the forced assignement here. See gx_spot_colors_set_overprint in gscspace for issues... */ const gs_overprint_t * op_pct = (const gs_overprint_t *) pct; - p14dev->blendspot = op_pct->params.blendspot; if (op_pct->params.retain_any_comps && !op_pct->params.retain_spot_comps) { p14dev->drawn_comps = op_pct->params.drawn_comps; } else { @@ -3200,11 +3857,43 @@ *pcdev = dev; return 0; } else - return gx_no_create_compositor(dev, pcdev, pct, pis, mem, cdev); + return gx_no_create_compositor(dev, pcdev, pct, pgs, mem, cdev); +} + +static int +pdf14_push_text_group(gx_device *dev, gs_gstate *pgs, gx_path *path, + const gx_clip_path *pcpath, gs_blend_mode_t blend_mode, float opacity, + bool is_clist) +{ + int code; + gs_transparency_group_params_t params = { 0 }; + gs_rect bbox = { 0 }; /* Bounding box is set by parent */ + pdf14_clist_device * pdev = (pdf14_clist_device *)dev; + + /* Push a non-isolated knock-out group making sure the opacity and blend + mode are correct */ + params.Isolated = false; + params.Knockout = true; + params.text_group = PDF14_TEXTGROUP_BT_PUSHED; + gs_setopacityalpha(pgs, 1.0); + gs_setblendmode(pgs, BLEND_MODE_Normal); + if (is_clist) { + code = pdf14_clist_update_params(pdev, pgs, false, NULL); + if (code < 0) + return code; + } + code = gs_begin_transparency_group(pgs, ¶ms, &bbox); + if (code < 0) + return code; + gs_setopacityalpha(pgs, opacity); + gs_setblendmode(pgs, blend_mode); + if (is_clist) + code = pdf14_clist_update_params(pdev, pgs, false, NULL); + return code; } static int -pdf14_text_begin(gx_device * dev, gs_imager_state * pis, +pdf14_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, @@ -3212,17 +3901,54 @@ { int code; gs_text_enum_t *penum; + gs_blend_mode_t blend_mode = gs_currentblendmode(pgs); + float opacity = gs_currentopacityalpha(pgs); + bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible); + pdf14_device *pdev = (pdf14_device*)dev; + bool draw = !(text->operation & TEXT_DO_NONE); if_debug0m('v', memory, "[v]pdf14_text_begin\n"); - pdf14_set_marking_params(dev, pis); - code = gx_default_text_begin(dev, pis, text, font, path, pdcolor, pcpath, + pdf14_set_marking_params(dev, pgs); + code = gx_default_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, &penum); if (code < 0) return code; + + /* We may need to push a non-isolated transparency group if the following + is true. + 1) We are not currently in one that we pushed for text and we are in + a BT/ET pair. This is determined by looking at the pdf14 text_group. + 2) The blend mode is not Normal or the opacity is not 1.0 + 3) Text knockout is set to true + 4) We are actually doing a text drawing + + Special note: If text-knockout is set to false while we are within a + BT ET pair, we should pop the group. I need to create a test file for + this case. */ + if (gs_currenttextknockout(pgs) && (blend_issue || opacity != 1.0) && + gs_currenttextrenderingmode(pgs) != 3 && /* don't bother with invisible text */ + pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) + if (draw) { + code = pdf14_push_text_group(dev, pgs, path, pcpath, blend_mode, opacity, + false); + } *ppenum = (gs_text_enum_t *)penum; return code; } +static int +pdf14_finish_copydevice(gx_device *new_dev, const gx_device *from_dev) +{ + pdf14_device *pdev = (pdf14_device*)new_dev; + + pdev->ctx = NULL; + pdev->trans_group_parent_cmap_procs = NULL; + pdev->smaskcolor = NULL; + + /* Only allow copying the prototype. */ + return (from_dev->memory ? gs_note_error(gs_error_rangecheck) : 0); +} + /* * Implement copy_mono by filling lots of small rectangles. */ @@ -3302,7 +4028,7 @@ a planar tile (pattern) and we are copying it into place here */ static int -pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster, +pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h, int plane_height) { pdf14_device *pdev = (pdf14_device *)dev; @@ -3310,46 +4036,56 @@ pdf14_ctx *ctx = pdev->ctx; #endif pdf14_buf *buf = pdev->ctx->stack; - int num_planes = dev->color_info.num_components; - byte *dptr = (byte *)data + data_x; - int yinc, xinc, pi; - gx_drawing_color dcolor; - int code = 0; + int xo = x; + int yo = y; + pdf14_buf fake_tos; fit_fill_xywh(dev, x, y, w, h); if (w <= 0 || h <= 0) return 0; - dcolor.type = gx_dc_type_devn; - /* Because of the complexity of the blending and my desire to finish - this planar sep device work, I am going to make this a series of - rect fills. ToDo: optimize this for more efficient planar operation. - It would be interesting to use the put_image procedure. */ - for (yinc = 0; yinc < h; yinc++) { - for (xinc = 0; xinc < w; xinc++) { - for (pi = 0; pi < num_planes; pi++) { - dcolor.colors.devn.values[pi] = - *(dptr + plane_height * raster * pi) << 8; - } - if (buf->knockout) - code = - pdf14_mark_fill_rectangle_ko_simple(dev, x + xinc, - y + yinc, 1, 1, 0, - &dcolor, true); - else - code = - pdf14_mark_fill_rectangle(dev, x + xinc, y + yinc, 1, 1, 0, - &dcolor, true); - dptr++; - } - dptr = (byte *)data + raster * yinc + data_x; - } - return code; + fake_tos.alpha = (byte)(0xff * pdev->alpha + 0.5); + fake_tos.backdrop = NULL; + fake_tos.blend_mode = pdev->blend_mode; + fake_tos.color_space = buf->color_space; + fake_tos.data = (byte *)data + data_x - (x - xo) - (y - yo) * raster; /* Nasty, cast away of const */ + fake_tos.dirty.p.x = x; + fake_tos.dirty.p.y = y; + fake_tos.dirty.q.x = x + w; + fake_tos.dirty.q.y = y + h; + fake_tos.has_alpha_g = 0; + fake_tos.has_shape = 0; + fake_tos.has_tags = 0; + fake_tos.idle = false; + fake_tos.isolated = false; + fake_tos.knockout = false; + fake_tos.mask_id = 0; + fake_tos.mask_stack = NULL; + fake_tos.matte = NULL; + fake_tos.matte_num_comps = 0; + fake_tos.memory = dev->memory; + fake_tos.n_chan = dev->color_info.num_components; + fake_tos.n_planes = dev->color_info.num_components; + fake_tos.num_spots = 0; + fake_tos.parent_color_info_procs = NULL; + fake_tos.planestride = raster * plane_height; + fake_tos.rect.p.x = x; + fake_tos.rect.p.y = y; + fake_tos.rect.q.x = x + w; + fake_tos.rect.q.y = y + h; + fake_tos.rowstride = raster; + fake_tos.saved = NULL; + fake_tos.shape = 0xff; + fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha; + fake_tos.transfer_fn = NULL; + pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h, + pdev->ctx->memory, dev); + return 0; } static int pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { pdf14_device *pdev = (pdf14_device *)dev; @@ -3363,7 +4099,7 @@ if (w <= 0 || h <= 0) return 0; if (buf->knockout) - return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor, + return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor, true); else return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true); @@ -3380,7 +4116,7 @@ if (w <= 0 || h <= 0) return 0; if (buf->knockout) - return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL, + return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL, false); else return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false); @@ -3405,9 +4141,9 @@ static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect, - const gs_rect *pbbox, gs_imager_state *pis) + const gs_rect *pbbox, gs_gstate *pgs) { - int code = pdf14_compute_group_device_int_rect(&ctm_only(pis), pbbox, rect); + int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect); if (code < 0) return code; @@ -3424,130 +4160,107 @@ pdf14_begin_transparency_group(gx_device *dev, const gs_transparency_group_params_t *ptgp, const gs_rect *pbbox, - gs_imager_state *pis, gs_memory_t *mem) + gs_gstate *pgs, gs_memory_t *mem) { pdf14_device *pdev = (pdf14_device *)dev; - double alpha = pis->opacity.alpha * pis->shape.alpha; + double alpha = pgs->opacity.alpha * pgs->shape.alpha; gs_int_rect rect; int code; - bool isolated; - bool sep_target; - int group_color_numcomps; + bool isolated = ptgp->Isolated; gs_transparency_color_t group_color; - cmm_profile_t *curr_profile; cmm_profile_t *group_profile; - gsicc_rendering_param_t render_cond; + cmm_profile_t *tos_profile; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; + bool cm_back_drop = false; + bool new_icc = false; - sep_target = (strcmp(pdev->dname, "pdf14cmykspot") == 0) || - (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)); code = dev_proc(dev, get_profile)(dev, &dev_profile); - gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile, - &render_cond); - /* If the target device supports separations, then - we should should NOT create the group. The exception to this - rule would be if we just popped a transparency mask */ - code = compute_group_device_int_rect(pdev, &rect, pbbox, pis); + if (code < 0) + return code; + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond); + + if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) { + rect = pdev->ctx->rect; /* Use parent group for text_group. */ + pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED; /* For immediate mode and clist reading */ + } else + code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs); + if (code < 0) return code; if_debug4m('v', pdev->memory, "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d\n", - ptgp->Isolated, ptgp->Knockout, alpha, pis->blend_mode); - /* If the group color is unknown then use the current device profile. Note - that if we have a sep device there may not be a profile */ + ptgp->Isolated, ptgp->Knockout, alpha, pgs->blend_mode); + + /* If the group color is unknown then use the current device profile. */ if (ptgp->group_color == UNKNOWN){ - if (pdev->ctx->stack){ - /* Use previous group color space */ - group_color_numcomps = pdev->ctx->stack->n_chan-1; /* Remove alpha */ - } else { - /* Use process color space */ - group_color_numcomps = pdev->color_info.num_components; - } - /* If we are not going out to a sep device then use - the ICC color space defined by the device profile - in the ICC manager. This is reset for each - group push. */ - if (group_color_numcomps < 5 ) { - group_color = ICC; - curr_profile = group_profile; - } else { - /* We can end up here if we are in - a deviceN color space and - we have a sep output device */ - group_color = DEVICEN; - curr_profile = NULL; - } + group_color = ICC; + group_profile = tos_profile; } else { - group_color_numcomps = ptgp->group_color_numcomps; group_color = ptgp->group_color; - curr_profile = ptgp->iccprofile; + group_profile = ptgp->iccprofile; } - /* If needed, update the color mapping procs. But only if we dont have a sep device. - The exception would be if we are in doing the group for a soft mask */ - if (!sep_target) { - if (curr_profile != NULL) { - /* If the cs is different then force isolation */ - if ( curr_profile->hashcode == group_profile->hashcode) { - /* cs same. use parameter setting */ - isolated = ptgp->Isolated; - } else { - /* blend cs different. force isolation. other - option would be to ignore the color space */ - isolated = true; - } - } else { - if (group_color_numcomps == pdev->color_info.num_components) { - /* cs same. use parameter setting */ - isolated = ptgp->Isolated; - } else { - /* blend cs different. force isolation. other - option would be to ignore the color space */ - isolated = true; - } + + /* We have to handle case where the profile is in the clist */ + if (group_profile == NULL && pdev->pclist_device != NULL) { + /* Get the serialized data from the clist. */ + gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device); + group_profile = gsicc_read_serial_icc((gx_device *) pcrdev, ptgp->icc_hashcode); + if (group_profile == NULL) + return gs_throw(gs_error_unknownerror, "ICC data not found in clist"); + /* Keep a pointer to the clist device */ + group_profile->dev = (gx_device *) pcrdev; + new_icc = true; + } + if (group_profile != NULL) { + /* If we have a non-isolated group and the color space is different, + we will need to CM the backdrop. */ + if (!(group_profile->hash_is_valid)) { + gsicc_get_icc_buff_hash(group_profile->buffer, + &(group_profile->hashcode), + group_profile->buffer_size); + group_profile->hash_is_valid = true; + } + if (group_profile->hashcode != tos_profile->hashcode) { + cm_back_drop = true; } - code = pdf14_update_device_color_procs(dev, group_color, - ptgp->icc_hashcode, pis, curr_profile); - if_debug0m('v', dev->memory, - "[v]Transparency group color space update\n"); - } else { - code = 0; - /* Sep devices always blend in the components */ - isolated = ptgp->Isolated; - group_color_numcomps = pdev->color_info.num_components; } + code = pdf14_update_device_color_procs(dev, group_color, ptgp->icc_hashcode, + pgs, group_profile, false); + if_debug0m('v', dev->memory, "[v]Transparency group color space update\n"); if (code < 0) return code; - code = pdf14_push_transparency_group(pdev->ctx, &rect, - isolated, ptgp->Knockout, + code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout, (byte)floor (255 * alpha + 0.5), - (byte)floor (255 * pis->shape.alpha + 0.5), - pis->blend_mode, ptgp->idle, - ptgp->mask_id,group_color_numcomps); + (byte)floor (255 * pgs->shape.alpha + 0.5), + pgs->blend_mode, ptgp->idle, + ptgp->mask_id, pdev->color_info.num_components, + cm_back_drop, group_profile, tos_profile, + pgs, dev); + if (new_icc) + gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group"); return code; } static int pdf14_end_transparency_group(gx_device *dev, - gs_imager_state *pis) + gs_gstate *pgs) { pdf14_device *pdev = (pdf14_device *)dev; int code; pdf14_parent_color_t *parent_color; cmm_profile_t *group_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile, &render_cond); if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n"); - vd_get_dc('c'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - vd_erase(RGB(192, 192, 192)); - code = pdf14_pop_transparency_group(pis, pdev->ctx, pdev->blend_procs, + code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs, pdev->color_info.num_components, group_profile, (gx_device *) pdev); #ifdef DEBUG @@ -3559,23 +4272,21 @@ parent_color = pdev->ctx->stack->parent_color_info_procs; if (!(parent_color->parent_color_mapping_procs == NULL && parent_color->parent_color_comp_index == NULL)) { - pis->get_cmap_procs = parent_color->get_cmap_procs; - gx_set_cmap_procs(pis, dev); - pdev->procs.get_color_mapping_procs = - parent_color->parent_color_mapping_procs; - pdev->procs.get_color_comp_index = - parent_color->parent_color_comp_index; + pgs->get_cmap_procs = parent_color->get_cmap_procs; + gx_set_cmap_procs(pgs, dev); + set_dev_proc(pdev, get_color_mapping_procs, parent_color->parent_color_mapping_procs); + set_dev_proc(pdev, get_color_comp_index, parent_color->parent_color_comp_index); pdev->color_info.polarity = parent_color->polarity; pdev->color_info.num_components = parent_color->num_components; pdev->blend_procs = parent_color->parent_blending_procs; pdev->ctx->additive = parent_color->isadditive; pdev->pdf14_procs = parent_color->unpack_procs; pdev->color_info.depth = parent_color->depth; - pdev->color_info.max_color = parent_color->max_color; - pdev->color_info.max_gray = parent_color->max_gray; - memcpy(&(pdev->color_info.comp_bits),&(parent_color->comp_bits), + pdev->color_info.max_color = parent_color->max_color; + pdev->color_info.max_gray = parent_color->max_gray; + memcpy(&(pdev->color_info.comp_bits),&(parent_color->comp_bits), GX_DEVICE_COLOR_MAX_COMPONENTS); - memcpy(&(pdev->color_info.comp_shift),&(parent_color->comp_shift), + memcpy(&(pdev->color_info.comp_shift),&(parent_color->comp_shift), GX_DEVICE_COLOR_MAX_COMPONENTS); parent_color->get_cmap_procs = NULL; parent_color->parent_color_comp_index = NULL; @@ -3583,37 +4294,33 @@ if (parent_color->icc_profile != NULL) { /* make sure to decrement the device profile. If it was allocated with the push then it will be freed. */ - rc_decrement(group_profile,"pdf14_end_transparency_group"); + gsicc_adjust_profile_rc(dev->icc_struct->device_profile[0], -1, "pdf14_end_transparency_group"); dev->icc_struct->device_profile[0] = parent_color->icc_profile; - rc_decrement(parent_color->icc_profile,"pdf14_end_transparency_group"); parent_color->icc_profile = NULL; } } - vd_release_dc; return code; } static int pdf14_update_device_color_procs(gx_device *dev, gs_transparency_color_t group_color, - int64_t icc_hashcode, gs_imager_state *pis, - cmm_profile_t *iccprofile) + int64_t icc_hashcode, gs_gstate *pgs, + cmm_profile_t *iccprofile, bool is_mask) { pdf14_device *pdevproto = NULL; pdf14_device *pdev = (pdf14_device *)dev; const pdf14_procs_t *new_14procs = NULL; pdf14_parent_color_t *parent_color_info; gx_color_polarity_t new_polarity; - int new_num_comps; + uchar new_num_comps; bool new_additive; - byte new_depth; gx_device_clist_reader *pcrdev; - byte comp_bits[] = {0,0,0,0}; - byte comp_shift[] = {0,0,0,0}; + byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS]; + byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS]; int k; - bool has_tags = dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS; - gsicc_rendering_param_t render_cond; - int code; + bool has_tags = device_encodes_tags(dev); + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; if (pdev->ctx->stack != NULL){ @@ -3624,6 +4331,9 @@ } if_debug0m('v', dev->memory, "[v]pdf14_update_device_color_procs\n"); + memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS); + memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS); + /* Update the device procs at this stage. Many of the procs are based upon the color space of the device. We want to remain in the color space defined by the color space of the soft mask or transparency group as @@ -3632,12 +4342,251 @@ space (or the parent layer space). In the case where we pop an isolated transparency group, we will do the blending in the proper color space and then transform the data when we pop the group. Remember that only isolated - groups can have color spaces that are different than their parent. */ - parent_color_info->get_cmap_procs = NULL; - parent_color_info->parent_color_mapping_procs = NULL; - parent_color_info->parent_color_comp_index = NULL; - switch (group_color) { - case GRAY_SCALE: + groups can have color spaces that are different than their parent. + Separation devices that have to maintain separate spot color planes need + special handling here */ + parent_color_info->get_cmap_procs = NULL; + parent_color_info->parent_color_mapping_procs = NULL; + parent_color_info->parent_color_comp_index = NULL; + + switch (group_color) { + case GRAY_SCALE: + new_polarity = GX_CINFO_POLARITY_ADDITIVE; + new_num_comps = 1; + pdevproto = (pdf14_device *)&gs_pdf14_Gray_device; + new_additive = true; + new_14procs = &gray_pdf14_procs; + comp_bits[0] = 8; + comp_shift[0] = 0; + break; + case DEVICE_RGB: + case CIE_XYZ: + new_polarity = GX_CINFO_POLARITY_ADDITIVE; + new_num_comps = 3; + pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; + new_additive = true; + new_14procs = &rgb_pdf14_procs; + for (k = 0; k < 3; k++) { + comp_bits[k] = 8; + comp_shift[k] = (2 - k) * 8; + } + break; + case DEVICE_CMYK: + new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE; + new_num_comps = 4; + pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; + new_additive = false; + /* This is needed due to the mismatched compressed encode decode + between the device procs and the pdf14 procs */ + if (dev->color_info.num_components > 4){ + new_14procs = &cmykspot_pdf14_procs; + } else { + new_14procs = &cmyk_pdf14_procs; + } + for (k = 0; k < 4; k++) { + comp_bits[k] = 8; + comp_shift[k] = (3 - k) * 8; + } + break; + case ICC: + /* If we are coming from the clist reader, then we need to get + the ICC data now */ + if (iccprofile == NULL && pdev->pclist_device != NULL) { + /* Get the serialized data from the clist. Not the whole + profile. */ + pcrdev = (gx_device_clist_reader *)(pdev->pclist_device); + iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev, + icc_hashcode); + if (iccprofile == NULL) + return gs_throw(gs_error_unknownerror, "ICC data not found in clist"); + /* Keep a pointer to the clist device */ + iccprofile->dev = (gx_device *) pcrdev; + } else { + /* Go ahead and rc increment right now. This way when + we pop, we will make sure to decrement and avoid a + leak for the above profile that we just created */ + if (iccprofile == NULL) + return gs_throw(gs_error_unknownerror, "ICC data unknown"); + gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_update_device_color_procs"); + } + new_num_comps = iccprofile->num_comps; + if (new_num_comps == 4) { + new_additive = false; + new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE; + } else { + new_additive = true; + new_polarity = GX_CINFO_POLARITY_ADDITIVE; + } + switch (new_num_comps) { + case 1: + if (pdev->sep_device && !is_mask) { + pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device; + new_14procs = &grayspot_pdf14_procs; + } else { + pdevproto = (pdf14_device *)&gs_pdf14_Gray_device; + new_14procs = &gray_pdf14_procs; + } + comp_bits[0] = 8; + comp_shift[0] = 0; + break; + case 3: + if (pdev->sep_device) { + pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device; + new_14procs = &rgbspot_pdf14_procs; + } + else { + pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; + new_14procs = &rgb_pdf14_procs; + } + for (k = 0; k < 3; k++) { + comp_bits[k] = 8; + comp_shift[k] = (2 - k) * 8; + } + break; + case 4: + if (pdev->sep_device) { + pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device; + new_14procs = &cmykspot_pdf14_procs; + } else { + pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; + new_14procs = &cmyk_pdf14_procs; + } + for (k = 0; k < 4; k++) { + comp_bits[k] = 8; + comp_shift[k] = (3 - k) * 8; + } + break; + default: + return_error(gs_error_rangecheck); + break; + } + break; + default: + return_error(gs_error_rangecheck); + break; + } + if_debug2m('v', pdev->memory, + "[v]pdf14_update_device_color_procs,num_components_old = %d num_components_new = %d\n", + pdev->color_info.num_components,new_num_comps); + + /* Save the old information */ + parent_color_info->get_cmap_procs = pgs->get_cmap_procs; + parent_color_info->parent_color_mapping_procs = + dev_proc(pdev, get_color_mapping_procs); + parent_color_info->parent_color_comp_index = + dev_proc(pdev, get_color_comp_index); + parent_color_info->parent_blending_procs = pdev->blend_procs; + parent_color_info->polarity = pdev->color_info.polarity; + parent_color_info->num_components = pdev->color_info.num_components; + parent_color_info->isadditive = pdev->ctx->additive; + parent_color_info->unpack_procs = pdev->pdf14_procs; + parent_color_info->depth = pdev->color_info.depth; + parent_color_info->max_color = pdev->color_info.max_color; + parent_color_info->max_gray = pdev->color_info.max_gray; + parent_color_info->encode = dev_proc(pdev, encode_color); + parent_color_info->decode = dev_proc(pdev, decode_color); + memcpy(&(parent_color_info->comp_bits), &(pdev->color_info.comp_bits), + GX_DEVICE_COLOR_MAX_COMPONENTS); + memcpy(&(parent_color_info->comp_shift), &(pdev->color_info.comp_shift), + GX_DEVICE_COLOR_MAX_COMPONENTS); + + /* Don't increment the space since we are going to remove it from the + ICC manager anyway. */ + if (group_color == ICC && iccprofile != NULL) { + dev_proc(dev, get_profile)(dev, &dev_profile); + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, + &(parent_color_info->icc_profile), &render_cond); + } + /* Set new information */ + /* If we are a sep device and this is not a softmask, ensure we maintain the + spot colorants and know how to index into them */ + if (pdev->sep_device && !is_mask) { + int num_spots = parent_color_info->num_components - + parent_color_info->icc_profile->num_comps; + + if (num_spots > 0) { + new_num_comps += num_spots; + for (k = 0; k < new_num_comps; k++) { + comp_bits[k] = 8; + comp_shift[k] = (new_num_comps - k - 1) * 8; + } + } + } + + set_dev_proc(pdev, get_color_mapping_procs, pdevproto->static_procs->get_color_mapping_procs); + set_dev_proc(pdev, get_color_comp_index, pdevproto->static_procs->get_color_comp_index); + pdev->blend_procs = pdevproto->blend_procs; + pdev->color_info.polarity = new_polarity; + pdev->color_info.num_components = new_num_comps; + pdev->ctx->additive = new_additive; + pdev->pdf14_procs = new_14procs; + pdev->color_info.depth = new_num_comps * 8; + memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS); + memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS); + memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps); + memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps); + if (has_tags) { + pdev->color_info.comp_shift[pdev->color_info.num_components] = pdev->color_info.depth; + pdev->color_info.depth += 8; + } + pdev->color_info.max_color = 255; + pdev->color_info.max_gray = 255; + /* If the CS was ICC based, we need to update the device ICC profile + in the ICC manager, since that is the profile that is used for the + PDF14 device */ + if (group_color == ICC && iccprofile != NULL) { + /* iccprofile was incremented above if we had not just created it. + When we do the pop we will decrement and if we just created it, it + will be destroyed */ + dev->icc_struct->device_profile[0] = iccprofile; + } + return 1; /* Lets us detect that we did do an update */ +} + +/* A new version that works with the color_procs stack + for transparency groups */ +static int +pdf14_update_device_color_procs_push_c(gx_device *dev, + gs_transparency_color_t group_color, int64_t icc_hashcode, + gs_gstate *pgs, cmm_profile_t *icc_profile, bool is_mask) +{ + pdf14_device *pdevproto; + pdf14_device *pdev = (pdf14_device *)dev; + gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device; + const pdf14_procs_t *new_14procs; + bool update_color_info; + gx_color_polarity_t new_polarity; + int new_num_comps; + bool new_additive = false; + byte new_depth; + byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS]; + byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS]; + int k; + bool has_tags = device_encodes_tags(dev); + cmm_profile_t *icc_profile_dev = NULL; + gsicc_rendering_param_t render_cond; + cmm_dev_profile_t *dev_profile; + + memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS); + memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS); + + if (group_color == ICC && icc_profile == NULL) + return gs_throw(gs_error_undefinedresult, "Missing ICC data"); + if_debug0m('v', cldev->memory, "[v]pdf14_update_device_color_procs_push_c\n"); + /* Check if we need to alter the device procs at this stage. Many of the procs + are based upon the color space of the device. We want to remain in the + color space defined by the color space of the soft mask or transparency + group as opposed to the device color space. Later, when we pop the softmask + we will collapse it to a single band and then compose with it to the device + color space (or the parent layer space). In the case where we pop an + isolated transparency group, we will do the blending in the proper color + space and then transform the data when we pop the group. Remember that only + isolated groups can have color spaces that are different than their parent. */ + update_color_info = false; + switch (group_color) { + case GRAY_SCALE: + if (pdev->color_info.num_components != 1){ + update_color_info = true; new_polarity = GX_CINFO_POLARITY_ADDITIVE; new_num_comps = 1; pdevproto = (pdf14_device *)&gs_pdf14_Gray_device; @@ -3646,9 +4595,12 @@ new_depth = 8; comp_bits[0] = 8; comp_shift[0] = 0; - break; - case DEVICE_RGB: - case CIE_XYZ: + } + break; + case DEVICE_RGB: + case CIE_XYZ: + if (pdev->color_info.num_components != 3){ + update_color_info = true; new_polarity = GX_CINFO_POLARITY_ADDITIVE; new_num_comps = 3; pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; @@ -3659,8 +4611,11 @@ comp_bits[k] = 8; comp_shift[k] = (2-k)*8; } - break; - case DEVICE_CMYK: + } + break; + case DEVICE_CMYK: + if (pdev->color_info.num_components != 4){ + update_color_info = true; new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE; new_num_comps = 4; pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; @@ -3677,352 +4632,154 @@ comp_bits[k] = 8; comp_shift[k] = (3-k)*8; } - break; - case ICC: - /* If we are coming from the clist reader, then we need to get - the ICC data now */ - if (iccprofile == NULL && pdev->pclist_device != NULL) { - /* Get the serialized data from the clist. Not the whole - profile. */ - pcrdev = (gx_device_clist_reader *)(pdev->pclist_device); - iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev, - icc_hashcode); - if (iccprofile == NULL) - return gs_rethrow(-1,"ICC data not found in clist"); - /* Keep a pointer to the clist device */ - iccprofile->dev = (gx_device *) pcrdev; - } else { - /* Go ahead and rc increment right now. This way when - we pop, we will make sure to decrement and avoid a - leak for the above profile that we just created */ - rc_increment(iccprofile); - } - new_num_comps = iccprofile->num_comps; - new_depth = new_num_comps * 8; - if (new_num_comps == 4) { - new_additive = false; - new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE; - } else { - new_additive = true; - new_polarity = GX_CINFO_POLARITY_ADDITIVE; - } + } + break; + case ICC: + /* Check if the profile is different. */ + dev_proc(dev, get_profile)(dev, &dev_profile); + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, + &icc_profile_dev, &render_cond); + if (icc_profile_dev->hashcode != icc_profile->hashcode) { + update_color_info = true; + new_num_comps = icc_profile->num_comps; + new_depth = icc_profile->num_comps * 8; switch (new_num_comps) { - case 1: + case 1: + if (pdev->sep_device && !is_mask) { + pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device; + new_14procs = &grayspot_pdf14_procs; + } else { pdevproto = (pdf14_device *)&gs_pdf14_Gray_device; new_14procs = &gray_pdf14_procs; - comp_bits[0] = 8; - comp_shift[0] = 0; - break; - case 3: - pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; - new_14procs = &rgb_pdf14_procs; - for (k = 0; k < 3; k++) { - comp_bits[k] = 8; - comp_shift[k] = (2-k)*8; - } - break; - case 4: - pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; - new_14procs = &cmyk_pdf14_procs; - for (k = 0; k < 4; k++) { - comp_bits[k] = 8; - comp_shift[k] = (3-k)*8; - } - break; - } - break; - default: - return_error(gs_error_rangecheck); - break; - } - if_debug2m('v', pdev->memory, - "[v]pdf14_update_device_color_procs,num_components_old = %d num_components_new = %d\n", - pdev->color_info.num_components,new_num_comps); - - /* Save the old information */ - parent_color_info->get_cmap_procs = pis->get_cmap_procs; - parent_color_info->parent_color_mapping_procs = - pdev->procs.get_color_mapping_procs; - parent_color_info->parent_color_comp_index = - pdev->procs.get_color_comp_index; - parent_color_info->parent_blending_procs = pdev->blend_procs; - parent_color_info->polarity = pdev->color_info.polarity; - parent_color_info->num_components = pdev->color_info.num_components; - parent_color_info->isadditive = pdev->ctx->additive; - parent_color_info->unpack_procs = pdev->pdf14_procs; - parent_color_info->depth = pdev->color_info.depth; - memcpy(&(parent_color_info->comp_bits),&(pdev->color_info.comp_bits), - GX_DEVICE_COLOR_MAX_COMPONENTS); - memcpy(&(parent_color_info->comp_shift),&(pdev->color_info.comp_shift), - GX_DEVICE_COLOR_MAX_COMPONENTS); - parent_color_info->max_color = pdev->color_info.max_color; - parent_color_info->max_gray = pdev->color_info.max_gray; - parent_color_info->encode = pdev->procs.encode_color; - parent_color_info->decode = pdev->procs.decode_color; - /* Don't increment the space since we are going to remove it from the - ICC manager anyway. */ - if (group_color == ICC && iccprofile != NULL) { - code = dev_proc(dev, get_profile)(dev, &dev_profile); - gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, - &(parent_color_info->icc_profile), - &render_cond); - } - /* Set new information */ - /* If we are in a soft mask and we are using compressed color - encoding, then go ahead and update the encoder and decoder. */ - if (pdev->procs.encode_color == pdf14_compressed_encode_color && - new_num_comps == 1) { - pdev->procs.decode_color = pdevproto->static_procs->decode_color; - if (has_tags) { - pdev->procs.encode_color = pdf14_encode_color_tag; - } else { - pdev->procs.encode_color = pdevproto->static_procs->encode_color; - } - } - pis->get_cmap_procs = pdf14_get_cmap_procs_group; - gx_set_cmap_procs(pis, dev); - pdev->procs.get_color_mapping_procs = - pdevproto->static_procs->get_color_mapping_procs; - pdev->procs.get_color_comp_index = - pdevproto->static_procs->get_color_comp_index; - pdev->blend_procs = pdevproto->blend_procs; - pdev->color_info.polarity = new_polarity; - pdev->color_info.num_components = new_num_comps; - pdev->ctx->additive = new_additive; - pdev->pdf14_procs = new_14procs; - if (has_tags) { - new_depth += 8; - } - pdev->color_info.depth = new_depth; - memset(&(pdev->color_info.comp_bits),0,GX_DEVICE_COLOR_MAX_COMPONENTS); - memset(&(pdev->color_info.comp_shift),0,GX_DEVICE_COLOR_MAX_COMPONENTS); - memcpy(&(pdev->color_info.comp_bits),comp_bits,4); - memcpy(&(pdev->color_info.comp_shift),comp_shift,4); - pdev->color_info.max_color = 255; - pdev->color_info.max_gray = 255; - /* If the CS was ICC based, we need to update the device ICC profile - in the ICC manager, since that is the profile that is used for the - PDF14 device */ - if (group_color == ICC && iccprofile != NULL) { - /* iccprofile was incremented above if we had not just created - it. when we do the pop we will decrement and if we just - created it, it will be destroyed */ - dev->icc_struct->device_profile[0] = iccprofile; - rc_increment(parent_color_info->icc_profile); - } - return(1); /* Lets us detect that we did do an update */ -} - -/* A new version that works with the color_procs stack - for transparency groups */ -static int -pdf14_update_device_color_procs_push_c(gx_device *dev, - gs_transparency_color_t group_color, int64_t icc_hashcode, - gs_imager_state *pis, cmm_profile_t *icc_profile) -{ - pdf14_device *pdevproto; - pdf14_device *pdev = (pdf14_device *)dev; - gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device; - const pdf14_procs_t *new_14procs; - bool update_color_info; - gx_color_polarity_t new_polarity; - int new_num_comps; - bool new_additive; - byte new_depth; - byte comp_bits[] = {0,0,0,0}; - byte comp_shift[] = {0,0,0,0}; - int k; - bool has_tags = dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS; - cmm_profile_t *icc_profile_dev; - gsicc_rendering_param_t render_cond; - int code; - cmm_dev_profile_t *dev_profile; - - if (group_color == ICC && icc_profile == NULL) { - return gs_rethrow(gs_error_undefinedresult, - "Missing ICC data"); - } - if_debug0m('v', cldev->memory, "[v]pdf14_update_device_color_procs_push_c\n"); - /* Check if we need to alter the device procs at this stage. Many of the procs - are based upon the color space of the device. We want to remain in the - color space defined by the color space of the soft mask or transparency - group as opposed to the device color space. Later, when we pop the softmask - we will collapse it to a single band and then compose with it to the device - color space (or the parent layer space). In the case where we pop an - isolated transparency group, we will do the blending in the proper color - space and then transform the data when we pop the group. Remember that only - isolated groups can have color spaces that are different than their parent. */ - update_color_info = false; - switch (group_color) { - case GRAY_SCALE: - if (pdev->color_info.num_components != 1){ - update_color_info = true; + } new_polarity = GX_CINFO_POLARITY_ADDITIVE; - new_num_comps = 1; - pdevproto = (pdf14_device *)&gs_pdf14_Gray_device; new_additive = true; - new_14procs = &gray_pdf14_procs; - new_depth = 8; comp_bits[0] = 8; comp_shift[0] = 0; - } - break; - case DEVICE_RGB: - case CIE_XYZ: - if (pdev->color_info.num_components != 3){ - update_color_info = true; + break; + case 3: + if (pdev->sep_device) { + pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device; + new_14procs = &rgbspot_pdf14_procs; + } else { + pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; + new_14procs = &rgb_pdf14_procs; + } new_polarity = GX_CINFO_POLARITY_ADDITIVE; - new_num_comps = 3; - pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; new_additive = true; - new_14procs = &rgb_pdf14_procs; - new_depth = 24; for (k = 0; k < 3; k++) { comp_bits[k] = 8; comp_shift[k] = (2-k)*8; } - } - break; - case DEVICE_CMYK: - if (pdev->color_info.num_components != 4){ - update_color_info = true; - new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE; - new_num_comps = 4; - pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; - new_additive = false; - /* This is needed due to the mismatched compressed encode decode - between the device procs and the pdf14 procs */ - if (dev->color_info.num_components > 4){ + break; + case 4: + if (pdev->sep_device) { + pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device; new_14procs = &cmykspot_pdf14_procs; } else { + pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; new_14procs = &cmyk_pdf14_procs; } - new_depth = 32; + new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE; + new_additive = false; for (k = 0; k < 4; k++) { comp_bits[k] = 8; comp_shift[k] = (3-k)*8; } + break; + default: + return gs_throw(gs_error_undefinedresult, + "ICC Number of colorants illegal"); } - break; - case ICC: - /* Check if the profile is different. */ - code = dev_proc(dev, get_profile)(dev, &dev_profile); - gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, - &icc_profile_dev, &render_cond); - if (icc_profile_dev->hashcode != icc_profile->hashcode) { - update_color_info = true; - new_num_comps = icc_profile->num_comps; - new_depth = icc_profile->num_comps*8; - switch (new_num_comps) { - case 1: - new_polarity = GX_CINFO_POLARITY_ADDITIVE; - new_additive = true; - pdevproto = (pdf14_device *)&gs_pdf14_Gray_device; - new_14procs = &gray_pdf14_procs; - comp_bits[0] = 8; - comp_shift[0] = 0; - break; - case 3: - new_polarity = GX_CINFO_POLARITY_ADDITIVE; - new_additive = true; - pdevproto = (pdf14_device *)&gs_pdf14_RGB_device; - new_14procs = &rgb_pdf14_procs; - for (k = 0; k < 3; k++) { - comp_bits[k] = 8; - comp_shift[k] = (2-k)*8; - } - break; - case 4: - new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE; - new_additive = false; - pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device; - new_14procs = &cmyk_pdf14_procs; - for (k = 0; k < 4; k++) { - comp_bits[k] = 8; - comp_shift[k] = (3-k)*8; - } - break; - default: - return gs_rethrow(gs_error_undefinedresult, - "ICC Number of colorants illegal"); - } - } - break; - default: - return_error(gs_error_rangecheck); - break; - } - if (update_color_info){ - if (has_tags) { - new_depth += 8; - } - if_debug2m('v', pdev->memory, - "[v]pdf14_update_device_color_procs_push_c,num_components_old = %d num_components_new = %d\n", - pdev->color_info.num_components,new_num_comps); - /* Set new information in the device */ - pis->get_cmap_procs = pdf14_get_cmap_procs_group; - gx_set_cmap_procs(pis, dev); - pdev->procs.get_color_mapping_procs = - pdevproto->static_procs->get_color_mapping_procs; - pdev->procs.get_color_comp_index = - pdevproto->static_procs->get_color_comp_index; - pdev->blend_procs = pdevproto->blend_procs; - pdev->color_info.polarity = new_polarity; - pdev->color_info.num_components = new_num_comps; - pdev->color_info.max_color = 255; - pdev->color_info.max_gray = 255; - pdev->pdf14_procs = new_14procs; - pdev->color_info.depth = new_depth; - memset(&(pdev->color_info.comp_bits),0,GX_DEVICE_COLOR_MAX_COMPONENTS); - memset(&(pdev->color_info.comp_shift),0,GX_DEVICE_COLOR_MAX_COMPONENTS); - memcpy(&(pdev->color_info.comp_bits),comp_bits,4); - memcpy(&(pdev->color_info.comp_shift),comp_shift,4); - /* If we have a compressed color codec, and we are doing a soft mask - push operation then go ahead and update the color encode and - decode for the pdf14 device to not used compressed color - encoding while in the soft mask. We will just check for gray - and compressed. Note that we probably don't have_tags if we - are dealing with compressed color. But is is possible so - we add it in to catch for future use. */ - if (pdev->procs.encode_color == pdf14_compressed_encode_color && - new_num_comps == 1) { - pdev->procs.decode_color = - pdevproto->static_procs->decode_color; - if (has_tags) { - pdev->procs.encode_color = pdf14_encode_color_tag; - } else { - pdev->procs.encode_color = - pdevproto->static_procs->encode_color; - } - } - cldev->clist_color_info.depth = pdev->color_info.depth; - cldev->clist_color_info.polarity = pdev->color_info.polarity; - cldev->clist_color_info.num_components = pdev->color_info.num_components; - cldev->clist_color_info.max_color = pdev->color_info.max_color; - cldev->clist_color_info.max_gray = pdev->color_info.max_gray; - /* For the ICC profiles, we want to update the ICC profile for the - device in the ICC manager. We already stored in in pdf14_parent_color_t. - That will be stored in the clist and restored during the reading phase. */ - if (group_color == ICC) { - dev->icc_struct->device_profile[0] = icc_profile; } - if (pdev->ctx) { - pdev->ctx->additive = new_additive; + break; + case UNKNOWN: + return 0; + break; + default: + return_error(gs_error_rangecheck); + break; + } + if (update_color_info){ + if (pdev->sep_device && !is_mask) { + int num_spots; + + if (icc_profile_dev == NULL) + return_error(gs_error_undefined); + + num_spots = pdev->color_info.num_components - icc_profile_dev->num_comps; + + if (num_spots > 0) { + new_num_comps += num_spots; + for (k = 0; k < new_num_comps; k++) { + comp_bits[k] = 8; + comp_shift[k] = (new_num_comps - k - 1) * 8; + } + new_depth = 8 * new_num_comps; } - return(1); /* Lets us detect that we did do an update */ - } - if_debug0m('v', pdev->memory, "[v]procs not updated\n"); - return 0; + } + if (has_tags) { + new_depth += 8; + } + if_debug2m('v', pdev->memory, + "[v]pdf14_update_device_color_procs_push_c,num_components_old = %d num_components_new = %d\n", + pdev->color_info.num_components,new_num_comps); + /* Set new information in the device */ + set_dev_proc(pdev, get_color_mapping_procs, pdevproto->static_procs->get_color_mapping_procs); + set_dev_proc(pdev, get_color_comp_index, pdevproto->static_procs->get_color_comp_index); + pdev->blend_procs = pdevproto->blend_procs; + pdev->color_info.polarity = new_polarity; + pdev->color_info.num_components = new_num_comps; + pdev->color_info.max_color = 255; + pdev->color_info.max_gray = 255; + pdev->pdf14_procs = new_14procs; + pdev->color_info.depth = new_depth; + memset(&(pdev->color_info.comp_bits),0,GX_DEVICE_COLOR_MAX_COMPONENTS); + memset(&(pdev->color_info.comp_shift),0,GX_DEVICE_COLOR_MAX_COMPONENTS); + memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps); + memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps); + pdev->color_info.comp_shift[new_num_comps] = new_depth - 8; /* in case we has_tags is set */ + + /* If we have a compressed color codec, and we are doing a soft mask + push operation then go ahead and update the color encode and + decode for the pdf14 device to not used compressed color + encoding while in the soft mask. We will just check for gray + and compressed. Note that we probably don't have_tags if we + are dealing with compressed color. But is is possible so + we add it in to catch for future use. */ + cldev->clist_color_info.depth = pdev->color_info.depth; + cldev->clist_color_info.polarity = pdev->color_info.polarity; + cldev->clist_color_info.num_components = pdev->color_info.num_components; + cldev->clist_color_info.max_color = pdev->color_info.max_color; + cldev->clist_color_info.max_gray = pdev->color_info.max_gray; + /* For the ICC profiles, we want to update the ICC profile for the + device in the ICC manager. We already stored in in pdf14_parent_color_t. + That will be stored in the clist and restored during the reading phase. */ + if (group_color == ICC) { + gsicc_adjust_profile_rc(icc_profile, 1, "pdf14_update_device_color_procs_push_c"); + gsicc_adjust_profile_rc(dev->icc_struct->device_profile[0], -1, "pdf14_update_device_color_procs_push_c"); + dev->icc_struct->device_profile[0] = icc_profile; + } + if (pdev->ctx) { + pdev->ctx->additive = new_additive; + } + return(1); /* Lets us detect that we did do an update */ + } + if_debug0m('v', pdev->memory, "[v]procs not updated\n"); + return 0; } static int -pdf14_update_device_color_procs_pop_c(gx_device *dev,gs_imager_state *pis) +pdf14_update_device_color_procs_pop_c(gx_device *dev,gs_gstate *pgs) { pdf14_device *pdev = (pdf14_device *)dev; pdf14_parent_color_t *parent_color = pdev->trans_group_parent_cmap_procs; gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device; + if (parent_color == NULL) + return_error(gs_error_unknownerror); /* Unmatched group pop */ + if_debug0m('v', pdev->memory, "[v]pdf14_update_device_color_procs_pop_c\n"); /* The color procs are always pushed. Simply restore them. */ if (!(parent_color->parent_color_mapping_procs == NULL && @@ -4030,10 +4787,10 @@ if_debug2m('v', pdev->memory, "[v]pdf14_update_device_color_procs_pop_c,num_components_old = %d num_components_new = %d\n", pdev->color_info.num_components,parent_color->num_components); - pis->get_cmap_procs = parent_color->get_cmap_procs; - gx_set_cmap_procs(pis, dev); - pdev->procs.get_color_mapping_procs = parent_color->parent_color_mapping_procs; - pdev->procs.get_color_comp_index = parent_color->parent_color_comp_index; + pgs->get_cmap_procs = parent_color->get_cmap_procs; + gx_set_cmap_procs(pgs, dev); + set_dev_proc(pdev, get_color_mapping_procs, parent_color->parent_color_mapping_procs); + set_dev_proc(pdev, get_color_comp_index, parent_color->parent_color_comp_index); pdev->color_info.polarity = parent_color->polarity; pdev->color_info.depth = parent_color->depth; pdev->color_info.num_components = parent_color->num_components; @@ -4041,13 +4798,13 @@ pdev->pdf14_procs = parent_color->unpack_procs; pdev->color_info.max_color = parent_color->max_color; pdev->color_info.max_gray = parent_color->max_gray; - pdev->procs.encode_color = parent_color->encode; - pdev->procs.decode_color = parent_color->decode; + set_dev_proc(pdev, encode_color, parent_color->encode); + set_dev_proc(pdev, decode_color, parent_color->decode); memcpy(&(pdev->color_info.comp_bits),&(parent_color->comp_bits), GX_DEVICE_COLOR_MAX_COMPONENTS); memcpy(&(pdev->color_info.comp_shift),&(parent_color->comp_shift), GX_DEVICE_COLOR_MAX_COMPONENTS); - /* clist writer fill rect has no access to imager state */ + /* clist writer fill rect has no access to gs_gstate */ /* and it forwards the target device. this information */ /* is passed along to use in this case */ cldev->clist_color_info.depth = pdev->color_info.depth; @@ -4062,50 +4819,49 @@ if (pdev->ctx){ pdev->ctx->additive = parent_color->isadditive; } - /* The device profile must be restored. No reference - count is done here - A match with pdf14_update_device_color_procs_push_c. There functions - are closely integrated with pdf14_pop_parent_color and pdf14_push_parent color. - All four are used only on the clist writer side of the transparency code */ - dev->icc_struct->device_profile[0] = parent_color->icc_profile; - if_debug0m('v', dev->memory, "[v]procs updated\n"); + /* The device profile must be restored. */ + gsicc_adjust_profile_rc(dev->icc_struct->device_profile[0], -1, "pdf14_update_device_color_procs_pop_c"); + dev->icc_struct->device_profile[0] = parent_color->icc_profile; + parent_color->icc_profile = NULL; + if_debug0m('v', dev->memory, "[v]procs updated\n"); } else { if_debug0m('v', dev->memory, "[v]pdf14_update_device_color_procs_pop_c ERROR \n"); } + pdf14_pop_parent_color(dev, pgs); return 0; } - /* When a transparency group is pushed, the parent colorprocs are initialized. - Since the color mapping procs are all based upon the device, we must have - a nested list based upon the transparency group color space. This nesting - must be outside the nested ctx structures to allow the nesting for the clist - writer */ +/* When a transparency group is pushed, the parent colorprocs are initialized. + Since the color mapping procs are all based upon the device, we must have + a nested list based upon the transparency group color space. This nesting + must be outside the nested ctx structures to allow the nesting for the clist + writer */ static void -pdf14_push_parent_color(gx_device *dev, const gs_imager_state *pis) +pdf14_push_parent_color(gx_device *dev, const gs_gstate *pgs) { pdf14_device *pdev = (pdf14_device *)dev; pdf14_parent_color_t *new_parent_color; cmm_profile_t *icc_profile; - gsicc_rendering_param_t render_cond; - int code; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; - code = dev_proc(dev, get_profile)(dev, &dev_profile); - gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, + dev_proc(dev, get_profile)(dev, &dev_profile); + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, &render_cond); if_debug0m('v', dev->memory, "[v]pdf14_push_parent_color\n"); /* Allocate a new one */ - new_parent_color = gs_alloc_struct(dev->memory, pdf14_parent_color_t, + new_parent_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_parent_color_t, &st_pdf14_clr,"pdf14_clr_new"); /* Link to old one */ new_parent_color->previous = pdev->trans_group_parent_cmap_procs; /* Reassign new one to dev */ pdev->trans_group_parent_cmap_procs = new_parent_color; /* Initialize with values */ - new_parent_color->get_cmap_procs = pis->get_cmap_procs; + new_parent_color->get_cmap_procs = pgs->get_cmap_procs; new_parent_color->parent_color_mapping_procs = - pdev->procs.get_color_mapping_procs; + dev_proc(pdev, get_color_mapping_procs); new_parent_color->parent_color_comp_index = - pdev->procs.get_color_comp_index; + dev_proc(pdev, get_color_comp_index); new_parent_color->parent_blending_procs = pdev->blend_procs; new_parent_color->polarity = pdev->color_info.polarity; new_parent_color->num_components = pdev->color_info.num_components; @@ -4113,15 +4869,15 @@ new_parent_color->depth = pdev->color_info.depth; new_parent_color->max_color = pdev->color_info.max_color; new_parent_color->max_gray = pdev->color_info.max_gray; - new_parent_color->decode = pdev->procs.decode_color; - new_parent_color->encode = pdev->procs.encode_color; + new_parent_color->decode = dev_proc(pdev, decode_color); + new_parent_color->encode = dev_proc(pdev, encode_color); memcpy(&(new_parent_color->comp_bits),&(pdev->color_info.comp_bits), GX_DEVICE_COLOR_MAX_COMPONENTS); memcpy(&(new_parent_color->comp_shift),&(pdev->color_info.comp_shift), GX_DEVICE_COLOR_MAX_COMPONENTS); /* The ICC manager has the ICC profile for the device */ new_parent_color->icc_profile = icc_profile; - rc_increment(icc_profile); + gsicc_adjust_profile_rc(icc_profile, 1, "pdf14_push_parent_color"); /* isadditive is only used in ctx */ if (pdev->ctx) { new_parent_color->isadditive = pdev->ctx->additive; @@ -4133,7 +4889,7 @@ must be outside the nested ctx structures to allow the nesting for the clist writer */ static void -pdf14_pop_parent_color(gx_device *dev, const gs_imager_state *pis) +pdf14_pop_parent_color(gx_device *dev, const gs_gstate *pgs) { pdf14_device *pdev = (pdf14_device *)dev; pdf14_parent_color_t *old_parent_color_info = pdev->trans_group_parent_cmap_procs; @@ -4141,31 +4897,44 @@ if_debug0m('v', dev->memory, "[v]pdf14_pop_parent_color\n"); /* We need to compliment pdf14_push_parent color */ if (old_parent_color_info->icc_profile != NULL) - rc_decrement(old_parent_color_info->icc_profile, "pdf14_pop_parent_color"); + gsicc_adjust_profile_rc(old_parent_color_info->icc_profile, -1, "pdf14_pop_parent_color"); /* Update the link */ pdev->trans_group_parent_cmap_procs = old_parent_color_info->previous; /* Free the old one */ - gs_free_object(dev->memory, old_parent_color_info, "pdf14_clr_free"); + gs_free_object(dev->memory->stable_memory, old_parent_color_info, "pdf14_clr_free"); } static int pdf14_begin_transparency_mask(gx_device *dev, const gx_transparency_mask_params_t *ptmp, const gs_rect *pbbox, - gs_imager_state *pis, gs_memory_t *mem) + gs_gstate *pgs, gs_memory_t *mem) { pdf14_device *pdev = (pdf14_device *)dev; byte bg_alpha = 0; /* By default the background alpha (area outside mask) is zero */ - byte *transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, 256, - "pdf14_begin_transparency_mask"); + byte *transfer_fn; gs_int_rect rect; int code; int group_color_numcomps; gs_transparency_color_t group_color; + if (ptmp->subtype == TRANSPARENCY_MASK_None) { + pdf14_ctx *ctx = pdev->ctx; + + /* free up any maskbuf on the current tos */ + if (ctx->mask_stack) { + if (ctx->mask_stack->rc_mask->mask_buf != NULL ) { + pdf14_buf_free(ctx->mask_stack->rc_mask->mask_buf); + ctx->mask_stack->rc_mask->mask_buf = NULL; + } + } + return 0; + } + transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, 256, + "pdf14_begin_transparency_mask"); if (transfer_fn == NULL) return_error(gs_error_VMerror); - code = compute_group_device_int_rect(pdev, &rect, pbbox, pis); + code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs); if (code < 0) return code; /* If we have background components the background alpha may be nonzero */ @@ -4207,7 +4976,7 @@ /* Always update the color mapping procs. Otherwise we end up fowarding to the target device. */ code = pdf14_update_device_color_procs(dev, group_color, ptmp->icc_hashcode, - pis, ptmp->iccprofile); + pgs, ptmp->iccprofile, true); if (code < 0) return code; /* Note that the soft mask always follows the group color requirements even @@ -4218,18 +4987,20 @@ group_color_numcomps, ptmp->Background_components, ptmp->Background, + ptmp->Matte_components, + ptmp->Matte, ptmp->GrayBackground); } static int -pdf14_end_transparency_mask(gx_device *dev, gs_imager_state *pis) +pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs) { pdf14_device *pdev = (pdf14_device *)dev; pdf14_parent_color_t *parent_color; int ok; if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n"); - ok = pdf14_pop_transparency_mask(pdev->ctx, pis, dev); + ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev); #ifdef DEBUG pdf14_debug_mask_stack_state(pdev->ctx); #endif @@ -4240,10 +5011,10 @@ parent_color = pdev->ctx->stack->parent_color_info_procs; if (!(parent_color->parent_color_mapping_procs == NULL && parent_color->parent_color_comp_index == NULL)) { - pis->get_cmap_procs = parent_color->get_cmap_procs; - gx_set_cmap_procs(pis, dev); - pdev->procs.get_color_mapping_procs = parent_color->parent_color_mapping_procs; - pdev->procs.get_color_comp_index = parent_color->parent_color_comp_index; + pgs->get_cmap_procs = parent_color->get_cmap_procs; + gx_set_cmap_procs(pgs, dev); + set_dev_proc(pdev, get_color_mapping_procs, parent_color->parent_color_mapping_procs); + set_dev_proc(pdev, get_color_comp_index, parent_color->parent_color_comp_index); pdev->color_info.polarity = parent_color->polarity; pdev->color_info.num_components = parent_color->num_components; pdev->color_info.depth = parent_color->depth; @@ -4255,17 +5026,16 @@ parent_color->get_cmap_procs = NULL; parent_color->parent_color_comp_index = NULL; parent_color->parent_color_mapping_procs = NULL; - pdev->procs.encode_color = parent_color->encode; - pdev->procs.decode_color = parent_color->decode; + set_dev_proc(pdev, encode_color, parent_color->encode); + set_dev_proc(pdev, decode_color, parent_color->decode); memcpy(&(pdev->color_info.comp_bits),&(parent_color->comp_bits), GX_DEVICE_COLOR_MAX_COMPONENTS); memcpy(&(pdev->color_info.comp_shift),&(parent_color->comp_shift), GX_DEVICE_COLOR_MAX_COMPONENTS); /* Take care of the ICC profile */ if (parent_color->icc_profile != NULL) { - rc_decrement(dev->icc_struct->device_profile[0],"pdf14_end_transparency_mask"); + gsicc_adjust_profile_rc(dev->icc_struct->device_profile[0], -1, "pdf14_end_transparency_mask"); dev->icc_struct->device_profile[0] = parent_color->icc_profile; - rc_decrement(parent_color->icc_profile,"pdf14_end_transparency_mask"); parent_color->icc_profile = NULL; } } @@ -4274,228 +5044,17 @@ } static int -pdf14_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, - gx_color_index color, const gx_device_color *pdc, - bool devn) -{ - pdf14_device *pdev = (pdf14_device *)dev; - pdf14_buf *buf = pdev->ctx->stack; - int i, j, k; - byte *dst_ptr; - byte src[PDF14_MAX_PLANES]; - byte dst[PDF14_MAX_PLANES]; - gs_blend_mode_t blend_mode = pdev->blend_mode; - bool additive = pdev->ctx->additive; - int rowstride = buf->rowstride; - int planestride = buf->planestride; - gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG; /* Quite compiler */ - bool has_alpha_g = buf->has_alpha_g; - bool has_shape = buf->has_shape; - bool has_tags = buf->has_tags; - int num_chan = buf->n_chan; - int num_comp = num_chan - 1; - int shape_off = num_chan * planestride; - int alpha_g_off = shape_off + (has_shape ? planestride : 0); - int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0); - bool overprint = pdev->overprint; - bool blendspot = pdev->blendspot; - gx_color_index drawn_comps = pdev->drawn_comps; - gx_color_index comps; - byte shape = 0; /* Quiet compiler. */ - byte src_alpha; - const gx_color_index mask = ((gx_color_index)1 << 8) - 1; - const int shift = 8; - - if (buf->data == NULL) - return 0; - /* NB: gx_color_index is 4 or 8 bytes */ -#if 0 - if (sizeof(color) <= sizeof(ulong)) - if_debug8m('v', dev->memory, - "[v]pdf14_mark_fill_rectangle, (%d, %d), %d x %d color = %lx bm %d, nc %d, overprint %d\n", - x, y, w, h, (ulong)color, blend_mode, num_chan, overprint); - else - if_debug9m('v', dev->memory, - "[v]pdf14_mark_fill_rectangle, (%d, %d), %d x %d color = %08lx%08lx bm %d, nc %d, overprint %d\n", - x, y, w, h, - (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color, - blend_mode, num_chan, overprint); -#endif - /* - * Unpack the gx_color_index values. Complement the components for subtractive - * color spaces. - */ - if (has_tags) { - curr_tag = (color >> (num_comp*8)) & 0xff; - } - if (devn) { - if (additive) { - for (j = 0; j < num_comp; j++) { - src[j] = ((pdc->colors.devn.values[j]) >> shift & mask); - } - } else { - for (j = 0; j < num_comp; j++) { - src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask); - } - } - } else - pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src); - src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5); - if (has_shape) - shape = (byte)floor (255 * pdev->shape + 0.5); - /* Fit the mark into the bounds of the buffer */ - if (x < buf->rect.p.x) { - w += x - buf->rect.p.x; - x = buf->rect.p.x; - } - if (y < buf->rect.p.y) { - h += y - buf->rect.p.y; - y = buf->rect.p.y; - } - if (x + w > buf->rect.q.x) w = buf->rect.q.x - x; - if (y + h > buf->rect.q.y) h = buf->rect.q.y - y; - /* Update the dirty rectangle with the mark */ - if (x < buf->dirty.p.x) buf->dirty.p.x = x; - if (y < buf->dirty.p.y) buf->dirty.p.y = y; - if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w; - if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h; - dst_ptr = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride; - src_alpha = 255-src_alpha; - shape = 255-shape; - if (!has_alpha_g) - alpha_g_off = 0; - if (!has_shape) - shape_off = 0; - if (!has_tags) - tag_off = 0; - rowstride -= w; - /* The num_comp == 1 && additive case is very common (mono output - * devices), so we optimise that specifically here. */ - if (num_comp == 1 && additive) { - for (j = h; j > 0; --j) { - for (i = w; i > 0; --i) { - if (src[1] == 0) { - /* background empty, nothing to change */ - } else if (dst_ptr[planestride] == 0) { - dst_ptr[0] = src[0]; - dst_ptr[planestride] = src[1]; - } else { - art_pdf_composite_pixel_alpha_8_fast_mono(dst_ptr, src, - blend_mode, pdev->blend_procs, planestride); - } - if (alpha_g_off) { - int tmp = (255 - dst_ptr[alpha_g_off]) * src_alpha + 0x80; - dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8); - } - if (shape_off) { - int tmp = (255 - dst_ptr[shape_off]) * shape + 0x80; - dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); - } - if (tag_off) { - /* If alpha is 100% then set to pure path, else or */ - if (dst_ptr[planestride] == 255) { - dst_ptr[tag_off] = curr_tag; - } else { - dst_ptr[tag_off] = ( dst_ptr[tag_off] |curr_tag ) & ~GS_UNTOUCHED_TAG; - } - } - ++dst_ptr; - } - dst_ptr += rowstride; - } - } else { - for (j = h; j > 0; --j) { - for (i = w; i > 0; --i) { - if (additive) { - if (src[num_comp] == 0) { - /* background empty, nothing to change */ - } else if (dst_ptr[num_comp * planestride] == 0) { - for (k = 0; k < num_chan; ++k) - dst_ptr[k * planestride] = src[k]; - } else { - art_pdf_composite_pixel_alpha_8_fast(dst_ptr, src, num_comp, - blend_mode, pdev->blend_procs, planestride); - } - } else { - /* Complement the components for subtractive color spaces */ - for (k = 0; k < num_comp; ++k) - dst[k] = 255 - dst_ptr[k * planestride]; - dst[num_comp] = dst_ptr[num_comp * planestride]; - art_pdf_composite_pixel_alpha_8(dst, src, num_comp, - blend_mode, pdev->blend_procs); - /* Complement the results for subtractive color spaces */ - if (overprint) { - if (blendspot) { - /* Overprint simulation of spot colorants */ - for (k = 0; k < num_comp; ++k) { - int temp = - (255 - dst_ptr[k * planestride]) * dst[k]; - temp = temp >> 8; - dst_ptr[k * planestride] = (255 - temp); - } - } else { - for (k = 0, comps = drawn_comps; comps != 0; ++k, comps >>= 1) { - if ((comps & 0x1) != 0) { - dst_ptr[k * planestride] = 255 - dst[k]; - } - } - } - /* The alpha channel */ - dst_ptr[num_comp * planestride] = dst[num_comp]; - } else { - for (k = 0; k < num_comp; ++k) - dst_ptr[k * planestride] = 255 - dst[k]; - dst_ptr[num_comp * planestride] = dst[num_comp]; - } - } - if (alpha_g_off) { - int tmp = (255 - dst_ptr[alpha_g_off]) * src_alpha + 0x80; - dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8); - } - if (shape_off) { - int tmp = (255 - dst_ptr[shape_off]) * shape + 0x80; - dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); - } - if (tag_off) { - /* If alpha is 100% then set to pure path, else or */ - if (dst[num_comp] == 255) { - dst_ptr[tag_off] = curr_tag; - } else { - dst_ptr[tag_off] = ( dst_ptr[tag_off] |curr_tag ) & ~GS_UNTOUCHED_TAG; - } - } - ++dst_ptr; - } - dst_ptr += rowstride; - } - } -#if 0 -/* #if RAW_DUMP */ - /* Dump the current buffer to see what we have. */ - - if(global_index/10.0 == (int) (global_index/10.0) ) - dump_raw_buffer(pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y, - pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x, - pdev->ctx->stack->n_planes, - pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, - "Draw_Rect",pdev->ctx->stack->data); - - global_index++; -#endif - return 0; -} - -static int -pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h, - gx_color_index color, +pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h, + gx_color_index color, const gx_device_color *pdc, bool devn) { pdf14_device *pdev = (pdf14_device *)dev; pdf14_buf *buf = pdev->ctx->stack; + gs_blend_mode_t blend_mode = pdev->blend_mode; int i, j, k; - byte *line, *dst_ptr; + byte *bline, *bg_ptr, *line, *dst_ptr; byte src[PDF14_MAX_PLANES]; - byte dst[PDF14_MAX_PLANES]; + byte dst[PDF14_MAX_PLANES] = { 0 }; int rowstride = buf->rowstride; int planestride = buf->planestride; int num_chan = buf->n_chan; @@ -4503,13 +5062,19 @@ int shape_off = num_chan * planestride; bool has_shape = buf->has_shape; bool has_alpha_g = buf->has_alpha_g; + int alpha_g_off = shape_off + (has_shape ? planestride : 0); int tag_off = shape_off + (has_alpha_g ? planestride : 0) + - (has_shape ? planestride : 0); + (has_shape ? planestride : 0); bool has_tags = buf->has_tags; bool additive = pdev->ctx->additive; - gs_graphics_type_tag_t curr_tag = dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS; + gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG; /* Quiet compiler */ gx_color_index mask = ((gx_color_index)1 << 8) - 1; int shift = 8; + byte shape = 0; /* Quiet compiler. */ + byte src_alpha; + bool overprint = pdev->overprint; + gx_color_index drawn_comps = pdev->drawn_comps; + gx_color_index comps; if (buf->data == NULL) return 0; @@ -4529,9 +5094,6 @@ * Unpack the gx_color_index values. Complement the components for subtractive * color spaces. */ - if (has_tags) { - curr_tag = (color >> (num_comp*8)) & 0xff; - } if (devn) { if (additive) { for (j = 0; j < num_comp; j++) { @@ -4542,9 +5104,25 @@ src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask); } } - } else + } else pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src); - src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5); + + src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5); + if (has_shape) { + shape = (byte)floor (255 * pdev->shape + 0.5); + } else { + shape_off = 0; + } + if (has_tags) { + curr_tag = (color >> (num_comp*8)) & 0xff; + } else { + tag_off = 0; + } + if (!has_alpha_g) + alpha_g_off = 0; + src_alpha = 255 - src_alpha; + shape = 255 - shape; + /* Fit the mark into the bounds of the buffer */ if (x < buf->rect.p.x) { w += x - buf->rect.p.x; @@ -4562,44 +5140,79 @@ if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w; if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h; + /* composite with backdrop only */ + bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride; line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride; for (j = 0; j < h; ++j) { + bg_ptr = bline; dst_ptr = line; for (i = 0; i < w; ++i) { /* Complement the components for subtractive color spaces */ if (additive) { for (k = 0; k < num_chan; ++k) - dst[k] = dst_ptr[k * planestride]; - } - else { + dst[k] = bg_ptr[k * planestride]; + } else { for (k = 0; k < num_comp; ++k) - dst[k] = 255 - dst_ptr[k * planestride]; - dst[num_comp] = dst_ptr[num_comp * planestride]; + dst[k] = 255 - bg_ptr[k * planestride]; } - if (has_shape) { - art_pdf_composite_knockout_simple_8(dst, - has_shape ? dst_ptr + shape_off : NULL, - has_tags ? dst_ptr + tag_off : NULL, - src, curr_tag, num_comp, 255); - } else { + dst[num_comp] = bg_ptr[num_comp * planestride]; /* alpha doesn't invert */ + if (buf->isolated) { art_pdf_knockoutisolated_group_8(dst, src, num_comp); + } else { + art_pdf_composite_knockout_8(dst, src, num_comp, + blend_mode, pdev->blend_procs, pdev); } - /* ToDo: Review use of shape and opacity above. */ /* Complement the results for subtractive color spaces */ if (additive) { for (k = 0; k < num_chan; ++k) dst_ptr[k * planestride] = dst[k]; - } - else { - for (k = 0; k < num_comp; ++k) - dst_ptr[k * planestride] = 255 - dst[k]; + } else { + if (overprint) { + for (k = 0, comps = drawn_comps; comps != 0; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = 255 - dst[k]; + } + } + } else { + for (k = 0; k < num_comp; ++k) + dst_ptr[k * planestride] = 255 - dst[k]; + } dst_ptr[num_comp * planestride] = dst[num_comp]; } + if (tag_off) { + /* If src alpha is 100% then set to curr_tag, else or */ + /* other than Normal BM, we always OR */ + if (src[num_comp] == 255 && blend_mode == BLEND_MODE_Normal) { + dst_ptr[tag_off] = curr_tag; + } else { + dst_ptr[tag_off] |= curr_tag; + } + } + if (alpha_g_off) { + int tmp = (255 - dst_ptr[alpha_g_off]) * src_alpha + 0x80; + dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + if (shape_off) { + int tmp = (255 - dst_ptr[shape_off]) * shape + 0x80; + dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } ++dst_ptr; + ++bg_ptr; } + bline += rowstride; line += rowstride; } +#if 0 +/* #if RAW_DUMP */ + /* Dump the current buffer to see what we have. */ + dump_raw_buffer(pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y, + pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x, + pdev->ctx->stack->n_planes, + pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, + "Draw_Rect_KO",pdev->ctx->stack->data); + global_index++; +#endif return 0; } @@ -4611,9 +5224,6 @@ static cmap_proc_gray(pdf14_cmap_gray_direct); static cmap_proc_rgb(pdf14_cmap_rgb_direct); static cmap_proc_cmyk(pdf14_cmap_cmyk_direct); -static cmap_proc_gray(pdf14_cmap_gray_direct_group); -static cmap_proc_rgb(pdf14_cmap_rgb_direct_group); -static cmap_proc_cmyk(pdf14_cmap_cmyk_direct_group); static cmap_proc_rgb_alpha(pdf14_cmap_rgb_alpha_direct); static cmap_proc_separation(pdf14_cmap_separation_direct); static cmap_proc_devicen(pdf14_cmap_devicen_direct); @@ -4629,15 +5239,17 @@ pdf14_cmap_is_halftoned }; +#if 0 /* NOT USED */ static const gx_color_map_procs pdf14_cmap_many_group = { - pdf14_cmap_gray_direct_group, - pdf14_cmap_rgb_direct_group, - pdf14_cmap_cmyk_direct_group, + pdf14_cmap_gray_direct, + pdf14_cmap_rgb_direct, + pdf14_cmap_cmyk_direct, pdf14_cmap_rgb_alpha_direct, pdf14_cmap_separation_direct, pdf14_cmap_devicen_direct, pdf14_cmap_is_halftoned }; +#endif /* NOT USED */ /** * Note: copied from gxcmap.c because it's inlined. @@ -4655,43 +5267,16 @@ } /* Map color components into output list */ for (i = pcolor_component_map->num_components - 1; i >= 0; i--) { - pos = pcolor_component_map->color_map[i]; - if (pos >= 0) - plist[pos] = pcc[i]; - } -} - -static void -pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_imager_state * pis, - gx_device * dev, gs_color_select_t select) -{ - int i,ncomps; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index color; - gx_device *trans_device; - - /* If trans device is set, we need to use its procs. */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; - } else { - trans_device = dev; - } - ncomps = trans_device->color_info.num_components; - /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_gray(trans_device, gray, cm_comps); - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); - /* encode as a color index */ - color = dev_proc(trans_device, encode_color)(trans_device, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); + pos = pcolor_component_map->color_map[i]; + if (pos >= 0) + plist[pos] = pcc[i]; + } } + static void -pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) +pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select) { int i,ncomps; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; @@ -4700,53 +5285,35 @@ gx_device *trans_device; /* If trans device is set, we need to use its procs. */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; + if (pgs->trans_device != NULL) { + trans_device = pgs->trans_device; } else { trans_device = dev; } ncomps = trans_device->color_info.num_components; /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pis, r, g, b, cm_comps); - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); - /* encode as a color index */ - color = dev_proc(trans_device, encode_color)(trans_device, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); -} - -static void -pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select, - const gs_color_space *pcs) -{ - int i,ncomps; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index color; - gx_device *trans_device; + dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_gray(trans_device, gray, cm_comps); - /* If trans device is set, we need to use its procs. */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; + /* If we are in a Gray blending color space and have spots then we have + * possibly an issue here with the transfer function */ + if (pgs->trans_device != NULL) { + cv[0] = frac2cv(gx_map_color_frac(pgs, cm_comps[0], effective_transfer[0])); + for (i = 1; i < ncomps; i++) + cv[i] = gx_color_value_from_byte(cm_comps[i]); } else { - trans_device = dev; + /* Not a transparency device. Just use the transfer functions directly */ + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); } - ncomps = trans_device->color_info.num_components; - /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_cmyk(trans_device, c, m, y, k, cm_comps); - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); + /* if output device supports devn, we need to make sure we send it the - proper color type */ + proper color type. We now support Gray + spots as devn colors */ if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) { for (i = 0; i < ncomps; i++) pdc->colors.devn.values[i] = cv[i]; pdc->type = gx_dc_type_devn; } else { - /* encode as a color index */ + /* encode as a color index */ color = dev_proc(trans_device, encode_color)(trans_device, cv); /* check if the encoding was successful; we presume failure is rare */ if (color != gx_no_color_index) @@ -4754,97 +5321,46 @@ } } -/* color mapping for when we have an smask or a isolated transparency group with - another color space */ static void -pdf14_cmap_gray_direct_group(frac gray, gx_device_color * pdc, const gs_imager_state * pis, - gx_device * dev, gs_color_select_t select) +pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + int i,ncomps; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; gx_device *trans_device; - /* We may be coming from the clist writer - which often forwards us the target device. - If this occurs we actually need to get to - the color space defined by the transparency group - and we use the operators defined by the transparency device - to do the job. - */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; + /* If trans device is set, we need to use its procs. */ + if (pgs->trans_device != NULL){ + trans_device = pgs->trans_device; } else { trans_device = dev; } ncomps = trans_device->color_info.num_components; - /* If we are doing concretization of colors in an SMask or isolated group - then just return the color as is */ - if (ncomps == 1 ) { - cv[0] = frac2cv(gray); - /* encode as a color index */ - color = dev_proc(trans_device, encode_color)(trans_device, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); + /* map to the color model */ + dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pgs, r, g, b, cm_comps); + + /* If we are in an RGB blending color space and have spots then we have + * possibly an issue here with the transfer function */ + if (pgs->trans_device != NULL) { + for (i = 0; i < 3; i++) + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + for (i = 3; i < ncomps; i++) + cv[i] = gx_color_value_from_byte(cm_comps[i]); } else { - /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_gray(trans_device, gray, cm_comps); + /* Not a transparency device. Just use the transfer functions directly */ for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); - /* encode as a color index */ - color = dev_proc(trans_device, encode_color)(trans_device, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); } -} -/* color mapping for when we have an smask or a isolated transparency group with - another color space */ -static void -pdf14_cmap_rgb_direct_group(frac r, frac g, frac b, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) -{ - int i, ncomps = dev->color_info.num_components; - frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index color; - gx_device *trans_device; - /* We may be coming from the clist writer which often forwards us the - target device. If this occurs we actually need to get to the color space - defined by the transparency group and we use the operators defined by - the transparency device to do the job. - */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; - } else { - trans_device = dev; - } - ncomps = trans_device->color_info.num_components; - if ( ncomps == 3 ){ - cv[0] = frac2cv(r); - cv[1] = frac2cv(g); - cv[2] = frac2cv(b); - /* encode as a color index */ - color = dev_proc(trans_device, encode_color)(trans_device, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); - } else { - /* map to the device color model */ - /* We can end up here, if for example we had a DeviceN color space with a - CIE based alternate space and a output device that was RGB but a - blending space that was CMYK. The proper way to solve this is to - introduce another color space for the graphic state that has its own - Joint CIE Cache between the source and a CMYK CRD (the transparency - color space). The problem is that we can only have one CRD, which is - defined by the output device. We will fix these issues with the ICC - based color architecture. */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pis, r, g, b, cm_comps); + /* if output device supports devn, we need to make sure we send it the + proper color type. We now support RGB + spots as devn colors */ + if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) { for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); + pdc->colors.devn.values[i] = cv[i]; + pdc->type = gx_dc_type_devn; + } else { /* encode as a color index */ color = dev_proc(trans_device, encode_color)(trans_device, cv); /* check if the encoding was successful; we presume failure is rare */ @@ -4853,45 +5369,38 @@ } } -/* color mapping for when we have an smask or a isolated transparency group with another color space */ static void -pdf14_cmap_cmyk_direct_group(frac c, frac m, frac y, frac k, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select, +pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select, const gs_color_space *pcs) { - int i, ncomps = dev->color_info.num_components; + int i,ncomps; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; gx_device *trans_device; - /* We may be coming from the clist writer which often forwards us the - target device. If this occurs we actually need to get to the color space - defined by the transparency group and we use the operators defined by - the transparency device to do the job. - */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; + /* If trans device is set, we need to use its procs. */ + if (pgs->trans_device != NULL){ + trans_device = pgs->trans_device; } else { trans_device = dev; } ncomps = trans_device->color_info.num_components; - if (ncomps == 4 ){ - cv[0] = frac2cv(c); - cv[1] = frac2cv(m); - cv[2] = frac2cv(y); - cv[3] = frac2cv(k); - /* encode as a color index */ - color = dev_proc(trans_device, encode_color)(trans_device, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); - } else { - /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_cmyk(trans_device, c, m, y, k, cm_comps); + /* map to the color model */ + dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_cmyk(trans_device, c, m, y, k, cm_comps); + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + /* if output device supports devn, we need to make sure we send it the + proper color type */ + if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) { for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); + pdc->colors.devn.values[i] = cv[i]; + pdc->type = gx_dc_type_devn; + } else { + /* encode as a color index */ color = dev_proc(trans_device, encode_color)(trans_device, cv); + /* check if the encoding was successful; we presume failure is rare */ if (color != gx_no_color_index) color_set_pure(pdc, color); } @@ -4899,7 +5408,7 @@ static void pdf14_cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { int i, ncomps; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; @@ -4911,14 +5420,14 @@ target device. If this occurs we actually need to get to the color space defined by the transparency group and we use the operators defined by the transparency device to do the job. */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; + if (pgs->trans_device != NULL){ + trans_device = pgs->trans_device; } else { trans_device = dev; } ncomps = trans_device->color_info.num_components; /* map to the color model */ - dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pis, r, g, b, cm_comps); + dev_proc(trans_device, get_color_mapping_procs)(trans_device)->map_rgb(trans_device, pgs, r, g, b, cm_comps); /* pre-multiply to account for the alpha weighting */ if (alpha != frac_1) { #ifdef PREMULTIPLY_TOWARDS_WHITE @@ -4931,25 +5440,40 @@ } for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(cm_comps[i]); + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); color = dev_proc(trans_device, encode_color)(trans_device, cv); /* check if the encoding was successful; we presume failure is rare */ if (color != gx_no_color_index) color_set_pure(pdc, color); } +static int +pdf14_get_num_spots(gx_device * dev) +{ + cmm_dev_profile_t *dev_profile; + cmm_profile_t *icc_profile; + gsicc_rendering_param_t render_cond; + + dev_proc(dev, get_profile)(dev, &dev_profile); + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, + &render_cond); + return dev->color_info.num_components - icc_profile->num_comps; +} + static void -pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_imager_state * pis, +pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { int i, ncomps = dev->color_info.num_components; + int num_spots = pdf14_get_num_spots(dev); bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE; - frac comp_value = all; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; - if (pis->color_component_map.sep_type == SEP_ALL) { + if (pgs->color_component_map.sep_type == SEP_ALL) { + frac comp_value = all; + /* * Invert the photometric interpretation for additive * color spaces because separations are always subtractive. @@ -4957,23 +5481,31 @@ if (additive) comp_value = frac_1 - comp_value; /* Use the "all" value for all components */ - i = pis->color_component_map.num_colorants - 1; + i = pgs->color_component_map.num_colorants - 1; for (; i >= 0; i--) cm_comps[i] = comp_value; - } - else { + } else { + frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS]; + /* map to the color model */ - map_components_to_colorants(&comp_value, &(pis->color_component_map), cm_comps); + for (i = pgs->color_component_map.num_components - 1; i >= 0; i--) + comp_value[i] = all; + map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps); } /* apply the transfer function(s); convert to color values */ - if (additive) + if (additive) { for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pis, - cm_comps[i], effective_transfer[i])); - else + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + /* We are in an additive mode (blend space) and drawing with a sep color + into a sep device. Make sure we are drawing "white" with the process + colorants, but only if we are not in an ALL case */ + if (pgs->color_component_map.sep_type != SEP_ALL) + for (i = 0; i < ncomps - num_spots; i++) + cv[i] = gx_max_color_value; + } else for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); + cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); + /* if output device supports devn, we need to make sure we send it the proper color type */ @@ -4992,10 +5524,11 @@ static void pdf14_cmap_devicen_direct(const frac * pcc, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { int i, ncomps = dev->color_info.num_components; + int num_spots = pdf14_get_num_spots(dev); frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; @@ -5006,23 +5539,26 @@ space defined by the transparency group and we use the operators defined by the transparency device to do the job. */ - if (pis->trans_device != NULL){ - trans_device = pis->trans_device; + if (pgs->trans_device != NULL){ + trans_device = pgs->trans_device; } else { trans_device = dev; } ncomps = trans_device->color_info.num_components; /* map to the color model */ - map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps);; + map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps);; /* apply the transfer function(s); convert to color values */ - if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pis, - cm_comps[i], effective_transfer[i])); - else + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); + /* We are in an additive mode (blend space) and drawing with a sep color + into a sep device. Make sure we are drawing "white" with the process + colorants */ + for (i = 0; i < ncomps - num_spots; i++) + cv[i] = gx_max_color_value; + } else for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); + cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); /* if output device supports devn, we need to make sure we send it the proper color type */ if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) { @@ -5039,33 +5575,31 @@ } static bool -pdf14_cmap_is_halftoned(const gs_imager_state * pis, gx_device * dev) +pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev) { return false; } static const gx_color_map_procs * -pdf14_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev) +pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev) { /* The pdf14 marking device itself is always continuous tone. */ return &pdf14_cmap_many; } -static const gx_color_map_procs * -pdf14_get_cmap_procs_group(const gs_imager_state *pis, const gx_device * dev) -{ - /* The pdf14 marking device itself is always continuous tone. */ - return &pdf14_cmap_many_group; -} - static int pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) { + pdf14_device * p14dev = (pdf14_device *)pdev; + if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path) return 1; - if (dev_spec_op == gxdso_is_pdf14_device) + if (dev_spec_op == gxdso_is_pdf14_device) { + if (data != NULL && size == sizeof(gx_device *)) + *(gx_device **)data = pdev; return 1; + } if (dev_spec_op == gxdso_device_child) { pdf14_device *dev = (pdf14_device *)pdev; gxdso_device_child_request *d = (gxdso_device_child_request *)data; @@ -5074,18 +5608,6 @@ return 1; } } - if (dev_spec_op == gxdso_is_native_planar) { - /* Only return true here if the target is planar. While the pdf14 - device is planar, the underlying buffers for the target - device is what is being asked about */ - gx_device_forward * fdev = (gx_device_forward *)pdev; - gx_device * target = fdev->target; - if (target != NULL) { - int depth = dev_proc(target, dev_spec_op)(target, gxdso_is_native_planar, - NULL, 0); - return (depth > 0 ? 8 : 0); - } else return 0; - } if (dev_spec_op == gxdso_supports_devn) { cmm_dev_profile_t *dev_profile; int code; @@ -5096,11 +5618,16 @@ return 0; } } + if (dev_spec_op == gxdso_get_dev_param || dev_spec_op == gxdso_restrict_bbox) { + return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size); + } + return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); + } /* Needed to set color monitoring in the target device's profile */ -int +int gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring) { pdf14_device * p14dev = (pdf14_device *)pdev; @@ -5114,24 +5641,55 @@ } int -gs_pdf14_device_push(gs_memory_t *mem, gs_imager_state * pis, +gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs, gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct) { pdf14_device * dev_proto; pdf14_device * p14dev, temp_dev_proto; int code; - bool has_tags = target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS; + bool has_tags; cmm_profile_t *icc_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; - int k; + uchar k; + int max_bitmap; + bool use_pdf14_accum = false; + + /* Guard against later seg faults, this should not be possible */ + if (target == NULL) + return gs_throw_code(gs_error_Fatal); + + has_tags = device_encodes_tags(target); + max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP : + target->space_params.MaxBitmap; + /* If the device is not a printer class device, it won't support saved-pages */ + /* and so we may need to make a clist device in order to prevent very large */ + /* or high resolution pages from having allocation problems. */ + /* We use MaxBitmap to decide when a clist is needed.*/ + if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 && + gx_device_is_pattern_clist(target) == 0 && + gx_device_is_pattern_accum(target) == 0 && + gs_device_is_memory(target) == 0) { + + uint32_t pdf14_trans_buffer_size = (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width), + target->color_info.num_components) >> 3); + if (target->height < max_ulong / pdf14_trans_buffer_size) + pdf14_trans_buffer_size *= target->height; + else + max_bitmap = 0; /* Force decision to clist */ + if (pdf14_trans_buffer_size > max_bitmap) + use_pdf14_accum = true; + } code = dev_proc(target, get_profile)(target, &dev_profile); + if (code < 0) + return code; gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, &render_cond); if_debug0m('v', mem, "[v]gs_pdf14_device_push\n"); - code = get_pdf14_device_proto(target, &dev_proto, - &temp_dev_proto, pis, pdf14pct); + + code = get_pdf14_device_proto(target, &dev_proto, &temp_dev_proto, pgs, + pdf14pct, use_pdf14_accum); if (code < 0) return code; code = gs_copydevice((gx_device **) &p14dev, @@ -5140,21 +5698,28 @@ return code; gs_pdf14_device_copy_params((gx_device *)p14dev, target); gx_device_set_target((gx_device_forward *)p14dev, target); - /* If the target profile was CIELAB, then overide with default RGB for + p14dev->pad = target->pad; + p14dev->log2_align_mod = target->log2_align_mod; + p14dev->is_planar = target->is_planar; + /* If the target profile was CIELAB (and we are not using a blend CS), + then overide with default RGB for proper blending. During put_image we will convert from RGB to CIELAB. Need to check that we have a default profile, which will not be the case if we are coming from the clist reader */ if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab) - && pis->icc_manager->default_rgb != NULL) { - p14dev->icc_struct->device_profile[0] = - pis->icc_manager->default_rgb; - rc_increment(pis->icc_manager->default_rgb); - } - /* The number of color planes should not exceed that of the target */ - if (p14dev->color_info.num_components > target->color_info.num_components) - p14dev->color_info.num_components = target->color_info.num_components; - if (p14dev->color_info.max_components > target->color_info.max_components) - p14dev->color_info.max_components = target->color_info.max_components; + && pgs->icc_manager->default_rgb != NULL && !p14dev->using_blend_cs) { + gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push"); + gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[0], -1, "gs_pdf14_device_push"); + p14dev->icc_struct->device_profile[0] = pgs->icc_manager->default_rgb; + } + /* The number of color planes should not exceed that of the target. + Unless we are using a blend CS */ + if (!p14dev->using_blend_cs) { + if (p14dev->color_info.num_components > target->color_info.num_components) + p14dev->color_info.num_components = target->color_info.num_components; + if (p14dev->color_info.max_components > target->color_info.max_components) + p14dev->color_info.max_components = target->color_info.max_components; + } p14dev->color_info.depth = p14dev->color_info.num_components * 8; /* If we have a tag device then go ahead and do a special encoder decoder for the pdf14 device to make sure we maintain this @@ -5164,24 +5729,30 @@ of colorants became large. If we need to do compressed color with tags that will be a special project at that time */ if (has_tags) { - p14dev->procs.encode_color = pdf14_encode_color_tag; + set_dev_proc(p14dev, encode_color, pdf14_encode_color_tag); + p14dev->color_info.comp_shift[p14dev->color_info.num_components] = p14dev->color_info.depth; p14dev->color_info.depth += 8; } - check_device_separable((gx_device *)p14dev); + /* by definition pdf14_encode _is_ standard */ + p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD; gx_device_fill_in_procs((gx_device *)p14dev); - p14dev->save_get_cmap_procs = pis->get_cmap_procs; - pis->get_cmap_procs = pdf14_get_cmap_procs; - gx_set_cmap_procs(pis, (gx_device *)p14dev); + p14dev->save_get_cmap_procs = pgs->get_cmap_procs; + pgs->get_cmap_procs = pdf14_get_cmap_procs; + gx_set_cmap_procs(pgs, (gx_device *)p14dev); /* Components shift, etc have to be based upon 8 bit */ for (k = 0; k < p14dev->color_info.num_components; k++) { p14dev->color_info.comp_bits[k] = 8; - p14dev->color_info.comp_shift[k] = + p14dev->color_info.comp_shift[k] = (p14dev->color_info.num_components - 1 - k) * 8; } + if (use_pdf14_accum) { + /* we will disable this device later, but we don't want to allocate large buffers */ + p14dev->width = 1; + p14dev->height = 1; + } code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev); *pdev = (gx_device *) p14dev; - pdf14_set_marking_params((gx_device *)p14dev, pis); - p14dev->blendspot = false; + pdf14_set_marking_params((gx_device *)p14dev, pgs); p14dev->trans_group_parent_cmap_procs = NULL; /* In case we have alphabits set */ p14dev->color_info.anti_alias = target->color_info.anti_alias; @@ -5195,7 +5766,76 @@ global_index++; #endif + /* We should never go into this when using a blend color space */ + if (use_pdf14_accum) { + const gx_device_pdf14_accum *accum_proto = NULL; + gx_device *new_target = NULL; + gx_device_color pdcolor; + frac pconc_white = frac_1; + + if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n"); + + /* get the prototype for the accumulator device based on colorspace */ + switch (target->color_info.num_components) { + case 1: + accum_proto = &pdf14_accum_Gray; + break; + case 3: + accum_proto = &pdf14_accum_RGB; + break; + case 4: + accum_proto = &pdf14_accum_CMYK; + break; + default: + /* FIXME: DeviceN ?? */ + break; /* accum_proto will be NULL, so no accum device */ + } + if (accum_proto == NULL || + (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0) + goto no_clist_accum; + + ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev; /* non-clist p14dev */ + /* Fill in values from the target device before opening */ + new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN; + new_target->color_info.anti_alias = p14dev->color_info.anti_alias; + set_linear_color_bits_mask_shift(new_target); + gs_pdf14_device_copy_params(new_target, target); + ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true; + gx_device_fill_in_procs(new_target); + + memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params)); + max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace); + new_target->space_params.BufferSpace = max_bitmap; + + new_target->PageHandlerPushed = true; + new_target->ObjectHandlerPushed = true; + + if ((code = gdev_prn_open(new_target)) < 0 || + !PRINTER_IS_CLIST((gx_device_printer *)new_target)) { + gs_free_object(mem->stable_memory, new_target, "pdf14-accum"); + goto no_clist_accum; + } + /* Do the initial fillpage into the pdf14-accum device we just created */ + dev_proc(new_target, set_graphics_type_tag)(new_target, GS_UNTOUCHED_TAG); + if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs), + &pconc_white, + &pdcolor, pgs, new_target, gs_color_select_all, + dev_profile)) < 0) + goto no_clist_accum; + + (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor); + code = clist_create_compositor(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL); + if (code < 0) + goto no_clist_accum; + + pdf14_disable_device((gx_device *)p14dev); /* make the non-clist device forward */ + pdf14_close((gx_device *)p14dev); /* and free up the little memory it had */ + } return code; + +no_clist_accum: + /* FIXME: We allocated a really small p14dev, but that won't work */ + return gs_throw_code(gs_error_Fatal); /* punt for now */ } /* @@ -5230,7 +5870,7 @@ static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES; #endif -#define put_value(dp, value)\ +#define put_value(dp, value)\ BEGIN\ memcpy(dp, &value, sizeof(value));\ dp += sizeof(value);\ @@ -5239,7 +5879,7 @@ static inline int c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams) { - /* Note: We can't skip writing CTM if it is equal to pis->ctm, + /* Note: We can't skip writing CTM if it is equal to pgs->ctm, because clist writer may skip this command for some bands. For a better result we need individual CTM for each band. */ @@ -5279,11 +5919,17 @@ bool found_icc; int64_t hashcode = 0; cmm_profile_t *icc_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; + /* We maintain and update working copies until we actually write the clist */ + int pdf14_needed = cdev->pdf14_needed; + int trans_group_level = cdev->pdf14_trans_group_level; + int smask_level = cdev->pdf14_smask_level; code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev, &dev_profile); + if (code < 0) + return code; gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, &render_cond); *pbuf++ = opcode; /* 1 byte */ @@ -5291,9 +5937,9 @@ default: /* Should not occur. */ break; case PDF14_PUSH_DEVICE: - cdev->pdf14_needed = false; /* reset pdf14_needed */ - cdev->pdf14_trans_group_level = 0; + trans_group_level = 0; cdev->pdf14_smask_level = 0; + cdev->page_pdf14_needed = false; put_value(pbuf, pparams->num_spot_colors); put_value(pbuf, pparams->is_pattern); /* If we happen to be going to a color space like CIELAB then @@ -5315,19 +5961,20 @@ } break; case PDF14_POP_DEVICE: - cdev->pdf14_needed = false; /* reset pdf14_needed */ - cdev->pdf14_trans_group_level = 0; - cdev->pdf14_smask_level = 0; + pdf14_needed = false; /* reset pdf14_needed */ + trans_group_level = 0; + smask_level = 0; put_value(pbuf, pparams->is_pattern); break; case PDF14_END_TRANS_GROUP: - cdev->pdf14_trans_group_level--; /* if now at page level, pdf14_needed will be updated */ - if (cdev->pdf14_smask_level == 0 && cdev->pdf14_trans_group_level == 0) - cdev->pdf14_needed = false; + case PDF14_END_TRANS_TEXT_GROUP: + trans_group_level--; /* if now at page level, pdf14_needed will be updated */ + if (smask_level == 0 && trans_group_level == 0) + pdf14_needed = cdev->page_pdf14_needed; break; /* No data */ case PDF14_BEGIN_TRANS_GROUP: - cdev->pdf14_needed = true; /* the compositor will be needed while reading */ - cdev->pdf14_trans_group_level++; + pdf14_needed = true; /* the compositor will be needed while reading */ + trans_group_level++; code = c_pdf14trans_write_ctm(&pbuf, pparams); if (code < 0) return code; @@ -5338,8 +5985,9 @@ put_value(pbuf, pparams->opacity.alpha); put_value(pbuf, pparams->shape.alpha); put_value(pbuf, pparams->bbox); + put_value(pbuf, pparams->text_group); mask_id = pparams->mask_id; - put_value(pbuf, pparams->mask_id); + put_value(pbuf, mask_id); /* Color space information maybe ICC based in this case we need to store the ICC profile or the ID if it is cached already */ @@ -5360,8 +6008,10 @@ } break; case PDF14_BEGIN_TRANS_MASK: - cdev->pdf14_needed = true; /* the compositor will be needed while reading */ - cdev->pdf14_smask_level++; + if (pparams->subtype != TRANSPARENCY_MASK_None) { + pdf14_needed = true; /* the compositor will be needed while reading */ + smask_level++; + } code = c_pdf14trans_write_ctm(&pbuf, pparams); if (code < 0) return code; @@ -5371,9 +6021,10 @@ *pbuf++ = pparams->replacing; *pbuf++ = pparams->function_is_identity; *pbuf++ = pparams->Background_components; + *pbuf++ = pparams->Matte_components; put_value(pbuf, pparams->bbox); mask_id = pparams->mask_id; - put_value(pbuf, pparams->mask_id); + put_value(pbuf, mask_id); if (pparams->Background_components) { const int l = sizeof(pparams->Background[0]) * pparams->Background_components; @@ -5382,6 +6033,12 @@ memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground)); pbuf += sizeof(pparams->GrayBackground); } + if (pparams->Matte_components) { + const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components; + + memcpy(pbuf, pparams->Matte, m); + pbuf += m; + } if (!pparams->function_is_identity) mask_size = sizeof(pparams->transfer_fn); /* Color space information may be ICC based @@ -5404,16 +6061,18 @@ } break; case PDF14_END_TRANS_MASK: - cdev->pdf14_smask_level--; - if (cdev->pdf14_smask_level == 0 && cdev->pdf14_trans_group_level == 0) - cdev->pdf14_needed = false; + smask_level--; + if (smask_level == 0 && trans_group_level == 0) + pdf14_needed = cdev->page_pdf14_needed; break; case PDF14_SET_BLEND_PARAMS: if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity.alpha != 1.0 || pparams->shape.alpha != 1.0) - cdev->pdf14_needed = true; /* the compositor will be needed while reading */ - else if (cdev->pdf14_trans_group_level == 0) - cdev->pdf14_needed = false; /* reset pdf14_needed */ + pdf14_needed = true; /* the compositor will be needed while reading */ + else if (smask_level == 0 && trans_group_level == 0) + pdf14_needed = false; /* At page level, set back to false */ + if (smask_level == 0 && trans_group_level == 0) + cdev->page_pdf14_needed = pdf14_needed; /* save for after popping to page level */ *pbuf++ = pparams->changed; if (pparams->changed & PDF14_SET_BLEND_MODE) *pbuf++ = pparams->blend_mode; @@ -5427,8 +6086,6 @@ put_value(pbuf, pparams->overprint); if (pparams->changed & PDF14_SET_OVERPRINT_MODE) put_value(pbuf, pparams->overprint_mode); - if (pparams->changed & PDF14_SET_OVERPRINT_BLEND) - put_value(pbuf, pparams->blendspot); break; case PDF14_PUSH_TRANS_STATE: break; @@ -5453,9 +6110,10 @@ } /* If we are writing more than the maximum ever expected, - * return a rangecheck error. + * return a rangecheck error. Second check is for Coverity */ - if ( need + 3 > (MAX_CLIST_COMPOSITOR_SIZE) ) + if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) || + (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) ) return_error(gs_error_rangecheck); /* Copy our serialized data into the output buffer */ @@ -5465,6 +6123,9 @@ if_debug3m('v', cdev->memory, "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n", pdf14_opcode_names[opcode], mask_id, need); + cdev->pdf14_needed = pdf14_needed; /* all OK to update */ + cdev->pdf14_trans_group_level = trans_group_level; + cdev->pdf14_smask_level = smask_level; return 0; } @@ -5508,11 +6169,16 @@ read_value(data, params.num_spot_colors); read_value(data, params.is_pattern); break; + case PDF14_ABORT_DEVICE: + break; case PDF14_POP_DEVICE: read_value(data, params.is_pattern); break; case PDF14_END_TRANS_GROUP: + case PDF14_END_TRANS_TEXT_GROUP: +#ifdef DEBUG code += 0; /* A good place for a breakpoint. */ +#endif break; /* No data */ case PDF14_PUSH_TRANS_STATE: break; @@ -5532,14 +6198,15 @@ read_value(data, params.opacity.alpha); read_value(data, params.shape.alpha); read_value(data, params.bbox); + read_value(data, params.text_group); read_value(data, params.mask_id); read_value(data, params.icc_hash); break; case PDF14_BEGIN_TRANS_MASK: /* This is the largest transparency parameter at this time (potentially - * 1275 bytes in size if Background_components = - * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function - * as well). + * 1531 bytes in size if Background_components = + * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components = + * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well). * * NOTE: * The clist reader must be able to handle this sized device. @@ -5555,6 +6222,7 @@ params.replacing = *data++; params.function_is_identity = *data++; params.Background_components = *data++; + params.Matte_components = *data++; read_value(data, params.bbox); read_value(data, params.mask_id); if (params.Background_components) { @@ -5565,6 +6233,12 @@ memcpy(¶ms.GrayBackground, data, sizeof(params.GrayBackground)); data += sizeof(params.GrayBackground); } + if (params.Matte_components) { + const int m = sizeof(params.Matte[0]) * params.Matte_components; + + memcpy(params.Matte, data, m); + data += m; + } read_value(data, params.icc_hash); if (params.function_is_identity) { int i; @@ -5599,8 +6273,6 @@ read_value(data, params.overprint); if (params.changed & PDF14_SET_OVERPRINT_MODE) read_value(data, params.overprint_mode); - if (params.changed & PDF14_SET_OVERPRINT_BLEND) - read_value(data, params.blendspot); break; } code = gs_create_pdf14trans(ppct, ¶ms, mem); @@ -5620,17 +6292,17 @@ * Adjust the compositor's CTM. */ static int -c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_imager_state *pis) +c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs) { gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0; gs_matrix mat = pct->params.ctm; - if_debug6m('L', pis->memory, " [%g %g %g %g %g %g]\n", + if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n", mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty); mat.tx -= x0; mat.ty -= y0; - gs_imager_setmatrix(pis, &mat); + gs_gstate_setmatrix(pgs, &mat); return 0; } @@ -5642,7 +6314,7 @@ */ static int c_pdf14trans_create_default_compositor(const gs_composite_t * pct, - gx_device ** pp14dev, gx_device * tdev, gs_imager_state * pis, + gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem) { const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct; @@ -5656,7 +6328,7 @@ */ switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: - code = gs_pdf14_device_push(mem, pis, &p14dev, tdev, pdf14pct); + code = gs_pdf14_device_push(mem, pgs, &p14dev, tdev, pdf14pct); *pp14dev = p14dev; break; default: @@ -5669,8 +6341,9 @@ /* * Find an opening compositor op. */ -static int -find_opening_op(int opening_op, gs_composite_t **ppcte, int return_code) +static gs_compositor_closing_state +find_opening_op(int opening_op, gs_composite_t **ppcte, + gs_compositor_closing_state return_code) { /* Assuming a right *BEGIN* - *END* operation balance. */ gs_composite_t *pcte = *ppcte; @@ -5685,29 +6358,30 @@ return return_code; if (op != PDF14_SET_BLEND_PARAMS) { if (opening_op == PDF14_BEGIN_TRANS_MASK) - return 0; + return COMP_ENQUEUE; if (opening_op == PDF14_BEGIN_TRANS_GROUP) { if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK) - return 0; + return COMP_ENQUEUE; } if (opening_op == PDF14_PUSH_DEVICE) { if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK && - op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_END_TRANS_GROUP) - return 0; + op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_END_TRANS_GROUP && + op != PDF14_END_TRANS_TEXT_GROUP) + return COMP_ENQUEUE; } } } else - return 0; + return COMP_ENQUEUE; pcte = pcte->prev; if (pcte == NULL) - return 2; /* Not in queue. */ + return COMP_EXEC_QUEUE; /* Not in queue. */ } } /* * Find an opening compositor op. */ -static int +static gs_compositor_closing_state find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte) { const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action; @@ -5719,29 +6393,29 @@ *ppcte = pct; if (pct_pdf14->params.pdf14_op != my_op) - return 0; + return COMP_ENQUEUE; if (pct_pdf14->params.csel == pct0->params.csel) { /* If the new parameters completely replace the old ones then remove the old one from the queu */ if ((pct_pdf14->params.changed & pct0->params.changed) == pct_pdf14->params.changed) { - return 4; + return COMP_REPLACE_CURR; } else { - return 0; + return COMP_ENQUEUE; } } } else - return 0; + return COMP_ENQUEUE; pct = pct->prev; if (pct == NULL) - return 0; /* Not in queue. */ + return COMP_ENQUEUE; /* Not in queue. */ } } /* * Check for closing compositor. */ -static int +static gs_compositor_closing_state c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte, gx_device *dev) { @@ -5751,42 +6425,45 @@ switch (op0) { default: return_error(gs_error_unregistered); /* Must not happen. */ case PDF14_PUSH_DEVICE: - return 0; + return COMP_ENQUEUE; + case PDF14_ABORT_DEVICE: + return COMP_ENQUEUE; case PDF14_POP_DEVICE: if (*ppcte == NULL) - return 0; + return COMP_ENQUEUE; else { - int code = find_opening_op(PDF14_PUSH_DEVICE, ppcte, 1); + gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE); - if (code == 1) - return 5; - return code; + if (state == COMP_EXEC_IDLE) + return COMP_DROP_QUEUE; + return state; } case PDF14_BEGIN_TRANS_GROUP: - return 0; + return COMP_ENQUEUE; case PDF14_END_TRANS_GROUP: + case PDF14_END_TRANS_TEXT_GROUP: if (*ppcte == NULL) - return 2; - return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, 6); + return COMP_EXEC_QUEUE; + return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE); case PDF14_BEGIN_TRANS_MASK: - return 0; + return COMP_ENQUEUE; case PDF14_PUSH_TRANS_STATE: - return 0; + return COMP_ENQUEUE; case PDF14_POP_TRANS_STATE: - return 0; + return COMP_ENQUEUE; case PDF14_PUSH_SMASK_COLOR: - return 0; + return COMP_ENQUEUE; break; case PDF14_POP_SMASK_COLOR: - return 0; + return COMP_ENQUEUE; break; case PDF14_END_TRANS_MASK: if (*ppcte == NULL) - return 2; - return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, 6); + return COMP_EXEC_QUEUE; + return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE); case PDF14_SET_BLEND_PARAMS: if (*ppcte == NULL) - return 0; + return COMP_ENQUEUE; /* hack : ignore csel - here it is always zero : */ return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte); } @@ -5801,7 +6478,8 @@ gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action; int op0 = pct0->params.pdf14_op; - if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP) { + if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP || + op0 == PDF14_END_TRANS_TEXT_GROUP) { /* Halftone commands are always passed to the target printer device, because transparency buffers are always contone. So we're safe to execute them before queued transparency compositors. */ @@ -5904,19 +6582,21 @@ * Send a PDF 1.4 transparency compositor action to the specified device. */ int -send_pdf14trans(gs_imager_state * pis, gx_device * dev, +send_pdf14trans(gs_gstate * pgs, gx_device * dev, gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem) { gs_composite_t * pct = NULL; int code; - pparams->ctm = ctm_only(pis); + pparams->ctm = ctm_only(pgs); code = gs_create_pdf14trans(&pct, pparams, mem); if (code < 0) return code; - code = dev_proc(dev, create_compositor) (dev, pcdev, pct, pis, mem, NULL); + code = dev_proc(dev, create_compositor) (dev, pcdev, pct, pgs, mem, NULL); + if (code == gs_error_handled) + code = 0; - gs_free_object(pis->memory, pct, "send_pdf14trans"); + gs_free_object(pgs->memory, pct, "send_pdf14trans"); return code; } @@ -5992,7 +6672,7 @@ pdf14_end_transparency_group,\ pdf14_begin_transparency_mask,\ pdf14_end_transparency_mask,\ - NULL, /* discard_transparency_layer */\ + gx_default_discard_transparency_layer, /* discard_transparency_layer */\ get_color_mapping_procs, /* get_color_mapping_procs */\ get_color_comp_index, /* get_color_comp_index */\ encode_color, /* encode_color */\ @@ -6010,9 +6690,9 @@ pdf14_pop_transparency_state,\ NULL, /* put_image */\ pdf14_dev_spec_op,\ - NULL, /* copy planes */\ + pdf14_clist_copy_planes, /* copy planes */\ NULL, /* get_profile */\ - NULL, /* set_graphics_type_tag */\ + gx_forward_set_graphics_type_tag, /* set_graphics_type_tag */\ NULL, /* strip_copy_rop2 */\ NULL, /* strip_tile_rect_devn */\ gx_forward_copy_alpha_hl_color\ @@ -6025,6 +6705,7 @@ static dev_proc_text_begin(pdf14_clist_text_begin); static dev_proc_begin_image(pdf14_clist_begin_image); static dev_proc_begin_typed_image(pdf14_clist_begin_typed_image); +static dev_proc_copy_planes(pdf14_clist_copy_planes); static const gx_device_procs pdf14_clist_Gray_procs = pdf14_clist_procs(gx_default_DevGray_get_color_mapping_procs, @@ -6043,25 +6724,25 @@ gx_default_DevCMYK_get_color_comp_index, pdf14_encode_color, pdf14_decode_color); -#if USE_COMPRESSED_ENCODING -static const gx_device_procs pdf14_clist_CMYKspot_procs = - pdf14_clist_procs(pdf14_cmykspot_get_color_mapping_procs, - pdf14_cmykspot_get_color_comp_index, - pdf14_compressed_encode_color, - pdf14_compressed_decode_color); -#else static const gx_device_procs pdf14_clist_CMYKspot_procs = pdf14_clist_procs(pdf14_cmykspot_get_color_mapping_procs, pdf14_cmykspot_get_color_comp_index, pdf14_encode_color, pdf14_decode_color); -#endif -static const gx_device_procs pdf14_clist_custom_procs = - pdf14_clist_procs(gx_forward_get_color_mapping_procs, - gx_forward_get_color_comp_index, - gx_forward_encode_color, - gx_forward_decode_color); +#if 0 /* NOT USED */ +static const gx_device_procs pdf14_clist_RGBspot_procs = + pdf14_clist_procs(pdf14_rgbspot_get_color_mapping_procs, + pdf14_rgbspot_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); + +static const gx_device_procs pdf14_clist_Grayspot_procs = + pdf14_clist_procs(pdf14_grayspot_get_color_mapping_procs, + pdf14_grayspot_get_color_comp_index, + pdf14_encode_color, + pdf14_decode_color); +#endif /* NOT USED */ const pdf14_clist_device pdf14_clist_Gray_device = { std_device_color_stype_body(pdf14_clist_device, &pdf14_clist_Gray_procs, @@ -6149,11 +6830,13 @@ */ static int get_pdf14_clist_device_proto(gx_device * dev, pdf14_clist_device ** pdevproto, - pdf14_clist_device * ptempdevproto, gs_imager_state * pis, - const gs_pdf14trans_t * pdf14pct) + pdf14_clist_device * ptempdevproto, gs_gstate * pgs, + const gs_pdf14trans_t * pdf14pct, bool use_pdf14_accum) { + bool using_blend_cs; pdf14_default_colorspace_t dev_cs = - pdf14_determine_default_blend_cs(dev); + pdf14_determine_default_blend_cs(dev, use_pdf14_accum, + &using_blend_cs); switch (dev_cs) { case PDF14_DeviceGray: @@ -6173,16 +6856,22 @@ ptempdevproto->color_info.max_gray = 255; ptempdevproto->color_info.gray_index = 0; /* Avoid halftoning */ ptempdevproto->color_info.dither_grays = 256; + ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; + ptempdevproto->sep_device = false; *pdevproto = ptempdevproto; break; case PDF14_DeviceRGB: *pdevproto = (pdf14_clist_device *)&pdf14_clist_RGB_device; *ptempdevproto = **pdevproto; + ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; + ptempdevproto->sep_device = false; *pdevproto = ptempdevproto; break; case PDF14_DeviceCMYK: *pdevproto = (pdf14_clist_device *)&pdf14_clist_CMYK_device; *ptempdevproto = **pdevproto; + ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; + ptempdevproto->sep_device = false; *pdevproto = ptempdevproto; break; case PDF14_DeviceCMYKspot: @@ -6203,9 +6892,11 @@ ptempdevproto->color_info.max_components) ptempdevproto->color_info.num_components = ptempdevproto->color_info.max_components; - ptempdevproto->color_info.depth = + ptempdevproto->color_info.depth = ptempdevproto->color_info.num_components * 8; } + ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; + ptempdevproto->sep_device = true; *pdevproto = ptempdevproto; break; case PDF14_DeviceCustom: @@ -6223,46 +6914,58 @@ ptempdevproto->color_info.max_color = 255; ptempdevproto->color_info.dither_grays = 256; ptempdevproto->color_info.dither_colors = 256; + ptempdevproto->color_info.anti_alias = dev->color_info.anti_alias; *pdevproto = ptempdevproto; break; default: /* Should not occur */ return_error(gs_error_rangecheck); } + ptempdevproto->using_blend_cs = using_blend_cs; return 0; } static int -pdf14_create_clist_device(gs_memory_t *mem, gs_imager_state * pis, +pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs, gx_device ** ppdev, gx_device * target, const gs_pdf14trans_t * pdf14pct) { pdf14_clist_device * dev_proto; pdf14_clist_device * pdev, temp_dev_proto; int code; - bool has_tags = target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS; + bool has_tags = device_encodes_tags(target); cmm_profile_t *target_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; - int k; + uchar k; code = dev_proc(target, get_profile)(target, &dev_profile); + if (code < 0) + return code; gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile, &render_cond); - if_debug0m('v', pis->memory, "[v]pdf14_create_clist_device\n"); + if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n"); code = get_pdf14_clist_device_proto(target, &dev_proto, - &temp_dev_proto, pis, pdf14pct); + &temp_dev_proto, pgs, pdf14pct, false); if (code < 0) return code; code = gs_copydevice((gx_device **) &pdev, (const gx_device *) dev_proto, mem); if (code < 0) return code; - /* The number of color planes should not exceed that of the target */ - if (pdev->color_info.num_components > target->color_info.num_components) - pdev->color_info.num_components = target->color_info.num_components; - if (pdev->color_info.max_components > target->color_info.max_components) - pdev->color_info.max_components = target->color_info.max_components; + + /* If we are not using a blending color space, the number of color planes + should not exceed that of the target */ + if (!pdev->using_blend_cs) { + if (pdev->color_info.num_components > target->color_info.num_components) + pdev->color_info.num_components = target->color_info.num_components; + if (pdev->color_info.max_components > target->color_info.max_components) + pdev->color_info.max_components = target->color_info.max_components; + } pdev->color_info.depth = pdev->color_info.num_components * 8; + pdev->pad = target->pad; + pdev->log2_align_mod = target->log2_align_mod; + pdev->is_planar = target->is_planar; + /* If we have a tag device then go ahead and do a special encoder decoder for the pdf14 device to make sure we maintain this information in the encoded color information. We could use the target device's methods but @@ -6270,13 +6973,15 @@ into other issues if the number of colorants became large. If we need to do compressed color with tags that will be a special project at that time */ if (has_tags) { - pdev->procs.encode_color = pdf14_encode_color_tag; + set_dev_proc(pdev, encode_color, pdf14_encode_color_tag); + pdev->color_info.comp_shift[pdev->color_info.num_components] = pdev->color_info.depth; pdev->color_info.depth += 8; } - check_device_separable((gx_device *)pdev); + pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD; /* this is the standard */ gx_device_fill_in_procs((gx_device *)pdev); gs_pdf14_device_copy_params((gx_device *)pdev, target); gx_device_set_target((gx_device_forward *)pdev, target); + /* Components shift, etc have to be based upon 8 bit */ for (k = 0; k < pdev->color_info.num_components; k++) { pdev->color_info.comp_bits[k] = 8; @@ -6287,15 +6992,16 @@ /* If the target profile was CIELAB, then overide with default RGB for proper blending. During put_image we will convert from RGB to CIELAB */ - if (target_profile->data_cs == gsCIELAB || target_profile->islab) { + if ((target_profile->data_cs == gsCIELAB || target_profile->islab) && + !pdev->using_blend_cs) { rc_assign(pdev->icc_struct->device_profile[0], - pis->icc_manager->default_rgb, "pdf14_create_clist_device"); + pgs->icc_manager->default_rgb, "pdf14_create_clist_device"); } - pdev->my_encode_color = pdev->procs.encode_color; - pdev->my_decode_color = pdev->procs.decode_color; - pdev->my_get_color_mapping_procs = pdev->procs.get_color_mapping_procs; - pdev->my_get_color_comp_index = pdev->procs.get_color_comp_index; - pdev->color_info.separable_and_linear = + pdev->my_encode_color = dev_proc(pdev, encode_color); + pdev->my_decode_color = dev_proc(pdev, decode_color); + pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs); + pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index); + pdev->color_info.separable_and_linear = target->color_info.separable_and_linear; *ppdev = (gx_device *) pdev; return code; @@ -6308,13 +7014,13 @@ * routine implements that action. */ static int -pdf14_disable_clist_device(gs_memory_t *mem, gs_imager_state * pis, +pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs, gx_device * dev) { gx_device_forward * pdev = (gx_device_forward *)dev; gx_device * target = pdev->target; - if_debug0m('v', pis->memory, "[v]pdf14_disable_clist_device\n"); + if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n"); /* * To disable the action of this device, we forward all device @@ -6334,223 +7040,35 @@ * routine will re-enable the compositor if the PDF 1.4 device is pushed * again. */ -static int -pdf14_recreate_clist_device(gs_memory_t *mem, gs_imager_state * pis, - gx_device * dev, const gs_pdf14trans_t * pdf14pct) -{ - pdf14_clist_device * pdev = (pdf14_clist_device *)dev; - gx_device * target = pdev->target; - pdf14_clist_device * dev_proto; - pdf14_clist_device temp_dev_proto; - int code; - - if_debug0m('v', pis->memory, "[v]pdf14_recreate_clist_device\n"); - /* - * We will not use the entire prototype device but we will set the - * color related info to match the prototype. - */ - code = get_pdf14_clist_device_proto(target, &dev_proto, - &temp_dev_proto, pis, pdf14pct); - if (code < 0) - return code; - pdev->color_info = dev_proto->color_info; - pdev->procs = dev_proto->procs; - gx_device_fill_in_procs(dev); - check_device_separable((gx_device *)pdev); - return code; -} - -/* - * Key names are normally C const strings. However we need to create temp - * parameter key names. They only need to have a short life. We need to - * create a parameter list with the key names. Then we will put the parameters - * into the clist. That process will create a permanent copy of the key - * name. At that point we can release our temp key names. - */ -typedef struct keyname_link_list_s { - struct keyname_link_list_s * next; - char * key_name; - } keyname_link_list_t; - -/* - * The GC description for the keyname link list is being included for - * completeness. Since this structure is only temporary, this structure - * should never be exposed to the GC. - */ -gs_private_st_ptrs2(st_keyname_link_list, keyname_link_list_t, - "keyname_link_list", keyname_link_list_enum_ptrs, - keyname_link_list_reloc_ptrs, next, key_name); - -/* See comments before the definition of keyname_link_list_t */ -static int -free_temp_keyname_list(gs_memory_t * mem, keyname_link_list_t * plist) -{ - keyname_link_list_t * pthis_elem; - - while (plist != NULL) { - pthis_elem = plist; - plist = plist->next; - gs_free_object(mem, (byte *)pthis_elem, "free_temp_keyname_list"); - } - return 0; -} - -/* Put a data value into our 'string' */ -#define put_data(pdata, value, count)\ - for(j = 0; j < count; j++)\ - *pdata++ = (byte)((value) >> (j * 8)) - -/* - * Convert a compressed color list element into a set of device parameters. - * Note: This routine recursively calls itself. As a result it can create - * mulitple device parameters. The parameters are 'strings'. Actually the - * data is stored in the strings as binary data. - * - * See comments before the definition of keyname_link_list_t - */ -static int -get_param_compressed_color_list_elem(pdf14_clist_device * pdev, - gs_param_list * plist, compressed_color_list_t * pcomp_list, - char * keyname, keyname_link_list_t ** pkeyname_list) -{ - int max_list_elem_size = - 6 + NUM_ENCODE_LIST_ITEMS * sizeof(comp_bit_map_list_t); - int code, i, j; - byte * pdata; - gs_param_string str; - - if (pcomp_list == NULL) /* Exit if we don not have a list. */ - return 0; - - /* Allocate a string for temp data */ - pdata = gs_alloc_bytes(pdev->memory, max_list_elem_size, - "convert_compressed_color_list_elem"); - str.data = (const byte *)pdata; - str.persistent = false; - - put_data(pdata, pcomp_list->num_sub_level_ptrs, 2); - put_data(pdata, pcomp_list->first_bit_map, 2); - - /* . */ - for (i = pcomp_list->first_bit_map; i < NUM_ENCODE_LIST_ITEMS; i++) { - put_data(pdata, pcomp_list->u.comp_data[i].num_comp, 2); - put_data(pdata, pcomp_list->u.comp_data[i].num_non_solid_comp, 2); - put_data(pdata, pcomp_list->u.comp_data[i].solid_not_100, 1); - put_data(pdata, pcomp_list->u.comp_data[i].colorants, - sizeof(pcomp_list->u.comp_data[i].colorants)); - if (pcomp_list->u.comp_data[i].num_comp != - pcomp_list->u.comp_data[i].num_non_solid_comp) { - put_data(pdata, pcomp_list->u.comp_data[i].solid_colorants, - sizeof(pcomp_list->u.comp_data[i].solid_colorants)); - } - } - str.size = pdata - str.data; - code = param_write_string(plist, keyname, &str); - gs_free_object(pdev->memory, (byte *)str.data, - "convert_compressed_color_list_elem"); - - /* Convert the sub levels. */ - for (i = 0; i < pcomp_list->num_sub_level_ptrs; i++) { - /* - * We generate a keyname for the sub level elements based upon - * the keyname for the current level. See comments before the - * definition of keyname_link_list_t for comments about the lifetime - * of the keynames. - */ - /* Allocate a string for the keyname */ - char * keyname_buf = (char *)gs_alloc_bytes(pdev->memory, - strlen(keyname) + 10, "convert_compressed_color_list_elem"); - /* - * Allocate a link list element so we can keep track of the memory - * allocated to hold the keynames. - */ - keyname_link_list_t * pkeyname_list_elem = - gs_alloc_struct(pdev->memory, keyname_link_list_t, - &st_keyname_link_list, "convert_compressed_color_list_elem"); - pkeyname_list_elem->next = *pkeyname_list; - pkeyname_list_elem->key_name = keyname_buf; - *pkeyname_list = pkeyname_list_elem; - gs_sprintf(keyname_buf, "%s_%d", keyname, i); - get_param_compressed_color_list_elem(pdev, plist, - pcomp_list->u.sub_level_ptrs[i], keyname_buf, - pkeyname_list); - } - - return 0; -} -#undef put_data - -/* Get data value from our 'string' */ -#define get_data(pdata, value, count)\ - j = count - 1;\ - value = pdata[j--];\ - for(; j >= 0; j--)\ - value = (value << 8) | pdata[j];\ - pdata += count - -/* - * Retrieve a compressed color list from a set of device parameters. - * Note: This routine recursively calls itself. As a result it can process - * mulitple device parameters and create the entire compressed color list. - * The parameters are 'strings'. Actually the data is stored in the strings - * as binary data. - */ -int -put_param_compressed_color_list_elem(gx_device * pdev, - gs_param_list * plist, compressed_color_list_t ** pret_comp_list, - char * keyname, int num_comps) +static int +pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs, + gx_device * dev, const gs_pdf14trans_t * pdf14pct) { - int code, i, j; - byte * pdata; - gs_param_string str; - compressed_color_list_t * pcomp_list; - - /* Check if the given keyname is present. */ - code = param_read_string(plist, keyname, &str); - switch (code) { - case 0: - break; /* We have the given keyname, continue. */ - default: - param_signal_error(plist, keyname, code); - case 1: - *pret_comp_list = NULL; - return 0; - } - /* Allocate a compressed color list element. */ - pdata = (byte *)str.data; - pcomp_list = alloc_compressed_color_list_elem(pdev->memory, num_comps); - get_data(pdata, pcomp_list->num_sub_level_ptrs, 2); - get_data(pdata, pcomp_list->first_bit_map, 2); - - /* Read the bit maps */ - for (i = pcomp_list->first_bit_map; i < NUM_ENCODE_LIST_ITEMS; i++) { - get_data(pdata, pcomp_list->u.comp_data[i].num_comp, 2); - get_data(pdata, pcomp_list->u.comp_data[i].num_non_solid_comp, 2); - get_data(pdata, pcomp_list->u.comp_data[i].solid_not_100, 1); - get_data(pdata, pcomp_list->u.comp_data[i].colorants, - sizeof(pcomp_list->u.comp_data[i].colorants)); - if (pcomp_list->u.comp_data[i].num_comp != - pcomp_list->u.comp_data[i].num_non_solid_comp) { - get_data(pdata, pcomp_list->u.comp_data[i].solid_colorants, - sizeof(pcomp_list->u.comp_data[i].solid_colorants)); - } - } - - /* Get the sub levels. */ - for (i = 0; i < pcomp_list->num_sub_level_ptrs; i++) { - char buff[50]; - compressed_color_list_t * sub_list_ptr; - - gs_sprintf(buff, "%s_%d", keyname, i); - put_param_compressed_color_list_elem(pdev, plist, - &sub_list_ptr, buff, num_comps - 1); - pcomp_list->u.sub_level_ptrs[i] = sub_list_ptr; - } + pdf14_clist_device * pdev = (pdf14_clist_device *)dev; + gx_device * target = pdev->target; + pdf14_clist_device * dev_proto; + pdf14_clist_device temp_dev_proto; + int code; - *pret_comp_list = pcomp_list; - return 0;; + if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n"); + /* + * We will not use the entire prototype device but we will set the + * color related info to match the prototype. + */ + code = get_pdf14_clist_device_proto(target, &dev_proto, + &temp_dev_proto, pgs, pdf14pct, false); + if (code < 0) + return code; + pdev->color_info = dev_proto->color_info; + pdev->procs = dev_proto->procs; + pdev->static_procs = dev_proto->static_procs; + pdev->pad = target->pad; + pdev->log2_align_mod = target->log2_align_mod; + pdev->is_planar = target->is_planar; + gx_device_fill_in_procs(dev); + check_device_separable((gx_device *)pdev); + return code; } -#undef get_data /* * devicen params @@ -6564,55 +7082,6 @@ } /* - * Convert a list of spot color names into a set of device parameters. - * This is done to transfer information from the PDf14 clist writer - * compositing device to the PDF14 clist reader compositing device. - * - * See comments before the definition of keyname_link_list_t - */ -static int -get_param_spot_color_names(pdf14_clist_device * pdev, - gs_param_list * plist, keyname_link_list_t ** pkeyname_list) -{ - int code, i; - gs_param_string str; - gs_separations * separations = &pdev->devn_params.separations; - int num_spot_colors = separations->num_separations; - - if (num_spot_colors == 0) - return 0; - - code = param_write_int(plist, PDF14NumSpotColorsParamName, - &num_spot_colors); - for (i = 0; i < num_spot_colors; i++) { - /* - * We generate a keyname for the spot color based upon the - * spot color number. See comments before the definition of - * keyname_link_list_t for comments about the lifetime of the keynames. - */ - /* Allocate a string for the keyname */ - char * keyname_buf = (char *)gs_alloc_bytes(pdev->memory, - strlen("PDF14SpotName_") + 10, "get_param_spot_color_names"); - /* - * Allocate a link list element so we can keep track of the memory - * allocated to hold the keynames. - */ - keyname_link_list_t * pkeyname_list_elem = - gs_alloc_struct(pdev->memory, keyname_link_list_t, - &st_keyname_link_list, "get_param_spot_color_names"); - pkeyname_list_elem->next = *pkeyname_list; - pkeyname_list_elem->key_name = keyname_buf; - *pkeyname_list = pkeyname_list_elem; - gs_sprintf(keyname_buf, "PDF14SpotName_%d", i); - str.size = separations->names[i].size; - str.data = separations->names[i].data; - str.persistent = false; - code = param_write_string(plist, keyname_buf, &str); - } - return 0;; -} - -/* * Retrieve a list of spot color names for the PDF14 device. */ int @@ -6659,49 +7128,6 @@ return 0;; } -static int -pdf14_clist_get_param_compressed_color_list(pdf14_device * p14dev) -{ - gx_device_clist_writer * cldev = (gx_device_clist_writer *)p14dev->pclist_device; - gs_c_param_list param_list; - keyname_link_list_t * pkeyname_list_head = NULL; - int code; - - /* - * If a put_params call fails, the device will be left in a closed - * state, but higher-level code won't notice this fact. We flag this by - * setting permanent_error, which prevents writing to the command list. - */ - if (cldev->permanent_error) - return cldev->permanent_error; - gs_c_param_list_write(¶m_list, p14dev->memory); - code = get_param_compressed_color_list_elem(p14dev, - (gs_param_list *)¶m_list, - p14dev->devn_params.compressed_color_list, - (char *)PDF14CompressedColorListParamName, &pkeyname_list_head); - get_param_spot_color_names(p14dev, (gs_param_list *)¶m_list, - &pkeyname_list_head); - if (code >= 0) { - gx_device * tdev = p14dev->target; - - gs_c_param_list_read(¶m_list); -#if 1 - code = dev_proc(tdev, put_params)(tdev, (gs_param_list *)¶m_list); -#else - /* - * This call will put the compressed color list info into the - * clist. However there are two problems. The info goes into - * the list at the end of the list. - */ - code = cmd_put_params(cldev, (gs_param_list *)¶m_list ); -#endif - } - gs_c_param_list_release(¶m_list); - free_temp_keyname_list(p14dev->memory, pkeyname_list_head); - - return code; -} - /* * This procedure will have information from the PDF 1.4 clist writing * clist compositior device. This is information output the compressed @@ -6716,11 +7142,8 @@ pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params, gs_param_list * plist) { - int code = put_param_compressed_color_list_elem(pdev, plist, - &pdevn_params->pdf14_compressed_color_list, - (char *)PDF14CompressedColorListParamName, TOP_ENCODED_LEVEL); - if (code >= 0) - code = put_param_pdf14_spot_names(pdev, + int code; + code = put_param_pdf14_spot_names(pdev, &pdevn_params->pdf14_separations, plist); return code; } @@ -6734,42 +7157,38 @@ */ static int pdf14_clist_create_compositor(gx_device * dev, gx_device ** pcdev, - const gs_composite_t * pct, gs_imager_state * pis, gs_memory_t * mem, + const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { pdf14_clist_device * pdev = (pdf14_clist_device *)dev; - int code; - bool sep_target; - - /* We only handle a few PDF 1.4 transparency operations 4 */ - if (gs_is_pdf14trans_compositor(pct)) { - const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct; + int code, is_pdf14_compositor; + const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct; + /* We only handle a few PDF 1.4 transparency operations */ + if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) { switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: /* Re-activate the PDF 1.4 compositor */ pdev->saved_target_color_info = pdev->target->color_info; pdev->target->color_info = pdev->color_info; - pdev->saved_target_encode_color = pdev->target->procs.encode_color; - pdev->saved_target_decode_color = pdev->target->procs.decode_color; - pdev->target->procs.encode_color = pdev->procs.encode_color = - pdev->my_encode_color; - pdev->target->procs.decode_color = pdev->procs.decode_color = - pdev->my_decode_color; + pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color); + pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color); + set_dev_proc(pdev->target, encode_color, pdev->my_encode_color); + set_dev_proc(pdev, encode_color, pdev->my_encode_color); + set_dev_proc(pdev->target, decode_color, pdev->my_decode_color); + set_dev_proc(pdev, decode_color, pdev->my_decode_color); pdev->saved_target_get_color_mapping_procs = - pdev->target->procs.get_color_mapping_procs; + dev_proc(pdev->target, get_color_mapping_procs); pdev->saved_target_get_color_comp_index = - pdev->target->procs.get_color_comp_index; - pdev->target->procs.get_color_mapping_procs = - pdev->procs.get_color_mapping_procs = - pdev->my_get_color_mapping_procs; - pdev->target->procs.get_color_comp_index = - pdev->procs.get_color_comp_index = - pdev->my_get_color_comp_index; - pdev->save_get_cmap_procs = pis->get_cmap_procs; - pis->get_cmap_procs = pdf14_get_cmap_procs; - gx_set_cmap_procs(pis, dev); - code = pdf14_recreate_clist_device(mem, pis, dev, pdf14pct); + dev_proc(pdev->target, get_color_comp_index); + set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs); + set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs); + set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index); + set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index); + pdev->save_get_cmap_procs = pgs->get_cmap_procs; + pgs->get_cmap_procs = pdf14_get_cmap_procs; + gx_set_cmap_procs(pgs, dev); + code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct); pdev->blend_mode = pdev->text_knockout = 0; pdev->opacity = pdev->shape = 0.0; if (code < 0) @@ -6780,40 +7199,36 @@ * do not need to create a chain of identical devices. */ { - gs_composite_t pctemp = *pct; + gs_pdf14trans_t pctemp = *pdf14pct; pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type; code = dev_proc(pdev->target, create_compositor) - (pdev->target, pcdev, &pctemp, pis, mem, cdev); + (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev); *pcdev = dev; return code; } case PDF14_POP_DEVICE: + /* If we hit an error during an SMask, we need to undo the color + * swapping before continuing. pdf14_decrement_smask_color() checks + * for itself if it needs to take action. + */ + pdf14_decrement_smask_color(pgs, dev); /* Restore the color_info for the clist device */ pdev->target->color_info = pdev->saved_target_color_info; - pdev->target->procs.encode_color = - pdev->saved_target_encode_color; - pdev->target->procs.decode_color = - pdev->saved_target_decode_color; - pdev->target->procs.get_color_mapping_procs = - pdev->saved_target_get_color_mapping_procs; - pdev->target->procs.get_color_comp_index = - pdev->saved_target_get_color_comp_index; - pis->get_cmap_procs = pdev->save_get_cmap_procs; - gx_set_cmap_procs(pis, pdev->target); - /* - * For spot colors we use a 'compressed encoding' for - * gx_color_index values. Send the related data struct - * to the clist. - */ - pdf14_clist_get_param_compressed_color_list(pdev); + set_dev_proc(pdev->target, encode_color, pdev->saved_target_encode_color); + set_dev_proc(pdev->target, decode_color, pdev->saved_target_decode_color); + set_dev_proc(pdev->target, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs); + set_dev_proc(pdev->target, get_color_comp_index, pdev->saved_target_get_color_comp_index); + pgs->get_cmap_procs = pdev->save_get_cmap_procs; + gx_set_cmap_procs(pgs, pdev->target); + gx_device_decache_colors(pdev->target); /* Disable the PDF 1.4 compositor */ - pdf14_disable_clist_device(mem, pis, dev); + pdf14_disable_clist_device(mem, pgs, dev); /* * Make sure that the transfer funtions, etc. are current. */ code = cmd_put_color_mapping( - (gx_device_clist_writer *)(pdev->target), pis); + (gx_device_clist_writer *)(pdev->target), pgs); if (code < 0) return code; break; @@ -6823,8 +7238,10 @@ These need to be written out in the same bands as the group information is written. Hence the passing of the dimensions for the group. */ - code = pdf14_clist_update_params(pdev, pis, true, + code = pdf14_clist_update_params(pdev, pgs, true, (gs_pdf14trans_params_t *)&(pdf14pct->params)); + if (code < 0) + return code; if (pdf14pct->params.Background_components != 0 && pdf14pct->params.Background_components != pdev->color_info.num_components) @@ -6833,83 +7250,190 @@ the group color space. For simplicity, the list item is created even if the color space did not change */ /* First store the current ones */ - pdf14_push_parent_color(dev, pis); - /* Now update the device procs. Not - if we have a sep target though */ - sep_target = (strcmp(pdev->dname, "pdf14clistcustom") == 0) || - (strcmp(pdev->dname, "pdf14clistcmykspot") == 0) || - (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)); - if (!sep_target) - code = pdf14_update_device_color_procs_push_c(dev, - pdf14pct->params.group_color, - pdf14pct->params.icc_hash, pis, - pdf14pct->params.iccprofile); + pdf14_push_parent_color(dev, pgs); + + code = pdf14_update_device_color_procs_push_c(dev, + pdf14pct->params.group_color, + pdf14pct->params.icc_hash, pgs, + pdf14pct->params.iccprofile, false); + if (code < 0) + return code; break; case PDF14_BEGIN_TRANS_MASK: /* We need to update the clist writer device procs based upon the the group color space. For simplicity, the list item is created even if the color space did not change */ /* First store the current ones */ - pdf14_push_parent_color(dev, pis); + if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None) + break; + pdf14_push_parent_color(dev, pgs); + /* If we are playing back from a clist, the iccprofile may need to be loaded */ + if (pdf14pct->params.iccprofile == NULL) { + gs_pdf14trans_params_t *pparams_noconst = (gs_pdf14trans_params_t *)&(pdf14pct->params); + + pparams_noconst->iccprofile = gsicc_read_serial_icc((gx_device *) cdev, + pdf14pct->params.icc_hash); + if (pparams_noconst->iccprofile == NULL) + return gs_throw(-1, "ICC data not found in clist"); + /* Keep a pointer to the clist device */ + pparams_noconst->iccprofile->dev = (gx_device *)cdev; + /* Now we need to load the rest of the profile buffer */ + if (pparams_noconst->iccprofile->buffer == NULL) { + gcmmhprofile_t dummy = gsicc_get_profile_handle_clist(pparams_noconst->iccprofile, mem); + + if (dummy == NULL) + return_error(gs_error_VMerror); + } + } /* Now update the device procs */ - code = pdf14_update_device_color_procs_push_c(dev, + code = pdf14_update_device_color_procs_push_c(dev, pdf14pct->params.group_color, - pdf14pct->params.icc_hash, pis, - pdf14pct->params.iccprofile); - /* Also, if the BC is a value that may end up as something other + pdf14pct->params.icc_hash, pgs, + pdf14pct->params.iccprofile, true); + if (code < 0) + return code; + /* Also, if the BC is a value that may end up as something other than transparent. We must use the parent colors bounding box in determining the range of bands in which this mask can affect. So, if needed change the masks bounding box at this time */ break; - /* When we get a trans group pop, we need to update the color mapping - procs if it was not a sep device */ - case PDF14_END_TRANS_GROUP: - /* We need to update the clist writer device procs based upon the - the group color space. */ - /* First restore our procs */ - sep_target = (strcmp(pdev->dname, "pdf14clistcustom") == 0) || - (strcmp(pdev->dname, "pdf14clistcmykspot") == 0) || - (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)); - if (!sep_target) - code = pdf14_update_device_color_procs_pop_c(dev,pis); - /* We always do this push and pop */ - pdf14_pop_parent_color(dev, pis); + case PDF14_BEGIN_TRANS_TEXT_GROUP: + pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED; + *pcdev = dev; + return 0; /* Never put into clist. Only used during writing */ + case PDF14_END_TRANS_TEXT_GROUP: + if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) { + *pcdev = dev; + return 0; /* Avoids spurious ET calls in interpreter */ + } + pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */ + code = pdf14_update_device_color_procs_pop_c(dev, pgs); + if (code < 0) + return code; break; + case PDF14_END_TRANS_GROUP: case PDF14_END_TRANS_MASK: /* We need to update the clist writer device procs based upon the the group color space. */ - /* First restore our procs */ - code = pdf14_update_device_color_procs_pop_c(dev,pis); - /* Now pop the old one */ - pdf14_pop_parent_color(dev, pis); + code = pdf14_update_device_color_procs_pop_c(dev,pgs); + if (code < 0) + return code; break; case PDF14_PUSH_TRANS_STATE: break; case PDF14_POP_TRANS_STATE: break; case PDF14_PUSH_SMASK_COLOR: - code = pdf14_increment_smask_color(pis,dev); + code = pdf14_increment_smask_color(pgs,dev); *pcdev = dev; return code; /* Note, this are NOT put in the clist */ break; case PDF14_POP_SMASK_COLOR: - code = pdf14_decrement_smask_color(pis,dev); + code = pdf14_decrement_smask_color(pgs,dev); *pcdev = dev; return code; /* Note, this are NOT put in the clist */ break; case PDF14_SET_BLEND_PARAMS: /* If there is a change we go ahead and apply it to the target */ - code = pdf14_clist_update_params(pdev, pis, false, + code = pdf14_clist_update_params(pdev, pgs, false, (gs_pdf14trans_params_t *)&(pdf14pct->params)); *pcdev = dev; return code; break; + case PDF14_ABORT_DEVICE: + break; default: break; /* Pass remaining ops to target */ } } code = dev_proc(pdev->target, create_compositor) - (pdev->target, pcdev, pct, pis, mem, cdev); + (pdev->target, pcdev, pct, pgs, mem, cdev); + /* If we were accumulating into a pdf14-clist-accum device, */ + /* we now have to render the page into it's target device */ + if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE && + pdev->target->stype == &st_pdf14_accum) { + + int y, rows_used; + byte *linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev"); + byte *actual_data; + gx_device *tdev = pdev->target; /* the printer class clist device used to accumulate */ + /* get the target device we want to send the image to */ + gx_device *target = ((pdf14_device *)((gx_device_pdf14_accum *)(tdev))->save_p14dev)->target; + gs_image1_t image; + gs_color_space *pcs; + gx_image_enum_common_t *info; + gx_image_plane_t planes; + gsicc_rendering_param_t render_cond; + cmm_dev_profile_t *dev_profile; + + /* + * Set color space in preparation for sending an image. + */ + code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory); + if (linebuf == NULL || pcs == NULL) + goto put_accum_error; + + /* Need to set this to avoid color management during the + image color render operation. Exception is for the special case + when the destination was CIELAB. Then we need to convert from + default RGB to CIELAB in the put image operation. That will happen + here as we should have set the profile for the pdf14 device to RGB + and the target will be CIELAB */ + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) { + rc_decrement_only_cs(pcs, "pdf14_put_image"); + return code; + } + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, + &(pcs->cmm_icc_profile_data), &render_cond); + /* pcs takes a reference to the profile data it just retrieved. */ + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_create_compositor"); + gsicc_set_icc_range(&(pcs->cmm_icc_profile_data)); + + gs_image_t_init_adjust(&image, pcs, false); + image.ImageMatrix.xx = (float)pdev->width; + image.ImageMatrix.yy = (float)pdev->height; + image.Width = pdev->width; + image.Height = pdev->height; + image.BitsPerComponent = 8; + ctm_only_writable(pgs).xx = (float)pdev->width; + ctm_only_writable(pgs).xy = 0; + ctm_only_writable(pgs).yx = 0; + ctm_only_writable(pgs).yy = (float)pdev->height; + ctm_only_writable(pgs).tx = 0.0; + ctm_only_writable(pgs).ty = 0.0; + code = dev_proc(target, begin_typed_image) (target, + pgs, NULL, + (gs_image_common_t *)&image, + NULL, NULL, NULL, + pgs->memory, &info); + if (code < 0) + goto put_accum_error; + for (y=0; y < tdev->height; y++) { + code = dev_proc(tdev, get_bits)(tdev, y, linebuf, &actual_data); + planes.data = actual_data; + planes.data_x = 0; + planes.raster = tdev->width * tdev->color_info.num_components; + if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0) + goto put_accum_error; + } + info->procs->end_image(info, true); + +put_accum_error: + gs_free_object(pdev->memory, linebuf, "pdf14_put_image"); + /* This will also decrement the device profile */ + rc_decrement_only_cs(pcs, "pdf14_put_image"); + dev_proc(tdev, close_device)(tdev); /* frees the prn_device memory */ + /* Now unhook the clist device and hook to the original so we can clean up */ + gx_device_set_target((gx_device_forward *)pdev, + ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev); + pdev->pclist_device = pdev->target; /* FIXME: is this kosher ? */ + *pcdev = pdev->target; /* pass upwards to switch devices */ + pdev->color_info = target->color_info; /* same as in pdf14_disable_clist */ + gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum"); + return 0; /* DON'T perform set_target */ + } + if (*pcdev != pdev->target) gx_device_set_target((gx_device_forward *)pdev, *pcdev); *pcdev = dev; @@ -6926,23 +7450,23 @@ */ static int pdf14_clist_forward_create_compositor(gx_device * dev, gx_device * * pcdev, - const gs_composite_t * pct, gs_imager_state * pis, + const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem, gx_device *cdev) { pdf14_device *pdev = (pdf14_device *)dev; gx_device * tdev = pdev->target; gx_device * ndev; - int code = 0; + int code; *pcdev = dev; if (gs_is_pdf14trans_compositor(pct)) { const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct; if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE) - return pdf14_clist_create_compositor(dev, &ndev, pct, pis, mem, cdev); + return pdf14_clist_create_compositor(dev, &ndev, pct, pgs, mem, cdev); return 0; } - code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pis, mem, cdev); + code = dev_proc(tdev, create_compositor)(tdev, &ndev, pct, pgs, mem, cdev); if (code < 0) return code; gx_device_set_target((gx_device_forward *)pdev, ndev); @@ -6954,7 +7478,7 @@ * need to send them to the PDF 1.4 compositor on the output side of the clist. */ static int -pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_imager_state * pis, +pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs, bool crop_blend_params, gs_pdf14trans_params_t *group_params) { @@ -6967,29 +7491,29 @@ params.crop_blend_params = crop_blend_params; params.pdf14_op = PDF14_SET_BLEND_PARAMS; - if (pis->blend_mode != pdev->blend_mode) { + if (pgs->blend_mode != pdev->blend_mode) { changed |= PDF14_SET_BLEND_MODE; - params.blend_mode = pdev->blend_mode = pis->blend_mode; + params.blend_mode = pdev->blend_mode = pgs->blend_mode; } - if (pis->text_knockout != pdev->text_knockout) { + if (pgs->text_knockout != pdev->text_knockout) { changed |= PDF14_SET_TEXT_KNOCKOUT; - params.text_knockout = pdev->text_knockout = pis->text_knockout; + params.text_knockout = pdev->text_knockout = pgs->text_knockout; } - if (pis->shape.alpha != pdev->shape) { + if (pgs->shape.alpha != pdev->shape) { changed |= PDF14_SET_SHAPE_ALPHA; - params.shape.alpha = pdev->shape = pis->shape.alpha; + params.shape.alpha = pdev->shape = pgs->shape.alpha; } - if (pis->opacity.alpha != pdev->opacity) { + if (pgs->opacity.alpha != pdev->opacity) { changed |= PDF14_SET_OPACITY_ALPHA; - params.opacity.alpha = pdev->opacity = pis->opacity.alpha; + params.opacity.alpha = pdev->opacity = pgs->opacity.alpha; } - if (pis->overprint != pdev->overprint) { + if (pgs->overprint != pdev->overprint) { changed |= PDF14_SET_OVERPRINT; - params.overprint = pdev->overprint = pis->overprint; + params.overprint = pdev->overprint = pgs->overprint; } - if (pis->overprint_mode != pdev->overprint_mode) { + if (pgs->overprint_mode != pdev->overprint_mode) { changed |= PDF14_SET_OVERPRINT_MODE; - params.overprint_mode = pdev->overprint_mode = pis->overprint_mode; + params.overprint_mode = pdev->overprint_mode = pgs->overprint_mode; } if (crop_blend_params) { params.ctm = group_params->ctm; @@ -7002,11 +7526,11 @@ need to often perform this operation when we are already starting to do a compositor action */ if (changed != 0) { - code = gs_create_pdf14trans(&pct_new, ¶ms, pis->memory); + code = gs_create_pdf14trans(&pct_new, ¶ms, pgs->memory); if (code < 0) return code; code = dev_proc(pdev->target, create_compositor) - (pdev->target, &pcdev, pct_new, (gs_imager_state *)pis, pis->memory, NULL); - gs_free_object(pis->memory, pct_new, "pdf14_clist_update_params"); + (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL); + gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params"); } return code; } @@ -7016,22 +7540,26 @@ * writing the clist. */ static int -pdf14_clist_fill_path(gx_device *dev, const gs_imager_state *pis, +pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { pdf14_clist_device * pdev = (pdf14_clist_device *)dev; - gs_imager_state new_is = *pis; + gs_gstate new_pgs = *pgs; int code; gs_pattern2_instance_t *pinst = NULL; gx_device_forward * fdev = (gx_device_forward *)dev; cmm_dev_profile_t *dev_profile, *fwd_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_profile_t *icc_profile_fwd, *icc_profile_dev; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; code = dev_proc(fdev->target, get_profile)(fdev->target, &fwd_profile); + if (code < 0) + return code; gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd, &render_cond); @@ -7041,10 +7569,10 @@ /* * Ensure that that the PDF 1.4 reading compositor will have the current * blending parameters. This is needed since the fill_rectangle routines - * do not have access to the imager state. Thus we have to pass any + * do not have access to the gs_gstate. Thus we have to pass any * changes explictly. */ - code = pdf14_clist_update_params(pdev, pis, false, NULL); + code = pdf14_clist_update_params(pdev, pgs, false, NULL); if (code < 0) return code; /* If we are doing a shading fill and we are in a transparency group of a @@ -7063,12 +7591,12 @@ clist writer device. */ pinst->saved->trans_device = dev; } - update_lop_for_pdf14(&new_is, pdcolor); - new_is.trans_device = dev; - new_is.has_transparency = true; - code = gx_forward_fill_path(dev, &new_is, ppath, params, pdcolor, pcpath); - new_is.trans_device = NULL; - new_is.has_transparency = false; + update_lop_for_pdf14(&new_pgs, pdcolor); + new_pgs.trans_device = dev; + new_pgs.has_transparency = true; + code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath); + new_pgs.trans_device = NULL; + new_pgs.has_transparency = false; if (pinst != NULL){ pinst->saved->trans_device = NULL; } @@ -7080,23 +7608,23 @@ * writing the clist. */ static int -pdf14_clist_stroke_path(gx_device *dev, const gs_imager_state *pis, +pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, const gx_stroke_params *params, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { pdf14_clist_device * pdev = (pdf14_clist_device *)dev; - gs_imager_state new_is = *pis; + gs_gstate new_pgs = *pgs; int code; gs_pattern2_instance_t *pinst = NULL; /* * Ensure that that the PDF 1.4 reading compositor will have the current * blending parameters. This is needed since the fill_rectangle routines - * do not have access to the imager state. Thus we have to pass any + * do not have access to the gs_gstate. Thus we have to pass any * changes explictly. */ - code = pdf14_clist_update_params(pdev, pis, false, NULL); + code = pdf14_clist_update_params(pdev, pgs, false, NULL); if (code < 0) return code; /* If we are doing a shading stroke and we are in a transparency group of a @@ -7113,12 +7641,12 @@ pinst->saved->trans_device = dev; } - update_lop_for_pdf14(&new_is, pdcolor); - new_is.trans_device = dev; - new_is.has_transparency = true; - code = gx_forward_stroke_path(dev, &new_is, ppath, params, pdcolor, pcpath); - new_is.trans_device = NULL; - new_is.has_transparency = false; + update_lop_for_pdf14(&new_pgs, pdcolor); + new_pgs.trans_device = dev; + new_pgs.has_transparency = true; + code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath); + new_pgs.trans_device = NULL; + new_pgs.has_transparency = false; if (pinst != NULL){ pinst->saved->trans_device = NULL; } @@ -7130,7 +7658,7 @@ * writing the clist. */ static int -pdf14_clist_text_begin(gx_device * dev, gs_imager_state * pis, +pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, @@ -7139,28 +7667,51 @@ pdf14_clist_device * pdev = (pdf14_clist_device *)dev; gs_text_enum_t *penum; int code; + gs_blend_mode_t blend_mode = gs_currentblendmode(pgs); + float opacity = gs_currentopacityalpha(pgs); + bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible); + bool draw = !(text->operation & TEXT_DO_NONE); + if_debug0m('v', memory, "[v]pdf14_clist_text_begin\n"); /* * Ensure that that the PDF 1.4 reading compositor will have the current * blending parameters. This is needed since the fill_rectangle routines - * do not have access to the imager state. Thus we have to pass any + * do not have access to the gs_gstate. Thus we have to pass any * changes explictly. */ - code = pdf14_clist_update_params(pdev, pis, false, NULL); + code = pdf14_clist_update_params(pdev, pgs, false, NULL); if (code < 0) return code; /* Pass text_begin to the target */ - code = gx_forward_text_begin(dev, pis, text, font, path, + code = gx_forward_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, &penum); if (code < 0) return code; + + /* We may need to push a non-isolated transparency group if the following + is true. + 1) We are not currently in one that we pushed for text. This is + is determined by looking at the pdf14 device. + 2) The blend mode is not Normal or the opacity is not 1.0 + 3) Text knockout is set to true + 4) And we are actually drawing text + */ + if (gs_currenttextknockout(pgs) && (blend_issue || opacity != 1.0) && + gs_currenttextrenderingmode(pgs) != 3 && /* don't bother with invisible text */ + pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) { + if (draw) { + code = pdf14_push_text_group(dev, pgs, path, pcpath, blend_mode, opacity, true); + if (code == 0) + pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED; /* Needed during clist writing */ + } + } *ppenum = (gs_text_enum_t *)penum; return code; } static int pdf14_clist_begin_image(gx_device * dev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, @@ -7172,24 +7723,24 @@ /* * Ensure that that the PDF 1.4 reading compositor will have the current * blending parameters. This is needed since the fill_rectangle routines - * do not have access to the imager state. Thus we have to pass any + * do not have access to the gs_gstate. Thus we have to pass any * changes explictly. */ - code = pdf14_clist_update_params(pdev, pis, false, NULL); + code = pdf14_clist_update_params(pdev, pgs, false, NULL); if (code < 0) return code; /* Pass image to the target */ - code = gx_forward_begin_image(dev, pis, pim, format, prect, + code = gx_forward_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); if (code < 0) - return gx_default_begin_image(dev, pis, pim, format, prect, + return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); else return code; } static int -pdf14_clist_begin_typed_image(gx_device * dev, const gs_imager_state * pis, +pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, @@ -7197,8 +7748,8 @@ gx_image_enum_common_t ** pinfo) { pdf14_clist_device * pdev = (pdf14_clist_device *)dev; - int code = 0; - gs_imager_state * pis_noconst = (gs_imager_state *)pis; /* Break 'const'. */ + int code; + gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */ const gs_image_t *pim = (const gs_image_t *)pic; gx_image_enum *penum; gx_color_tile *ptile; @@ -7207,27 +7758,27 @@ /* * Ensure that that the PDF 1.4 reading compositor will have the current * blending parameters. This is needed since the fill_rectangle routines - * do not have access to the imager state. Thus we have to pass any + * do not have access to the gs_gstate. Thus we have to pass any * changes explictly. */ - code = pdf14_clist_update_params(pdev, pis, false, NULL); + code = pdf14_clist_update_params(pdev, pgs, false, NULL); if (code < 0) return code; /* Pass image to the target */ - /* Do a quick change to the imager state so that if we can return with -1 in + /* Do a quick change to the gs_gstate so that if we can return with -1 in case the clist writer cannot handle this image itself. In such a case, we want to make sure we dont use the target device. I don't necc. like doing it this way. Probably need to go back and do something a bit more elegant. */ - pis_noconst->has_transparency = true; - pis_noconst->trans_device = dev; + pgs_noconst->has_transparency = true; + pgs_noconst->trans_device = dev; /* If we are filling an image mask with a pattern that has a transparency then we need to do some special handling */ if (pim->ImageMask) { if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) { if( gx_pattern1_get_transptr(pdcolor) != NULL){ - if (dev->procs.begin_image != pdf14_clist_begin_image) { + if (dev_proc(dev, begin_image) != pdf14_clist_begin_image) { ptile = pdcolor->colors.pattern.p_tile; /* Set up things in the ptile so that we get the proper blending etc */ @@ -7241,12 +7792,16 @@ ptile->ttrans->is_additive = false; } /* Set the blending mode in the ptile based upon the current - setting in the imager state */ - ptile->ttrans->blending_mode = pis->blend_mode; + setting in the gs_gstate */ + ptile->blending_mode = pgs->blend_mode; /* Set the procs so that we use the proper filling method. */ /* Let the imaging stuff get set up */ - code = gx_default_begin_typed_image(dev, pis, pmat, pic, - prect, pdcolor,pcpath, mem, pinfo); + code = gx_default_begin_typed_image(dev, pgs, pmat, pic, + prect, pdcolor, + pcpath, mem, pinfo); + if (code < 0) + return code; + penum = (gx_image_enum *) *pinfo; /* Apply inverse of the image matrix to our image size to get our bounding box. */ @@ -7255,10 +7810,10 @@ bbox_in.q.x = pim->Width; bbox_in.q.y = pim->Height; code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix), - &bbox_out); + &bbox_out); if (code < 0) return code; /* Set up a compositor action for pushing the group */ - if_debug0m('v', pis->memory, "[v]Pushing special trans group for image\n"); + if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n"); tgp.Isolated = true; tgp.Knockout = false; tgp.mask_id = 0; @@ -7268,14 +7823,15 @@ tgp.icc_hashcode = 0; tgp.group_color_numcomps = ptile->ttrans->n_chan-1; tgp.ColorSpace = NULL; + tgp.text_group = 0; /* This will handle the compositor command */ - gs_begin_transparency_group((gs_state *) pis_noconst, &tgp, + gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp, &bbox_out); ptile->ttrans->image_render = penum->render; penum->render = &pdf14_pattern_trans_render; ptile->trans_group_popped = false; - pis_noconst->has_transparency = false; - pis_noconst->trans_device = NULL; + pgs_noconst->has_transparency = false; + pgs_noconst->trans_device = NULL; return code; } } @@ -7283,21 +7839,83 @@ } /* This basically tries high level images for clist. If that fails then we do the default */ - code = gx_forward_begin_typed_image(dev, pis, pmat, + code = gx_forward_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); if (code < 0){ - code = gx_default_begin_typed_image(dev, pis, pmat, pic, prect, + code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); - pis_noconst->has_transparency = false; - pis_noconst->trans_device = NULL; + pgs_noconst->has_transparency = false; + pgs_noconst->trans_device = NULL; return code; } else { - pis_noconst->has_transparency = false; - pis_noconst->trans_device = NULL; + pgs_noconst->has_transparency = false; + pgs_noconst->trans_device = NULL; return code; } } +static int +pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster, + gx_bitmap_id id, int x, int y, int w, int h, int plane_height) +{ + int code; + + code = gx_forward_copy_planes(dev, data, data_x, raster, id, + x, y, w, h, plane_height); + return code; +} + +static int +gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev, + gx_device *dev, const gs_pdf14trans_t *pdf14pct) +{ + int code; + pdf14_clist_device *p14dev; + gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer; + + code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct); + /* + * Set the color_info of the clist device to match the compositing + * device. We will restore it when the compositor is popped. + * See pdf14_clist_create_compositor for the restore. Do the + * same with the gs_gstate's get_cmap_procs. We do not want + * the gs_gstate to use transfer functions on our color values. + * The transfer functions will be applied at the end after we + * have done our PDF 1.4 blend operations. + */ + p14dev = (pdf14_clist_device *)(*pcdev); + p14dev->saved_target_color_info = dev->color_info; + dev->color_info = (*pcdev)->color_info; + /* Make sure that we keep the anti-alias information though */ + dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias; + p14dev->color_info.anti_alias = dev->color_info.anti_alias; + + /* adjust the clist_color_info now */ + cdev->clist_color_info.depth = p14dev->color_info.depth; + cdev->clist_color_info.polarity = p14dev->color_info.polarity; + cdev->clist_color_info.num_components = p14dev->color_info.num_components; + cdev->clist_color_info.max_color = p14dev->color_info.max_color; + cdev->clist_color_info.max_gray = p14dev->color_info.max_gray; + + p14dev->saved_target_encode_color = dev_proc(dev, encode_color); + p14dev->saved_target_decode_color = dev_proc(dev, decode_color); + set_dev_proc(dev, encode_color, p14dev->my_encode_color); + set_dev_proc(p14dev, encode_color, p14dev->my_encode_color); + set_dev_proc(dev, decode_color, p14dev->my_decode_color); + set_dev_proc(p14dev, decode_color, p14dev->my_decode_color); + p14dev->saved_target_get_color_mapping_procs = + dev_proc(dev, get_color_mapping_procs); + p14dev->saved_target_get_color_comp_index = + dev_proc(dev, get_color_comp_index); + set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs); + set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs); + set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index); + set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index); + p14dev->save_get_cmap_procs = pgs->get_cmap_procs; + pgs->get_cmap_procs = pdf14_get_cmap_procs; + gx_set_cmap_procs(pgs, dev); + return code; +} /* * When we push a PDF 1.4 transparency compositor onto the clist, we also need * to create a compositing device for clist writing. The primary purpose of @@ -7308,61 +7926,16 @@ */ static int c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev, - gx_device ** pcdev, gs_imager_state * pis, gs_memory_t * mem) + gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem) { gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer; const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte; - pdf14_clist_device * p14dev; int code = 0; - p14dev = (pdf14_clist_device *)(*pcdev); /* We only handle the push/pop operations */ switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: - code = pdf14_create_clist_device(mem, pis, pcdev, dev, pdf14pct); - /* - * Set the color_info of the clist device to match the compositing - * device. We will restore it when the compositor is popped. - * See pdf14_clist_create_compositor for the restore. Do the - * same with the imager state's get_cmap_procs. We do not want - * the imager state to use transfer functions on our color values. - * The transfer functions will be applied at the end after we - * have done our PDF 1.4 blend operations. - */ - p14dev = (pdf14_clist_device *)(*pcdev); - p14dev->saved_target_color_info = dev->color_info; - dev->color_info = (*pcdev)->color_info; - /* Make sure that we keep the anti-alias information though */ - dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias; - p14dev->color_info.anti_alias = dev->color_info.anti_alias; - - /* adjust the clist_color_info now */ - cdev->clist_color_info.depth = p14dev->color_info.depth; - cdev->clist_color_info.polarity = p14dev->color_info.polarity; - cdev->clist_color_info.num_components = p14dev->color_info.num_components; - cdev->clist_color_info.max_color = p14dev->color_info.max_color; - cdev->clist_color_info.max_gray = p14dev->color_info.max_gray; - - p14dev->saved_target_encode_color = dev->procs.encode_color; - p14dev->saved_target_decode_color = dev->procs.decode_color; - dev->procs.encode_color = p14dev->procs.encode_color = - p14dev->my_encode_color; - dev->procs.decode_color = p14dev->procs.decode_color = - p14dev->my_decode_color; - p14dev->saved_target_get_color_mapping_procs = - dev->procs.get_color_mapping_procs; - p14dev->saved_target_get_color_comp_index = - dev->procs.get_color_comp_index; - dev->procs.get_color_mapping_procs = - p14dev->procs.get_color_mapping_procs = - p14dev->my_get_color_mapping_procs; - dev->procs.get_color_comp_index = - p14dev->procs.get_color_comp_index = - p14dev->my_get_color_comp_index; - p14dev->save_get_cmap_procs = pis->get_cmap_procs; - pis->get_cmap_procs = pdf14_get_cmap_procs; - gx_set_cmap_procs(pis, dev); - return code; + return gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct); case PDF14_POP_DEVICE: # if 0 /* Disabled because pdf14_clist_create_compositor does so. */ @@ -7370,9 +7943,9 @@ * Ensure that the tranfer functions, etc. are current before we * dump our transparency image to the output device. */ - if (pis->dev_ht) + if (pgs->dev_ht) code = cmd_put_halftone((gx_device_clist_writer *) - (((pdf14_clist_device *)dev)->target), pis->dev_ht); + (((pdf14_clist_device *)dev)->target), pgs->dev_ht); # else code = 0; # endif @@ -7390,12 +7963,13 @@ softmask group through which this transparency group must be rendered. Store it now. */ pdf14pct_noconst->params.mask_id = cdev->mask_id; - if_debug1m('v', pis->memory, + if_debug1m('v', pgs->memory, "[v]c_pdf14trans_clist_write_update group mask_id=%d \n", cdev->mask_id); } break; case PDF14_END_TRANS_GROUP: + case PDF14_END_TRANS_TEXT_GROUP: code = 0; /* A place for breakpoint. */ break; case PDF14_BEGIN_TRANS_MASK: @@ -7410,7 +7984,7 @@ pdf14pct_noconst = (gs_pdf14trans_t *) pcte; pdf14pct_noconst->params.mask_id = cdev->mask_id; - if_debug1m('v', pis->memory, + if_debug1m('v', pgs->memory, "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n", cdev->mask_id); } @@ -7424,10 +7998,15 @@ case PDF14_POP_TRANS_STATE: code = 0; /* A place for breakpoint. */ break; + case PDF14_ABORT_DEVICE: + code = 0; + break; case PDF14_PUSH_SMASK_COLOR: + *pcdev = dev; return 0; break; case PDF14_POP_SMASK_COLOR: + *pcdev = dev; return 0; break; default: @@ -7438,7 +8017,7 @@ return code; /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and apply_create_compositor. */ - code = gs_imager_setmatrix(&cdev->imager_state, &pdf14pct->params.ctm); + code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm); /* Wrote an extra ctm. */ cmd_clear_known(cdev, ctm_known); @@ -7455,43 +8034,41 @@ */ static int c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev, - gx_device * tdev, gs_imager_state * pis, gs_memory_t * mem) + gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem) { pdf14_device * p14dev = (pdf14_device *)tdev; gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte; gs_devn_params * pclist_devn_params; gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev; cmm_profile_t *cl_icc_profile, *p14_icc_profile; - gsicc_rendering_param_t render_cond; - int code; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; - code = dev_proc(cdev, get_profile)(cdev, &dev_profile); + dev_proc(cdev, get_profile)(cdev, &dev_profile); gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile, &render_cond); - code = dev_proc(p14dev, get_profile)((gx_device *)p14dev, &dev_profile); + + /* If we are using the blending color space, then be sure to use that. */ + if (p14dev->using_blend_cs && dev_profile->blend_profile != NULL) + cl_icc_profile = dev_profile->blend_profile; + + dev_proc(p14dev, get_profile)((gx_device *)p14dev, &dev_profile); gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile, &render_cond); /* * We only handle the push/pop operations. Save and restore the color_info - * field for the clist device. (This is needed since the process color + * field for the clist device. This is needed since the process color * model of the clist device needs to match the PDF 1.4 compositing * device. */ switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: - /* If the CMM is not threadsafe, then the pdf14 device actually - needs to inherit the ICC profile from the clist thread device - not the target device. */ -#if !CMM_THREAD_SAFE - gx_monitor_enter(p14_icc_profile->lock); - rc_assign(p14dev->icc_struct->device_profile[0], cl_icc_profile, - "c_pdf14trans_clist_read_update"); - gx_monitor_leave(p14_icc_profile->lock); -#endif + gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update"); + gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[0], -1, "c_pdf14trans_clist_read_update"); + p14dev->icc_struct->device_profile[0] = cl_icc_profile; /* * If we are blending using spot colors (i.e. the output device - * supports spot colors) then we need to transfer compressed + * supports spot colors) then we need to transfer * color info from the clist PDF 1.4 compositing reader device * to the clist writer PDF 1.4 compositing device. * This info was transfered from that device to the output @@ -7517,15 +8094,19 @@ if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) { p14dev->color_info.num_components = num_comp; } else { - p14dev->color_info.num_components = - p14dev->devn_params.num_std_colorant_names + - p14dev->devn_params.page_spot_colors; + /* if page_spot_colors < 0, this will be wrong, so don't update num_components */ + if (p14dev->devn_params.page_spot_colors >= 0) { + p14dev->color_info.num_components = + p14dev->devn_params.num_std_colorant_names + + p14dev->devn_params.page_spot_colors; + } } - /* Transfer the data for the compressed color encoding. + /* limit the num_components to the max. */ + if (p14dev->color_info.num_components > p14dev->color_info.max_components) + p14dev->color_info.num_components = p14dev->color_info.max_components; + /* Transfer the data for the spot color names But we have to free what may be there before we do this */ devn_free_params((gx_device*) p14dev); - p14dev->devn_params.compressed_color_list = - pclist_devn_params->pdf14_compressed_color_list; p14dev->devn_params.separations = pclist_devn_params->pdf14_separations; p14dev->free_devicen = false; /* to avoid freeing the clist ones */ @@ -7537,6 +8118,7 @@ before reopening the device */ if (p14dev->ctx != NULL) { pdf14_ctx_free(p14dev->ctx); + p14dev->ctx = NULL; } dev_proc(tdev, open_device) (tdev); } @@ -7546,17 +8128,11 @@ happens to be something like CIELAB. Then we will blend in RGB (unless a trans group is specified) */ if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) { - cl_icc_profile = - gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash); + gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[0], -1, "c_pdf14trans_clist_read_update"); + /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */ + p14dev->icc_struct->device_profile[0] = gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash); /* Keep a pointer to the clist device */ - cl_icc_profile->dev = (gx_device *) cdev; - gx_monitor_enter(p14_icc_profile->lock); - rc_assign(p14dev->icc_struct->device_profile[0], cl_icc_profile, - "c_pdf14trans_clist_read_update"); - /* Initial ref count was ok. remove increment from assign */ - rc_decrement(p14dev->icc_struct->device_profile[0], - "c_pdf14trans_clist_read_update"); - gx_monitor_leave(p14_icc_profile->lock); + p14dev->icc_struct->device_profile[0]->dev = (gx_device *) cdev; } break; @@ -7586,24 +8162,27 @@ switch (pdf14pct->params.pdf14_op) { case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */ case PDF14_POP_DEVICE: return ALLBANDS; /* Applies to all bands. */ - + case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */ case PDF14_BEGIN_TRANS_GROUP: { gs_int_rect rect; - int code; - code = pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm, - &pdf14pct->params.bbox, &rect); - /* We have to crop this by the parent object. */ - *ry = max(rect.p.y, cropping_min); - *rheight = min(rect.q.y, cropping_max) - *ry; + /* Text group always uses parents size*/ + if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) { + *ry = cropping_min; + *rheight = cropping_max - *ry; + } else { + pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm, + &pdf14pct->params.bbox, &rect); + /* We have to crop this by the parent object. */ + *ry = max(rect.p.y, cropping_min); + *rheight = min(rect.q.y, cropping_max) - *ry; + } return PUSHCROP; /* Push cropping. */ } case PDF14_BEGIN_TRANS_MASK: { gs_int_rect rect; - int code; - code = - pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm, + pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm, &pdf14pct->params.bbox, &rect); /* We have to crop this by the parent object and worry about the BC outside the range, except for image SMask which don't affect areas outside the image */ @@ -7620,16 +8199,21 @@ OUTSIDE the bounding box of the soft mask */ *ry = cropping_min; *rheight = cropping_max - cropping_min; - return PUSHCROP; /* Push cropping. */ + if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None) + return SAMEAS_PUSHCROP_BUTNOPUSH; + else + return PUSHCROP; /* Push cropping. */ } } case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */ + case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */ case PDF14_END_TRANS_MASK: return POPCROP; /* Pop the cropping */ case PDF14_PUSH_TRANS_STATE: return CURRBANDS; case PDF14_POP_TRANS_STATE: return CURRBANDS; case PDF14_SET_BLEND_PARAMS: return ALLBANDS; case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */ case PDF14_POP_SMASK_COLOR: return POPCROP; /* Pop the cropping */ + case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */ } return ALLBANDS; } @@ -7643,13 +8227,14 @@ * Notes: There are currently three different versions of The PDF 1.4 * transparency compositor device. The choice of which one is being used * depends upon the process color model of the output device. This procedure - * is only used if the output (target) device uses a CMYK plus spot color - * process color model. + * is only used if the output (target) device uses a CMYK, or RGB or Gray + * plus spot color process color model. * * Parameters: * dev - pointer to device data structure. * pname - pointer to name (zero termination not required) * nlength - length of the name + * number of process colorants (either 1, 3, or 4) * * This routine returns a positive value (0 to n) which is the device colorant * number if the name is found. It returns GX_DEVICE_COLOR_MAX_COMPONENTS if @@ -7657,16 +8242,39 @@ * It returns a negative value if not found. */ static int -pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname, - int name_size, int component_type) +pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname, + int name_size, int component_type, int num_process_colors) { - pdf14_device * pdev = (pdf14_device *) dev; - gx_device * tdev = pdev->target; - gs_devn_params * pdevn_params = &pdev->devn_params; - gs_separations * pseparations = &pdevn_params->separations; + pdf14_device *pdev = (pdf14_device *)dev; + gx_device *tdev = pdev->target; + gs_devn_params *pdevn_params = &pdev->devn_params; + gs_separations *pseparations; int comp_index; - dev_proc_get_color_comp_index(*target_get_color_comp_index) = - dev_proc(tdev, get_color_comp_index); + dev_proc_get_color_comp_index(*target_get_color_comp_index); + int offset = 4 - num_process_colors; + + while (tdev->child) { + tdev = tdev->child; + } + /* If something has gone wrong and this is no longer the pdf14 compositor, */ + /* get the devn_params from the target to avoid accessing using the wrong */ + /* pointer. Bug 696372. */ + if (tdev == (gx_device *)pdev) + pdevn_params = dev_proc(pdev, ret_devn_params)(dev); + pseparations = &pdevn_params->separations; + /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation + * where we are in a blend color space that is RGB or Gray based and we + * have a spot colorant. If the spot colorant name is Cyan, Magenta + * Yellow or Black, then we should use the alternate tint transform */ + if (num_process_colors < 4) { + int k; + for (k = 0; k < 4; k++) { + if (strncmp(pname, pdev->devn_params.std_colorant_names[k], name_size) == 0) + return -1; + } + } + + target_get_color_comp_index = dev_proc(tdev, get_color_comp_index); /* The pdf14_clist_create_compositor may have set the color procs. We need the real target procs */ @@ -7674,67 +8282,93 @@ target_get_color_comp_index = ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index; /* - * If this is not a separation name then simply forward it to the target - * device. - */ + * If this is not a separation name then simply forward it to the target + * device. + */ if (component_type == NO_COMP_NAME_TYPE) return (*target_get_color_comp_index)(tdev, pname, name_size, component_type); /* - * Check if the component is in either the process color model list - * or in the SeparationNames list. - */ - comp_index = check_pcm_and_separation_names(dev, pdevn_params, - pname, name_size, component_type); + * Check if the component is in either the process color model list + * or in the SeparationNames list. + */ + comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname, + name_size, component_type); /* - * Return the colorant number if we know this name. - */ + * Return the colorant number if we know this name. Note adjustment for + * compensating of blend color space. + */ if (comp_index >= 0) - return comp_index; + return comp_index - offset; /* - * If we do not know this color, check if the output (target) device does. - */ + * If we do not know this color, check if the output (target) device does. + */ comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type); /* - * Ignore color if unknown to the output device or if color is not being - * imaged due to the SeparationOrder device parameter. - */ + * Ignore color if unknown to the output device or if color is not being + * imaged due to the SeparationOrder device parameter. + */ if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS) - return comp_index; + return comp_index - offset; /* - * This is a new colorant. Add it to our list of colorants. - */ + * This is a new colorant. Add it to our list of colorants. + */ if (pseparations->num_separations < GX_DEVICE_COLOR_MAX_COMPONENTS - 1) { int sep_num = pseparations->num_separations++; int color_component_number; byte * sep_name; sep_name = gs_alloc_bytes(dev->memory->stable_memory, - name_size, "pdf14_cmykspot_get_color_comp_index"); + name_size, "pdf14_spot_get_color_comp_index"); memcpy(sep_name, pname, name_size); pseparations->names[sep_num].size = name_size; pseparations->names[sep_num].data = sep_name; - color_component_number = sep_num + pdevn_params->num_std_colorant_names; - if (color_component_number >= dev->color_info.num_components) + color_component_number = sep_num + num_process_colors; + if (color_component_number >= dev->color_info.max_components) color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS; else pdevn_params->separation_order_map[color_component_number] = - color_component_number; + color_component_number; return color_component_number; } return GX_DEVICE_COLOR_MAX_COMPONENTS; } + +/* CMYK process + spots */ +static int +pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname, + int name_size, int component_type) +{ + return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4); +} + +/* RGB process + spots */ +static int +pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname, + int name_size, int component_type) +{ + return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3); +} + +/* Gray process + spots */ +static int +pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname, + int name_size, int component_type) +{ + return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1); +} + /* These functions keep track of when we are dealing with soft masks. In such a case, we set the default color profiles to ones that ensure proper soft mask rendering. */ static int -pdf14_increment_smask_color(gs_imager_state * pis, gx_device * dev) +pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev) { pdf14_device * pdev = (pdf14_device *) dev; pdf14_smaskcolor_t *result; - gsicc_smask_t *smask_profiles = pis->icc_manager->smask_profiles; + gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles; int k; /* See if we have profiles already in place. Note we also have to @@ -7745,15 +8379,15 @@ which also has a transparency mask. The state of the icc_manager is that it already has done the swap and there is no need to fool with any of this while dealing with the soft mask within the pattern */ - if (pdev->smaskcolor == NULL && pis->icc_manager->smask_profiles != NULL && - pis->icc_manager->smask_profiles->swapped) { + if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL && + pgs->icc_manager->smask_profiles->swapped) { return 0; } if (pdev->smaskcolor != NULL) { pdev->smaskcolor->ref_count++; if_debug1m(gs_debug_flag_icc, dev->memory, "[icc] Increment smask color now %d\n", - pdev->smaskcolor->ref_count); + pdev->smaskcolor->ref_count); } else { /* Allocate and swap out the current profiles. The softmask profiles should already be in place */ @@ -7764,55 +8398,55 @@ result->profiles = gsicc_new_iccsmask(pdev->memory); if (result->profiles == NULL ) return(-1); pdev->smaskcolor = result; - /* Theoretically there should not be any reason to change ref counts - on the profiles for a well-formed PDF with clean soft mask groups. - The only issue could be if the graphic state is popped while we - are still within a softmask group. */ - result->profiles->smask_gray = pis->icc_manager->default_gray; - result->profiles->smask_rgb = pis->icc_manager->default_rgb; - result->profiles->smask_cmyk = pis->icc_manager->default_cmyk; - pis->icc_manager->default_gray = smask_profiles->smask_gray; - pis->icc_manager->default_rgb = smask_profiles->smask_rgb; - pis->icc_manager->default_cmyk = smask_profiles->smask_cmyk; - pis->icc_manager->smask_profiles->swapped = true; - if_debug0m(gs_debug_flag_icc, pis->memory, + + result->profiles->smask_gray = pgs->icc_manager->default_gray; + result->profiles->smask_rgb = pgs->icc_manager->default_rgb; + result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk; + pgs->icc_manager->default_gray = smask_profiles->smask_gray; + gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color"); + pgs->icc_manager->default_rgb = smask_profiles->smask_rgb; + gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color"); + pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk; + gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color"); + pgs->icc_manager->smask_profiles->swapped = true; + if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Initial creation of smask color. Ref count 1\n"); pdev->smaskcolor->ref_count = 1; /* We also need to update the profile that is currently in the color spaces of the graphic state. Otherwise this can be referenced, which will result in a mismatch. What we want to do is see if it was the original default and only swap in that case. */ - if (pis->is_gstate) { - gs_state *pgs = (gs_state*) pis; - for (k = 0; k < 2; k++) { - gs_color_space *pcs = pgs->color[k].color_space; - cmm_profile_t *profile = pcs->cmm_icc_profile_data; - if (profile != NULL) { - switch(profile->data_cs) { - case gsGRAY: - if (profile->hashcode == - result->profiles->smask_gray->hashcode) { - profile = pis->icc_manager->default_gray; - } - break; - case gsRGB: - if (profile->hashcode == - result->profiles->smask_rgb->hashcode) { - profile = pis->icc_manager->default_rgb; - } - break; - case gsCMYK: - if (profile->hashcode == - result->profiles->smask_cmyk->hashcode) { - profile = pis->icc_manager->default_cmyk; - } - break; - default: + for (k = 0; k < 2; k++) { + gs_color_space *pcs = pgs->color[k].color_space; + cmm_profile_t *profile = pcs->cmm_icc_profile_data; + if (profile != NULL) { + switch(profile->data_cs) { + case gsGRAY: + if (profile->hashcode == + result->profiles->smask_gray->hashcode) { + profile = pgs->icc_manager->default_gray; + } + break; + case gsRGB: + if (profile->hashcode == + result->profiles->smask_rgb->hashcode) { + profile = pgs->icc_manager->default_rgb; + } + break; + case gsCMYK: + if (profile->hashcode == + result->profiles->smask_cmyk->hashcode) { + profile = pgs->icc_manager->default_cmyk; + } + break; + default: - break; - } - rc_assign(pcs->cmm_icc_profile_data, profile, - "pdf14_increment_smask_color"); + break; + } + if (pcs->cmm_icc_profile_data != profile) { + gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color"); + pcs->cmm_icc_profile_data = profile; } } } @@ -7821,71 +8455,81 @@ } static int -pdf14_decrement_smask_color(gs_imager_state * pis, gx_device * dev) +pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev) { pdf14_device * pdev = (pdf14_device *) dev; pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor; - gsicc_manager_t *icc_manager = pis->icc_manager; + gsicc_manager_t *icc_manager = pgs->icc_manager; int k; /* See comment in pdf14_increment_smask_color to understand this one */ - if (pdev->smaskcolor == NULL && pis->icc_manager->smask_profiles != NULL && - pis->icc_manager->smask_profiles->swapped) { + if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL && + pgs->icc_manager->smask_profiles->swapped) { return 0; } if (smaskcolor != NULL) { smaskcolor->ref_count--; - if_debug1m(gs_debug_flag_icc, pis->memory, + if_debug1m(gs_debug_flag_icc, pgs->memory, "[icc] Decrement smask color. Now %d\n", - smaskcolor->ref_count); + smaskcolor->ref_count); if (smaskcolor->ref_count == 0) { - if_debug0m(gs_debug_flag_icc, pis->memory, "[icc] Reset smask color.\n"); + if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n"); /* Lets return the profiles and clean up */ /* First see if we need to "reset" the profiles that are in the graphic state */ - if (pis->is_gstate) { - gs_state *pgs = (gs_state*) pis; - if_debug0m(gs_debug_flag_icc, pis->memory, "[icc] Reseting graphic state color spaces\n"); - for (k = 0; k < 2; k++) { - gs_color_space *pcs = pgs->color[k].color_space; - cmm_profile_t *profile = pcs->cmm_icc_profile_data; - if (profile != NULL) { - switch(profile->data_cs) { - case gsGRAY: - if (profile->hashcode == - pis->icc_manager->default_gray->hashcode) { - profile = - smaskcolor->profiles->smask_gray; - } - break; - case gsRGB: - if (profile->hashcode == - pis->icc_manager->default_rgb->hashcode) { - profile = - smaskcolor->profiles->smask_rgb; - } - break; - case gsCMYK: - if (profile->hashcode == - pis->icc_manager->default_cmyk->hashcode) { - profile = - smaskcolor->profiles->smask_cmyk; - } - break; - default: + if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n"); + for (k = 0; k < 2; k++) { + gs_color_space *pcs = pgs->color[k].color_space; + cmm_profile_t *profile = pcs->cmm_icc_profile_data; + if (profile != NULL) { + switch(profile->data_cs) { + case gsGRAY: + if (profile->hashcode == + pgs->icc_manager->default_gray->hashcode) { + profile = + smaskcolor->profiles->smask_gray; + } + break; + case gsRGB: + if (profile->hashcode == + pgs->icc_manager->default_rgb->hashcode) { + profile = + smaskcolor->profiles->smask_rgb; + } + break; + case gsCMYK: + if (profile->hashcode == + pgs->icc_manager->default_cmyk->hashcode) { + profile = + smaskcolor->profiles->smask_cmyk; + } + break; + default: - break; - } - rc_assign(pcs->cmm_icc_profile_data, profile, - "pdf14_decrement_smask_color"); + break; + } + if (pcs->cmm_icc_profile_data != profile) { + gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color"); + pcs->cmm_icc_profile_data = profile; } } } - /* Decrement handled in pdf14_free_smask_color */ + + gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color"); icc_manager->default_gray = smaskcolor->profiles->smask_gray; + gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color"); icc_manager->default_rgb = smaskcolor->profiles->smask_rgb; + gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color"); icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk; icc_manager->smask_profiles->swapped = false; + /* We didn't increment the reference count when we assigned these + * so NULL them to avoid decrementing when smaskcolor is freed + */ + smaskcolor->profiles->smask_gray = + smaskcolor->profiles->smask_rgb = + smaskcolor->profiles->smask_cmyk = NULL; + pdf14_free_smask_color(pdev); } } @@ -7895,14 +8539,11 @@ static void pdf14_free_smask_color(pdf14_device * pdev) { - gsicc_smask_t *profiles; - if (pdev->smaskcolor != NULL) { if ( pdev->smaskcolor->profiles != NULL) { - profiles = pdev->smaskcolor->profiles; - /* Do not decrement the softmask enties. They will remain - in the icc_manager softmask member. They were not - incremented when moved here */ + /* Do not decrement the profiles - the references were moved + here and moved back again, so the ref counts don't change + */ gs_free_object(pdev->memory, pdev->smaskcolor->profiles, "pdf14_free_smask_color"); } @@ -7911,6 +8552,25 @@ } } +void +pdf14_device_finalize(const gs_memory_t *cmem, void *vptr) +{ + gx_device * const dev = (gx_device *)vptr; + pdf14_device * pdev = (pdf14_device *)dev; + + pdf14_cleanup_parent_color_profiles (pdev); + + if (pdev->ctx) { + pdf14_ctx_free(pdev->ctx); + pdev->ctx = NULL; + } + + while (pdev->trans_group_parent_cmap_procs) { + pdf14_pop_parent_color(dev, NULL); + } + gx_device_finalize(cmem, vptr); +} + #if DUMP_MASK_STACK static void diff -Nru ghostscript-9.10~dfsg/base/gdevp14.h ghostscript-9.25~dfsg+1/base/gdevp14.h --- ghostscript-9.10~dfsg/base/gdevp14.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevp14.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Definitions and interface for PDF 1.4 rendering device */ @@ -58,7 +58,7 @@ * output device as an image. */ int (* put_image)(gx_device * dev, - gs_imager_state * pis, gx_device * target); + gs_gstate * pgs, gx_device * target); } pdf14_procs_s; typedef pdf14_procs_s pdf14_procs_t; @@ -111,7 +111,7 @@ byte depth; /* used in clist writer cmd_put_color */ uint max_gray; /* Used to determine if device halftones */ uint max_color; /* Causes issues if these are not maintained */ - const gx_color_map_procs *(*get_cmap_procs)(const gs_imager_state *, + const gx_color_map_procs *(*get_cmap_procs)(const gs_gstate *, const gx_device *); const gx_cm_color_map_procs *(*parent_color_mapping_procs)(const gx_device *); gx_color_index (*encode)(gx_device *, const gx_color_value value[]); @@ -127,13 +127,13 @@ struct pdf14_buf_s { pdf14_buf *saved; - + byte *backdrop; /* This is needed for proper non-isolated knockout support */ bool isolated; bool knockout; byte alpha; byte shape; gs_blend_mode_t blend_mode; - + int num_spots; /* helpful when going between Gray+spots, RGB+spots, CMYK+spots */ bool has_alpha_g; bool has_shape; bool has_tags; @@ -146,10 +146,12 @@ int rowstride; int planestride; - int n_chan; /* number of pixel planes including alpha */ + int n_chan; /* number of pixel planes including alpha */ int n_planes; /* total number of planes including alpha, shape, alpha_g */ byte *data; byte *transfer_fn; + int matte_num_comps; + byte *matte; /* actually floats */ gs_int_rect dirty; pdf14_mask_t *mask_stack; bool idle; @@ -160,6 +162,7 @@ pdf14_parent_color_t *parent_color_info_procs; gs_transparency_color_t color_space; /* Different groups can have different spaces for blending */ + gs_memory_t *memory; }; typedef struct pdf14_smaskcolor_s { @@ -183,9 +186,9 @@ typedef struct gs_devn_params_s gs_devn_params; #endif -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_device_DEFINED @@ -224,11 +227,13 @@ bool text_knockout; bool overprint; bool overprint_mode; - bool blendspot; + int text_group; gx_color_index drawn_comps; /* Used for overprinting. Passed from overprint compositor */ gx_device * pclist_device; - bool free_devicen; /* Used to avoid freeing a deviceN parameter from target clist device */ - const gx_color_map_procs *(*save_get_cmap_procs)(const gs_imager_state *, + bool free_devicen; /* Used to avoid freeing a deviceN parameter from target clist device */ + bool sep_device; + bool using_blend_cs; + const gx_color_map_procs *(*save_get_cmap_procs)(const gs_gstate *, const gx_device *); gx_device_color_info saved_target_color_info; dev_proc_encode_color(*saved_target_encode_color); @@ -255,7 +260,7 @@ /* * Send a PDF 1.4 transparency compositor action to the specified device. */ -int send_pdf14trans(gs_imager_state * pis, gx_device * dev, +int send_pdf14trans(gs_gstate * pgs, gx_device * dev, gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem); /* @@ -285,4 +290,9 @@ /* Needed so that we can set the monitoring in the target device */ int gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring); +/* When playing back the clist, we need to know if the buffer device is compatible */ +/* with the pdf14 compositor that was used when writing the clist. Colorspace and */ +/* depth are critical since these must match when reading back colors. */ +bool pdf14_ok_to_optimize(gx_device *bdev); + #endif /* gdevp14_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevpccm.c ghostscript-9.25~dfsg+1/base/gdevpccm.c --- ghostscript-9.10~dfsg/base/gdevpccm.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevpccm.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Support routines for PC color mapping */ diff -Nru ghostscript-9.10~dfsg/base/gdevpccm.h ghostscript-9.25~dfsg+1/base/gdevpccm.h --- ghostscript-9.10~dfsg/base/gdevpccm.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevpccm.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gdevpipe.c ghostscript-9.25~dfsg+1/base/gdevpipe.c --- ghostscript-9.10~dfsg/base/gdevpipe.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevpipe.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -29,7 +29,7 @@ static iodev_proc_fclose(pipe_fclose); const gx_io_device gs_iodev_pipe = { "%pipe%", "Special", - {iodev_no_init, iodev_no_open_device, + {iodev_no_init, iodev_no_finit, iodev_no_open_device, NULL /*iodev_os_open_file */ , pipe_fopen, pipe_fclose, iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status, iodev_no_enumerate_files, NULL, NULL, @@ -43,6 +43,9 @@ pipe_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) { +#ifdef GS_NO_FILESYSTEM + return 0; +#else errno = 0; /* * Some platforms allow opening a pipe with a '+' in the access @@ -60,11 +63,14 @@ if (rfname != NULL) strcpy(rfname, fname); return 0; +#endif } static int pipe_fclose(gx_io_device * iodev, FILE * file) { +#ifndef GS_NO_FILESYSTEM pclose(file); +#endif return 0; } diff -Nru ghostscript-9.10~dfsg/base/gdevplnx.c ghostscript-9.25~dfsg+1/base/gdevplnx.c --- ghostscript-9.10~dfsg/base/gdevplnx.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevplnx.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,7 +28,7 @@ #include "gxdither.h" #include "gxgetbit.h" #include "gxiparam.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gdevplnx.h" /* Define the size of the locally allocated bitmap buffers. */ @@ -560,14 +560,14 @@ static int plane_fill_path(gx_device *dev, - const gs_imager_state *pis, gx_path *ppath, + const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_drawing_color *pdevc, const gx_clip_path *pcpath) { gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev; gx_device * const plane_dev = edev->plane_dev; gs_logical_operation_t lop_orig = - gs_current_logical_op((const gs_state *)pis); + gs_current_logical_op((const gs_gstate *)pgs); gs_logical_operation_t lop = lop_orig; gx_device_color dcolor; @@ -575,32 +575,32 @@ case REDUCE_SKIP: return 0; case REDUCE_DRAW: { - gs_imager_state lopis; - const gs_imager_state *pis_draw = pis; + gs_gstate lopgs; + const gs_gstate *pgs_draw = pgs; if (lop != lop_orig) { - lopis = *pis; - gs_set_logical_op((gs_state *)&lopis, lop); - pis_draw = &lopis; + lopgs = *pgs; + gs_set_logical_op((gs_gstate *)&lopgs, lop); + pgs_draw = &lopgs; } return dev_proc(plane_dev, fill_path) - (plane_dev, pis_draw, ppath, params, &dcolor, pcpath); + (plane_dev, pgs_draw, ppath, params, &dcolor, pcpath); } default /*REDUCE_FAILED*/: - return gx_default_fill_path(dev, pis, ppath, params, pdevc, pcpath); + return gx_default_fill_path(dev, pgs, ppath, params, pdevc, pcpath); } } static int plane_stroke_path(gx_device *dev, - const gs_imager_state *pis, gx_path *ppath, + const gs_gstate *pgs, gx_path *ppath, const gx_stroke_params *params, const gx_drawing_color *pdevc, const gx_clip_path *pcpath) { gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev; gx_device * const plane_dev = edev->plane_dev; gs_logical_operation_t lop_orig = - gs_current_logical_op((const gs_state *)pis); + gs_current_logical_op((const gs_gstate *)pgs); gs_logical_operation_t lop = lop_orig; gx_device_color dcolor; @@ -608,19 +608,19 @@ case REDUCE_SKIP: return 0; case REDUCE_DRAW: { - gs_imager_state lopis; - const gs_imager_state *pis_draw = pis; + gs_gstate lopgs; + const gs_gstate *pgs_draw = pgs; if (lop != lop_orig) { - lopis = *pis; - gs_set_logical_op((gs_state *)&lopis, lop); - pis_draw = &lopis; + lopgs = *pgs; + gs_set_logical_op((gs_gstate *)&lopgs, lop); + pgs_draw = &lopgs; } return dev_proc(plane_dev, stroke_path) - (plane_dev, pis_draw, ppath, params, &dcolor, pcpath); + (plane_dev, pgs_draw, ppath, params, &dcolor, pcpath); } default /*REDUCE_FAILED*/: - return gx_default_stroke_path(dev, pis, ppath, params, pdevc, pcpath); + return gx_default_stroke_path(dev, pgs, ppath, params, pdevc, pcpath); } } @@ -843,85 +843,85 @@ typedef struct plane_image_enum_s { gx_image_enum_common; gx_image_enum_common_t *info; /* plane device enumerator */ - const gs_imager_state *pis; /* original imager state */ - gs_imager_state *pis_image; /* modified imager state */ + const gs_gstate *pgs; /* original gs_gstate */ + gs_gstate *pgs_image; /* modified gs_gstate state */ } plane_image_enum_t; gs_private_st_suffix_add3(st_plane_image_enum, plane_image_enum_t, "plane_image_enum_t", plane_image_enum_enum_ptrs, - plane_image_enum_reloc_ptrs, st_gx_image_enum_common, info, pis, pis_image); + plane_image_enum_reloc_ptrs, st_gx_image_enum_common, info, pgs, pgs_image); /* * Reduce drawing colors returned by color mapping. Note that these * assume that the call of reduce_drawing_color will not fail: * plane_begin_typed_image must ensure this. * - * In the imager state passed to these procedures, the client data is + * In the gs_gstate passed to these procedures, the client data is * the plane_image_enum_t. */ static void plane_cmap_gray(frac gray, gx_device_color * pdc, - const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select) + const gs_gstate *pgs_image, gx_device *dev, gs_color_select_t select) { const plane_image_enum_t *ppie = - (const plane_image_enum_t *)pis_image->client_data; + (const plane_image_enum_t *)pgs_image->client_data; gx_device_plane_extract * const edev = (gx_device_plane_extract *)ppie->dev; - gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image); + gs_logical_operation_t lop = gs_current_logical_op_inline(pgs_image); gx_device_color dcolor; - gx_remap_concrete_gray(gray, &dcolor, ppie->pis, + gx_remap_concrete_gray(gray, &dcolor, ppie->pgs, (gx_device *)edev, select); reduce_drawing_color(pdc, edev, &dcolor, &lop); } static void plane_cmap_rgb(frac r, frac g, frac b, gx_device_color * pdc, - const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select) + const gs_gstate *pgs_image, gx_device *dev, gs_color_select_t select) { const plane_image_enum_t *ppie = - (const plane_image_enum_t *)pis_image->client_data; + (const plane_image_enum_t *)pgs_image->client_data; gx_device_plane_extract * const edev = (gx_device_plane_extract *)ppie->dev; - gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image); + gs_logical_operation_t lop = gs_current_logical_op_inline(pgs_image); gx_device_color dcolor; - gx_remap_concrete_rgb(r, g, b, &dcolor, ppie->pis, + gx_remap_concrete_rgb(r, g, b, &dcolor, ppie->pgs, (gx_device *)edev, select); reduce_drawing_color(pdc, edev, &dcolor, &lop); } static void plane_cmap_cmyk(frac c, frac m, frac y, frac k, gx_device_color * pdc, - const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select, + const gs_gstate *pgs_image, gx_device *dev, gs_color_select_t select, const gs_color_space *source_pcs) { const plane_image_enum_t *ppie = - (const plane_image_enum_t *)pis_image->client_data; + (const plane_image_enum_t *)pgs_image->client_data; gx_device_plane_extract * const edev = (gx_device_plane_extract *)ppie->dev; - gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image); + gs_logical_operation_t lop = gs_current_logical_op_inline(pgs_image); gx_device_color dcolor; - gx_remap_concrete_cmyk(c, m, y, k, &dcolor, ppie->pis, + gx_remap_concrete_cmyk(c, m, y, k, &dcolor, ppie->pgs, (gx_device *)edev, select, NULL); reduce_drawing_color(pdc, edev, &dcolor, &lop); } static void plane_cmap_rgb_alpha(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, - const gs_imager_state *pis_image, gx_device *dev, gs_color_select_t select) + const gs_gstate *pgs_image, gx_device *dev, gs_color_select_t select) { const plane_image_enum_t *ppie = - (const plane_image_enum_t *)pis_image->client_data; + (const plane_image_enum_t *)pgs_image->client_data; gx_device_plane_extract * const edev = (gx_device_plane_extract *)ppie->dev; - gs_logical_operation_t lop = gs_current_logical_op_inline(pis_image); + gs_logical_operation_t lop = gs_current_logical_op_inline(pgs_image); gx_device_color dcolor; - gx_remap_concrete_rgb_alpha(r, g, b, alpha, &dcolor, ppie->pis, + gx_remap_concrete_rgb_alpha(r, g, b, alpha, &dcolor, ppie->pgs, (gx_device *)edev, select); reduce_drawing_color(pdc, edev, &dcolor, &lop); } static bool -plane_cmap_is_halftoned(const gs_imager_state *pis_image, gx_device *dev) +plane_cmap_is_halftoned(const gs_gstate *pgs_image, gx_device *dev) { return false; } @@ -931,7 +931,7 @@ NULL, NULL, plane_cmap_is_halftoned }; static const gx_color_map_procs * -plane_get_cmap_procs(const gs_imager_state *pis, const gx_device *dev) +plane_get_cmap_procs(const gs_gstate *pgs, const gx_device *dev) { return &plane_color_map_procs; } @@ -945,22 +945,22 @@ static int plane_begin_typed_image(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * memory, gx_image_enum_common_t ** pinfo) { /* - * For images, we intercept the imager state's cmap_procs and apply + * For images, we intercept the gs_gstate's cmap_procs and apply * reduce_drawing_color to the colors as they are returned to the image * processing code. For reasons explained above, we can't do this in * some cases of RasterOp that include transparency. */ gx_device_plane_extract * const edev = (gx_device_plane_extract *)dev; - gs_logical_operation_t lop = gs_current_logical_op((const gs_state *)pis); + gs_logical_operation_t lop = gs_current_logical_op((const gs_gstate *)pgs); const gs_pixel_image_t *pim; plane_image_enum_t *info = 0; - gs_imager_state *pis_image = 0; + gs_gstate *pgs_image = 0; gx_device_color dcolor; bool uses_color = false; int code; @@ -999,14 +999,14 @@ } info = gs_alloc_struct(memory, plane_image_enum_t, &st_plane_image_enum, "plane_image_begin_typed(info)"); - pis_image = gs_imager_state_copy(pis, memory); - if (pis_image == 0 || info == 0) + pgs_image = gs_gstate_copy_temp(pgs, memory); + if (pgs_image == 0 || info == 0) goto fail; - *pis_image = *pis; - pis_image->client_data = info; - pis_image->get_cmap_procs = plane_get_cmap_procs; + *pgs_image = *pgs; + pgs_image->client_data = info; + pgs_image->get_cmap_procs = plane_get_cmap_procs; code = dev_proc(edev->plane_dev, begin_typed_image) - (edev->plane_dev, pis_image, pmat, pic, prect, + (edev->plane_dev, pgs_image, pmat, pic, prect, &dcolor, pcpath, memory, &info->info); if (code < 0) goto fail; @@ -1015,14 +1015,14 @@ info->dev = (gx_device *)edev; info->id = gs_next_ids(memory, 1); info->memory = memory; - info->pis = pis; - info->pis_image = pis_image; + info->pgs = pgs; + info->pgs_image = pgs_image; *pinfo = (gx_image_enum_common_t *)info; return code; fail: - gs_free_object(memory, pis_image, "plane_image_begin_typed(pis_image)"); + gs_free_object(memory, pgs_image, "plane_image_begin_typed(pgs_image)"); gs_free_object(memory, info, "plane_image_begin_typed(info)"); - return gx_default_begin_typed_image(dev, pis, pmat, pic, prect, + return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); } @@ -1042,8 +1042,8 @@ plane_image_enum_t * const ppie = (plane_image_enum_t *)info; int code = gx_image_end(ppie->info, draw_last); - gs_free_object(ppie->memory, ppie->pis_image, - "plane_image_end_image(pis_image)"); + gs_free_object(ppie->memory, ppie->pgs_image, + "plane_image_end_image(pgs_image)"); gx_image_free_enum(&info); return code; } @@ -1059,7 +1059,7 @@ int plane_index = edev->plane.index; gs_get_bits_options_t options = params->options; gs_get_bits_params_t plane_params; - int plane; + uchar plane; int code; /* diff -Nru ghostscript-9.10~dfsg/base/gdevplnx.h ghostscript-9.25~dfsg+1/base/gdevplnx.h --- ghostscript-9.10~dfsg/base/gdevplnx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevplnx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gdevppla.c ghostscript-9.25~dfsg+1/base/gdevppla.c --- ghostscript-9.10~dfsg/base/gdevppla.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevppla.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,17 +20,6 @@ #include "gdevppla.h" #include "gxdevsop.h" -static int -prn_planar_dev_spec_op(gx_device *pdev, int dev_spec_op, - void *data, int size) -{ - gx_device_printer *dev = (gx_device_printer *)pdev; - - if (dev_spec_op == gxdso_is_native_planar) - return dev->color_info.depth / dev->color_info.num_components; - return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); -} - /* Set the buf_procs in a printer device to planar mode. */ int gdev_prn_set_procs_planar(gx_device *dev) @@ -42,7 +31,7 @@ pdev->printer_procs.buf_procs.size_buf_device = gdev_prn_size_buf_planar; if (dev_proc(pdev, dev_spec_op) == gx_default_dev_spec_op) - set_dev_proc(pdev, dev_spec_op, prn_planar_dev_spec_op); + set_dev_proc(pdev, dev_spec_op, gdev_prn_dev_spec_op); return 0; } @@ -50,8 +39,10 @@ int gdev_prn_open_planar(gx_device *dev, bool upb) { - if (upb) + if (upb) { gdev_prn_set_procs_planar(dev); + dev->is_planar = 1; + } return gdev_prn_open(dev); } @@ -138,12 +129,15 @@ return gx_default_size_buf_device(space, target, render_plane, height, for_band); mdev.color_info = target->color_info; + mdev.pad = target->pad; + mdev.log2_align_mod = target->log2_align_mod; + mdev.is_planar = target->is_planar; code = gdev_prn_set_planar(&mdev, target); if (code < 0) return code; if (gdev_mem_bits_size(&mdev, target->width, height, &(space->bits)) < 0) return_error(gs_error_VMerror); space->line_ptrs = gdev_mem_line_ptrs_size(&mdev, target->width, height); - space->raster = bitmap_raster(target->width * mdev.planes[0].depth); + space->raster = bitmap_raster_pad_align(target->width * mdev.planes[0].depth, mdev.pad, mdev.log2_align_mod); return 0; } diff -Nru ghostscript-9.10~dfsg/base/gdevppla.h ghostscript-9.25~dfsg+1/base/gdevppla.h --- ghostscript-9.10~dfsg/base/gdevppla.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevppla.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gdevprna.c ghostscript-9.25~dfsg+1/base/gdevprna.c --- ghostscript-9.10~dfsg/base/gdevprna.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevprna.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,795 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Generic asynchronous printer driver support */ - -/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */ -/* Revised 8/7/98 by L. Peter Deutsch (ghost@aladdin.com) for */ -/* memory manager changes */ -/* 12/1/98 soho@crl.com - Removed unnecessary flush & reopen in */ -/* gdev_prn_async_write_get_hardware_params */ -#include "gdevprna.h" -#include "gsalloc.h" -#include "gsdevice.h" -#include "gsmemlok.h" -#include "gsmemret.h" -#include "gsnogc.h" -#include "gxcldev.h" -#include "gxclpath.h" -#include "gxpageq.h" -#include "gzht.h" /* for gx_ht_cache_default_bits_size */ - -/* ----------------- Constants ----------------------- */ -/* - * Fixed overhead # bytes to run renderer in (+ driver-spec'd variable bytes): - * empirical & still very subject to change. - */ -#define RendererAllocationOverheadBytes 503000 /* minimum is 503,000 as of 4/26/99 */ - -#ifdef DEBUG -/* 196000 is pretty much the minimum, given 16K phys memfile blocks */ -/*# define DebugBandlistMemorySize 196000*/ /* comment out to disable fixed (debug) bandlist size */ -#endif /* defined(DEBUG) */ - -/* ---------------- Standard device procedures ---------------- */ -static dev_proc_close_device(gdev_prn_async_write_close_device); -static dev_proc_output_page(gdev_prn_async_write_output_page); -static dev_proc_put_params(gdev_prn_async_write_put_params); -static dev_proc_get_hardware_params(gdev_prn_async_write_get_hardware_params); -static dev_proc_put_params(gdev_prn_async_render_put_params); - -/* ---------------- Forward Declarations ---------------------- */ -static void gdev_prn_dealloc(gx_device_printer *); -static proc_free_up_bandlist_memory(gdev_prn_async_write_free_up_bandlist_memory); -static int flush_page(gx_device_printer *, bool); -static int reopen_clist_after_flush(gx_device_printer *); -static void reinit_printer_into_printera(gx_device_printer * const); -static int alloc_bandlist_memory(gs_memory_t **, gs_memory_t *); -static void free_bandlist_memory(gs_memory_t *); -static int alloc_render_memory(gs_memory_t **, gs_memory_t *, long); -static void free_render_memory(gs_memory_t *); -static gs_memory_recover_status_t - prna_mem_recover(gs_memory_retrying_t *rmem, void *proc_data); - -/* ------ Open/close ------ */ - -/* - * Open this printer device in ASYNC (overlapped) mode. - * This routine must always called by the concrete device's xx_open routine - * in lieu of gdev_prn_open. - */ -int -gdev_prn_async_write_open(gx_device_printer * pwdev, int max_raster, - int min_band_height, int max_src_image_row) -{ - gx_device *const pdev = (gx_device *) pwdev; - int code; - bool writer_is_open = false; - gx_device_clist_writer *const pcwdev = - &((gx_device_clist *) pwdev)->writer; - gx_device_clist_reader *pcrdev = 0; - gx_device_printer *prdev = 0; - gs_memory_t *render_memory = 0; /* renderer's mem allocator */ - - pwdev->page_queue = 0; - pwdev->bandlist_memory = 0; - pwdev->async_renderer = 0; - - /* allocate & init render memory */ - /* The big memory consumers are: */ - /* - the buffer used to read images from the command list */ - /* - buffer used by gx_real_default_strip_copy_rop() */ - /* - line pointer tables for memory devices used in plane extraction */ - /* - the halftone cache */ - /* - the band rendering buffer */ - /* The * 2's in the next statement are a ****** HACK ****** to deal with */ - /* sandbars in the memory manager. */ - if ((code = alloc_render_memory(&render_memory, - pwdev->memory->non_gc_memory, RendererAllocationOverheadBytes + max_raster - /* the first * 2 is not a hack */ - + (max_raster + sizeof(void *) * 2) * min_band_height - + max_src_image_row + gx_ht_cache_default_bits_size() * 2)) < 0) - goto open_err; - - /* Alloc & init bandlist allocators */ - /* Bandlist mem is threadsafe & common to rdr/wtr, so it's used */ - /* for page queue & cmd list buffers. */ - if ((code = alloc_bandlist_memory - (&pwdev->bandlist_memory, pwdev->memory->non_gc_memory)) < 0) - goto open_err; - - /* Dictate banding parameters for both renderer & writer */ - /* Protect from user change, since user changing these won't be */ - /* detected, ergo the necessary close/reallocate/open wouldn't happen. */ - pwdev->space_params.banding_type = BandingAlways; - pwdev->space_params.params_are_read_only = true; - - /* Make a copy of device for use as rendering device b4 opening writer */ - code = gs_copydevice((gx_device **) & prdev, pdev, render_memory); - pcrdev = &((gx_device_clist *) prdev)->reader; - if (code < 0) - goto open_err; - - /* -------------- Open cmd list WRITER instance of device ------- */ - /* --------------------------------------------------------------- */ - /* This is wrong, because it causes the same thing in the renderer */ - pwdev->OpenOutputFile = 0; /* Don't open output file in writer */ - - /* Hack: set this vector to tell gdev_prn_open to allocate for async rendering */ - pwdev->free_up_bandlist_memory = &gdev_prn_async_write_free_up_bandlist_memory; - - /* prevent clist writer from queuing path graphics & force it to split images */ - pwdev->clist_disable_mask |= clist_disable_fill_path | - clist_disable_stroke_path | clist_disable_complex_clip | - clist_disable_nonrect_hl_image | clist_disable_pass_thru_params; - - if ((code = gdev_prn_open(pdev)) >= 0) { - writer_is_open = true; - - /* set up constant async-specific fields in device */ - reinit_printer_into_printera(pwdev); - - /* keep ptr to renderer device */ - pwdev->async_renderer = prdev; - - /* Allocate the page queue, then initialize it */ - /* Use bandlist memory since it's shared between rdr & wtr */ - if ((pwdev->page_queue = gx_page_queue_alloc(pwdev->bandlist_memory)) == 0) - code = gs_note_error(gs_error_VMerror); - else - /* Allocate from clist allocator since it is thread-safe */ - code = gx_page_queue_init(pwdev->page_queue, pwdev->bandlist_memory); - } - /* ------------ Open cmd list RENDERER instance of device ------- */ - /* --------------------------------------------------------------- */ - if (code >= 0) { - gx_semaphore_t *open_semaphore; - - /* Force writer's actual band params into reader's requested params */ - prdev->space_params.band = pcwdev->page_info.band_params; - - /* copydevice has already set up prdev->memory = render_memory */ - /* prdev->bandlist_memory = pwdev->bandlist_memory; */ - prdev->buffer_memory = prdev->memory; - - /* enable renderer to accept changes to params computed by writer */ - prdev->space_params.params_are_read_only = false; - - /* page queue is common to both devices */ - prdev->page_queue = pwdev->page_queue; - - /* Start renderer thread & wait for its successful open of device */ - if (!(open_semaphore = gx_semaphore_alloc(prdev->memory))) - code = gs_note_error(gs_error_VMerror); - else { - gdev_prn_start_render_params thread_params; - - thread_params.writer_device = pwdev; - thread_params.open_semaphore = open_semaphore; - thread_params.open_code = 0; - code = (*pwdev->printer_procs.start_render_thread) - (&thread_params); - if (code >= 0) - gx_semaphore_wait(open_semaphore); - code = thread_params.open_code; - gx_semaphore_free(open_semaphore); - } - } - /* ----- Set the recovery procedure for the mem allocator ----- */ - if (code >= 0) { - gs_memory_retrying_set_recover( - (gs_memory_retrying_t *)pwdev->memory->non_gc_memory, - prna_mem_recover, - (void *)pcwdev - ); - } - /* --------------------- Wrap up --------------------------------- */ - /* --------------------------------------------------------------- */ - if (code < 0) { -open_err: - /* error mop-up */ - if (render_memory && !prdev) - free_render_memory(render_memory); - - gdev_prn_dealloc(pwdev); - if (writer_is_open) { - gdev_prn_close(pdev); - pwdev->free_up_bandlist_memory = 0; - } - } - return code; -} - -/* This procedure is called from within the memory allocator when regular */ -/* malloc's fail -- this procedure tries to free up pages from the queue */ -/* and returns a status code indicating whether any more can be freed. */ -static gs_memory_recover_status_t -prna_mem_recover(gs_memory_retrying_t *rmem, void *proc_data) -{ - int pages_remain = 0; - gx_device_clist_writer *cldev = proc_data; - - if (cldev->free_up_bandlist_memory != NULL) - pages_remain = - (*cldev->free_up_bandlist_memory)( (gx_device *)cldev, false ); - return (pages_remain > 0) ? RECOVER_STATUS_RETRY_OK : RECOVER_STATUS_NO_RETRY; -} - -/* (Re)set printer device fields which get trampled by gdevprn_open & put_params */ -static void -reinit_printer_into_printera( - gx_device_printer * const pdev /* printer to convert */ -) -{ - /* Change some of the procedure vector to point at async procedures */ - /* Originals were already saved by gdev_prn_open */ - if (dev_proc(pdev, close_device) == gdev_prn_close) - set_dev_proc(pdev, close_device, gdev_prn_async_write_close_device); - set_dev_proc(pdev, output_page, gdev_prn_async_write_output_page); - set_dev_proc(pdev, put_params, gdev_prn_async_write_put_params); - set_dev_proc(pdev, get_xfont_procs, gx_default_get_xfont_procs); - set_dev_proc(pdev, get_xfont_device, gx_default_get_xfont_device); - set_dev_proc(pdev, get_hardware_params, gdev_prn_async_write_get_hardware_params); - - /* clist writer calls this if it runs out of memory & wants to retry */ - pdev->free_up_bandlist_memory = &gdev_prn_async_write_free_up_bandlist_memory; -} - -/* Generic closing for the writer device. */ -static int -gdev_prn_async_write_close_device(gx_device * pdev) -{ - gx_device_printer *const pwdev = (gx_device_printer *) pdev; - gx_device_clist_writer *const pcwdev = - &((gx_device_clist *) pdev)->writer; - - /* Signal render thread to close & terminate when done */ - gx_page_queue_add_page(pcwdev, pwdev->page_queue, - GX_PAGE_QUEUE_ACTION_TERMINATE, 0, 0); - - /* Wait for renderer to finish all pages & terminate req */ - gx_page_queue_wait_until_empty(pwdev->page_queue); - - /* Cascade down to original close rtn */ - gdev_prn_close(pdev); - pwdev->free_up_bandlist_memory = 0; - - /* Deallocte dynamic stuff */ - gdev_prn_dealloc(pwdev); - return 0; -} - -/* Deallocte dynamic memory attached to device. Aware of possible imcomplete open */ -static void -gdev_prn_dealloc(gx_device_printer * pwdev) -{ - gx_device_printer *const prdev = pwdev->async_renderer; - - /* Delete renderer device & its memory allocator */ - if (prdev) { - gs_memory_t *render_alloc = prdev->memory; - - gs_free_object(render_alloc, prdev, "gdev_prn_dealloc"); - free_render_memory(render_alloc); - } - /* Free page queue */ - if (pwdev->page_queue) { - gx_page_queue_dnit(pwdev->page_queue); - gs_free_object(pwdev->bandlist_memory, pwdev->page_queue, - "gdev_prn_dealloc"); - pwdev->page_queue = 0; - } - /* Free memory bandlist allocators */ - if (pwdev->bandlist_memory) - free_bandlist_memory(pwdev->bandlist_memory); -} - -/* Open the render portion of a printer device in ASYNC (overlapped) mode. - - * This routine is always called by concrete device's xx_open_render_device - * in lieu of gdev_prn_open. - */ -int -gdev_prn_async_render_open(gx_device_printer * prdev) -{ - gx_device *const pdev = (gx_device *) prdev; - - prdev->is_async_renderer = true; - return gdev_prn_open(pdev); -} - -/* Generic closing for the rendering device. */ -int -gdev_prn_async_render_close_device(gx_device_printer * prdev) -{ - gx_device *const pdev = (gx_device *) prdev; - - return gdev_prn_close(pdev); -} - -/* (Re)set renderer device fields which get trampled by gdevprn_open & put_params */ -static void -reinit_printer_into_renderer( - gx_device_printer * const pdev /* printer to convert */ -) -{ - set_dev_proc(pdev, put_params, gdev_prn_async_render_put_params); -} - -/* ---------- Start rasterizer thread ------------ */ -/* - * Must be called by async device driver implementation (see gdevprna.h - * under "Synchronizing the Instances"). This is the rendering loop, which - * requires its own thread for as long as the device is open. This proc only - * returns after the device is closed, or if the open failed. NB that an - * open error leaves things in a state where the writer thread will not be - * able to close since it's expecting the renderer to acknowledge its - * requests before the writer can close. Ergo, if this routine fails you'll - * crash unless the caller fixes the problem & successfully retries this. - */ -int /* rets 0 ok, -ve error code if open failed */ -gdev_prn_async_render_thread( - gdev_prn_start_render_params * params -) -{ - gx_device_printer *const pwdev = params->writer_device; - gx_device_printer *const prdev = pwdev->async_renderer; - gx_page_queue_entry_t *entry; - int code; - - /* Open device, but don't use default if user didn't override */ - if (prdev->printer_procs.open_render_device == - gx_default_open_render_device) - code = gdev_prn_async_render_open(prdev); - else - code = (*prdev->printer_procs.open_render_device) (prdev); - reinit_printer_into_renderer(prdev); - - /* The cmd list logic assumes reader's & writer's tile caches are same size */ - if (code >= 0 && - ((gx_device_clist *) pwdev)->writer.page_tile_cache_size != - ((gx_device_clist *) prdev)->writer.page_tile_cache_size) { - gdev_prn_async_render_close_device(prdev); - code = gs_note_error(gs_error_VMerror); - } - params->open_code = code; - gx_semaphore_signal(params->open_semaphore); - if (code < 0) - return code; - - /* fake open, since not called by gs_opendevice */ - prdev->is_open = true; - - /* Successful open */ - while ((entry = gx_page_queue_start_dequeue(prdev->page_queue)) - && entry->action != GX_PAGE_QUEUE_ACTION_TERMINATE) { - /* Force printer open again if it mysteriously closed. */ - /* This shouldn't ever happen, but... */ - if (!prdev->is_open) { - if (prdev->printer_procs.open_render_device == - gx_default_open_render_device) - code = gdev_prn_async_render_open(prdev); - else - code = (*prdev->printer_procs.open_render_device) (prdev); - reinit_printer_into_renderer(prdev); - - if (code >= 0) { - prdev->is_open = true; - gdev_prn_output_page((gx_device *) prdev, 0, true); - } - } - if (prdev->is_open) { - /* Force retrieved entry onto render device */ - ((gx_device_clist *) prdev)->common.page_info = entry->page_info; - - /* Set up device geometry */ - if (clist_setup_params((gx_device *) prdev) >= 0) - /* Go this again, since setup_params may have trashed it */ - ((gx_device_clist *) prdev)->common.page_info = entry->page_info; - - /* Call appropriate renderer routine to deal w/buffer */ - /* Ignore status, since we don't know how to deal w/errors! */ - switch (entry->action) { - - case GX_PAGE_QUEUE_ACTION_FULL_PAGE: - (*dev_proc(prdev, output_page))((gx_device *) prdev, - entry->num_copies, true); - break; - - case GX_PAGE_QUEUE_ACTION_PARTIAL_PAGE: - case GX_PAGE_QUEUE_ACTION_COPY_PAGE: - (*dev_proc(prdev, output_page))((gx_device *) prdev, - entry->num_copies, false); - break; - } - /* - * gx_page_queue_finish_dequeue will close and free the band - * list files, so we don't need to call clist_close_output_file. - */ - } - /* Finalize dequeue & free retrieved queue entry */ - gx_page_queue_finish_dequeue(entry); - } - - /* Close device, but don't use default if user hasn't overriden. */ - /* Ignore status, since returning bad status means open failed */ - if (prdev->printer_procs.close_render_device == - gx_default_close_render_device) - gdev_prn_async_render_close_device(prdev); - else - (*prdev->printer_procs.close_render_device)(prdev); - - /* undo fake open, since not called by gs_closedevice */ - prdev->is_open = false; - - /* Now that device is closed, acknowledge gx_page_queue_terminate */ - gx_page_queue_finish_dequeue(entry); - - return 0; -} - -/* ------ Get/put parameters ------ */ - -/* Put parameters. */ -static int -gdev_prn_async_write_put_params(gx_device * pdev, gs_param_list * plist) -{ - gx_device_clist_writer *const pclwdev = - &((gx_device_clist *) pdev)->writer; - gx_device_printer *const pwdev = (gx_device_printer *) pdev; - gdev_prn_space_params save_sp = pwdev->space_params; - int save_height = pwdev->height; - int save_width = pwdev->width; - int code, ecode; - - if (!pwdev->is_open) - return (*pwdev->orig_procs.put_params) (pdev, plist); - - /* - * First, cascade to real device's put_params. - * If that put_params made any changes that require re-opening - * the device, just flush the page; the parameter block at the - * head of the next page will reflect the changes just made. - * If the put_params requires no re-open, just slip it into the - * stream in the command buffer. This way, the - * writer device should parallel the renderer status at the same point - * in their respective executions. - * - * NB. that all this works only because we take the position that - * put_params can make no change that actually affects hardware's state - * before the final output_page on the RASTERIZER. - */ - /* Call original procedure, but "closed" to prevent closing device */ - pwdev->is_open = false; /* prevent put_params from closing device */ - code = (*pwdev->orig_procs.put_params) (pdev, plist); - pwdev->is_open = true; - pwdev->OpenOutputFile = 0; /* This is wrong, because it causes the same thing in the renderer */ - - /* Flush device or emit to command list, depending if device changed geometry */ - if (memcmp(&pwdev->space_params, &save_sp, sizeof(save_sp)) != 0 || - pwdev->width != save_width || pwdev->height != save_height - ) { - int pageq_remaining; - int new_width = pwdev->width; - int new_height = pwdev->height; - gdev_prn_space_params new_sp = pwdev->space_params; - - /* Need to start a new page, reallocate clist memory */ - pwdev->width = save_width; - pwdev->height = save_height; - pwdev->space_params = save_sp; - - /* First, get rid of any pending partial pages */ - code = flush_page(pwdev, false); - - /* Free and reallocate the printer memory. */ - pageq_remaining = 1; /* assume there are pages left in queue */ - do { - ecode = - gdev_prn_reallocate_memory(pdev, - &new_sp, new_width, new_height); - if (ecode >= 0) - break; /* managed to recover enough memory */ - if (!pdev->is_open) { - /* Disaster! Device was forced closed, which async drivers */ - /* aren't suppsed to do. */ - gdev_prn_async_write_close_device(pdev); - return ecode; /* caller 'spozed to know could be closed now */ - } - pclwdev->error_is_retryable = (ecode == gs_error_VMerror); - } - while (pageq_remaining >= 1 && - (pageq_remaining = ecode = - clist_VMerror_recover(pclwdev, ecode)) >= 0); - if (ecode < 0) { - gdev_prn_free_memory(pdev); - pclwdev->is_open = false; - code = ecode; - } - } else if (code >= 0) { - do - if ((ecode = cmd_put_params(pclwdev, plist)) >= 0) - break; - while ((ecode = clist_VMerror_recover(pclwdev, ecode)) >= 0); - if (ecode < 0 && pclwdev->error_is_retryable && - pclwdev->driver_call_nesting == 0 - ) - ecode = clist_VMerror_recover_flush(pclwdev, ecode); - if (ecode < 0) - code = ecode; - } - /* Reset fields that got trashed by gdev_prn_put_params and/or gdev_prn_open */ - reinit_printer_into_printera(pwdev); - - return code; -} - -/* Get hardware-detected params. Drain page queue, then call renderer version */ -static int -gdev_prn_async_write_get_hardware_params(gx_device * pdev, gs_param_list * plist) -{ - gx_device_printer *const pwdev = (gx_device_printer *) pdev; - gx_device_printer *const prdev = pwdev->async_renderer; - - if (!pwdev->is_open || !prdev) - /* if not open, just use device's get hw params */ - return (dev_proc(pwdev, get_hardware_params))(pdev, plist); - else { - /* wait for empty pipeline */ - gx_page_queue_wait_until_empty(pwdev->page_queue); - - /* get reader's h/w params, now that writer & reader are sync'ed */ - return (dev_proc(prdev, get_hardware_params)) - ((gx_device *) prdev, plist); - } -} - -/* Put parameters on RENDERER. */ -static int /* returns -ve err code only if FATAL error (can't keep rendering) */ -gdev_prn_async_render_put_params(gx_device * pdev, gs_param_list * plist) -{ - gx_device_printer *const prdev = (gx_device_printer *) pdev; - bool save_is_open = prdev->is_open; - - /* put_parms from clist are guaranteed to never re-init device */ - /* They're also pretty much guaranteed to always succeed */ - (*prdev->orig_procs.put_params) (pdev, plist); - - /* If device closed itself, try to open & clear it */ - if (!prdev->is_open && save_is_open) { - int code; - - if (prdev->printer_procs.open_render_device == - gx_default_open_render_device) - code = gdev_prn_async_render_open(prdev); - else - code = (*prdev->printer_procs.open_render_device) (prdev); - reinit_printer_into_renderer(prdev); - if (code >= 0) - /****** CLEAR PAGE SOMEHOW ******/; - else - return code; /* this'll cause clist to stop processing this band! */ - } - return 0; /* return this unless FATAL status */ -} - -/* ------ Others ------ */ - -/* Output page causes file to get added to page queue for later rasterizing */ -static int -gdev_prn_async_write_output_page(gx_device * pdev, int num_copies, int flush) -{ - gx_device_printer *const pwdev = (gx_device_printer *) pdev; - gx_device_clist_writer *const pcwdev = - &((gx_device_clist *) pdev)->writer; - int flush_code; - int add_code; - int open_code; - int one_last_time = 1; - - /* do NOT close files before sending to page queue */ - flush_code = clist_end_page(pcwdev); - add_code = gx_page_queue_add_page(pcwdev, pwdev->page_queue, - (flush ? GX_PAGE_QUEUE_ACTION_FULL_PAGE : - GX_PAGE_QUEUE_ACTION_COPY_PAGE), - &pcwdev->page_info, num_copies); - if (flush && (flush_code >= 0) && (add_code >= 0)) { - /* This page is finished */ - gx_finish_output_page(pdev, num_copies, flush); - } - - /* Open new band files to take the place of ones added to page queue */ - while ((open_code = (*gs_clist_device_procs.open_device) - ((gx_device *) pdev)) == gs_error_VMerror) { - /* Open failed, try after a page gets rendered */ - if (!gx_page_queue_wait_one_page(pwdev->page_queue) - && one_last_time-- <= 0) - break; - } - - return - (flush_code < 0 ? flush_code : open_code < 0 ? open_code : - add_code < 0 ? add_code : 0); -} - -/* Free bandlist memory waits until the rasterizer runs enough to free some mem */ -static int /* -ve err, 0 if no pages remain to rasterize, 1 if more pages to go */ -gdev_prn_async_write_free_up_bandlist_memory(gx_device * pdev, bool flush_current) -{ - gx_device_printer *const pwdev = (gx_device_printer *) pdev; - - if (flush_current) { - int code = flush_page(pwdev, true); - - if (code < 0) - return code; - } - return gx_page_queue_wait_one_page(pwdev->page_queue); -} - -/* -------- Utility Routines --------- */ - -/* Flush out any partial pages accumulated in device */ -/* LEAVE DEVICE in a state where it must be re-opened/re-init'd */ -static int /* ret 0 ok no flush, -ve error code */ -flush_page( - gx_device_printer * pwdev, /* async writer device to flush */ - bool partial /* true if only partial page */ -) -{ - gx_device_clist *const pcldev = (gx_device_clist *) pwdev; - gx_device_clist_writer *const pcwdev = &pcldev->writer; - int flush_code = 0; - int add_code = 0; - - /* do NOT close files before sending to page queue */ - flush_code = clist_end_page(pcwdev); - add_code = gx_page_queue_add_page(pcwdev, pwdev->page_queue, - (partial ? GX_PAGE_QUEUE_ACTION_PARTIAL_PAGE : - GX_PAGE_QUEUE_ACTION_FULL_PAGE), - &pcwdev->page_info, 0); - - /* Device no longer has BANDFILES, so it must be re-init'd by caller */ - pcwdev->page_info.bfile = pcwdev->page_info.cfile = 0; - - /* return the worst of the status. */ - if (flush_code < 0) - return flush_code; - return add_code; -} - -/* Flush any pending partial pages, re-open device */ -static int -reopen_clist_after_flush( - gx_device_printer * pwdev /* async writer device to flush */ -) -{ - int open_code; - int one_last_time = 1; - - /* Open new band files to take the place of ones added to page queue */ - while ((open_code = (*gs_clist_device_procs.open_device) - ((gx_device *) pwdev)) == gs_error_VMerror) { - /* Open failed, try after a page gets rendered */ - if (!gx_page_queue_wait_one_page(pwdev->page_queue) - && one_last_time-- <= 0) - break; - } - return open_code; -} - -/* - * The bandlist does allocations on the writer's thread & deallocations on - * the reader's thread, so it needs to have mutual exclusion from itself, as - * well as from other memory allocators since the reader can run at the same - * time as the interpreter. The bandlist allocator therefore consists of - * a monitor-locking wrapper around either a direct heap allocator or (for - * testing) a fixed-limit allocator. - */ - -/* Create a bandlist allocator. */ -static int -alloc_bandlist_memory(gs_memory_t ** final_allocator, - gs_memory_t * base_allocator) -{ - gs_memory_t *data_allocator = 0; - gs_memory_locked_t *locked_allocator = 0; - int code = 0; - -#if defined(DEBUG) && defined(DebugBandlistMemorySize) - code = alloc_render_memory(&data_allocator, base_allocator, - DebugBandlistMemorySize); - if (code < 0) - return code; -#else - data_allocator = (gs_memory_t *)gs_malloc_memory_init(); - if (!data_allocator) - return_error(gs_error_VMerror); -#endif - locked_allocator = (gs_memory_locked_t *) - gs_alloc_bytes_immovable(data_allocator, sizeof(gs_memory_locked_t), - "alloc_bandlist_memory(locked allocator)"); - if (!locked_allocator) - goto alloc_err; - code = gs_memory_locked_init(locked_allocator, data_allocator); - if (code < 0) - goto alloc_err; - *final_allocator = (gs_memory_t *)locked_allocator; - return 0; -alloc_err: - if (locked_allocator) - free_bandlist_memory((gs_memory_t *)locked_allocator); - else if (data_allocator) - gs_memory_free_all(data_allocator, FREE_ALL_EVERYTHING, - "alloc_bandlist_memory(data allocator)"); - return (code < 0 ? code : gs_note_error(gs_error_VMerror)); -} - -/* Free a bandlist allocator. */ -static void -free_bandlist_memory(gs_memory_t *bandlist_allocator) -{ - gs_memory_locked_t *const lmem = (gs_memory_locked_t *)bandlist_allocator; - gs_memory_t *data_mem = gs_memory_locked_target(lmem); - - gs_memory_free_all(bandlist_allocator, - FREE_ALL_STRUCTURES | FREE_ALL_ALLOCATOR, - "free_bandlist_memory(locked allocator)"); - if (data_mem) - gs_memory_free_all(data_mem, FREE_ALL_EVERYTHING, - "free_bandlist_memory(data allocator)"); -} - -/* Create an allocator with a fixed memory limit. */ -static int -alloc_render_memory(gs_memory_t **final_allocator, - gs_memory_t *base_allocator, long space) -{ - gs_ref_memory_t *rmem = - ialloc_alloc_state((gs_memory_t *)base_allocator, space); - vm_spaces spaces; - int i, code; - - if (rmem == 0) - return_error(gs_error_VMerror); - code = ialloc_add_chunk(rmem, space, "alloc_render_memory"); - if (code < 0) { - gs_memory_free_all((gs_memory_t *)rmem, FREE_ALL_EVERYTHING, - "alloc_render_memory"); - return code; - } - *final_allocator = (gs_memory_t *)rmem; - - /* Call the reclaim procedure to delete the string marking tables */ - /* Only need this once since no other chunks will ever exist */ - - for ( i = 0; i < countof(spaces_indexed); ++i ) - spaces_indexed[i] = 0; - space_local = space_global = (gs_ref_memory_t *)rmem; - spaces.vm_reclaim = gs_nogc_reclaim; /* no real GC on this chunk */ - GS_RECLAIM(&spaces, false); - - return 0; -} - -/* Free an allocator with a fixed memory limit. */ -static void -free_render_memory(gs_memory_t *render_allocator) -{ - if (render_allocator) - gs_memory_free_all(render_allocator, FREE_ALL_EVERYTHING, - "free_render_memory"); -} diff -Nru ghostscript-9.10~dfsg/base/gdevprna.h ghostscript-9.25~dfsg+1/base/gdevprna.h --- ghostscript-9.10~dfsg/base/gdevprna.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevprna.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Generic asynchronous printer driver support */ - -/* Initial version 2/1/1998 by John Desrosiers (soho@crl.com) */ -/* 7/28/98 ghost@aladdin.com - Updated to Ghostscript coding standards. */ - -#ifndef gdevprna_INCLUDED -# define gdevprna_INCLUDED - -# include "gdevprn.h" -# include "gxsync.h" - -/* - * General - * ------- - * Async drivers actually create two separate instances of the device at - * the same time. The first (the writer instance) is only used in the - * interpretation operation; it feeds rendering commands into the command - * lists. The second device instance is used only for rendering the - * commands placed into the command list by the writer. - - * The writer builds a command list for an entire page; the command list - * is only queued for rendering once a page's command list is completely - * built. The only exception to this rule is when the interpreter runs - * out of memory, or when no free command list memory is available. In - * such cases, the interpreter queues a "partial page" consisting of all - * command list data written so far, plus a command indicating that the - * page description is not complete. After queuing the partial page, the - * interpereter waits until the rendering process has freed enough - * command list memory to enable the interpreter to proceed. - - * To avoid deadlocks when the system runs out of memory, special - * memory allocation provisions are made on both the writer and - * renderer sides. On the writer side, enough "reserve" bandlist - * memory is set aside at startup time to cover the needs of queuing a - * partial page to the renderer. The renderer operates out of a fixed - * memory space; that way, it can always complete rendering pages with - * the memory it has. To this end, the writer protects the renderer - * from consuming unbounded amounts of memory by a) never putting - * complex paths into the command list, b) pre-clipping any output - * unless the clip path consists of a single rectangle, c) never putting - * high-level images into the clip path unless the image in question - * meets some very stringent requirements, such as only being rotated by - * even multiples of 90 degrees and having source-image data rows which - * fit into the command buffer in one piece. These restrictions are what - * dictate the "restricted bandlist format." - - * Note that the renderer's instance of the device driver uses the - * renderer's memory. That implies that it must also operate in a small, - * fixed amount of memory, and must do all memory allocation using the - * memory allocator pointed to by the render device's ->memory member. - - * Opening the Device - * ------------------ - * The writer instance is opened first. This occurs when the system - * calls the "standard" open procedure via the device's procedure - * vector. The driver must implement the open function, but must call - * down to gdev_prn_async_write_open instead of calling down to - * gdev_prn_open. Before calling down to gdev_prn_async_write_open, the - * driver must: - * a - init several procedure vectors, to wit: start_render_thread, - * buffer_page, print_page_copies, - * b - init space_params.band.BandWidth, space_params.band.BandHeight, - * space_params.BufferSpace (see extended comments in gdevasyn.c - * for details on computing appropriate values). - * c - if it implements those functions, the driver must init the - * procedure vectors for: put_params, get_hardware_params, - * output_page, open_render_device. - * Notice that there are two procedure vectors: the usual std_procs, and - * the printer-specific printer_procs. - - * Since partial page support imposes extra requirements on drivers, - * such support can be disabled by zeroing out (in the async writer open - * routine, after calling down to gdev_prn_async_write_open) the - * free_up_bandlist_memory member of the driver structure. Doing so - * will, of course, cause interpretation to fail if memory runs out. - - * Once the driver calls down to gdev_prn_async_write_open, the async - * support logic will create a second instance of the driver for - * rendering, but will not open it just yet. Instead, the async logic - * will attempt to synchronize the two device instances. - - * Synchrnonizing the instances - * ---------------------------- - * While still in the gdev_prn_async_write_open routine, the async logic - * will call printer_procs.start_render_thread (which the driver is - * required to implement). start_render_thread must somehow either start a new - * thread or rendez-vous with an existing thread for use in rendering, - * then return. start_render_thread must also have caused the render thread - * to call gdev_prn_async_render_thread, passing it as an argument a magic - * cookie passed to start_render_thread. start_render_thread will only - * return once the device has been closed and all renering has been - * completed. - - * The render device will be opened on the render device's thread, by - * calling printer_procs.open_render_device. - - * Rendering Operation - * ------------------- - * During rendering, the device will not see rendering operations -- the - * first "rendering" operations the driver will see is when the renderer - * instance's print_page_copies or buffer_page routines get called. In - * both cases, the appropriate routine must then perform get_bits calls - * on the async logic in order to retrieve rendered bits, then transmit - * them to the appropriate device buffers. - - * The complication that is introduced is that which is related to partial - * pages: A buffer_page call instructs the driver to grab the rendered bits, - * but to keep the rendered bits available for later instead of marking on - * media. This implies that a buffer_page call opens a context where - * subsequent buffer_page's and print_page_copies' must first initialize the - * rendering buffers with the previous rendering results before calling - * get_bits. The first print_page_copies closes the context that was opened - * by the initial buffer_page -- the driver must go back to normal rendering - * until a new buffer_page comes along. - */ - -/* -------------- Type declarations --------------- */ - -/* typedef is in gdevprn.h */ -/* typedef struct gdev_prn_start_render_params_s gdev_prn_start_render_params;*/ -struct gdev_prn_start_render_params_s { - gx_device_printer *writer_device;/* writer dev that points to render dev */ - gx_semaphore_t *open_semaphore; /* signal this once open_code is set */ - int open_code; /* RETURNS status of open of reader device */ -}; - -/* -------- Macros used to initialize render-specific structures ------ */ - -#define init_async_render_procs(xpdev, xstart_render_thread,\ - xbuffer_page, xprint_page_copies)\ - BEGIN\ - (xpdev)->printer_procs.start_render_thread = (xstart_render_thread);\ - (xpdev)->printer_procs.buffer_page = (xbuffer_page);\ - (xpdev)->printer_procs.print_page_copies = (xprint_page_copies);\ - END - -/* -------------- Global procedure declarations --------- */ - -/* Open this printer device in ASYNC (overlapped) mode. - * - * This routine is always called by the concrete device's xx_open routine - * in lieu of gdev_prn_open. - */ -int gdev_prn_async_write_open(gx_device_printer *pdev, int max_raster, - int min_band_height, int max_src_image_row); - -/* Open the render portion of a printer device in ASYNC (overlapped) mode. - * - * This routine is always called by concrete device's xx_open_render_device - * in lieu of gdev_prn_open. - */ -int gdev_prn_async_render_open(gx_device_printer *prdev); - -/* - * Must be called by async device driver implementation (see - * gdevprna.h under "Synchronizing the Instances"). This is the - * rendering loop, which requires its own thread for as long as - * the device is open. This proc only returns after the device is closed. - */ -int /* rets 0 ok, -ve error code */ -gdev_prn_async_render_thread(gdev_prn_start_render_params *); - -#endif /* gdevprna_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevprn.c ghostscript-9.25~dfsg+1/base/gdevprn.c --- ghostscript-9.10~dfsg/base/gdevprn.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevprn.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,6 +20,7 @@ #include "gp.h" #include "gdevdevn.h" /* for gs_devn_params_s */ #include "gsdevice.h" /* for gs_deviceinitialmatrix */ +#include "gxdevsop.h" /* for gxdso_* */ #include "gsfname.h" #include "gsparam.h" #include "gxclio.h" @@ -28,19 +29,26 @@ #include "gstrans.h" #include "gxdownscale.h" +#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and obejct filter */ + /*#define DEBUGGING_HACKS*/ /* GC information */ static -ENUM_PTRS_WITH(device_printer_enum_ptrs, gx_device_printer *pdev) +ENUM_PTRS_WITH(device_printer_enum_ptrs, gx_device_printer *pdev); if (PRINTER_IS_CLIST(pdev)) - ENUM_PREFIX(st_device_clist, 0); + ENUM_PREFIX(st_device_clist, 2); else - ENUM_PREFIX(st_device_forward, 0); + ENUM_PREFIX(st_device_forward, 2); + break; +case 0:ENUM_RETURN(gx_device_enum_ptr(pdev->parent)); +case 1:ENUM_RETURN(gx_device_enum_ptr(pdev->child)); ENUM_PTRS_END static RELOC_PTRS_WITH(device_printer_reloc_ptrs, gx_device_printer *pdev) { + pdev->parent = gx_device_reloc_ptr(pdev->parent, gcst); + pdev->child = gx_device_reloc_ptr(pdev->child, gcst); if (PRINTER_IS_CLIST(pdev)) RELOC_PREFIX(st_device_clist); else @@ -75,17 +83,31 @@ static void prn_finish_bg_print(gx_device_printer *ppdev); /* ------ Open/close ------ */ - /* Open a generic printer device. */ /* Specific devices may wish to extend this. */ int gdev_prn_open(gx_device * pdev) { - gx_device_printer * const ppdev = (gx_device_printer *)pdev; + gx_device_printer * ppdev; int code; + bool update_procs = false; + + code = install_internal_subclass_devices(&pdev, &update_procs); + if (code < 0) + return code; + + ppdev = (gx_device_printer *)pdev; ppdev->file = NULL; code = gdev_prn_allocate_memory(pdev, NULL, 0, 0); + if (update_procs) { + if (pdev->ObjectHandlerPushed) { + gx_copy_device_procs(pdev->parent, pdev, &gs_obj_filter_device); + pdev = pdev->parent; + } + if (pdev->PageHandlerPushed) + gx_copy_device_procs(pdev->parent, pdev, &gs_flp_device); + } if (code < 0) return code; if (ppdev->OpenOutputFile) @@ -103,13 +125,38 @@ /* close and unlink the files and free the device and its private allocator */ if (ppdev->bg_print.device != NULL) { int closecode; + gx_device_printer *bgppdev = (gx_device_printer *)ppdev->bg_print.device; gx_semaphore_wait(ppdev->bg_print.sema); + /* If numcopies > 1, then the bg_print->device will have closed and reopened + * the output file, so the pointer in the original device is now stale, + * so copy it back. + * If numcopies == 1, this is pointless, but benign. + */ + ppdev->file = bgppdev->file; closecode = gdev_prn_close_printer((gx_device *)ppdev); if (ppdev->bg_print.return_code == 0) ppdev->bg_print.return_code = closecode; /* return code here iff there wasn't another error */ teardown_device_and_mem_for_thread(ppdev->bg_print.device, ppdev->bg_print.thread_id, true); ppdev->bg_print.device = NULL; + if (ppdev->bg_print.ocfile) { + closecode = ppdev->bg_print.oio_procs->fclose(ppdev->bg_print.ocfile, ppdev->bg_print.ocfname, true); + if (ppdev->bg_print.return_code == 0) + ppdev->bg_print.return_code = closecode; + } + if (ppdev->bg_print.ocfname) { + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.ocfname, "prn_finish_bg_print(ocfname)"); + } + if (ppdev->bg_print.obfile) { + closecode = ppdev->bg_print.oio_procs->fclose(ppdev->bg_print.obfile, ppdev->bg_print.obfname, true); + if (ppdev->bg_print.return_code == 0) + ppdev->bg_print.return_code = closecode; + } + if (ppdev->bg_print.obfname) { + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.obfname, "prn_finish_bg_print(obfname)"); + } + ppdev->bg_print.ocfile = ppdev->bg_print.obfile = + ppdev->bg_print.ocfname = ppdev->bg_print.obfname = NULL; } } /* Generic closing for the printer device. */ @@ -133,6 +180,39 @@ return code; } +int +gdev_prn_forwarding_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) +{ + gx_device_printer *ppdev = (gx_device_printer *)pdev; + int code; + + /* if the device is a printer device, we will get here, but allow for a printer device */ + /* that has a non-default dev_spec_op that may want to not support saved_pages, if so */ + /* that device can return an error from the supports_saved_pages spec_op. */ + code = ppdev->orig_procs.dev_spec_op(pdev, dev_spec_op, data, size); + if (dev_spec_op == gxdso_supports_saved_pages) /* printer devices support saved pages */ + return code == 0 ? 1: code; /*default returns 0, but we still want saved-page support */ + return code; +} + +int +gdev_prn_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) +{ + if (dev_spec_op == gxdso_supports_saved_pages) + return 1; + + if (dev_spec_op == gxdso_get_dev_param) { + int code; + dev_param_req_t *request = (dev_param_req_t *)data; + + code = gdev_prn_get_param(pdev, request->Param, request->list); + if (code != gs_error_undefined) + return code; + } + + return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); +} + static int /* returns 0 ok, else -ve error cde */ gdev_prn_setup_as_command_list(gx_device *pdev, gs_memory_t *buffer_memory, byte **the_memory, @@ -140,6 +220,7 @@ bool bufferSpace_is_exact) { gx_device_printer * const ppdev = (gx_device_printer *)pdev; + gx_device *target = pdev; uint space; int code; gx_device_clist *const pclist_dev = (gx_device_clist *)pdev; @@ -147,6 +228,11 @@ bool reallocate = *the_memory != 0; byte *base; + while (target->parent != NULL) { + target = target->parent; + gx_update_from_subclass(target); + } + /* Try to allocate based simply on param-requested buffer size */ #ifdef DEBUGGING_HACKS #define BACKTRACE(first_arg)\ @@ -178,13 +264,14 @@ open_c: ppdev->buf = base; ppdev->buffer_space = space; + pclist_dev->common.is_printer = 1; clist_init_io_procs(pclist_dev, ppdev->BLS_force_memory); - clist_init_params(pclist_dev, base, space, pdev, + clist_init_params(pclist_dev, base, space, target, ppdev->printer_procs.buf_procs, - space_params->band, ppdev->is_async_renderer, + space_params->band, + false, /* do_not_open_or_close_bandfiles */ (ppdev->bandlist_memory == 0 ? pdev->memory->non_gc_memory: ppdev->bandlist_memory), - ppdev->free_up_bandlist_memory, ppdev->clist_disable_mask, ppdev->page_uses_transparency); code = (*gs_clist_device_procs.open_device)( (gx_device *)pcldev ); @@ -195,7 +282,7 @@ space >= space_params->BufferSpace && !bufferSpace_is_exact ) { - space <<= 1; + space += space / 8; if (reallocate) { base = gs_resize_object(buffer_memory, *the_memory, space, @@ -241,6 +328,17 @@ ppdev->buffer_space = 0; was_command_list = true; + prn_finish_bg_print(ppdev); + + gs_free_object(pcldev->memory->non_gc_memory, pcldev->cache_chunk, "free tile cache for clist"); + pcldev->cache_chunk = 0; + + rc_decrement(pcldev->icc_cache_cl, "gdev_prn_tear_down"); + pcldev->icc_cache_cl = NULL; + + clist_free_icc_table(pcldev->icc_table, pcldev->memory); + pcldev->icc_table = NULL; + /* If the clist is a reader clist, free any color_usage_array * memory used by same. */ @@ -323,7 +421,6 @@ pdf14_trans_buffer_size = (ESTIMATED_PDF14_ROW_SPACE(max(1, pdev->width), pdev->color_info.num_components) >> 3); if (new_height < (max_ulong - mem_space) / pdf14_trans_buffer_size) { pdf14_trans_buffer_size *= pdev->height; - mem_space += pdf14_trans_buffer_size; } else { size_ok = 0; } @@ -334,9 +431,7 @@ space_params = ppdev->space_params; space_params.BufferSpace = 0; (*ppdev->printer_procs.get_space_params)(ppdev, &space_params); - if (ppdev->is_async_renderer && space_params.band.BandBufferSpace != 0) - space_params.BufferSpace = space_params.band.BandBufferSpace; - else if (space_params.BufferSpace == 0) { + if (space_params.BufferSpace == 0) { if (space_params.band.BandBufferSpace > 0) space_params.BufferSpace = space_params.band.BandBufferSpace; else { @@ -350,21 +445,35 @@ is_command_list = save_is_command_list; else { is_command_list = space_params.banding_type == BandingAlways || - mem_space >= space_params.MaxBitmap || + ppdev->saved_pages_list != NULL || + mem_space + pdf14_trans_buffer_size >= space_params.MaxBitmap || !size_ok; /* too big to allocate */ } if (!is_command_list) { - /* Try to allocate memory for full memory buffer */ - base = - (reallocate ? - (byte *)gs_resize_object(buffer_memory, the_memory, - (uint)mem_space, "printer buffer") : - gs_alloc_bytes(buffer_memory, (uint)mem_space, - "printer_buffer")); + byte *trans_buffer_reserve_space = NULL; + + /* Try to allocate memory for full memory buffer, then allocate the + pdf14_trans_buffer_size to make sure we have enough space for that */ + /* NOTE: Assumes that caller won't normally call this function if page + size didn't actually change, so we can free/alloc without checking + that the new size is different than old size. + */ + if (reallocate) { + gs_free_object(buffer_memory, the_memory, "printer_buffer"); + } + base = gs_alloc_bytes(buffer_memory, (uint)mem_space, "printer_buffer"); if (base == 0) is_command_list = true; else the_memory = base; + trans_buffer_reserve_space = gs_alloc_bytes(buffer_memory, (uint)pdf14_trans_buffer_size, + "pdf14_trans_buffer_reserve test"); + if (trans_buffer_reserve_space == NULL) { + /* the pdf14 reserve test failed, switch to clist mode, the 'base' memory freed below */ + is_command_list = true; + } else { + gs_free_object(buffer_memory, trans_buffer_reserve_space, "pdf14_trans_buffer_reserve OK"); + } } if (!is_command_list && pass == 1 && PRN_MIN_MEMORY_LEFT != 0 && buffer_memory == pdev->memory->non_gc_memory) { @@ -381,6 +490,8 @@ /* Buffer the image in a command list. */ /* Release the buffer if we allocated it. */ int code; + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + if (!reallocate) { gs_free_object(buffer_memory, the_memory, "printer buffer(open)"); @@ -390,6 +501,9 @@ ecode = gs_note_error(gs_error_VMerror); continue; } + ppdev->bg_print.ocfname = ppdev->bg_print.obfname = + ppdev->bg_print.obfile = ppdev->bg_print.ocfile = NULL; + code = gdev_prn_setup_as_command_list(pdev, buffer_memory, &the_memory, &space_params, !bufferSpace_is_default); @@ -423,7 +537,6 @@ ppdev->orig_procs.open_device = 0; /* prevent uninit'd restore of procs */ return_error(code); } - pmemdev->base = base; } if (ecode == 0) break; @@ -458,7 +571,8 @@ COPY_PROC(update_spot_equivalent_colors); COPY_PROC(ret_devn_params); /* This can be set from the memory device (planar) or target */ - fill_dev_proc(ppdev, put_image, ppdev->orig_procs.put_image); + if ( dev_proc(ppdev, put_image) == gx_default_put_image ) + set_dev_proc(ppdev, put_image, ppdev->orig_procs.put_image); #undef COPY_PROC /* If using a command list, already opened the device. */ if (is_command_list) @@ -504,30 +618,87 @@ return 0; } -/* ------------- Stubs related only to async rendering ------- */ - -int /* rets 0 ok, -ve error if couldn't start thread */ -gx_default_start_render_thread(gdev_prn_start_render_params *params) +/* for saved pages, we need to make sure and free up the saved_pages_list */ +void +gdev_prn_finalize(gx_device *pdev) { - return gs_error_unknownerror; -} + gx_device_printer * const ppdev = (gx_device_printer *)pdev; -/* Open the renderer's copy of a device. */ -/* This is overriden in gdevprna.c */ -int -gx_default_open_render_device(gx_device_printer *pdev) -{ - return gs_error_unknownerror; + if (ppdev->saved_pages_list != NULL) { + gx_saved_pages_list_free(ppdev->saved_pages_list); + ppdev->saved_pages_list = NULL; + } } -/* Close the renderer's copy of a device. */ + +/* ------ Get/put parameters ------ */ + int -gx_default_close_render_device(gx_device_printer *pdev) +gdev_prn_get_param(gx_device *dev, char *Param, void *list) { - return gdev_prn_close( (gx_device *)pdev ); -} + gx_device_printer * const ppdev = (gx_device_printer *)dev; + gs_param_list * plist = (gs_param_list *)list; + bool pageneutralcolor = false; + + if (strcmp(Param, "Duplex") == 0) { + if (ppdev->Duplex_set >= 0) { + if (ppdev->Duplex_set) + return param_write_bool(plist, "Duplex", &ppdev->Duplex); + else + return param_write_null(plist, "Duplex"); + } + } + if (strcmp(Param, "NumRenderingThreads") == 0) { + return param_write_int(plist, "NumRenderingThreads", &ppdev->num_render_threads_requested); + } + if (strcmp(Param, "OpenOutputFile") == 0) { + return param_write_bool(plist, "OpenOutputFile", &ppdev->OpenOutputFile); + } + if (strcmp(Param, "BGPrint") == 0) { + return param_write_bool(plist, "BGPrint", &ppdev->bg_print_requested); + } + if (strcmp(Param, "ReopenPerPage") == 0) { + return param_write_bool(plist, "ReopenPerPage", &ppdev->ReopenPerPage); + } + if (strcmp(Param, "BandListStorage") == 0) { + gs_param_string bls; + /* Force the default to 'memory' if clist file I/O is not included in this build */ + if (clist_io_procs_file_global == NULL) + ppdev->BLS_force_memory = true; + if (ppdev->BLS_force_memory) { + bls.data = (byte *)"memory"; + bls.size = 6; + bls.persistent = false; + } else { + bls.data = (byte *)"file"; + bls.size = 4; + bls.persistent = false; + } + return param_write_string(plist, "BandListStorage", &bls); + } + if (strcmp(Param, "OutputFile") == 0) { + gs_param_string ofns; -/* ------ Get/put parameters ------ */ + ofns.data = (const byte *)ppdev->fname, + ofns.size = strlen(ppdev->fname), + ofns.persistent = false; + return param_write_string(plist, "OutputFile", &ofns); + } + if (strcmp(Param, "saved-pages") == 0) { + gs_param_string saved_pages; + /* Always return an empty string for saved-pages */ + saved_pages.data = (const byte *)""; + saved_pages.size = 0; + saved_pages.persistent = false; + return param_write_string(plist, "saved-pages", &saved_pages); + } + if (dev->icc_struct != NULL) + pageneutralcolor = dev->icc_struct->pageneutralcolor; + if (strcmp(Param, "pageneutralcolor") == 0) { + return param_write_bool(plist, "pageneutralcolor", &pageneutralcolor); + } + return gx_default_get_param(dev, Param, list); +} /* Get parameters. Printer devices add several more parameters */ /* to the default set. */ @@ -538,22 +709,21 @@ int code = gx_default_get_params(pdev, plist); gs_param_string ofns; gs_param_string bls; + gs_param_string saved_pages; + bool pageneutralcolor = false; + if (pdev->icc_struct != NULL) + pageneutralcolor = pdev->icc_struct->pageneutralcolor; if (code < 0 || - (code = param_write_long(plist, "BandBufferSpace", &ppdev->space_params.band.BandBufferSpace)) < 0 || - (code = param_write_int(plist, "BandHeight", &ppdev->space_params.band.BandHeight)) < 0 || - (code = param_write_int(plist, "BandWidth", &ppdev->space_params.band.BandWidth)) < 0 || - (code = param_write_long(plist, "BufferSpace", &ppdev->space_params.BufferSpace)) < 0 || (ppdev->Duplex_set >= 0 && (code = (ppdev->Duplex_set ? param_write_bool(plist, "Duplex", &ppdev->Duplex) : param_write_null(plist, "Duplex"))) < 0) || - (code = param_write_long(plist, "MaxBitmap", &ppdev->space_params.MaxBitmap)) < 0 || (code = param_write_int(plist, "NumRenderingThreads", &ppdev->num_render_threads_requested)) < 0 || (code = param_write_bool(plist, "OpenOutputFile", &ppdev->OpenOutputFile)) < 0 || - (code = param_write_bool(plist, "PageUsesTransparency", &ppdev->page_uses_transparency)) < 0 || (code = param_write_bool(plist, "BGPrint", &ppdev->bg_print_requested)) < 0 || - (code = param_write_bool(plist, "ReopenPerPage", &ppdev->ReopenPerPage)) < 0 + (code = param_write_bool(plist, "ReopenPerPage", &ppdev->ReopenPerPage)) < 0 || + (code = param_write_bool(plist, "pageneutralcolor", &pageneutralcolor)) < 0 ) return code; @@ -575,7 +745,15 @@ ofns.data = (const byte *)ppdev->fname, ofns.size = strlen(ppdev->fname), ofns.persistent = false; - return param_write_string(plist, "OutputFile", &ofns); + if ((code = param_write_string(plist, "OutputFile", &ofns)) < 0) + return code; + + /* Always return an empty string for saved-pages so that get_params followed */ + /* by put_params will have no effect. */ + saved_pages.data = (const byte *)""; + saved_pages.size = 0; + saved_pages.persistent = false; + return param_write_string(plist, "saved-pages", &saved_pages); } /* Validate an OutputFile name by checking any %-formats. */ @@ -600,7 +778,6 @@ bool is_open = pdev->is_open; bool oof = ppdev->OpenOutputFile; bool rpp = ppdev->ReopenPerPage; - bool page_uses_transparency = ppdev->page_uses_transparency; bool old_page_uses_transparency = ppdev->page_uses_transparency; bool bg_print_requested = ppdev->bg_print_requested; bool duplex; @@ -608,13 +785,15 @@ int width = pdev->width; int height = pdev->height; int nthreads = ppdev->num_render_threads_requested; - gdev_prn_space_params sp, save_sp; + gdev_prn_space_params save_sp; gs_param_string ofs; gs_param_string bls; gs_param_dict mdict; + gs_param_string saved_pages; + bool pageneutralcolor = false; - sp = ppdev->space_params; - save_sp = sp; + memset(&saved_pages, 0, sizeof(gs_param_string)); + save_sp = ppdev->space_params; switch (code = param_read_bool(plist, (param_name = "OpenOutputFile"), &oof)) { default: @@ -634,16 +813,6 @@ break; } - switch (code = param_read_bool(plist, (param_name = "PageUsesTransparency"), - &page_uses_transparency)) { - default: - ecode = code; - param_signal_error(plist, param_name, ecode); - case 0: - case 1: - break; - } - if (ppdev->Duplex_set >= 0) /* i.e., Duplex is supported */ switch (code = param_read_bool(plist, (param_name = "Duplex"), &duplex)) { @@ -660,50 +829,17 @@ case 1: ; } -#define CHECK_PARAM_CASES(member, bad, label)\ - case 0:\ - if ((sp.params_are_read_only ? sp.member != save_sp.member : bad))\ - ecode = gs_error_rangecheck;\ - else\ - break;\ - goto label;\ - default:\ - ecode = code;\ -label:\ - param_signal_error(plist, param_name, ecode);\ - case 1:\ - break - - switch (code = param_read_long(plist, (param_name = "MaxBitmap"), &sp.MaxBitmap)) { - CHECK_PARAM_CASES(MaxBitmap, sp.MaxBitmap < 0, mbe); - } - - switch (code = param_read_long(plist, (param_name = "BufferSpace"), &sp.BufferSpace)) { - CHECK_PARAM_CASES(BufferSpace, sp.BufferSpace < 10000, bse); - } - - switch (code = param_read_int(plist, (param_name = "BandWidth"), &sp.band.BandWidth)) { - CHECK_PARAM_CASES(band.BandWidth, sp.band.BandWidth < 0, bwe); - } - - switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) { - CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < 0, bhe); - } - - switch (code = param_read_long(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) { - CHECK_PARAM_CASES(band.BandBufferSpace, sp.band.BandBufferSpace < 0, bbse); - } - switch (code = param_read_string(plist, (param_name = "BandListStorage"), &bls)) { case 0: /* Only accept 'file' if the file procs are include in the build */ if ((bls.size > 1) && (bls.data[0] == 'm' || (clist_io_procs_file_global != NULL && bls.data[0] == 'f'))) break; - /* falls through */ + /* fall through */ default: ecode = code; param_signal_error(plist, param_name, ecode); + /* fall through */ case 1: bls.data = 0; break; @@ -720,10 +856,11 @@ code = validate_output_file(&ofs, pdev->memory); if (code >= 0) break; - /* falls through */ + /* fall through */ default: ecode = code; param_signal_error(plist, param_name, ecode); + /* fall through */ case 1: ofs.data = 0; break; @@ -766,6 +903,25 @@ break; } + switch (code = param_read_string(plist, (param_name = "saved-pages"), + &saved_pages)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + + /* NB: put_params to change pageneutralcolor is allowed, but has no effect */ + /* It will be set according the GrayDetection. Allowing it prevents errors */ + if (pdev->icc_struct != NULL) + pageneutralcolor = pdev->icc_struct->pageneutralcolor; + if ((code = param_read_bool(plist, (param_name = "pageneutralcolor"), + &pageneutralcolor)) < 0) { + ecode = code; + param_signal_error(plist, param_name, ecode); + } if (ecode < 0) return ecode; @@ -778,13 +934,16 @@ ppdev->OpenOutputFile = oof; ppdev->ReopenPerPage = rpp; - ppdev->page_uses_transparency = page_uses_transparency; + + if (ppdev->bg_print_requested && !bg_print_requested) { + prn_finish_bg_print(ppdev); + } + ppdev->bg_print_requested = bg_print_requested; if (duplex_set >= 0) { ppdev->Duplex = duplex; ppdev->Duplex_set = duplex_set; } - ppdev->space_params = sp; ppdev->num_render_threads_requested = nthreads; if (bls.data != 0) { ppdev->BLS_force_memory = (bls.data[0] == 'm'); @@ -794,7 +953,7 @@ /* Formerly, would not reallocate if device is not open: */ /* we had to patch this out (see News for 5.50). */ code = gdev_prn_maybe_realloc_memory(ppdev, &save_sp, width, height, - old_page_uses_transparency); + old_page_uses_transparency); if (code < 0) return code; @@ -821,6 +980,13 @@ if (code < 0) return code; } + + /* Processing the saved_pages string MAY have side effects, such as printing, */ + /* allocating or freeing a list. This is (sort of) a write-only parameter, so */ + /* the get_params will always return an empty string (a no-op action). */ + if (saved_pages.data != 0 && saved_pages.size != 0) { + return gx_saved_pages_param_process(ppdev, (byte *)saved_pages.data, saved_pages.size); + } return 0; } @@ -838,30 +1004,28 @@ /* If seekable is true, then the printer outputfile must be seekable. */ /* If bg_print_ok is true, the device print_page_copies is compatible with the */ /* background printing, i.e., thread safe and does not change the device. */ -static int /* 0 ok, -ve error, or 1 if successfully upgraded to buffer_page */ +/* If the printer device is in 'saved_pages' mode, then background printing is */ +/* irrelevant and is ignored. In this case, pages are saved to the list. */ +static int /* 0 ok, -ve error */ gdev_prn_output_page_aux(gx_device * pdev, int num_copies, int flush, bool seekable, bool bg_print_ok) { gx_device_printer * const ppdev = (gx_device_printer *)pdev; gs_devn_params *pdevn_params; - int outcode = 0, closecode = 0, errcode = 0, endcode; - bool upgraded_copypage = false; + int outcode = 0, errcode = 0, endcode, closecode = 0; + int code; prn_finish_bg_print(ppdev); /* finish any previous background printing */ - if (num_copies > 0 || !flush) { - int code = gdev_prn_open_printer_seekable(pdev, 1, seekable); + if (num_copies > 0 && ppdev->saved_pages_list != NULL) { + /* We are putting pages on a list */ + if ((code = gx_saved_pages_list_add(ppdev)) < 0) + return code; - if (code < 0) + } else if (num_copies > 0 || !flush) { + if ((code = gdev_prn_open_printer_seekable(pdev, 1, seekable)) < 0) return code; - /* If copypage request, try to do it using buffer_page */ - if ( !flush && - (*ppdev->printer_procs.buffer_page) - (ppdev, ppdev->file, num_copies) >= 0 - ) { - upgraded_copypage = true; - flush = true; - } else if (num_copies > 0) { + if (num_copies > 0) { int threads_enabled = 0; int print_foreground = 1; /* default to foreground printing */ @@ -881,51 +1045,71 @@ while (ppdev->bg_print_requested && threads_enabled) { gx_device *ndev; gx_device_printer *npdev; - gx_device_clist_reader *ncrdev; gx_device_clist_reader *crdev = (gx_device_clist_reader *)ppdev; - gs_devn_params *pdevn_params; if ((code = clist_close_writer_and_init_reader((gx_device_clist *)ppdev)) < 0) /* should not happen -- do foreground print */ break; + /* We need to hang onto references to these files, so we can ensure the main file data + * gets freed with the correct allocator. + */ + ppdev->bg_print.ocfname = + (char *)gs_alloc_bytes(ppdev->memory->non_gc_memory, + strnlen(crdev->page_info.cfname, gp_file_name_sizeof - 1) + 1, "gdev_prn_output_page_aux(ocfname)"); + ppdev->bg_print.obfname = + (char *)gs_alloc_bytes(ppdev->memory->non_gc_memory, + strnlen(crdev->page_info.bfname, gp_file_name_sizeof - 1) + 1,"gdev_prn_output_page_aux(ocfname)"); + + if (!ppdev->bg_print.ocfname || !ppdev->bg_print.obfname) + break; + + strncpy(ppdev->bg_print.ocfname, crdev->page_info.cfname, strnlen(crdev->page_info.cfname, gp_file_name_sizeof - 1) + 1); + strncpy(ppdev->bg_print.obfname, crdev->page_info.bfname, strnlen(crdev->page_info.bfname, gp_file_name_sizeof - 1) + 1); + ppdev->bg_print.obfile = crdev->page_info.bfile; + ppdev->bg_print.ocfile = crdev->page_info.cfile; + ppdev->bg_print.oio_procs = crdev->page_info.io_procs; + crdev->page_info.cfile = crdev->page_info.bfile = NULL; + if (ppdev->bg_print.sema == NULL) - if (((ppdev->bg_print.sema = gx_semaphore_alloc(ppdev->memory->non_gc_memory)) == NULL)) + { + ppdev->bg_print.sema = gx_semaphore_label(gx_semaphore_alloc(ppdev->memory->non_gc_memory), "BGPrint"); + if (ppdev->bg_print.sema == NULL) break; /* couldn't create the semaphore */ + } - ndev = setup_device_and_mem_for_thread(pdev->memory->thread_safe_memory, pdev, true); + ndev = setup_device_and_mem_for_thread(pdev->memory->thread_safe_memory, pdev, true, NULL); if (ndev == NULL) { break; } ppdev->bg_print.device = ndev; ppdev->bg_print.num_copies = num_copies; npdev = (gx_device_printer *)ndev; - ncrdev = (gx_device_clist_reader *)ndev; npdev->bg_print_requested = 0; npdev->num_render_threads_requested = ppdev->num_render_threads_requested; /* Now start the thread to print the page */ - if ((code == gp_thread_start(prn_print_page_in_background, - (void *)&(ppdev->bg_print), - &(ppdev->bg_print.thread_id))) < 0) { + if ((code = gp_thread_start(prn_print_page_in_background, + (void *)&(ppdev->bg_print), + &(ppdev->bg_print.thread_id))) < 0) { /* Did not start cleanly - clean up is in print_foreground block below */ break; } + gp_thread_label(ppdev->bg_print.thread_id, "BG print thread"); /* Page was succesfully started in bg_print mode */ print_foreground = 0; /* Now we need to set up the next page so it will use new clist files */ - /* Close (but don't delete) the files since the background printing now owns them */ - if ((code = crdev->page_info.io_procs->fclose(crdev->page_info.cfile, crdev->page_info.cfname, false)) < 0 || - (code = crdev->page_info.io_procs->fclose(crdev->page_info.bfile, crdev->page_info.bfname, false)) < 0) { - return_error(gs_error_unknownerror); /* shouldn't happen */ - } - crdev->page_info.cfile = crdev->page_info.bfile = NULL; if ((code = clist_open(pdev)) < 0) /* this should do it */ /* OOPS! can't proceed with the next page */ return code; /* probably ioerror */ break; /* exit the while loop */ } if (print_foreground) { + + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.ocfname, "gdev_prn_output_page_aux(ocfname)"); + gs_free_object(ppdev->memory->non_gc_memory, ppdev->bg_print.obfname, "gdev_prn_output_page_aux(obfname)"); + ppdev->bg_print.ocfname = ppdev->bg_print.obfname = NULL; + /* either bg_print was not requested or was not able to start */ if (ppdev->bg_print.sema != NULL && ppdev->bg_print.device != NULL) { /* There was a problem. Teardown the device and its allocator, but */ @@ -941,8 +1125,8 @@ fflush(ppdev->file); errcode = (ferror(ppdev->file) ? gs_note_error(gs_error_ioerror) : 0); /* NB: background printing does this differently in its thread */ - if (!upgraded_copypage) - closecode = gdev_prn_close_printer(pdev); + closecode = gdev_prn_close_printer(pdev); + } } } @@ -954,19 +1138,19 @@ free_separation_names(pdev->memory, &(pdevn_params->separations)); pdevn_params->num_separation_order_names = 0; } - endcode = (PRINTER_IS_CLIST(ppdev) && !ppdev->is_async_renderer ? - clist_finish_page(pdev, flush) : 0); + endcode = (PRINTER_IS_CLIST(ppdev) && + !((gx_device_clist_common *)ppdev)->do_not_open_or_close_bandfiles ? + clist_finish_page(pdev, flush) : 0); if (outcode < 0) return outcode; if (errcode < 0) return errcode; - if (closecode < 0) - return closecode; if (endcode < 0) return endcode; endcode = gx_finish_output_page(pdev, num_copies, flush); - return (endcode < 0 ? endcode : upgraded_copypage ? 1 : 0); + code = (endcode < 0 ? endcode : closecode < 0 ? closecode : 0); + return code; } int @@ -1038,18 +1222,6 @@ } /* - * Buffer a (partial) rasterized page & optionally print result multiple times. - * The default implementation returns error, since the driver needs to override - * this (in procedure vector) in configurations where this call may occur. - */ -int -gx_default_buffer_page(gx_device_printer *pdev, FILE *prn_stream, - int num_copies) -{ - return gs_error_unknownerror; -} - -/* * Print a page in the background. When printing is complete, * post the return code and signal the foreground (semaphore). * This is the procedure that is run in the background thread. @@ -1149,8 +1321,8 @@ if (seekable && !gp_fseekable(ppdev->file)) { errprintf(pdev->memory, "I/O Error: Output File \"%s\" must be seekable\n", ppdev->fname); - if (ppdev->file != pdev->memory->gs_lib_ctx->fstdout - && ppdev->file != pdev->memory->gs_lib_ctx->fstderr) { + if (!IS_LIBCTX_STDOUT(pdev->memory, ppdev->file) + && !IS_LIBCTX_STDERR(pdev->memory ,ppdev->file)) { code = gx_device_close_output_file(pdev, ppdev->fname, ppdev->file); if (code < 0) @@ -1162,6 +1334,7 @@ } } ppdev->file_is_new = true; + return 0; } int @@ -1205,6 +1378,7 @@ start = y / band_height; end = (y + height + band_height - 1) / band_height; if (crdev->color_usage_array == NULL) { + return -1; } for (i = start; i < end; ++i) { or |= crdev->color_usage_array[i].or; @@ -1274,8 +1448,12 @@ if (plane_index >= 0) depth = render_plane->depth; - else + else { depth = target->color_info.depth; + if (target->is_planar) + depth /= target->color_info.num_components; + } + mdproto = gdev_mem_device_for_bits(depth); if (mdproto == 0) return_error(gs_error_rangecheck); @@ -1291,13 +1469,25 @@ /* The following is a special hack for setting up printer devices. */ assign_dev_procs(mdev, mdproto); check_device_separable((gx_device *)mdev); + /* In order for saved-pages to work, we need to hook the dev_spec_op */ + if (mdev->procs.dev_spec_op == NULL) + set_dev_proc(mdev, dev_spec_op, gdev_prn_dev_spec_op); +#ifdef DEBUG + /* scanning sources didn't show anything, but if a device gets changed or added */ + /* that has its own dev_spec_op, it should call the gdev_prn_spec_op as well */ + else + errprintf(mdev->memory, "Warning: printer device has private dev_spec_op\n"); +#endif gx_device_fill_in_procs((gx_device *)mdev); } else { gs_make_mem_device(mdev, mdproto, mem, (color_usage == NULL ? 1 : 0), - (target == (gx_device *)mdev ? NULL : target)); + target); } mdev->width = target->width; mdev->band_y = y; + mdev->log2_align_mod = target->log2_align_mod; + mdev->pad = target->pad; + mdev->is_planar = target->is_planar; /* * The matrix in the memory device is irrelevant, * because all we do with the device is call the device-level @@ -1306,8 +1496,13 @@ */ gs_deviceinitialmatrix(target, &mdev->initial_matrix); if (plane_index >= 0) { - gx_device_plane_extract *edev = - gs_alloc_struct(mem, gx_device_plane_extract, + gx_device_plane_extract *edev; + + /* Guard against potential NULL dereference in gs_alloc_struct */ + if (!mem) + return_error(gs_error_undefined); + + edev = gs_alloc_struct(mem, gx_device_plane_extract, &st_device_plane_extract, "create_buf_device"); if (edev == 0) { @@ -1342,7 +1537,9 @@ (render_plane && render_plane->index >= 0 ? render_plane->depth : target->color_info.depth); mdev.width = target->width; - mdev.num_planes = 0; + mdev.is_planar = target->is_planar; + mdev.pad = target->pad; + mdev.log2_align_mod = target->log2_align_mod; if (gdev_mem_bits_size(&mdev, target->width, height, &(space->bits)) < 0) return_error(gs_error_VMerror); space->line_ptrs = gdev_mem_line_ptrs_size(&mdev, target->width, height); @@ -1352,7 +1549,7 @@ /* Set up the buffer device. */ int -gx_default_setup_buf_device(gx_device *bdev, byte *buffer, int bytes_per_line, +gx_default_setup_buf_device(gx_device *bdev, byte *buffer, int raster, byte **line_ptrs, int y, int setup_height, int full_height) { @@ -1360,12 +1557,8 @@ (gs_device_is_memory(bdev) ? (gx_device_memory *)bdev : (gx_device_memory *)(((gx_device_plane_extract *)bdev)->plane_dev)); byte **ptrs = line_ptrs; - int raster = bytes_per_line; int code; - /****** HACK ******/ - if ((gx_device *)mdev == bdev && mdev->num_planes) - raster = bitmap_raster(mdev->planes[0].depth * mdev->width); if (ptrs == 0) { /* * Before allocating a new line pointer array, if there is a previous @@ -1381,8 +1574,8 @@ */ ptrs = (byte **) gs_alloc_byte_array(mdev->memory, - (mdev->num_planes ? - full_height * mdev->num_planes : + (mdev->is_planar ? + full_height * mdev->color_info.num_components : setup_height), sizeof(byte *), "setup_buf_device"); if (ptrs == 0) @@ -1391,7 +1584,7 @@ mdev->foreign_line_pointers = false; } mdev->height = full_height; - code = gdev_mem_set_line_ptrs(mdev, buffer + raster * y, bytes_per_line, + code = gdev_mem_set_line_ptrs(mdev, buffer + raster * y, raster, ptrs, setup_height); mdev->height = setup_height; bdev->height = setup_height; /* do here in case mdev == bdev */ @@ -1536,14 +1729,14 @@ return(1); if (sp1.BufferSpace != sp2.BufferSpace) return(1); - if (sp1.band.page_uses_transparency != sp2.band.page_uses_transparency) - return(1); if (sp1.band.BandWidth != sp2.band.BandWidth) return(1); if (sp1.band.BandHeight != sp2.band.BandHeight) return(1); if (sp1.band.BandBufferSpace != sp2.band.BandBufferSpace) return(1); + if (sp1.band.tile_cache_size != sp2.band.tile_cache_size) + return(1); if (sp1.params_are_read_only != sp2.params_are_read_only) return(1); if (sp1.banding_type != sp2.banding_type) diff -Nru ghostscript-9.10~dfsg/base/gdevprn.h ghostscript-9.25~dfsg+1/base/gdevprn.h --- ghostscript-9.10~dfsg/base/gdevprn.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevprn.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,49 +30,21 @@ #include "gxdevmem.h" #include "gxclist.h" #include "gxclthrd.h" /* for background printing */ +#include "gxclpage.h" /* for saved_pages */ #include "gxrplane.h" #include "gsparam.h" /* * Define the parameters for the printer rendering method. - * If the entire bitmap fits in PRN_MAX_BITMAP, and there is at least + * If the entire bitmap fits in MAX_BITMAP, and there is at least * PRN_MIN_MEMORY_LEFT memory left after allocating it, render in RAM, * otherwise use a command list with a size of PRN_BUFFER_SPACE. * (These are parameters that can be changed by a client program.) */ -/* Define parameters for machines with little dinky RAMs.... */ -#define PRN_MAX_BITMAP_SMALL 32000 -#define PRN_BUFFER_SPACE_SMALL 25000 -#define PRN_MIN_MEMORY_LEFT_SMALL 32000 -/* Define parameters for machines with great big hulking RAMs.... */ -#define PRN_MAX_BITMAP_LARGE 10000000L -#define PRN_BUFFER_SPACE_LARGE 4000000L -#define PRN_MIN_MEMORY_LEFT_LARGE 500000L -/* Define parameters valid on all machines. */ -#define PRN_MIN_BUFFER_SPACE 10000 /* give up if less than this */ -/* Now define conditional parameters. */ -#if arch_small_memory -# define PRN_MAX_BITMAP PRN_MAX_BITMAP_SMALL -# define PRN_BUFFER_SPACE PRN_BUFFER_SPACE_SMALL -# define PRN_MIN_MEMORY_LEFT PRN_MIN_MEMORY_LEFT_SMALL -#else -/****** These should really be conditional on gs_debug_c('.') if - ****** DEBUG is defined, but they're used in static initializers, - ****** so we can't do it. - ******/ -# if 0 /****** # ifdef DEBUG ***** */ -# define PRN_MAX_BITMAP\ - (gs_debug_c('.') ? PRN_MAX_BITMAP_SMALL : PRN_MAX_BITMAP_LARGE) -# define PRN_BUFFER_SPACE\ - (gs_debug_c('.') ? PRN_BUFFER_SPACE_SMALL : PRN_BUFFER_SPACE_LARGE) -# define PRN_MIN_MEMORY_LEFT\ - (gs_debug_c('.') ? PRN_MIN_MEMORY_LEFT_SMALL : PRN_MIN_MEMORY_LEFT_LARGE) -# else -# define PRN_MAX_BITMAP PRN_MAX_BITMAP_LARGE -# define PRN_BUFFER_SPACE PRN_BUFFER_SPACE_LARGE -# define PRN_MIN_MEMORY_LEFT PRN_MIN_MEMORY_LEFT_LARGE -# endif -#endif +#define PRN_MAX_BITMAP MAX_BITMAP /* see gxdevice.h */ +#define PRN_BUFFER_SPACE BUFFER_SPACE /* see gxdevice.h */ +#define PRN_MIN_MEMORY_LEFT MIN_MEMORY_LEFT /* see gxdevice.h */ +#define PRN_MIN_BUFFER_SPACE MIN_BUFFER_SPACE /* see gxdevice.h */ /* Define the abstract type for a printer device. */ #ifndef gx_device_printer_DEFINED @@ -80,21 +52,21 @@ typedef struct gx_device_printer_s gx_device_printer; #endif -/* Define the abstract type for some band device procedures' arguments. */ -typedef struct gdev_prn_start_render_params_s gdev_prn_start_render_params; - -/* Define the abstract type for a page queue for async rendering. */ -#ifndef gx_page_queue_DEFINED -# define gx_page_queue_DEFINED -typedef struct gx_page_queue_s gx_page_queue_t; -#endif - /* Define the abstract type for parameters describing buffer space. */ #ifndef gdev_prn_space_params_DEFINED # define gdev_prn_space_params_DEFINED -typedef struct gdev_prn_space_params_s gdev_prn_space_params; +typedef struct gdev_space_params_s gdev_prn_space_params; +#endif + +/* Define the abstract type for parameters describing buffer space. */ +#ifndef gdev_prn_banding_type_DEFINED +# define gdev_prn_banding_type_DEFINED +typedef struct gdev_banding_type gdev_prn_banding_type; #endif +/* Define the abstract type for some band device procedures' arguments. */ +typedef struct gdev_prn_start_render_params_s gdev_prn_start_render_params; + /* * Define the special procedures for band devices. */ @@ -142,62 +114,6 @@ void proc(const gx_device_printer *, gdev_prn_space_params *) prn_dev_proc_get_space_params((*get_space_params)); - /* - * Only for gx_device_printer devices that overlap interpreting and - * rasterizing. Since there are 2 instances of the device (1 for writing - * the cmd list & 1 for rasterizing it), and each device is associated - * with an different thread, this function is called to start the - * rasterizer's thread. Once started, the rasterizer thread must call - * down to gdev_prn_asnyc_render_thread, which will only return after - * device closes. - * - * Caller is gdevprna.open, calls driver implementation or default. - */ - -#define prn_dev_proc_start_render_thread(proc)\ - int proc(gdev_prn_start_render_params *) - prn_dev_proc_start_render_thread((*start_render_thread)); - - /* - * Only for gx_device_printer devices that overlap interpreting and - * rasterizing. Since there are 2 instances of the device (1 for writing - * the cmd list & 1 for rasterizing it), these fns are called to - * open/close the rasterizer's instance, once the writer's instance has - * been created & init'd. These procs must cascade down to - * gdev_prn_async_render_open/close. - * - * Caller is gdevprna, calls driver implementation or default. - */ - -#define prn_dev_proc_open_render_device(proc)\ - int proc(gx_device_printer *) - prn_dev_proc_open_render_device((*open_render_device)); - -#define prn_dev_proc_close_render_device(proc)\ - int proc(gx_device_printer *) - prn_dev_proc_close_render_device((*close_render_device)); - - /* - * Buffer a page on the output device. A page may or may not have been - * fully rendered, but the rasterizer needs to realize the page to free - * up resources or support copypage. Printing a page may involve zero or - * more buffer_pages. All buffer_page output is overlaid in the buffer - * until a terminating print_page or print_page_copies clears the - * buffer. Note that, after the first buffer_page, the driver must call - * the lower-level gdev_prn_render_lines procedure instead of - * get_bits. The difference is that gdev_prn_render_lines requires the - * caller to supply the same buffered bitmap that was computed as a - * result of a previous buffer_page, so that gdev_prn_render_lines can - * add further marks to the existing buffered image. NB that output must - * be accumulated in buffer even if num_copies == 0. - * - * Caller is expected to be gdevprn, calls driver implementation or - * default. */ - -#define prn_dev_proc_buffer_page(proc)\ - int proc(gx_device_printer *, FILE *, int) - prn_dev_proc_buffer_page((*buffer_page)); - } gx_printer_device_procs; /* ------ Printer device definition ------ */ @@ -206,23 +122,8 @@ /* This must be preceded by gx_device_common. */ /* Printer devices are actually a union of a memory device */ /* and a clist device, plus some additional state. */ + #define prn_fname_sizeof gp_file_name_sizeof -typedef enum { - BandingAuto = 0, - BandingAlways, - BandingNever -} gdev_prn_banding_type; - -/* if you make any additions/changes to this structure you need to make - the appropriate additions/changes to the compare_gdev_prn_space_params() - function in gdevprn.c */ -struct gdev_prn_space_params_s { - long MaxBitmap; /* max size of non-buffered bitmap */ - long BufferSpace; /* space to use for buffer */ - gx_band_params_t band; /* see gxband.h */ - bool params_are_read_only; /* true if put_params may not modify this struct */ - gdev_prn_banding_type banding_type; /* used to force banding or bitmap */ -}; typedef struct bg_print_s { gx_semaphore_t *sema; /* used by foreground to wait */ @@ -230,6 +131,11 @@ gp_thread_id thread_id; int num_copies; int return_code; /* result from background print thread */ + char *ocfname; /* command file name */ + clist_file_ptr ocfile; /* command file, normally 0 */ + char *obfname; /* block file name */ + clist_file_ptr obfile; /* block file, normally 0 */ + const clist_io_procs_t *oio_procs; } bg_print_t; #define gx_prn_device_common\ @@ -238,13 +144,10 @@ gx_printer_device_procs printer_procs;\ /* ------ Device parameters that must be set ------ */\ /* ------ before calling the device open routine. ------ */\ - gdev_prn_space_params space_params;\ char fname[prn_fname_sizeof]; /* OutputFile */\ - bool BLS_force_memory;\ /* ------ Other device parameters ------ */\ bool OpenOutputFile;\ bool ReopenPerPage;\ - bool page_uses_transparency; /* PDF 1.4 transparency is used on page */\ bool Duplex;\ int Duplex_set; /* -1 = not supported */\ /* ------ End of parameters ------ */\ @@ -253,18 +156,13 @@ long buffer_space; /* amount of space for clist buffer, */\ /* 0 means not using clist */\ byte *buf; /* buffer for rendering */\ - /* ---- Begin async rendering support --- */\ gs_memory_t *buffer_memory; /* allocator for command list */\ gs_memory_t *bandlist_memory; /* allocator for bandlist files */\ - proc_free_up_bandlist_memory((*free_up_bandlist_memory)); /* if nz, proc to free some bandlist memory */\ - gx_page_queue_t *page_queue; /* if <> 0,page queue for gdevprna NOT GC'd */\ - bool is_async_renderer; /* device is only the rendering part of async device */\ - gx_device_printer *async_renderer; /* in async writer, pointer to async renderer */\ uint clist_disable_mask; /* mask of clist options to disable */\ - /* ---- End async rendering support --- */\ bool bg_print_requested; /* request background printing of page from clist */\ bg_print_t bg_print; /* background printing data shared with thread */\ int num_render_threads_requested; /* for multiple band rendering threads */\ + gx_saved_pages_list *saved_pages_list; /* list when we are saving pages instead of printing */\ gx_device_procs save_procs_while_delaying_erasepage; /* save device procs while delaying erasepage. */\ gx_device_procs orig_procs /* original (std_)procs */ @@ -297,16 +195,17 @@ #define gdev_prn_map_color_rgb gx_default_b_w_map_color_rgb dev_proc_get_params(gdev_prn_get_params); dev_proc_put_params(gdev_prn_put_params); +dev_proc_dev_spec_op(gdev_prn_forwarding_dev_spec_op); +dev_proc_dev_spec_op(gdev_prn_dev_spec_op); + +void gdev_prn_finalize(gx_device *dev); /* cleanup when device is freed */ +int gdev_prn_get_param(gx_device *dev, char *Param, void *list); /* Default printer-specific procedures */ /* VMS limits procedure names to 31 characters. */ prn_dev_proc_get_space_params(gx_default_get_space_params); /* BACKWARD COMPATIBILITY */ #define gdev_prn_default_get_space_params gx_default_get_space_params -prn_dev_proc_start_render_thread(gx_default_start_render_thread); /* for async rendering only, see gdevprna.c */ -prn_dev_proc_open_render_device(gx_default_open_render_device); -prn_dev_proc_close_render_device(gx_default_close_render_device); -prn_dev_proc_buffer_page(gx_default_buffer_page); /* returns an error */ /* Macro for generating procedure table */ #define prn_procs(p_open, p_output_page, p_close)\ @@ -386,7 +285,7 @@ NULL, /* push_transparency_state */\ NULL, /* pop_transparency_state */\ NULL, /* put_image */\ - NULL, /* dev_spec_op */\ + gdev_prn_dev_spec_op, /* dev_spec_op */\ NULL, /* copy plane */\ gx_default_get_profile, /* get_profile */\ gx_default_set_graphics_type_tag /* set_graphics_type_tag */\ @@ -421,28 +320,23 @@ gx_default_setup_buf_device,\ gx_default_destroy_buf_device\ },\ - gdev_prn_default_get_space_params,\ - gx_default_start_render_thread,\ - gx_default_open_render_device,\ - gx_default_close_render_device,\ - gx_default_buffer_page\ - },\ - { PRN_MAX_BITMAP, PRN_BUFFER_SPACE,\ - { BAND_PARAMS_INITIAL_VALUES },\ - 0/*false*/, /* params_are_read_only */\ - BandingAuto /* banding_type */\ + gdev_prn_default_get_space_params\ },\ { 0 }, /* fname */\ - 0/*false*/, /* BLS_force_memory */\ 0/*false*/, /* OpenOutputFile */\ 0/*false*/, /* ReopenPerPage */\ - 0/*false*/, /* page_uses_transparency */\ 0/*false*/, duplex_set, /* Duplex[_set] */\ - 0/*false*/, 0, 0, 0, /* file_is_new ... buf */\ - 0, 0, 0, 0, 0/*false*/, 0, 0, /* buffer_memory ... clist_dis'_mask */\ + 0/*false*/, /* file_is_new */\ + 0, /* *file */\ + 0, /* buffer_space */\ + 0, /* *buf */\ + 0, /* *buffer_memory */\ + 0, /* *bandlist_memory */\ + 0, /* clist_disable_mask */\ 0/*false*/, /* bg_print_requested */\ { 0/*sema*/, 0/*device*/, 0/*thread_id*/, 0/*num_copies*/, 0/*return_code*/ }, /* bg_print */\ 0, /* num_render_threads_requested */\ + 0, /* saved_pages_list */\ { 0 }, /* save_procs_while_delaying_erasepage */\ { 0 } /* ... orig_procs */ #define prn_device_body_rest_(print_page)\ @@ -574,6 +468,8 @@ */ #define gdev_prn_raster(pdev) gx_device_raster((gx_device *)(pdev), 0) +#define gdev_prn_raster_chunky(pdev) gx_device_raster_chunky((gx_device *)(pdev), 0) + /* * Determine (conservatively) what colors are used in a given range of scan * lines, and return the actual range of scan lines to which the result diff -Nru ghostscript-9.10~dfsg/base/gdevpxat.h ghostscript-9.25~dfsg+1/base/gdevpxat.h --- ghostscript-9.10~dfsg/base/gdevpxat.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevpxat.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -106,7 +106,6 @@ pxaBlockByteLength, /* 2.0 */ pxaNumberOfScanLines = 115, - pxaPrintableArea = 116, /* 3.0+ */ pxaColorTreatment = 120, diff -Nru ghostscript-9.10~dfsg/base/gdevpxen.h ghostscript-9.25~dfsg+1/base/gdevpxen.h --- ghostscript-9.10~dfsg/base/gdevpxen.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevpxen.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -52,11 +52,6 @@ } pxeColorDepth_t; typedef enum { - eCRGB = 5, /* Note: for this enumeration, 0 is not a valid value */ - pxeColorimetricColorSpace_next -} pxeColorimetricColorSpace_t; /* 2.0 */ - -typedef enum { eDirectPixel = 0, eIndexedPixel, pxeColorMapping_next @@ -67,7 +62,6 @@ eGray, eRGB, eSRGB = 6, /* 2.0, Note: HP's value is 6 not the expected 3 */ - eGraySub = 7, /* 3.0+ */ pxeColorSpace_next } pxeColorSpace_t; diff -Nru ghostscript-9.10~dfsg/base/gdevpxop.h ghostscript-9.25~dfsg+1/base/gdevpxop.h --- ghostscript-9.10~dfsg/base/gdevpxop.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevpxop.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gdevrops.c ghostscript-9.25~dfsg+1/base/gdevrops.c --- ghostscript-9.10~dfsg/base/gdevrops.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevrops.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -135,13 +135,14 @@ } /* Initialize a RasterOp source device. */ +/* 'target' device must not be NULL */ void gx_make_rop_texture_device(gx_device_rop_texture * dev, gx_device * target, gs_logical_operation_t log_op, const gx_device_color * texture) { gx_device_init((gx_device *) dev, (const gx_device *)&gs_rop_texture_device, - (target ? target->memory : NULL), true); + target->memory, true); gx_device_set_target((gx_device_forward *)dev, target); /* Drawing operations are defaulted, non-drawing are forwarded. */ check_device_separable((gx_device *) dev); diff -Nru ghostscript-9.10~dfsg/base/gdevsclass.c ghostscript-9.25~dfsg+1/base/gdevsclass.c --- ghostscript-9.10~dfsg/base/gdevsclass.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevsclass.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,911 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Common code for subclassing devices */ +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gsdevice.h" /* requires gsmatrix.h */ +#include "gxdcolor.h" /* for gx_device_black/white */ +#include "gxiparam.h" /* for image source size */ +#include "gxgstate.h" +#include "gxpaint.h" +#include "gxpath.h" +#include "gxcpath.h" +#include "gxcmap.h" /* color mapping procs */ +#include "gsstype.h" +#include "gdevprn.h" +#include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ +#include "gdevsclass.h" + +/* This seems to be broadly similar to the 'device filter stack' which is defined in gsdfilt.c + * and the stack for which is defined in the graphics state (dfilter_stack) but which seems to be + * completely unused. We should probably remove dfilter_stack from the graphics state and remove + * gsdfilt.c from the build. + */ + +/* + * It would be nice if we could rewrite the clist handling to use this kind of device class chain + * instead of the nasty hackery it currently utilises (stores the device procs for the existing + * device in 'orig_procs' which is in the device structure) and overwrites the procs with its + * own ones. The bbox forwarding device could also be rewritten this way and would probably then + * be usable as a real forwarding device (last time I tried to do this for eps2write I was unable + * to solve the problems with text enumerators). + */ + +/* At first sight we should never have a method in a device structure which is NULL + * because gx_device_fill_in_procs() should replace all the NULLs with default routines. + * However, obselete routines, and a number of newer routines (especially those involving + * transparency) don't get filled in. Its not obvious to me if this is deliberate or not, + * but we'll be careful and check the subclassed device's method before trying to execute + * it. Same for all the methods. NB the fill_rectangle method is deliberately not filled in + * because that gets set up by gdev_prn_allocate_memory(). Isn't it great the way we do our + * initialisation in lots of places? + */ + +/* TODO make gx_device_fill_in_procs fill in *all* the procs, currently it doesn't. + * this will mean declaring gx_default_ methods for the transparency methods, possibly + * some others. Like a number of other default methods, these can simply return an error + * which hopefuly will avoid us having to check for NULL device methods. + * We also agreed to set the fill_rectangle method to a default as well (currently it explicitly + * does not do this) and have gdev_prn_alloc_buffer check to see if the method is the default + * before overwriting it, rather than the current check for NULL. + */ + +/* More observations; method naems, we have text_begin, but begin_image. + * The enumerator initialiser for images gx_image_enum_common_init doesn't initialise + * the 'memory' member variable. The text enumerator initialiser gs_text_enum_init does. + * The default text enum init routine increments the reference count of the device, but the image enumerator + * doesn't. + */ + +/* We have a device method for 'get_profile' but we don't have one for 'set_profile' which causes some + * problems, the 'set' simply sets the profile in the top device. This is modified in gsicc_set_device_profile + * for now but really should have a method to itself. + * + * And in a delightful asymmetry, we have a set_graphics_type_tag, but no get_graphics_type_tag. Instead + * (shudder) the code pulls the currently encoded colour and tag *directly* from the current device. + * This means we have to copy the ENCODE_TAGS from the device we are subclassing, into the device which + * is newly created at installation time. We also have to have our default set_graphics_type_tag method + * update its graphics_type_tag, even though this device has no interest in it, just in case we happen + * to be the top device in the chain...... + */ + +/* + * gsdparam.c line 272 checks for method being NULL, this is bad, we should check for a return error + * or default method and do initialisation based on that. + */ + + +/* For printing devices the 'open' routine in gdevprn calls gdevprn_allocate_memory + * which is responsible for creating the page buffer. This *also* fills in some of + * the device procs, in particular fill_rectangle() so its vitally important that + * we pass this on. + */ +int default_subclass_open_device(gx_device *dev) +{ + if (dev->child) { + dev_proc(dev->child, open_device)(dev->child); + dev->child->is_open = true; + gx_update_from_subclass(dev); + } + + return 0; +} + +void default_subclass_get_initial_matrix(gx_device *dev, gs_matrix *pmat) +{ + if (dev->child) + dev_proc(dev->child, get_initial_matrix)(dev->child, pmat); + else + gx_default_get_initial_matrix(dev, pmat); + return; +} + +int default_subclass_sync_output(gx_device *dev) +{ + if (dev->child) + return dev_proc(dev->child, sync_output)(dev->child); + else + gx_default_sync_output(dev); + + return 0; +} + +int default_subclass_output_page(gx_device *dev, int num_copies, int flush) +{ + if (dev->child) + return dev_proc(dev->child, output_page)(dev->child, num_copies, flush); + return 0; +} + +int default_subclass_close_device(gx_device *dev) +{ + int code; + + if (dev->child) { + code = dev_proc(dev->child, close_device)(dev->child); + dev->is_open = dev->child->is_open = false; + return code; + } + dev->is_open = false; + return 0; +} + +gx_color_index default_subclass_map_rgb_color(gx_device *dev, const gx_color_value cv[]) +{ + if (dev->child) + return dev_proc(dev->child, map_rgb_color)(dev->child, cv); + else + gx_error_encode_color(dev, cv); + return 0; +} + +int default_subclass_map_color_rgb(gx_device *dev, gx_color_index color, gx_color_value rgb[3]) +{ + if (dev->child) + return dev_proc(dev->child, map_color_rgb)(dev->child, color, rgb); + else + gx_default_map_color_rgb(dev, color, rgb); + + return 0; +} + +int default_subclass_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color) +{ + if (dev->child) + return dev_proc(dev->child, fill_rectangle)(dev->child, x, y, width, height, color); + return 0; +} + +int default_subclass_tile_rectangle(gx_device *dev, const gx_tile_bitmap *tile, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + if (dev->child) + return dev_proc(dev->child, tile_rectangle)(dev->child, tile, x, y, width, height, color0, color1, phase_x, phase_y); + return 0; +} + +int default_subclass_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1) +{ + if (dev->child) + return dev_proc(dev->child, copy_mono)(dev->child, data, data_x, raster, id, x, y, width, height, color0, color1); + return 0; +} + +int default_subclass_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id,\ + int x, int y, int width, int height) +{ + if (dev->child) + return dev_proc(dev->child, copy_color)(dev->child, data, data_x, raster, id, x, y, width, height); + return 0; +} + +int default_subclass_draw_line(gx_device *dev, int x0, int y0, int x1, int y1, gx_color_index color) +{ + if (dev->child) + return dev_proc(dev->child, obsolete_draw_line)(dev->child, x0, y0, x1, y1, color); + return 0; +} + +int default_subclass_get_bits(gx_device *dev, int y, byte *data, byte **actual_data) +{ + if (dev->child) + return dev_proc(dev->child, get_bits)(dev->child, y, data, actual_data); + else + return gx_default_get_bits(dev, y, data, actual_data); + return 0; +} + +int default_subclass_get_params(gx_device *dev, gs_param_list *plist) +{ + if (dev->child) + return dev_proc(dev->child, get_params)(dev->child, plist); + else + return gx_default_get_params(dev, plist); + + return 0; +} + +int default_subclass_put_params(gx_device *dev, gs_param_list *plist) +{ + int code; + + if (dev->child) { + code = dev_proc(dev->child, put_params)(dev->child, plist); + /* The child device might have closed itself (yes seriously, this can happen!) */ + dev->is_open = dev->child->is_open; + gx_update_from_subclass(dev); + return code; + } + else + return gx_default_put_params(dev, plist); + + return 0; +} + +gx_color_index default_subclass_map_cmyk_color(gx_device *dev, const gx_color_value cv[]) +{ + if (dev->child) + return dev_proc(dev->child, map_cmyk_color)(dev->child, cv); + else + return gx_default_map_cmyk_color(dev, cv); + + return 0; +} + +const gx_xfont_procs *default_subclass_get_xfont_procs(gx_device *dev) +{ + if (dev->child) + return dev_proc(dev->child, get_xfont_procs)(dev->child); + else + return gx_default_get_xfont_procs(dev); + + return 0; +} + +gx_device *default_subclass_get_xfont_device(gx_device *dev) +{ + if (dev->child) + return dev_proc(dev->child, get_xfont_device)(dev->child); + else + return gx_default_get_xfont_device(dev); + + return 0; +} + +gx_color_index default_subclass_map_rgb_alpha_color(gx_device *dev, gx_color_value red, gx_color_value green, gx_color_value blue, + gx_color_value alpha) +{ + if (dev->child) { + return dev_proc(dev->child, map_rgb_alpha_color)(dev->child, red, green, blue, alpha); + } else + return gx_default_map_rgb_alpha_color(dev, red, green, blue, alpha); + + return 0; +} + +gx_device *default_subclass_get_page_device(gx_device *dev) +{ + if (dev->child) + return dev_proc(dev->child, get_page_device)(dev->child); + else + return gx_default_get_page_device(dev); + + return 0; +} + +int default_subclass_get_alpha_bits(gx_device *dev, graphics_object_type type) +{ + if (dev->child) + return dev_proc(dev->child, get_alpha_bits)(dev->child, type); + return 0; +} + +int default_subclass_copy_alpha(gx_device *dev, const byte *data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ + if (dev->child) + return dev_proc(dev->child, copy_alpha)(dev->child, data, data_x, raster, id, x, y, width, height, color, depth); + return 0; +} + +int default_subclass_get_band(gx_device *dev, int y, int *band_start) +{ + if (dev->child) + return dev_proc(dev->child, get_band)(dev->child, y, band_start); + else + return gx_default_get_band(dev, y, band_start); + return 0; +} + +int default_subclass_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, + const gx_tile_bitmap *texture, const gx_color_index *tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + if (dev->child) { + return dev_proc(dev->child, copy_rop)(dev->child, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); + } else + return gx_default_copy_rop(dev, sdata, sourcex, sraster, id, scolors, texture, tcolors, x, y, width, height, phase_x, phase_y, lop); + return 0; +} + +int default_subclass_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_fill_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + if (dev->child) { + return dev_proc(dev->child, fill_path)(dev->child, pgs, ppath, params, pdcolor, pcpath); + } else + return gx_default_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); + + return 0; +} + +int default_subclass_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, + const gx_stroke_params *params, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + if (dev->child) { + return dev_proc(dev->child, stroke_path)(dev->child, pgs, ppath, params, pdcolor, pcpath); + } else + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); + return 0; +} + +int default_subclass_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, + const gx_drawing_color *pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path *pcpath) +{ + if (dev->child) { + return dev_proc(dev->child, fill_mask)(dev->child, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); + } else + return gx_default_fill_mask(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); + return 0; +} + +int default_subclass_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, + fixed ybot, fixed ytop, bool swap_axes, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + if (dev->child) { + return dev_proc(dev->child, fill_trapezoid)(dev->child, left, right, ybot, ytop, swap_axes, pdcolor, lop); + } else + return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); + return 0; +} + +int default_subclass_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + if (dev->child) { + return dev_proc(dev->child, fill_parallelogram)(dev->child, px, py, ax, ay, bx, by, pdcolor, lop); + } else + return gx_default_fill_parallelogram(dev, px, py, ax, ay, bx, by, pdcolor, lop); + return 0; +} + +int default_subclass_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop) +{ + if (dev->child) { + return dev_proc(dev->child, fill_triangle)(dev->child, px, py, ax, ay, bx, by, pdcolor, lop); + } else + return gx_default_fill_triangle(dev, px, py, ax, ay, bx, by, pdcolor, lop); + return 0; +} + +int default_subclass_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_drawing_color *pdcolor, gs_logical_operation_t lop, + fixed adjustx, fixed adjusty) +{ + if (dev->child) { + return dev_proc(dev->child, draw_thin_line)(dev->child, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); + } else + return gx_default_draw_thin_line(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); + return 0; +} + +int default_subclass_begin_image(gx_device *dev, const gs_gstate *pgs, const gs_image_t *pim, + gs_image_format_t format, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + if (dev->child) { + return dev_proc(dev->child, begin_image)(dev->child, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); + } else + return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo); + + return 0; +} + +int default_subclass_image_data(gx_device *dev, gx_image_enum_common_t *info, const byte **planes, int data_x, + uint raster, int height) +{ + if (dev->child) + return dev_proc(dev->child, image_data)(dev->child, info, planes, data_x, raster, height); + return 0; +} + +int default_subclass_end_image(gx_device *dev, gx_image_enum_common_t *info, bool draw_last) +{ + if (dev->child) + return dev_proc(dev->child, end_image)(dev->child, info, draw_last); + return 0; +} + +int default_subclass_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, + gx_color_index color0, gx_color_index color1, + int phase_x, int phase_y) +{ + if (dev->child) { + return dev_proc(dev->child, strip_tile_rectangle)(dev->child, tiles, x, y, width, height, color0, color1, phase_x, phase_y); + } else + return gx_default_strip_tile_rectangle(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); + return 0; +} + +int default_subclass_strip_copy_rop(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, + const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + if (dev->child) { + return dev_proc(dev->child, strip_copy_rop)(dev->child, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); + } else + return gx_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); + return 0; +} + +void default_subclass_get_clipping_box(gx_device *dev, gs_fixed_rect *pbox) +{ + if (dev->child) { + dev_proc(dev->child, get_clipping_box)(dev->child, pbox); + } else + gx_default_get_clipping_box(dev, pbox); + + return; +} + +int default_subclass_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, + const gs_image_common_t *pic, const gs_int_rect *prect, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gx_image_enum_common_t **pinfo) +{ + if (dev->child) { + return dev_proc(dev->child, begin_typed_image)(dev->child, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); + } else + return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); + return 0; +} + +int default_subclass_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, + gs_get_bits_params_t *params, gs_int_rect **unread) +{ + if (dev->child) { + return dev_proc(dev->child, get_bits_rectangle)(dev->child, prect, params, unread); + } else + return gx_default_get_bits_rectangle(dev, prect, params, unread); + + return 0; +} + +int default_subclass_map_color_rgb_alpha(gx_device *dev, gx_color_index color, gx_color_value rgba[4]) +{ + if (dev->child) { + return dev_proc(dev->child, map_color_rgb_alpha)(dev->child, color, rgba); + } else + return gx_default_map_color_rgb_alpha(dev, color, rgba); + + return 0; +} + +int default_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, + gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) +{ + default_subclass_subclass_data *psubclass_data = dev->subclass_data; + int code; + + if (dev->child) { + /* Some more unpleasantness here. If the child device is a clist, then it will use the first argument + * that we pass to access its own data (not unreasonably), so we need to make sure we pass in the + * child device. This has some follow on implications detailed below. + */ + code = dev_proc(dev->child, create_compositor)(dev->child, pcdev, pcte, pgs, memory, cdev); + if (code < 0) + return code; + + if (*pcdev != 0L && *pcdev != dev->child){ + /* If the child created a new compositor, which it wants to be the new 'device' in the + * graphics state, it sets it in the returned pcdev variable. When we return from this + * method, if pcdev is not the same as the device in the graphics state then the interpreter + * sets pcdev as the new device in the graphics state. But because we passed in the child device + * to the child method, if it did create a compositor it will be a forwarding device, and it will + * be forwarding to our child, we need it to point to us instead. So if pcdev is not the same as the + * child device, we fixup the target in the child device to point to us. + */ + gx_device_forward *fdev = (gx_device_forward *)*pcdev; + + if (fdev->target == dev->child) { + if (gs_is_pdf14trans_compositor(pcte) != 0 && strncmp(fdev->dname, "pdf14clist", 10) == 0) { + pdf14_clist_device *p14dev; + + p14dev = (pdf14_clist_device *)*pcdev; + + dev->color_info = dev->child->color_info; + + psubclass_data->saved_compositor_method = p14dev->procs.create_compositor; + psubclass_data->forwarding_dev = fdev; + p14dev->procs.create_compositor = gx_subclass_create_compositor; + } + + fdev->target = dev; + rc_decrement_only(dev->child, "first-last page compositor code"); + rc_increment(dev); + } + return_error(gs_error_handled); + } + else { + /* See the 2 comments above. Now, if the child did not create a new compositor (eg its a clist) + * then it returns pcdev pointing to the passed in device (the child in our case). Now this is a + * problem, if we return with pcdev == child->dev, and teh current device is 'dev' then the + * compositor code will think we wanted to push a new device and will select the child device. + * so here if pcdev == dev->child we change it to be our own device, so that the calling code + * won't redirect the device in the graphics state. + */ + *pcdev = dev; + return code; + } + } + return 0; +} + +int default_subclass_get_hardware_params(gx_device *dev, gs_param_list *plist) +{ + if (dev->child) { + return dev_proc(dev->child, get_hardware_params)(dev->child, plist); + } else + return gx_default_get_hardware_params(dev, plist); + + return 0; +} + +int default_subclass_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, + gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, + gs_memory_t *memory, gs_text_enum_t **ppte) +{ + if (dev->child) { + return dev_proc(dev->child, text_begin)(dev->child, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + } else + return gx_default_text_begin(dev, pgs, text, font, path, pdcolor, pcpath, memory, ppte); + + return 0; +} + +/* This method seems (despite the name) to be intended to allow for + * devices to initialise data before being invoked. For our subclassed + * device this should already have been done. + */ +int default_subclass_finish_copydevice(gx_device *dev, const gx_device *from_dev) +{ + return 0; +} + +int default_subclass_begin_transparency_group(gx_device *dev, const gs_transparency_group_params_t *ptgp, + const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) +{ + if (dev->child) + return dev_proc(dev->child, begin_transparency_group)(dev->child, ptgp, pbbox, pgs, mem); + + return 0; +} + +int default_subclass_end_transparency_group(gx_device *dev, gs_gstate *pgs) +{ + if (dev->child) + return dev_proc(dev->child, end_transparency_group)(dev->child, pgs); + + return 0; +} + +int default_subclass_begin_transparency_mask(gx_device *dev, const gx_transparency_mask_params_t *ptmp, + const gs_rect *pbbox, gs_gstate *pgs, gs_memory_t *mem) +{ + if (dev->child) + return dev_proc(dev->child, begin_transparency_mask)(dev->child, ptmp, pbbox, pgs, mem); + + return 0; +} + +int default_subclass_end_transparency_mask(gx_device *dev, gs_gstate *pgs) +{ + if (dev->child) + return dev_proc(dev->child, end_transparency_mask)(dev->child, pgs); + return 0; +} + +int default_subclass_discard_transparency_layer(gx_device *dev, gs_gstate *pgs) +{ + if (dev->child) + return dev_proc(dev->child, discard_transparency_layer)(dev->child, pgs); + + return 0; +} + +const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev) +{ + if (dev->child) { + return dev_proc(dev->child, get_color_mapping_procs)(dev->child); + } else + return gx_default_DevGray_get_color_mapping_procs(dev); + + return 0; +} + +int default_subclass_get_color_comp_index(gx_device *dev, const char * pname, int name_size, int component_type) +{ + if (dev->child) { + return dev_proc(dev->child, get_color_comp_index)(dev->child, pname, name_size, component_type); + } else + return gx_error_get_color_comp_index(dev, pname, name_size, component_type); + + return 0; +} + +gx_color_index default_subclass_encode_color(gx_device *dev, const gx_color_value colors[]) +{ + if (dev->child) { + return dev_proc(dev->child, encode_color)(dev->child, colors); + } else + return gx_error_encode_color(dev, colors); + + return 0; +} + +int default_subclass_decode_color(gx_device *dev, gx_color_index cindex, gx_color_value colors[]) +{ + if (dev->child) + return dev_proc(dev->child, decode_color)(dev->child, cindex, colors); + else { + memset(colors, 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS])); + } + + return 0; +} + +int default_subclass_pattern_manage(gx_device *dev, gx_bitmap_id id, + gs_pattern1_instance_t *pinst, pattern_manage_t function) +{ + if (dev->child) + return dev_proc(dev->child, pattern_manage)(dev->child, id, pinst, function); + + return 0; +} + +int default_subclass_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) +{ + if (dev->child) + return dev_proc(dev->child, fill_rectangle_hl_color)(dev->child, rect, pgs, pdcolor, pcpath); + else + return_error(gs_error_rangecheck); + + return 0; +} + +int default_subclass_include_color_space(gx_device *dev, gs_color_space *cspace, const byte *res_name, int name_length) +{ + if (dev->child) + return dev_proc(dev->child, include_color_space)(dev->child, cspace, res_name, name_length); + + return 0; +} + +int default_subclass_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, + int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, + int32_t cg_den) +{ + if (dev->child) { + return dev_proc(dev->child, fill_linear_color_scanline)(dev->child, fa, i, j, w, c0, c0_f, cg_num, cg_den); + } else + return gx_default_fill_linear_color_scanline(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); + + return 0; +} + +int default_subclass_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const gs_fixed_point *p3, + const frac31 *c0, const frac31 *c1, + const frac31 *c2, const frac31 *c3) +{ + if (dev->child) { + return dev_proc(dev->child, fill_linear_color_trapezoid)(dev->child, fa, p0, p1, p2, p3, c0, c1, c2, c3); + } else + return gx_default_fill_linear_color_trapezoid(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); + + return 0; +} + +int default_subclass_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, + const gs_fixed_point *p0, const gs_fixed_point *p1, + const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) +{ + if (dev->child) { + return dev_proc(dev->child, fill_linear_color_triangle)(dev->child, fa, p0, p1, p2, c0, c1, c2); + } else + return gx_default_fill_linear_color_triangle(dev, fa, p0, p1, p2, c0, c1, c2); + + return 0; +} + +int default_subclass_update_spot_equivalent_colors(gx_device *dev, const gs_gstate * pgs) +{ + if (dev->child) + return dev_proc(dev->child, update_spot_equivalent_colors)(dev->child, pgs); + + return 0; +} + +gs_devn_params *default_subclass_ret_devn_params(gx_device *dev) +{ + if (dev->child) + return dev_proc(dev->child, ret_devn_params)(dev->child); + + return 0; +} + +int default_subclass_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) +{ + if (dev->child) { + return dev_proc(dev->child, fillpage)(dev->child, pgs, pdevc); + } else + return gx_default_fillpage(dev, pgs, pdevc); + + return 0; +} + +int default_subclass_push_transparency_state(gx_device *dev, gs_gstate *pgs) +{ + if (dev->child) + return dev_proc(dev->child, push_transparency_state)(dev->child, pgs); + + return 0; +} + +int default_subclass_pop_transparency_state(gx_device *dev, gs_gstate *pgs) +{ + if (dev->child) + return dev_proc(dev->child, pop_transparency_state)(dev->child, pgs); + + return 0; +} + +int default_subclass_put_image(gx_device *dev, const byte **buffers, int num_chan, int x, int y, + int width, int height, int row_stride, + int alpha_plane_index, int tag_plane_index) +{ + if (dev->child) + return dev_proc(dev->child, put_image)(dev->child, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); + + return 0; +} + +int default_subclass_dev_spec_op(gx_device *dev, int op, void *data, int datasize) +{ + if (dev->child) + return dev_proc(dev->child, dev_spec_op)(dev->child, op, data, datasize); + + return 0; +} + +int default_subclass_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height, int plane_height) +{ + if (dev->child) + return dev_proc(dev->child, copy_planes)(dev->child, data, data_x, raster, id, x, y, width, height, plane_height); + + return 0; +} + +int default_subclass_get_profile(gx_device *dev, cmm_dev_profile_t **dev_profile) +{ + if (dev->child) { + return dev_proc(dev->child, get_profile)(dev->child, dev_profile); + } + else { + return gx_default_get_profile(dev, dev_profile); + } + + return 0; +} + +/* In a delightful asymmetry, we have a set_graphics_type_tag, but no get_graphics_type_tag. Instead + * (shudder) the code pulls the currently encoded colour and tag *directly* from the current device. + * This means we have to copy the ENCODE_TAGS from the device we are subclassing, into the device which + * is newly created at installation time. We also have to have our default set_graphics_type_tag method + * update its graphics_type_tag, even though this device has no interest in it, just in case we happen + * to be the top device in the chain...... + */ + +void default_subclass_set_graphics_type_tag(gx_device *dev, gs_graphics_type_tag_t tag) +{ + /* + * AIUI we should not be calling this method *unless* the ENCODE_TAGS bit is set, so we don't need + * to do any checking. Just set the supplied tag in the current device, and pass it on to the underlying + * device(s). This line is a direct copy from gx_default_set_graphics_type_tag. + */ + dev->graphics_type_tag = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) | tag; + + if (dev->child) + dev_proc(dev->child, set_graphics_type_tag)(dev->child, tag); + + return; +} + +int default_subclass_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, + int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) +{ + if (!dev->child) + return 0; + + return dev_proc(dev->child, strip_copy_rop2)(dev->child, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height); +} + +int default_subclass_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, + const gx_drawing_color *pdcolor0, const gx_drawing_color *pdcolor1, int phase_x, int phase_y) +{ + if (dev->child) + return dev_proc(dev->child, strip_tile_rect_devn)(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); + else + return gx_default_strip_tile_rect_devn(dev->child, tiles, x, y, width, height, pdcolor0, pdcolor1, phase_x, phase_y); + + return 0; +} + +int default_subclass_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + const gx_drawing_color *pdcolor, int depth) +{ + if (dev->child) + return dev_proc(dev->child, copy_alpha_hl_color)(dev->child, data, data_x, raster, id, x, y, width, height, pdcolor, depth); + else + return_error(gs_error_rangecheck); + + return 0; +} + +int default_subclass_process_page(gx_device *dev, gx_process_page_options_t *options) +{ + if (dev->child) + return dev_proc(dev->child, process_page)(dev->child, options); + + return 0; +} + +void default_subclass_finalize(const gs_memory_t *cmem, void *vptr) +{ + gx_device * const dev = (gx_device *)vptr; + generic_subclass_data *psubclass_data = (generic_subclass_data *)dev->subclass_data; + (void)cmem; /* unused */ + + if (psubclass_data) { + gs_free_object(dev->memory->non_gc_memory, psubclass_data, "gx_epo_finalize(suclass data)"); + dev->subclass_data = NULL; + } + if (dev->child) { + gs_free_object(dev->memory->stable_memory, dev->child, "free child device memory for subclassing device"); + } + if (dev->parent) + dev->parent->child = dev->child; + if (dev->child) + dev->child->parent = dev->parent; + if (dev->icc_struct) + rc_decrement(dev->icc_struct, "finalize subclass device"); + if (dev->PageList) + rc_decrement(dev->PageList, "finalize subclass device"); +} diff -Nru ghostscript-9.10~dfsg/base/gdevsclass.h ghostscript-9.25~dfsg+1/base/gdevsclass.h --- ghostscript-9.10~dfsg/base/gdevsclass.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevsclass.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,106 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Common definitions for default subclass device */ + +#ifndef gdev_default_subclass_INCLUDED +# define gdev_default_subclass_INCLUDED + +#ifndef gxdevice_INCLUDED +#include "gxdevice.h" +#endif + +typedef struct { + subclass_common; +} default_subclass_subclass_data; + +/* Device procedures, we need to prototype all of them */ +dev_proc_open_device(default_subclass_open_device); +dev_proc_get_initial_matrix(default_subclass_get_initial_matrix); +dev_proc_sync_output(default_subclass_sync_output); +dev_proc_output_page(default_subclass_output_page); +dev_proc_close_device(default_subclass_close_device); +dev_proc_map_rgb_color(default_subclass_map_rgb_color); +dev_proc_map_color_rgb(default_subclass_map_color_rgb); +dev_proc_fill_rectangle(default_subclass_fill_rectangle); +dev_proc_tile_rectangle(default_subclass_tile_rectangle); +dev_proc_copy_mono(default_subclass_copy_mono); +dev_proc_copy_color(default_subclass_copy_color); +dev_proc_draw_line(default_subclass_draw_line); +dev_proc_get_bits(default_subclass_get_bits); +dev_proc_get_params(default_subclass_get_params); +dev_proc_put_params(default_subclass_put_params); +dev_proc_map_cmyk_color(default_subclass_map_cmyk_color); +dev_proc_get_xfont_procs(default_subclass_get_xfont_procs); +dev_proc_get_xfont_device(default_subclass_get_xfont_device); +dev_proc_map_rgb_alpha_color(default_subclass_map_rgb_alpha_color); +dev_proc_get_page_device(default_subclass_get_page_device); +dev_proc_get_alpha_bits(default_subclass_get_alpha_bits); +dev_proc_copy_alpha(default_subclass_copy_alpha); +dev_proc_get_band(default_subclass_get_band); +dev_proc_copy_rop(default_subclass_copy_rop); +dev_proc_fill_path(default_subclass_fill_path); +dev_proc_stroke_path(default_subclass_stroke_path); +dev_proc_fill_mask(default_subclass_fill_mask); +dev_proc_fill_trapezoid(default_subclass_fill_trapezoid); +dev_proc_fill_parallelogram(default_subclass_fill_parallelogram); +dev_proc_fill_triangle(default_subclass_fill_triangle); +dev_proc_draw_thin_line(default_subclass_draw_thin_line); +dev_proc_begin_image(default_subclass_begin_image); +dev_proc_image_data(default_subclass_image_data); +dev_proc_end_image(default_subclass_end_image); +dev_proc_strip_tile_rectangle(default_subclass_strip_tile_rectangle); +dev_proc_strip_copy_rop(default_subclass_strip_copy_rop); +dev_proc_get_clipping_box(default_subclass_get_clipping_box); +dev_proc_begin_typed_image(default_subclass_begin_typed_image); +dev_proc_get_bits_rectangle(default_subclass_get_bits_rectangle); +dev_proc_map_color_rgb_alpha(default_subclass_map_color_rgb_alpha); +dev_proc_create_compositor(default_subclass_create_compositor); +dev_proc_get_hardware_params(default_subclass_get_hardware_params); +dev_proc_text_begin(default_subclass_text_begin); +dev_proc_finish_copydevice(default_subclass_finish_copydevice); +dev_proc_begin_transparency_group(default_subclass_begin_transparency_group); +dev_proc_end_transparency_group(default_subclass_end_transparency_group); +dev_proc_begin_transparency_mask(default_subclass_begin_transparency_mask); +dev_proc_end_transparency_mask(default_subclass_end_transparency_mask); +dev_proc_discard_transparency_layer(default_subclass_discard_transparency_layer); +dev_proc_get_color_mapping_procs(default_subclass_get_color_mapping_procs); +dev_proc_get_color_comp_index(default_subclass_get_color_comp_index); +dev_proc_encode_color(default_subclass_encode_color); +dev_proc_decode_color(default_subclass_decode_color); +dev_proc_pattern_manage(default_subclass_pattern_manage); +dev_proc_fill_rectangle_hl_color(default_subclass_fill_rectangle_hl_color); +dev_proc_include_color_space(default_subclass_include_color_space); +dev_proc_fill_linear_color_scanline(default_subclass_fill_linear_color_scanline); +dev_proc_fill_linear_color_trapezoid(default_subclass_fill_linear_color_trapezoid); +dev_proc_fill_linear_color_triangle(default_subclass_fill_linear_color_triangle); +dev_proc_update_spot_equivalent_colors(default_subclass_update_spot_equivalent_colors); +dev_proc_ret_devn_params(default_subclass_ret_devn_params); +dev_proc_fillpage(default_subclass_fillpage); +dev_proc_push_transparency_state(default_subclass_push_transparency_state); +dev_proc_pop_transparency_state(default_subclass_pop_transparency_state); +dev_proc_put_image(default_subclass_put_image); +dev_proc_dev_spec_op(default_subclass_dev_spec_op); +dev_proc_copy_planes(default_subclass_copy_planes); +dev_proc_get_profile(default_subclass_get_profile); +dev_proc_set_graphics_type_tag(default_subclass_set_graphics_type_tag); +dev_proc_strip_copy_rop2(default_subclass_strip_copy_rop2); +dev_proc_strip_tile_rect_devn(default_subclass_strip_tile_rect_devn); +dev_proc_copy_alpha_hl_color(default_subclass_copy_alpha_hl_color); +dev_proc_process_page(default_subclass_process_page); + +void default_subclass_finalize(const gs_memory_t *cmem, void *vptr); +#endif /* gdev_obj_filter_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gdevvec.c ghostscript-9.25~dfsg+1/base/gdevvec.c --- ghostscript-9.10~dfsg/base/gdevvec.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevvec.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,6 +31,9 @@ #include "gxpaint.h" /* requires gx_path, ... */ #include "gzpath.h" #include "gzcpath.h" +#include "gxdevsop.h" + +#include "gdevkrnlsclass.h" /* 'standard' built in subclasses, currently First/Last Page and obejct filter */ /* Structure descriptors */ public_st_device_vector(); @@ -39,7 +42,7 @@ /* ================ Default implementations of vector procs ================ */ int -gdev_vector_setflat(gx_device_vector * vdev, floatp flatness) +gdev_vector_setflat(gx_device_vector * vdev, double flatness) { return 0; } @@ -82,9 +85,9 @@ ) { gs_point p, q; - gs_point_transform_inverse((floatp)rbox.p.x, (floatp)rbox.p.y, + gs_point_transform_inverse((double)rbox.p.x, (double)rbox.p.y, &state.scale_mat, &p); - gs_point_transform_inverse((floatp)rbox.q.x, (floatp)rbox.q.y, + gs_point_transform_inverse((double)rbox.q.x, (double)rbox.q.y, &state.scale_mat, &q); code = vdev_proc(vdev, dorect)(vdev, (fixed)p.x, (fixed)p.y, (fixed)q.x, (fixed)q.y, type); @@ -241,6 +244,9 @@ gdev_vector_init(gx_device_vector * vdev) { gdev_vector_reset(vdev); + if (dev_proc(vdev, dev_spec_op) == gx_default_dev_spec_op) + set_dev_proc(vdev, dev_spec_op, gdev_vector_dev_spec_op); + vdev->scale.x = vdev->scale.y = 1.0; vdev->in_page = false; gdev_vector_load_cache(vdev); @@ -250,8 +256,8 @@ void gdev_vector_reset(gx_device_vector * vdev) { - static const gs_imager_state state_initial = - {gs_imager_state_initial(1, false)}; + static const gs_gstate state_initial = + {gs_gstate_initial(1.0)}; vdev->state = state_initial; gx_hld_saved_color_init(&vdev->saved_fill_color); @@ -267,7 +273,7 @@ { bool binary = !(open_options & VECTOR_OPEN_FILE_ASCII); int code = -1; /* (only for testing, never returned) */ - cmm_dev_profile_t *icc_struct; + cmm_dev_profile_t *icc_struct = 0; /* Open the file as seekable or sequential, as requested. */ if (!(open_options & VECTOR_OPEN_FILE_SEQUENTIAL)) { @@ -340,6 +346,11 @@ (*dev_proc(vdev->bbox_device, open_device)) ((gx_device *) vdev->bbox_device); } + + code = install_internal_subclass_devices((gx_device **)&vdev, NULL); + if (code < 0) + return code; + return 0; } @@ -373,22 +384,22 @@ /* Update color (fill or stroke). */ static int gdev_vector_update_color(gx_device_vector * vdev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_drawing_color * pdcolor, gx_hl_saved_color *sc, int (*setcolor) (gx_device_vector * vdev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_drawing_color * pdc)) { gx_hl_saved_color temp; int code; - bool hl_color = (*vdev_proc(vdev, can_handle_hl_color)) (vdev, pis, pdcolor); - const gs_imager_state *pis_for_hl_color = (hl_color ? pis : NULL); + bool hl_color = (*vdev_proc(vdev, can_handle_hl_color)) (vdev, pgs, pdcolor); + const gs_gstate *pgs_for_hl_color = (hl_color ? pgs : NULL); - gx_hld_save_color(pis_for_hl_color, pdcolor, &temp); + gx_hld_save_color(pgs_for_hl_color, pdcolor, &temp); if (gx_hld_saved_color_equal(&temp, sc)) return 0; - code = (*setcolor) (vdev, pis_for_hl_color, pdcolor); + code = (*setcolor) (vdev, pgs_for_hl_color, pdcolor); if (code < 0) return code; *sc = temp; @@ -398,19 +409,19 @@ /* Update the fill color. */ int gdev_vector_update_fill_color(gx_device_vector * vdev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_drawing_color * pdcolor) { - return gdev_vector_update_color(vdev, pis, pdcolor, &vdev->saved_fill_color, + return gdev_vector_update_color(vdev, pgs, pdcolor, &vdev->saved_fill_color, vdev_proc(vdev, setfillcolor)); } /* Update the state for filling a region. */ static int -update_fill(gx_device_vector * vdev, const gs_imager_state * pis, +update_fill(gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdcolor, gs_logical_operation_t lop) { - int code = gdev_vector_update_fill_color(vdev, pis, pdcolor); + int code = gdev_vector_update_fill_color(vdev, pgs, pdcolor); if (code < 0) return code; @@ -419,7 +430,7 @@ /* Bring state up to date for filling. */ int -gdev_vector_prepare_fill(gx_device_vector * vdev, const gs_imager_state * pis, +gdev_vector_prepare_fill(gx_device_vector * vdev, const gs_gstate * pgs, const gx_fill_params * params, const gx_drawing_color * pdcolor) { if (params->flatness != vdev->state.flatness) { @@ -429,12 +440,12 @@ return code; vdev->state.flatness = params->flatness; } - return update_fill(vdev, pis, pdcolor, pis->log_op); + return update_fill(vdev, pgs, pdcolor, pgs->log_op); } /* Compare two dash patterns. */ static bool -dash_pattern_eq(const float *stored, const gx_dash_params * set, floatp scale) +dash_pattern_eq(const float *stored, const gx_dash_params * set, double scale) { int i; @@ -447,34 +458,36 @@ /* Bring state up to date for stroking. */ int gdev_vector_prepare_stroke(gx_device_vector * vdev, - const gs_imager_state * pis, /* may be NULL */ + const gs_gstate * pgs, /* may be NULL */ const gx_stroke_params * params, /* may be NULL */ const gx_drawing_color * pdcolor, /* may be NULL */ - floatp scale) + double scale) { - if (pis) { - int pattern_size = pis->line_params.dash.pattern_size; - float dash_offset = pis->line_params.dash.offset * scale; - float half_width = pis->line_params.half_width * scale; + if (pgs) { + int pattern_size = pgs->line_params.dash.pattern_size; + float dash_offset = pgs->line_params.dash.offset * scale; + float half_width = pgs->line_params.half_width * scale; - if (pattern_size > max_dash) - return_error(gs_error_limitcheck); if (dash_offset != vdev->state.line_params.dash.offset || pattern_size != vdev->state.line_params.dash.pattern_size || (pattern_size != 0 && - !dash_pattern_eq(vdev->dash_pattern, &pis->line_params.dash, + !dash_pattern_eq(vdev->dash_pattern, &pgs->line_params.dash, scale)) ) { - float pattern[max_dash]; + float *pattern; int i, code; + pattern = (float *)gs_alloc_bytes(vdev->memory->stable_memory, pattern_size * sizeof(float), "vector allocate dash pattern"); for (i = 0; i < pattern_size; ++i) - pattern[i] = pis->line_params.dash.pattern[i] * scale; + pattern[i] = pgs->line_params.dash.pattern[i] * scale; code = (*vdev_proc(vdev, setdash)) (vdev, pattern, pattern_size, dash_offset); if (code < 0) return code; - memcpy(vdev->dash_pattern, pattern, pattern_size * sizeof(float)); + if (vdev->dash_pattern) + gs_free_object(vdev->memory->stable_memory, vdev->dash_pattern, "vector free old dash pattern"); + vdev->dash_pattern = pattern; + vdev->dash_pattern_size = pattern_size; vdev->state.line_params.dash.pattern_size = pattern_size; vdev->state.line_params.dash.offset = dash_offset; @@ -487,33 +500,33 @@ return code; vdev->state.line_params.half_width = half_width; } - if (pis->line_params.miter_limit != vdev->state.line_params.miter_limit) { + if (pgs->line_params.miter_limit != vdev->state.line_params.miter_limit) { int code = (*vdev_proc(vdev, setmiterlimit)) - (vdev, pis->line_params.miter_limit); + (vdev, pgs->line_params.miter_limit); if (code < 0) return code; gx_set_miter_limit(&vdev->state.line_params, - pis->line_params.miter_limit); + pgs->line_params.miter_limit); } /* FIXME: Should cope with end_cap and dash_cap too */ - if (pis->line_params.start_cap != vdev->state.line_params.start_cap) { + if (pgs->line_params.start_cap != vdev->state.line_params.start_cap) { int code = (*vdev_proc(vdev, setlinecap)) - (vdev, pis->line_params.start_cap); + (vdev, pgs->line_params.start_cap); if (code < 0) return code; - vdev->state.line_params.start_cap = pis->line_params.start_cap; + vdev->state.line_params.start_cap = pgs->line_params.start_cap; } - if (pis->line_params.join != vdev->state.line_params.join) { + if (pgs->line_params.join != vdev->state.line_params.join) { int code = (*vdev_proc(vdev, setlinejoin)) - (vdev, pis->line_params.join); + (vdev, pgs->line_params.join); if (code < 0) return code; - vdev->state.line_params.join = pis->line_params.join; + vdev->state.line_params.join = pgs->line_params.join; } { - int code = gdev_vector_update_log_op(vdev, pis->log_op); + int code = gdev_vector_update_log_op(vdev, pgs->log_op); if (code < 0) return code; @@ -529,7 +542,7 @@ } } if (pdcolor) { - int code = gdev_vector_update_color(vdev, pis, pdcolor, + int code = gdev_vector_update_color(vdev, pgs, pdcolor, &vdev->saved_stroke_color, vdev_proc(vdev, setstrokecolor)); if (code < 0) @@ -546,7 +559,7 @@ */ int gdev_vector_stroke_scaling(const gx_device_vector *vdev, - const gs_imager_state *pis, + const gs_gstate *pgs, double *pscale, gs_matrix *pmat) { bool set_ctm = true; @@ -562,16 +575,16 @@ * do it before constructing the path, and inverse-transform all * the coordinates. */ - if (is_xxyy(&pis->ctm)) { - scale = fabs(pis->ctm.xx); - set_ctm = fabs(pis->ctm.yy) != scale; - } else if (is_xyyx(&pis->ctm)) { - scale = fabs(pis->ctm.xy); - set_ctm = fabs(pis->ctm.yx) != scale; - } else if ((pis->ctm.xx == pis->ctm.yy && pis->ctm.xy == -pis->ctm.yx) || - (pis->ctm.xx == -pis->ctm.yy && pis->ctm.xy == pis->ctm.yx) + if (is_xxyy(&pgs->ctm)) { + scale = fabs(pgs->ctm.xx); + set_ctm = fabs(pgs->ctm.yy) != scale; + } else if (is_xyyx(&pgs->ctm)) { + scale = fabs(pgs->ctm.xy); + set_ctm = fabs(pgs->ctm.yx) != scale; + } else if ((pgs->ctm.xx == pgs->ctm.yy && pgs->ctm.xy == -pgs->ctm.yx) || + (pgs->ctm.xx == -pgs->ctm.yy && pgs->ctm.xy == pgs->ctm.yx) ) { - scale = hypot(pis->ctm.xx, pis->ctm.xy); + scale = hypot(pgs->ctm.xx, pgs->ctm.xy); set_ctm = false; } if (set_ctm) { @@ -583,10 +596,10 @@ * formats.) */ double - mxx = pis->ctm.xx / vdev->scale.x, - mxy = pis->ctm.xy / vdev->scale.y, - myx = pis->ctm.yx / vdev->scale.x, - myy = pis->ctm.yy / vdev->scale.y; + mxx = pgs->ctm.xx / vdev->scale.x, + mxy = pgs->ctm.xy / vdev->scale.y, + myx = pgs->ctm.yx / vdev->scale.x, + myy = pgs->ctm.yy / vdev->scale.y; scale = 0.5 * (fabs(mxx) + fabs(mxy) + fabs(myx) + fabs(myy)); pmat->xx = mxx / scale, pmat->xy = mxy / scale; @@ -816,6 +829,10 @@ FILE *f = vdev->file; int err; + if (vdev->dash_pattern) { + gs_free_object(vdev->memory->stable_memory, vdev->dash_pattern, "vector free dash pattern"); + vdev->dash_pattern = 0; + } if (vdev->bbox_device) { rc_decrement(vdev->bbox_device->icc_struct, "vector_close(bbox_device->icc_struct"); vdev->bbox_device->icc_struct = NULL; @@ -847,7 +864,7 @@ /* Initialize for enumerating an image. */ int gdev_vector_begin_image(gx_device_vector * vdev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, const gx_image_enum_procs_t * pprocs, @@ -873,14 +890,14 @@ pie->num_planes; pie->default_info = 0; pie->bbox_info = 0; - if ((code = gdev_vector_update_log_op(vdev, pis->log_op)) < 0 || + if ((code = gdev_vector_update_log_op(vdev, pgs->log_op)) < 0 || (code = gdev_vector_update_clip_path(vdev, pcpath)) < 0 || ((pim->ImageMask || - (pim->CombineWithColor && rop3_uses_T(pis->log_op))) && - (code = gdev_vector_update_fill_color(vdev, pis, pdcolor)) < 0) || + (pim->CombineWithColor && rop3_uses_T(pgs->log_op))) && + (code = gdev_vector_update_fill_color(vdev, pgs, pdcolor)) < 0) || (vdev->bbox_device && (code = (*dev_proc(vdev->bbox_device, begin_image)) - ((gx_device *) vdev->bbox_device, pis, pim, format, prect, + ((gx_device *) vdev->bbox_device, pgs, pim, format, prect, pdcolor, pcpath, mem, &pie->bbox_info)) < 0) ) return code; @@ -941,6 +958,27 @@ #define vdev ((gx_device_vector *)dev) +int gdev_vector_get_param(gx_device *dev, char *Param, void *list) +{ + gs_param_list * plist = (gs_param_list *)list; + gs_param_string ofns; + bool bool_true = 1; + + ofns.data = (const byte *)vdev->fname, + ofns.size = strlen(vdev->fname), + ofns.persistent = false; + if (strcmp(Param, "OutputFile") == 0) { + return param_write_string(plist, "OutputFile", &ofns); + } + if (strcmp(Param, "HighLevelDevice") == 0) { + return param_write_bool(plist, "HighLevelDevice", &bool_true); + } + if (strcmp(Param, "NoInterpolateImagemasks") == 0) { + return param_write_bool(plist, "NoInterpolateImagemasks", &bool_true); + } + return gx_default_get_param(dev, Param, list); +} + /* Get parameters. */ int gdev_vector_get_params(gx_device * dev, gs_param_list * plist) @@ -959,6 +997,8 @@ return ecode; if ((ecode = param_write_bool(plist, "HighLevelDevice", &bool_true)) < 0) return ecode; + if ((ecode = param_write_bool(plist, "NoInterpolateImagemasks", &bool_true)) < 0) + return ecode; return code; } @@ -968,15 +1008,20 @@ { int ecode = 0; int code; + int igni; + bool ignb; gs_param_name param_name; gs_param_string ofns; - bool open = dev->is_open, HighLevelDevice; - + bool open = dev->is_open, HighLevelDevice, NoInterpolateImagemasks; code = param_read_bool(plist, (param_name = "HighLevelDevice"), &HighLevelDevice); if (code < 0) return code; + code = param_read_bool(plist, (param_name = "NoInterpolateImagemasks"), &NoInterpolateImagemasks); + if (code < 0) + return code; + switch (code = param_read_string(plist, (param_name = "OutputFile"), &ofns)) { case 0: /* @@ -984,8 +1029,10 @@ * beginning of the file: changing the file name after writing * any pages should be an error. */ - if (ofns.size > fname_size) + if (ofns.size > fname_size) { + eprintf1("\nERROR: Output filename too long (maximum %d bytes).\n", fname_size); ecode = gs_error_limitcheck; + } else if (!bytes_compare(ofns.data, ofns.size, (const byte *)vdev->fname, strlen(vdev->fname)) @@ -1001,13 +1048,32 @@ default: ecode = code; ofe: param_signal_error(plist, param_name, ecode); + /* fall through */ case 1: ofns.data = 0; break; } + /* Ignore the following printer device params */ + switch (code = param_read_bool(plist, (param_name = "BGPrint"), &ignb)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + switch (code = param_read_int(plist, (param_name = "NumRenderingThreads"), &igni)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } if (ecode < 0) return ecode; + { /* Don't let gx_default_put_params close the device. */ dev->is_open = false; @@ -1017,6 +1083,12 @@ if (code < 0) return code; + if (dev->color_info.anti_alias.text_bits != 1 || dev->color_info.anti_alias.graphics_bits != 1) { + emprintf(dev->memory, + "\n\n ERROR:\n Can't set GraphicsAlphaBits or TextAlphaBits with a vector device.\n"); + return_error(gs_error_unregistered); + } + if (ofns.data != 0) { /* If ofns.data is not NULL, then we have a different file name */ memcpy(vdev->fname, ofns.data, ofns.size); @@ -1090,17 +1162,17 @@ } int -gdev_vector_fill_path(gx_device * dev, const gs_imager_state * pis, +gdev_vector_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { int code; if ((code = gdev_vector_update_clip_path(vdev, pcpath)) < 0 || - (code = gdev_vector_prepare_fill(vdev, pis, params, pdevc)) < 0 || + (code = gdev_vector_prepare_fill(vdev, pgs, params, pdevc)) < 0 || (vdev->bbox_device && (code = (*dev_proc(vdev->bbox_device, fill_path)) - ((gx_device *) vdev->bbox_device, pis, ppath, params, + ((gx_device *) vdev->bbox_device, pgs, ppath, params, pdevc, pcpath)) < 0) || (code = (*vdev_proc(vdev, dopath)) (vdev, ppath, @@ -1109,12 +1181,12 @@ vdev->fill_options, NULL)) < 0 ) - return gx_default_fill_path(dev, pis, ppath, params, pdevc, pcpath); + return gx_default_fill_path(dev, pgs, ppath, params, pdevc, pcpath); return code; } int -gdev_vector_stroke_path(gx_device * dev, const gs_imager_state * pis, +gdev_vector_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_stroke_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) { @@ -1124,16 +1196,16 @@ gs_matrix mat; if ((code = gdev_vector_update_clip_path(vdev, pcpath)) < 0 || - (set_ctm = gdev_vector_stroke_scaling(vdev, pis, &scale, &mat)) != 0 || - (code = gdev_vector_prepare_stroke(vdev, pis, params, pdcolor, scale)) < 0 || + (set_ctm = gdev_vector_stroke_scaling(vdev, pgs, &scale, &mat)) != 0 || + (code = gdev_vector_prepare_stroke(vdev, pgs, params, pdcolor, scale)) < 0 || (vdev->bbox_device && (code = (*dev_proc(vdev->bbox_device, stroke_path)) - ((gx_device *) vdev->bbox_device, pis, ppath, params, + ((gx_device *) vdev->bbox_device, pgs, ppath, params, pdcolor, pcpath)) < 0) || (code = (*vdev_proc(vdev, dopath)) (vdev, ppath, gx_path_type_stroke | vdev->stroke_options, NULL)) < 0 ) - return gx_default_stroke_path(dev, pis, ppath, params, pdcolor, pcpath); + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); return code; } @@ -1265,4 +1337,17 @@ gx_path_type_fill); } +int +gdev_vector_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) +{ + if (dev_spec_op == gxdso_get_dev_param) { + int code; + dev_param_req_t *request = (dev_param_req_t *)data; + code = gdev_vector_get_param(pdev, request->Param, request->list); + if (code != gs_error_undefined) + return code; + } + return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); +} + #undef vdev diff -Nru ghostscript-9.10~dfsg/base/gdevvec.h ghostscript-9.25~dfsg+1/base/gdevvec.h --- ghostscript-9.10~dfsg/base/gdevvec.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gdevvec.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ #include "gxdevice.h" #include "gdevbbox.h" #include "gxiparam.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxhldevc.h" #include "stream.h" @@ -66,9 +66,6 @@ /* Define the maximum size of the output file name. */ #define fname_size (gp_file_name_sizeof - 1) -/* Define the longest dash pattern we can remember. */ -#define max_dash 11 - /* * Define procedures for writing common output elements. Not all devices * will support all of these elements. Note that these procedures normally @@ -89,6 +86,7 @@ gx_path_type_even_odd = 8, gx_path_type_optimize = 16, /* OK to optimize paths by merging seg.s */ gx_path_type_always_close = 32, /* include final closepath even if not stroke */ + gx_path_type_dashed_stroke = 64, /* for high level devices, safe to optimise rectangular subpaths as rectangles if available (not legal if dashing strokes) */ gx_path_type_rule = gx_path_type_winding_number | gx_path_type_even_odd } gx_path_type_t; typedef enum { @@ -104,22 +102,22 @@ beginpage. in_page must also be set to false in the device's output_page method to request that beginpage be called again when drawing next occurs. */ - /* Imager state */ - int (*setlinewidth) (gx_device_vector * vdev, floatp width); + /* gs_gstate */ + int (*setlinewidth) (gx_device_vector * vdev, double width); int (*setlinecap) (gx_device_vector * vdev, gs_line_cap cap); int (*setlinejoin) (gx_device_vector * vdev, gs_line_join join); - int (*setmiterlimit) (gx_device_vector * vdev, floatp limit); + int (*setmiterlimit) (gx_device_vector * vdev, double limit); int (*setdash) (gx_device_vector * vdev, const float *pattern, - uint count, floatp offset); - int (*setflat) (gx_device_vector * vdev, floatp flatness); + uint count, double offset); + int (*setflat) (gx_device_vector * vdev, double flatness); int (*setlogop) (gx_device_vector * vdev, gs_logical_operation_t lop, gs_logical_operation_t diff); /* Other state */ - bool (*can_handle_hl_color) (gx_device_vector * vdev, const gs_imager_state * pis, + bool (*can_handle_hl_color) (gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); - int (*setfillcolor) (gx_device_vector * vdev, const gs_imager_state * pis, + int (*setfillcolor) (gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); - int (*setstrokecolor) (gx_device_vector * vdev, const gs_imager_state * pis, + int (*setstrokecolor) (gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); /* Paths */ /* dopath and dorect are normally defaulted */ @@ -128,21 +126,21 @@ int (*dorect) (gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, fixed y1, gx_path_type_t type); int (*beginpath) (gx_device_vector * vdev, gx_path_type_t type); - int (*moveto) (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x, floatp y, gx_path_type_t type); - int (*lineto) (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x, floatp y, gx_path_type_t type); - int (*curveto) (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x1, floatp y1, floatp x2, floatp y2, - floatp x3, floatp y3, gx_path_type_t type); - int (*closepath) (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x_start, floatp y_start, gx_path_type_t type); + int (*moveto) (gx_device_vector * vdev, double x0, double y0, + double x, double y, gx_path_type_t type); + int (*lineto) (gx_device_vector * vdev, double x0, double y0, + double x, double y, gx_path_type_t type); + int (*curveto) (gx_device_vector * vdev, double x0, double y0, + double x1, double y1, double x2, double y2, + double x3, double y3, gx_path_type_t type); + int (*closepath) (gx_device_vector * vdev, double x0, double y0, + double x_start, double y_start, gx_path_type_t type); int (*endpath) (gx_device_vector * vdev, gx_path_type_t type); } gx_device_vector_procs; /* Default implementations of procedures */ /* setflat does nothing */ -int gdev_vector_setflat(gx_device_vector * vdev, floatp flatness); +int gdev_vector_setflat(gx_device_vector * vdev, double flatness); /* dopath may call dorect, beginpath, moveto/lineto/curveto/closepath, */ /* endpath */ @@ -167,8 +165,9 @@ uint strmbuf_size;\ int open_options; /* see below */\ /* Graphics state */\ - gs_imager_state state;\ - float dash_pattern[max_dash];\ + gs_gstate state;\ + float *dash_pattern;\ + uint dash_pattern_size;\ bool fill_used_process_color;\ bool stroke_used_process_color;\ gx_hl_saved_color saved_fill_color;\ @@ -194,7 +193,8 @@ 0, /* strmbuf_size */\ 0, /* open_options */\ { 0 }, /* state */\ - { 0 }, /* dash_pattern */\ + 0, /* dash_pattern */\ + 0, /* dash pattern size */\ true, /* fill_used_process_color */\ true, /* stroke_used_process_color */\ { 0 }, /* fill_color ****** WRONG ****** */\ @@ -216,11 +216,11 @@ /* extern its descriptor for the sake of subclasses. */ extern_st(st_device_vector); #define public_st_device_vector() /* in gdevvec.c */\ - gs_public_st_suffix_add3_final(st_device_vector, gx_device_vector,\ + gs_public_st_suffix_add4_final(st_device_vector, gx_device_vector,\ "gx_device_vector", device_vector_enum_ptrs,\ device_vector_reloc_ptrs, gx_device_finalize, st_device, strm, strmbuf,\ - bbox_device) -#define st_device_vector_max_ptrs (st_device_max_ptrs + 3) + dash_pattern, bbox_device) +#define st_device_vector_max_ptrs (st_device_max_ptrs + 4) /* ================ Utility procedures ================ */ @@ -258,13 +258,13 @@ /* Bring the fill color up to date. */ /* May call setfillcolor. */ int gdev_vector_update_fill_color(gx_device_vector * vdev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_drawing_color * pdcolor); /* Bring state up to date for filling. */ /* May call setflat, setfillcolor, setlogop. */ int gdev_vector_prepare_fill(gx_device_vector * vdev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_fill_params * params, const gx_drawing_color * pdcolor); @@ -272,12 +272,12 @@ /* for the line width and dash offset explicitly. */ /* May call setlinewidth, setlinecap, setlinejoin, setmiterlimit, */ /* setdash, setflat, setstrokecolor, setlogop. */ -/* Any of pis, params, and pdcolor may be NULL. */ +/* Any of pgs, params, and pdcolor may be NULL. */ int gdev_vector_prepare_stroke(gx_device_vector * vdev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_stroke_params * params, const gx_drawing_color * pdcolor, - floatp scale); + double scale); /* * Compute the scale for transforming the line width and dash pattern for a @@ -286,7 +286,7 @@ * Return 0 if only scaling, 1 if a full matrix is needed. */ int gdev_vector_stroke_scaling(const gx_device_vector *vdev, - const gs_imager_state *pis, + const gs_gstate *pgs, double *pscale, gs_matrix *pmat); /* Prepare to write a path using the default implementation. */ @@ -308,6 +308,11 @@ int gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, gs_fixed_point vs[3]); +typedef struct gdev_vector_path_seg_record_s { + int op; + gs_fixed_point vs[3]; +} gdev_vector_path_seg_record; + /* Write a polygon as part of a path (type = gx_path_type_none) */ /* or as a path. */ /* May call moveto, lineto, closepath (if close); */ @@ -363,7 +368,7 @@ * enumerator. */ int gdev_vector_begin_image(gx_device_vector * vdev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, const gx_image_enum_procs_t * pprocs, @@ -379,6 +384,7 @@ /* Redefine get/put_params to handle OutputFile. */ dev_proc_put_params(gdev_vector_put_params); dev_proc_get_params(gdev_vector_get_params); +int gdev_vector_get_param(gx_device *dev, char *Param, void *list); /* ---------------- Defaults ---------------- */ @@ -393,5 +399,6 @@ dev_proc_fill_trapezoid(gdev_vector_fill_trapezoid); dev_proc_fill_parallelogram(gdev_vector_fill_parallelogram); dev_proc_fill_triangle(gdev_vector_fill_triangle); +dev_proc_dev_spec_op(gdev_vector_dev_spec_op); #endif /* gdevvec_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/genarch.c ghostscript-9.25~dfsg+1/base/genarch.c --- ghostscript-9.10~dfsg/base/genarch.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/genarch.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -181,7 +181,10 @@ define_int(f, "ARCH_ALIGN_INT_MOD", OFFSET_IN(si, i)); define_int(f, "ARCH_ALIGN_LONG_MOD", OFFSET_IN(sl, l)); -#if defined (sparc) +#if defined (GS_MEMPTR_ALIGNMENT) && GS_MEMPTR_ALIGNMENT != 0 + define_int(f, "ARCH_ALIGN_PTR_MOD", GS_MEMPTR_ALIGNMENT); +#else +#if defined (sparc) || defined (__hpux) # ifndef __BIGGEST_ALIGNMENT__ # define __BIGGEST_ALIGNMENT__ 8 # endif @@ -189,6 +192,7 @@ #else define_int(f, "ARCH_ALIGN_PTR_MOD", OFFSET_IN(sp, p)); #endif +#endif define_int(f, "ARCH_ALIGN_FLOAT_MOD", OFFSET_IN(sf, f)); define_int(f, "ARCH_ALIGN_DOUBLE_MOD", OFFSET_IN(sd, d)); diff -Nru ghostscript-9.10~dfsg/base/genconf.c ghostscript-9.25~dfsg+1/base/genconf.c --- ghostscript-9.10~dfsg/base/genconf.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/genconf.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,6 +22,10 @@ #include /* for calloc */ #include +#ifndef DEBUG_GENCONF_MEMORY +# define DEBUG_GENCONF_MEMORY 0 +#endif + /* * This program reads .dev files, which contain definitions of modules, * and generates merged configuration files. @@ -238,6 +242,24 @@ #define MAX_STR 120 +static const char * const empty_str = ""; + +#if DEBUG_GENCONF_MEMORY +static long long int mem_alloc_count = 0; + +typedef struct mem_hdr memhdr; +struct mem_hdr { + size_t s; + long long int count; + memhdr *next; +}; + +#define SIZEOF_MEMHDR_ALIGNED ((sizeof(memhdr) + 7) & ~7) + +static memhdr memhdr_lst = {0}; +static memhdr *memhdr_tail = &memhdr_lst; +#endif + /* Structures for accumulating information. */ typedef struct string_item_s { const char *str; @@ -261,6 +283,7 @@ string_item_t *items; } string_list_t; +#define MAX_TEMPLAT 80 #define MAX_PATTERN 60 typedef struct string_pattern_s { bool upper_case; @@ -322,8 +345,14 @@ }; /* Forward definitions */ -static void *mrealloc(void *, size_t, size_t); +static void *mrealloc(void *, size_t, size_t, const char *label); +static void *mmalloc(size_t s, const char *label); +static void *mcalloc(size_t nmemb, size_t size, const char *label); +static void mfree (void *om, const char *label); + int alloc_list(string_list_t *); +void free_list(string_list_t * list); + void dev_file_name(char *); int process_replaces(config_t *); int read_dev(config_t *, const char *); @@ -337,6 +366,10 @@ void add_definition(const char *, const char *, string_list_t *, bool); string_item_t *lookup(const char *, const string_list_t *); +void validate_list(string_list_t *sl); +void validate_lists(config_t *conf); +void validate_memory(void); + int main(int argc, char *argv[]) { @@ -379,7 +412,7 @@ switch (arg[1]) { case 'C': /* change directory, by analogy with make */ conf.file_prefix = - (argv[i + 1][0] == '-' ? "" : argv[i + 1]); + (argv[i + 1][0] == '-' ? empty_str : argv[i + 1]); ++i; continue; case 'e': @@ -388,7 +421,7 @@ continue; case 'n': conf.name_prefix = - (argv[i + 1][0] == '-' ? "" : argv[i + 1]); + (argv[i + 1][0] == '-' ? empty_str : argv[i + 1]); ++i; continue; case 'p': @@ -474,7 +507,7 @@ fputs("/* This file was generated automatically by genconf.c. */\n", out); fputs("/* For documentation, see gsconfig.c. */\n", out); { - char templat[80]; + char templat[MAX_TEMPLAT + 1]; sprintf(templat, "font_(\"0.font_%%s\",%sf_%%s,zf_%%s)\n", @@ -520,25 +553,101 @@ fclose(out); } + free_list(&conf.file_names); + free_list(&conf.file_contents); + free_list(&conf.replaces); + for (i = 0; i < NUM_RESOURCE_LISTS; ++i) + free_list(&conf.lists.indexed[i]); + return 0; } -/* - * We would like to use the real realloc, but it doesn't work on all systems - * (e.g., some Linux versions). Also, this procedure does the right thing - * if old_ptr = NULL. - */ static void * -mrealloc(void *old_ptr, size_t old_size, size_t new_size) +mmalloc(size_t s, const char *label) { - void *new_ptr = malloc(new_size); +#if DEBUG_GENCONF_MEMORY + char *m; + memhdr *h; + + s += SIZEOF_MEMHDR_ALIGNED; + + m = malloc(s); + if (!m) return m; + h = (memhdr *)m; + h->s = s; + h->next = NULL; + h->count = mem_alloc_count++; + memhdr_tail->next = h; + memhdr_tail = h; + m += SIZEOF_MEMHDR_ALIGNED; + + return (void *)m; +#else + (void)label; + return malloc(s); +#endif +} + +static void * +mcalloc(size_t nmemb, size_t size, const char *label) +{ +#if DEBUG_GENCONF_MEMORY + char *m; + m = mmalloc(nmemb * size, label); + if (m) { + memset(m, 0x00, nmemb * size); + } + + return (void *)m; +#else + (void)label; + return calloc (nmemb, size); +#endif +} + +static void +mfree (void *om, const char *label) +{ +#if DEBUG_GENCONF_MEMORY + char *m = om; + memhdr *h, *hcur, *hprev; + + if (!m) return; + + h = (memhdr *)(m - SIZEOF_MEMHDR_ALIGNED); + hcur = memhdr_lst.next; + hprev = &memhdr_lst; + while (hcur && hcur != h) { + hprev = hcur; + hcur = hprev->next; + } + if (hcur == h) { + hprev->next = h->next; + } + if (h == memhdr_tail) + memhdr_tail = hprev; + + free(h); +#else + (void)label; + free(om); +#endif +} + +static void * +mrealloc(void *old_ptr, size_t old_size, size_t new_size, const char *label) +{ + void *new_ptr = mmalloc(new_size, label); if (new_ptr == NULL) return NULL; + memset(new_ptr, 0x00, new_size); /* We have to pass in the old size, since we have no way to */ /* determine it otherwise. */ - if (old_ptr) + if (old_ptr) { memcpy(new_ptr, old_ptr, min(old_size, new_size)); + mfree(old_ptr, "realloc"); + } return new_ptr; } @@ -548,11 +657,28 @@ { list->count = 0; list->items = - (string_item_t *) calloc(list->max_count, sizeof(string_item_t)); + (string_item_t *) mcalloc(list->max_count, sizeof(string_item_t), "alloc_list(items->items)"); assert(list->items != NULL); return 0; } +void +free_list(string_list_t * list) +{ + int i; + + for (i = 0; i < list->max_count; i++) { + if (list->items[i].str != empty_str) { + mfree((void *)list->items[i].str, "free_list(list->items[i].str)"); + } + list->items[i].str = empty_str; + } + + list->count = 0; + mfree(list->items, "free_list(list->items)"); + list->items = NULL; +} + /* If necessary, convert a .dev name to its file name. */ void dev_file_name(char *str) @@ -567,13 +693,13 @@ int process_replaces(config_t * pconf) { - char bufname[MAX_STR]; + char bufname[MAX_STR + 1]; int i; for (i = 0; i < pconf->replaces.count; ++i) { int j; - strcpy(bufname, pconf->replaces.items[i].str); + strncpy(bufname, pconf->replaces.items[i].str, MAX_STR); /* See if the file being replaced was included. */ dev_file_name(bufname); for (j = 0; j < pconf->file_names.count; ++j) { @@ -603,13 +729,20 @@ printf("Replacing %s %s.\n", pconf->lists.indexed[rn].list_name, items[tn].str); + if (items[tn].str && items[tn].str != empty_str) { + mfree((void *)items[tn].str, "process_replaces(items[tn].str)"); + } items[tn--] = items[--count]; + items[count].str = empty_str; } } pconf->lists.indexed[rn].count = count; } } - pconf->file_names.items[j].str = ""; + if (pconf->file_names.items[j].str != empty_str) { + mfree((void *)pconf->file_names.items[j].str, "process_replaces(pconf->file_names.items[j].str)"); + } + pconf->file_names.items[j].str = empty_str; break; } } @@ -628,7 +761,7 @@ static string_item_t * read_file(config_t * pconf, const char *fname) { - char *cname = malloc(strlen(fname) + strlen(pconf->file_prefix) + 1); + char *cname = mmalloc(strlen(fname) + strlen(pconf->file_prefix) + 1, "read_file(cname)"); int i; FILE *in; int end, nread; @@ -644,7 +777,7 @@ strcat(cname, fname); for (i = 0; i < pconf->file_names.count; ++i) if (!strcmp(pconf->file_names.items[i].str, cname)) { - free(cname); + mfree(cname, "read_file(cname)"); return &pconf->file_contents.items[i]; } /* Try to open the file in binary mode, to avoid the overhead */ @@ -654,19 +787,34 @@ in = fopen(cname, "r"); if (in == 0) { fprintf(stderr, "Can't read %s.\n", cname); + mfree(cname, "read_file(cname)"); exit(1); } } fseek(in, 0L, 2 /*SEEK_END */ ); end = ftell(in); - cont = malloc(end + 1); + if (end < 0) { + fclose(in); + fprintf(stderr, "Error reading file: %s.\n", cname); + mfree(cname, "read_file(cname)"); + exit(1); + } + cont = mmalloc(end + 1, "read_file(cont)"); if (cont == 0) { fprintf(stderr, "Can't allocate %d bytes to read %s.\n", end + 1, cname); + mfree(cname, "read_file(cname)"); exit(1); } rewind(in); nread = fread(cont, 1, end, in); + if (nread < 0) { + fclose(in); + mfree(cname, "read_file(cname)"); + mfree(cont, "read_file(cont)"); + fprintf(stderr, "Error reading file: %s.\n", cname); + exit(1); + } fclose(in); cont[nread] = 0; if (pconf->debug) @@ -674,6 +822,8 @@ add_item(&pconf->file_names, cname, -1); item = add_item(&pconf->file_contents, cont, -1); item->index = 0; /* union of uniq_mode_ts */ + mfree(cname, "read_file(cname)"); + mfree(cont, "read_file(cont)"); return item; } @@ -699,13 +849,21 @@ return uniq_first; } in = item->str; - token = malloc(MAX_TOKEN + 1); - category = malloc(MAX_TOKEN + 1); + token = mmalloc(MAX_TOKEN + 1, "read_dev(token)"); + category = mmalloc(MAX_TOKEN + 1, "read_dev(category)"); file_index = item - pconf->file_contents.items; strcpy(category, "obj"); - while ((len = read_token(token, MAX_TOKEN, &in)) > 0) - item->index |= add_entry(pconf, category, token, file_index); - free(category); + while ((len = read_token(token, MAX_TOKEN, &in)) > 0) { + int ind = add_entry(pconf, category, token, file_index); + /* we have to call "read_file" here in case add_entry has caused + * the memory for item to be realloc'ed. + * It will return the cached contents, not actually reread the entire + * file + */ + item = read_file(pconf, arg); + item->index |= ind; + } + mfree(category, "read_dev(category)"); #undef MAX_TOKEN if (len < 0) { fprintf(stderr, "Token too long: %s.\n", token); @@ -713,7 +871,7 @@ } if (pconf->debug) printf("Finished %s.\n", arg); - free(token); + mfree(token, "read_dev(token)"); return item->index; } @@ -751,7 +909,7 @@ return 0; } else { /* add to current category */ char str[MAX_STR]; - char templat[80]; + char templat[MAX_TEMPLAT + 1]; const char *pat = 0; string_list_t *list = &pconf->lists.named.resources; @@ -834,7 +992,7 @@ case 'o': if (IS_CAT("obj")) { list = &pconf->lists.named.objs; - strcpy(templat, pconf->file_prefix); + strncpy(templat, pconf->file_prefix, MAX_TEMPLAT); strcat(templat, "%s"); pat = templat; break; @@ -881,7 +1039,7 @@ string_item_t * add_item(string_list_t * list, const char *str, int file_index) { - char *rstr = malloc(strlen(str) + 1); + char *rstr = mmalloc(strlen(str) + 1, "add_item(rstr)"); int count = list->count; string_item_t *item; @@ -894,7 +1052,8 @@ (list->max_count >> 1) * sizeof(string_item_t), list->max_count * - sizeof(string_item_t)); + sizeof(string_item_t), + "add_item(list->items)"); assert(list->items != NULL); } item = &list->items[count]; @@ -933,23 +1092,37 @@ { string_item_t *strlist = list->items; int count = list->count; - const string_item_t *from; + string_item_t *from; string_item_t *to; int i; + char *str; bool last = list->mode == uniq_last; if (count == 0) return; qsort((char *)strlist, count, sizeof(string_item_t), cmp_str); - for (from = to = strlist + 1, i = 1; i < count; from++, i++) - if (strcmp(from->str, to[-1].str)) - *to++ = *from; - else if ((last ? from->index > to[-1].index : - from->index < to[-1].index) - ) - to[-1] = *from; + for (from = to = strlist + 1, i = 1; i < count; from++, i++) { + if (strcmp(from->str, to[-1].str)) { + if (to != from) { + str = (char *)to->str; + *to = *from; + if (str != empty_str) mfree(str, "sort_uniq(to->str)"); + from->str = empty_str; + } + to++; + } + else if ((last ? from->index > to[-1].index : from->index < to[-1].index)) { + if (&to[-1] != from) { + str = (char *)to[-1].str; + to[-1] = *from; + if (str != empty_str) mfree(str, "sort_uniq(to->str)"); + from->str = empty_str; + } + } + } count = to - strlist; list->count = count; + if (by_index) qsort((char *)strlist, count, sizeof(string_item_t), cmp_index); } @@ -962,7 +1135,7 @@ pat.upper_case = false; pat.drop_extn = false; - strcpy(pat.pattern, pstr); + strncpy(pat.pattern, pstr, MAX_PATTERN); write_list_pattern(out, list, &pat); } void @@ -970,16 +1143,16 @@ const string_pattern_t * pat) { int i; - char macname[40]; + char macname[MAX_PATTERN + 1]; int plen = strlen(pat->pattern); *macname = 0; for (i = 0; i < list->count; i++) { const char *lstr = list->items[i].str; int len = strlen(lstr); - char *str = malloc(len + 1); + char *str = mmalloc(len + 1, "write_list_pattern(str)"); int xlen = plen + len * 3; - char *xstr = malloc(xlen + 1); + char *xstr = mmalloc(xlen + 1, "write_list_pattern(xstr)"); char *alist; strcpy(str, lstr); @@ -1010,7 +1183,7 @@ if (*macname) fputs("#endif\n", out); fprintf(out, "#ifdef %s\n", xstr); - strcpy(macname, xstr); + strncpy(macname, xstr, MAX_PATTERN); } *alist = '('; } else { @@ -1020,9 +1193,53 @@ } } fputs(xstr, out); - free(xstr); - free(str); + mfree(xstr, "write_list_pattern(xstr)"); + mfree(str, "write_list_pattern(str)"); } if (*macname) fputs("#endif\n", out); } + +#if DEBUG_GENCONF_MEMORY +void +validate_list(string_list_t *sl) +{ + int i, j; + for (i = 0; i < sl->max_count; i++) { + if (sl->items[i].str && sl->items[i].str != empty_str) { + for (j = i + 1; j < sl->count; j++){ + if (sl->items[i].str == sl->items[j].str) { + printf("Duplicate found: %s\n", sl->items[j].str); + } + } + } + } + +} + +void +validate_lists(config_t *conf) +{ + int i; + printf("Validating lists....\n"); + validate_list(&conf->file_names); + validate_list(&conf->file_contents); + validate_list(&conf->replaces); + for (i = 0; i < NUM_RESOURCE_LISTS; ++i) + validate_list(&conf->lists.indexed[i]); + + printf("Done validating lists\n"); +} + +void validate_memory(void) +{ + memhdr *h = memhdr_lst.next; + printf("Validating memory....\n"); + + while (h) { + printf("hdr: 0x%llx, from allocation %lld not freed\n", h, h->count); + h = h->next; + } + printf("Done validating memory\n"); +} +#endif diff -Nru ghostscript-9.10~dfsg/base/gendev.c ghostscript-9.25~dfsg+1/base/gendev.c --- ghostscript-9.10~dfsg/base/gendev.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gendev.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/genht.c ghostscript-9.25~dfsg+1/base/genht.c --- ghostscript-9.10~dfsg/base/genht.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/genht.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -198,7 +198,7 @@ phtr->bit_data = malloc(num_bits * sizeof(ushort)); Thresholds = malloc(num_bits); - s_AXD_init_inline(&ss); + (void)s_AXD_init_inline(&ss); r.ptr = (const byte *)eol; r.limit = (const byte *)eol + strlen(eol + 1); w.ptr = Thresholds - 1; diff -Nru ghostscript-9.10~dfsg/base/gen_ordered.c ghostscript-9.25~dfsg+1/base/gen_ordered.c --- ghostscript-9.10~dfsg/base/gen_ordered.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gen_ordered.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,2012 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ +/* Ordered Dither Screen Creation Tool. */ + +#include + +#ifdef GS_LIB_BUILD +#define LIB_BUILD + +#include "std.h" +#include "string_.h" +#include "gsmemory.h" +#include "math_.h" + +# define ALLOC(mem, size) (gs_alloc_bytes((gs_memory_t *)mem, size, "gen_ordered")) +# define FREE(mem, ptr) gs_free_object((gs_memory_t *)mem, ptr, "gen_ordered") + +# define PRINTF(mem, str) outprintf((gs_memory_t *)mem, str) +# define PRINTF2(mem, str, v1, v2) outprintf((gs_memory_t *)mem, str, v1, v2) +# define PRINTF4(mem, str, v1, v2, v3, v4) outprintf((gs_memory_t *)mem, str, v1, v2, v3, v4) +# define PRINTF7(mem, str, v1, v2, v3, v4, v5, v6, v7) outprintf((gs_memory_t *)mem, str, v1, v2, v3, v4, v5, v6, v7) +# define EPRINTF(mem, str) errprintf((gs_memory_t *)mem, str) +# define EPRINTF1(mem, str, v1) errprintf((gs_memory_t *)mem, str, v1) +# define EPRINTF3(mem, str, v1, v2, v3) errprintf((gs_memory_t *)mem, str, v1, v2, v3) + +#endif /* defined GS_LIB_BUILD */ + +#ifndef LIB_BUILD + +#include +#include +#include +#include +#include + +typedef unsigned char byte; +#define false 0 +#define true 1 +#ifndef __cplusplus + typedef int bool; +#endif /* __cpluplus */ + +/* Needed if standalone (main) */ + +# define ALLOC(mem, size) (malloc(size)) +# define FREE(mem, ptr) (free(ptr)) + +# define PRINTF(mem, str) printf(str) +# define PRINTF2(mem, str, v1, v2) printf(str, v1, v2) +# define PRINTF4(mem, str, v1, v2, v3, v4) printf(str, v1, v2, v3, v4) +# define PRINTF7(mem, str, v1, v2, v3, v4, v5, v6, v7) printf(str, v1, v2, v3, v4, v5, v6, v7) +# define EPRINTF(mem, str) fprintf(stderr, str) +# define EPRINTF1(mem, str, v1) fprintf(stderr, str, v1) +# define EPRINTF3(mem, str, v1, v2, v3) fprintf(stderr, str, v1, v2, v3) + +#endif /* ndef LIB_BUILD */ + +#include "gen_ordered.h" + +typedef struct htsc_point_s { + double x; + double y; +} htsc_point_t; + +typedef struct htsc_threshpoint { + int x; + int y; + int value; + int index; + double dist_to_center; +} htsc_threshpoint_t; + +typedef struct htsc_vertices_s { + htsc_point_t lower_left; + htsc_point_t upper_left; + htsc_point_t upper_right; + htsc_point_t lower_right; +} htsc_vertices_t; + +typedef struct htsc_dot_shape_search_s { + double norm; + int index_x; + int index_y; +} htsc_dot_shape_search_t; + +typedef struct htsc_matrix_s { + htsc_vector_t row[2]; +} htsc_matrix_t; + +typedef struct htsc_dither_pos_s { + htsc_point_t *point; + int number_points; + int *locations; +} htsc_dither_pos_t; + +static void htsc_determine_cell_shape(double *x, double *y, double *v, double *u, + double *N, htsc_param_t params, void *mem); +static double htsc_spot_value(spottype_t spot_type, double x, double y); +static int htsc_getpoint(htsc_dig_grid_t *dig_grid, int x, int y); +static void htsc_setpoint(htsc_dig_grid_t *dig_grid, int x, int y, int value); +static int htsc_create_dot_mask(htsc_dig_grid_t *dig_grid, int x, int y, int u, int v, + double screen_angle, htsc_vertices_t vertices); +static void htsc_find_bin_center(htsc_dig_grid_t *dot_grid, htsc_vector_t *bin_center); +static int htsc_sumsum(htsc_dig_grid_t dig_grid); +static void htsc_create_dot_profile(htsc_dig_grid_t *dig_grid, int N, int x, int y, + int u, int v, double horiz_dpi, + double vert_dpi, htsc_vertices_t vertices, + htsc_point_t *one_index, spottype_t spot_type, + htsc_matrix_t trans_matrix); +static int htsc_allocate_supercell(htsc_dig_grid_t *super_cell, int x, int y, int u, + int v, int target_size, bool use_holladay_grid, + htsc_dig_grid_t dot_grid, int N, int *S, int *H, int *L); +static void htsc_tile_supercell(htsc_dig_grid_t *super_cell, htsc_dig_grid_t *dot_grid, + int x, int y, int u, int v, int N); +void create_2d_gauss_filter(float *filter, int x_size, int y_size, + float stdvalx, float stdvaly); +static int htsc_create_holladay_mask(htsc_dig_grid_t super_cell, int H, int L, + double gamma, htsc_dig_grid_t *final_mask); +static int htsc_create_dither_mask(htsc_dig_grid_t super_cell, + htsc_dig_grid_t *final_mask, int verbose, + int num_levels, int y, int x, double vert_dpi, + double horiz_dpi, int N, double gamma, + htsc_dig_grid_t dot_grid, htsc_point_t one_index); +static int htsc_create_nondithered_mask(htsc_dig_grid_t super_cell, int H, int L, + double gamma, htsc_dig_grid_t *final_mask); +static int htsc_gcd(int a, int b); +static int htsc_lcm(int a, int b); +static int htsc_matrix_inverse(htsc_matrix_t matrix_in, htsc_matrix_t *matrix_out); +static void htsc_matrix_vector_mult(htsc_matrix_t matrix_in, htsc_vector_t vector_in, + htsc_vector_t *vector_out); +static int htsc_mask_to_tos(htsc_dig_grid_t *final_mask); +#if RAW_SCREEN_DUMP +static void htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]); +static void htsc_dump_float_image(float *image, int height, int width, float max_val, + char filename[]); +static void htsc_dump_byte_image(byte *image, int height, int width, float max_val, + char filename[]); +#endif + +/* Initialize default values */ +void htsc_set_default_params(htsc_param_t *params) +{ + params->scr_ang = 0; + params->targ_scr_ang = 0; + params->targ_lpi = 75; + params->vert_dpi = 300; + params->horiz_dpi = 300; + params->targ_quant_spec = false; + params->targ_quant = 256; + params->targ_size = 1; + params->targ_size_spec = false; + params->spot_type = CIRCLE; + params->holladay = false; + params->gamma = 1.0; + params->output_format = OUTPUT_TOS; + params->verbose = 0; +} + +int +htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask) +{ + double num_levels; + double x=0.0, y=0.0, v=0.0, u=0.0, N=0.0; + htsc_vertices_t vertices; + htsc_vector_t bin_center; + htsc_point_t one_index = { 0., 0. }; + htsc_dig_grid_t dot_grid; + htsc_dig_grid_t super_cell; + int code; + int H, L; + htsc_matrix_t trans_matrix, trans_matrix_inv; + int min_size; + + dot_grid.data = NULL; + dot_grid.memory = final_mask->memory; + super_cell.data = NULL; + super_cell.memory = final_mask->memory; + final_mask->data = NULL; + params.targ_scr_ang = params.targ_scr_ang % 90; + params.scr_ang = params.targ_scr_ang; + /* Get the vector values that define the small cell shape */ + htsc_determine_cell_shape(&x, &y, &v, &u, &N, params, final_mask->memory); + + /* Figure out how many levels to dither across. */ + if (params.targ_quant_spec) { + num_levels = ROUND((double) params.targ_quant / N); + } else { + num_levels = 1; + } + if (num_levels < 1) num_levels = 1; + if (num_levels == 1) { + if (params.verbose > 0) + PRINTF(final_mask->memory, "No additional dithering , creating minimal sized periodic screen\n"); + params.targ_size = 1; + } + + /* Lower left of the cell is at the origin. Define the other vertices */ + vertices.lower_left.x = 0; + vertices.lower_left.y = 0; + vertices.upper_left.x = x; + vertices.upper_left.y = y; + vertices.upper_right.x = x + u; + vertices.upper_right.y = y + v; + vertices.lower_right.x = u; + vertices.lower_right.y = v; + + /* Create the matrix that is used to get us correctly into the dot shape function */ + trans_matrix.row[0].xy[0] = u; + trans_matrix.row[0].xy[1] = x; + trans_matrix.row[1].xy[0] = v; + trans_matrix.row[1].xy[1] = y; + code = htsc_matrix_inverse(trans_matrix, &trans_matrix_inv); + if (code < 0) { + EPRINTF(final_mask->memory, "ERROR! Singular Matrix Inversion!\n"); + return -1; + } + + /* Create a binary mask that indicates where we need to define the dot turn + on sequence or dot profile */ + code = htsc_create_dot_mask(&dot_grid, x, y, u, v, params.scr_ang, vertices); + if (code < 0) { + return -1; + } +#if RAW_SCREEN_DUMP + htsc_dump_screen(&dot_grid, "mask"); +#endif + /* A sanity check */ + if (htsc_sumsum(dot_grid) != -N) { + EPRINTF(final_mask->memory, "ERROR! grid size problem!\n"); + return -1; + } + + /* From the binary mask, find the center point. This is needed to remove + ambiguity during the TOS calculation from the dot profile. We want to + turn on those dots that are closests to the center first when there + are ties */ + htsc_find_bin_center(&dot_grid, &bin_center); + + + /* Now actually determine the turn on sequence */ + htsc_create_dot_profile(&dot_grid, N, x, y, u, v, params.horiz_dpi, + params.vert_dpi, vertices, &one_index, + params.spot_type, trans_matrix_inv); + +#if RAW_SCREEN_DUMP + htsc_dump_screen(&dot_grid, "dot_profile"); +#endif + /* Allocate super cell */ + code = htsc_allocate_supercell(&super_cell, x, y, u, v, params.targ_size, + params.holladay, dot_grid, N, S, &H, &L); + if (code < 0) { + EPRINTF(final_mask->memory, "ERROR! grid size problem!\n"); + return -1; + } + + /* Make a warning about large requested quantization levels with no -s set */ + if (params.targ_size == 1 && num_levels > 1) { + min_size = (int)ceil((double)params.targ_quant / N); + EPRINTF1(final_mask->memory, "To achieve %d quantization levels with the desired lpi,\n", params.targ_quant); + EPRINTF1(final_mask->memory, "it is necessary to specify a SuperCellSize (-s) of at least %d.\n", min_size); + EPRINTF(final_mask->memory, "Note that an even larger size may be needed to reduce pattern artifacts.\n"); + EPRINTF(final_mask->memory, "Because no SuperCellSize was specified, the minimum possible size\n"); + EPRINTF(final_mask->memory, "that can approximate the requested angle and lpi will be created\n"); + EPRINTF1(final_mask->memory, "with %d quantization levels.\n", (int) N); + } + + /* Go ahead and fill up the super cell grid with our growth dot values */ + htsc_tile_supercell(&super_cell, &dot_grid, x, y, u, v, N); +#if RAW_SCREEN_DUMP + htsc_dump_screen(&super_cell, "super_cell_tiled"); +#endif + /* If we are using the Holladay grid (non dithered) then we are done. */ + if (params.holladay) { + htsc_create_holladay_mask(super_cell, H, L, params.gamma, final_mask); + } else { + if ((super_cell.height == dot_grid.height && + super_cell.width == dot_grid.width) || num_levels == 1) { + htsc_create_nondithered_mask(super_cell, H, L, params.gamma, final_mask); + } else { + /* Dont allow nonsense settings */ + if (num_levels * N > super_cell.height * super_cell.width) { + EPRINTF3(final_mask->memory, + "Notice, %3.0lf quantization levels not possible with super cell of %d by %d\n", + num_levels, super_cell.height, super_cell.width); + num_levels = ROUND((super_cell.height * super_cell.width) / N); + EPRINTF1(final_mask->memory, "Reducing dithering quantization to %3.0lf\n", + num_levels); + EPRINTF1(final_mask->memory, "For an effective quantization of %d\n", + super_cell.height * super_cell.width); + } + code = htsc_create_dither_mask(super_cell, final_mask, params.verbose, num_levels, + y, x, params.vert_dpi, params.horiz_dpi, N, + params.gamma, dot_grid, one_index); + } + } + final_mask->bin_center = bin_center; + + /* Now if the requested format is turn-on-sequence, convert the "data" */ + if (code == 0 && params.output_format == OUTPUT_TOS) { + code = htsc_mask_to_tos(final_mask); + } + /* result in in final_mask, clean up working arrays allocated. */ + FREE(final_mask->memory, dot_grid.data); + FREE(final_mask->memory, super_cell.data); + return code; +} + +/* comparison for use in qsort */ +static int +compare(const void * a, const void * b) +{ + const htsc_threshpoint_t *val_a = a; + const htsc_threshpoint_t *val_b = b; + double cost = val_a->value - val_b->value; + + /* If same value, use distance to center for decision */ + if (cost == 0) { + /* Don't think these should ever be the same due to tiling effect */ + return val_a->dist_to_center - val_b->dist_to_center; + } else { + return cost; + } +} + +static int +htsc_mask_to_tos(htsc_dig_grid_t *final_mask) +{ + int width = final_mask->width; + int height = final_mask->height; + htsc_vector_t center = final_mask->bin_center; + int *buff_ptr = final_mask->data; + int x, y, k = 0; + int count = height * width; + htsc_threshpoint_t *values; + int *tos; + + values = (htsc_threshpoint_t *) ALLOC(final_mask->memory, + sizeof(htsc_threshpoint_t) * width * height); + if (values == NULL) { + EPRINTF(final_mask->memory, "ERROR! malloc failure in htsc_mask_to_tos!\n"); + return -1; + } + tos = (int *) ALLOC(final_mask->memory, sizeof(int) * 2 * height * width); + if (tos == NULL) { + FREE(final_mask->memory, values); + EPRINTF(final_mask->memory, "ERROR! malloc failure in htsc_mask_to_tos!\n"); + return -1; + } + /* Do a sort on the values and then output the coordinates */ + /* First get a list made with the unsorted values and coordinates */ + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + values[k].value = *buff_ptr; + values[k].x = x; + values[k].y = y; + values[k].index = k; + values[k].dist_to_center = (x - center.xy[0]) * (x - center.xy[0]) + + (y - center.xy[1]) * (y - center.xy[1]); + buff_ptr++; + k = k + 1; + } + } +#if RAW_SCREEN_DUMP + EPRINTF(final_mask->memory, "Unsorted\n"); + for (k = 0; k < count; k++) { + EPRINTF(final_mask->memory, "Index %d : x = %d y = %d dist = %4.2lf value = %d \n", + values[k].index, values[k].x, values[k].y, values[k].dist_to_center, values[k].value); + } +#endif + /* Sort */ + qsort(values, height * width, sizeof(htsc_threshpoint_t), compare); +#if RAW_SCREEN_DUMP + EPRINTF(final_mask->memory, "Sorted\n"); + for (k = 0; k < count; k++) { + EPRINTF(final_mask->memory, "Index %d : x = %d y = %d dist = %4.2lf value = %d \n", + values[k].index, values[k].x, values[k].y, values[k].dist_to_center, values[k].value); + } +#endif + + FREE(final_mask->memory, final_mask->data); + final_mask->data = tos; + buff_ptr = tos; + + for (k=0; k < count; k++) { + *buff_ptr++ = values[count - 1 - k].x; + *buff_ptr++ = values[count - 1 - k].y; + } + FREE(final_mask->memory, values); + return 0; +} + +static void +htsc_determine_cell_shape(double *x_out, double *y_out, double *v_out, + double *u_out, double *N_out, htsc_param_t params, void *mem) +{ + double x = 0., y = 0., v = 0., u = 0., N = 0.; + double frac, scaled_x; + double ratio; + const double pi = 3.14159265358979323846f; + double true_angle, lpi; + double prev_lpi, max_lpi = 0.; + bool use = false; + double x_use = 0.,y_use = 0.; + + /* Go through and find the rational angle options that gets us to the + best LPI. Pick the one that is just over what is requested. + That is really our limiting factor here. Pick it and + then figure out how much dithering we need to do to get to the proper + number of levels. */ + frac = tan( params.scr_ang * pi / 180.0 ); + ratio = frac * params.horiz_dpi / params.vert_dpi; + scaled_x = params.horiz_dpi / params.vert_dpi; + /* The minimal step is in x */ + prev_lpi = 0; + if (ratio < 1 && ratio != 0) { + if (params.verbose > 0) { + PRINTF(mem, "x\ty\tu\tv\tAngle\tLPI\tLevels\n"); + PRINTF(mem, "-----------------------------------------------------------\n"); + } + for (x = 1; x < 11; x++) { + x_use = x; + y=ROUND((double) x_use / ratio); + true_angle = 180.0 * atan(((double) x_use / params.horiz_dpi) / ( (double) y / params.vert_dpi) ) / pi; + lpi = 1.0/( sqrt( ((double) y / params.vert_dpi) * ( (double) y / params.vert_dpi) + + ( (double) x_use / params.horiz_dpi) * ((double) x_use / params.horiz_dpi) )); + v = -x_use / scaled_x; + u = y * scaled_x; + N = y *u - x_use * v; + if (prev_lpi == 0) { + prev_lpi = lpi; + if (params.targ_lpi > lpi) { + EPRINTF(mem, "Warning this lpi is not achievable!\n"); + EPRINTF(mem, "Resulting screen will be poorly quantized\n"); + EPRINTF(mem, "or completely stochastic!\n"); + use = true; + } + max_lpi = lpi; + } + if (prev_lpi >= params.targ_lpi && lpi < params.targ_lpi) { + if (prev_lpi == max_lpi) { + EPRINTF(mem, "Notice lpi is at the maximimum level possible.\n"); + EPRINTF(mem, "This may result in poor quantization. \n"); + } + /* Reset these to previous x */ + x_use = x - 1; + y=ROUND((double) x_use / ratio); + true_angle = + 180.0 * atan(((double) x_use / params.horiz_dpi) / ( (double) y / params.vert_dpi) ) / pi; + lpi = + 1.0/( sqrt( ((double) y / params.vert_dpi) * ( (double) y / params.vert_dpi) + + ( (double) x_use / params.horiz_dpi) * ((double) x_use / params.horiz_dpi) )); + v = -x_use / scaled_x; + u = y * scaled_x; + N = y *u - x_use * v; + use = true; + } + if (use == true) { + if (prev_lpi == max_lpi) { + /* Print out the final one that we will use */ + if (params.verbose > 0) + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x_use,y,u,v,true_angle,lpi,N); + } + break; + } + if (params.verbose > 0) + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x_use,y,u,v,true_angle,lpi,N); + prev_lpi = lpi; + } + x = x_use; + } + if (ratio >= 1 && ratio!=0) { + /* The minimal step is in y */ + if (params.verbose > 0) { + PRINTF(mem, "x\ty\tu\tv\tAngle\tLPI\tLevels\n"); + PRINTF(mem, "-----------------------------------------------------------\n"); + } + for (y = 1, lpi = 99999999; lpi > params.targ_lpi; y++) { + y_use = y; + x = ROUND(y_use * ratio); + /* compute the true angle */ + true_angle = 180.0 * atan((x / params.horiz_dpi) / (y_use / params.vert_dpi)) / pi; + lpi = 1.0 / sqrt( (y_use / params.vert_dpi) * (y_use / params.vert_dpi) + + (x / params.horiz_dpi) * (x / params.horiz_dpi)); + v = ROUND(-x / scaled_x); + u = ROUND(y_use * scaled_x); + N = y_use * u - x * v; + if (prev_lpi == 0) { + prev_lpi = lpi; + if (params.targ_lpi > lpi) { + EPRINTF(mem, "Warning this lpi is not achievable!\n"); + EPRINTF(mem, "Resulting screen will be poorly quantized\n"); + EPRINTF(mem, "or completely stochastic!\n"); + use = true; + } + max_lpi = lpi; + } + if (prev_lpi >= params.targ_lpi && lpi < params.targ_lpi) { + if (prev_lpi == max_lpi) { + EPRINTF(mem, "Warning lpi will be slightly lower than target.\n"); + EPRINTF(mem, "An increase will result in poor \n"); + EPRINTF(mem, "quantization or a completely stochastic screen!\n"); + } else { + /* Reset these to previous x */ + y_use = y - 1; + x = ROUND(y_use * ratio); + /* compute the true angle */ + true_angle = 180.0 * atan((x / params.horiz_dpi) / (y_use / params.vert_dpi)) / pi; + lpi = 1.0 / sqrt( (y_use / params.vert_dpi) * (y_use / params.vert_dpi) + + (x / params.horiz_dpi) * (x / params.horiz_dpi)); + v = ROUND(-x / scaled_x); + u = ROUND(y_use * scaled_x); + N = y_use * u - x * v; + } + use = true; + } + if (use == true) { + if (prev_lpi == max_lpi) { + /* Print out the final one that we will use */ + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x,y_use,u,v,true_angle,lpi,N); + } + break; + } + if (params.verbose > 0) + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x,y_use,u,v,true_angle,lpi,N); + prev_lpi = lpi; + } + y = y_use; + } + if (ratio == 0) { + /* 0 degrees */ + if (scaled_x >= 1) { + if (params.verbose > 0) { + PRINTF(mem, "x\ty\tu\tv\tAngle\tLPI\tLevels\n"); + PRINTF(mem, "-----------------------------------------------------------\n"); + } + for (y = 1, lpi=9999999; lpi > params.targ_lpi; y++) { + y_use = y; + x = ROUND( y_use * ratio ); + v = ROUND(-x / scaled_x); + u = ROUND(y_use * scaled_x); + N = y_use * u - x * v; + true_angle = 0; + lpi = 1.0/(double) sqrt( (double) ((y_use / params.vert_dpi) * + (y_use / params.vert_dpi) + (x / params.horiz_dpi) * (x / params.horiz_dpi)) ); + if (prev_lpi == 0) { + prev_lpi = lpi; + if (params.targ_lpi > lpi) { + EPRINTF(mem, "Warning this lpi is not achievable!\n"); + EPRINTF(mem, "Resulting screen will be poorly quantized\n"); + EPRINTF(mem, "or completely stochastic!\n"); + use = true; + } + max_lpi = lpi; + } + if (prev_lpi >= params.targ_lpi && lpi < params.targ_lpi) { + if (prev_lpi == max_lpi) { + EPRINTF(mem, "Warning lpi will be slightly lower than target.\n"); + EPRINTF(mem, "An increase will result in poor \n"); + EPRINTF(mem, "quantization or a completely stochastic screen!\n"); + } else { + /* Reset these to previous x */ + y_use = y - 1; + x = ROUND( y_use * ratio ); + v = ROUND(-x / scaled_x); + u = ROUND(y_use * scaled_x); + N = y_use * u - x * v; + true_angle = 0; + lpi = 1.0/(double) sqrt( (double) ((y_use / params.vert_dpi) * + (y_use / params.vert_dpi) + (x / params.horiz_dpi) * (x / params.horiz_dpi)) ); + } + use = true; + } + if (use == true) { + if (prev_lpi == max_lpi) { + /* Print out the final one that we will use */ + if (params.verbose > 0) + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x,y_use,u,v,true_angle,lpi,N); + } + break; + } + if (params.verbose > 0) + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x,y_use,u,v,true_angle,lpi,N); + prev_lpi = lpi; + } + y = y_use; + } else { + if (params.verbose > 0) { + PRINTF(mem, "x\ty\tu\tv\tAngle\tLPI\tLevels\n"); + PRINTF(mem, "-----------------------------------------------------------\n"); + } + for (x = 1; x < 11; x++) { + x_use = x; + y = ROUND(x_use * ratio); + true_angle = 0; + lpi = 1.0/( sqrt( (y / params.vert_dpi) * (y / params.vert_dpi) + + (x_use / params.horiz_dpi) * (x_use / params.horiz_dpi) )); + v = ROUND( -x_use / scaled_x); + u = ROUND( y * scaled_x); + N = y *u - x_use * v; + if (prev_lpi == 0) { + prev_lpi = lpi; + if (params.targ_lpi > lpi) { + EPRINTF(mem, "Warning this lpi is not achievable!\n"); + EPRINTF(mem, "Resulting screen will be poorly quantized\n"); + EPRINTF(mem, "or completely stochastic!\n"); + use = true; + } + max_lpi = lpi; + } + if (prev_lpi > params.targ_lpi && lpi < params.targ_lpi) { + if (prev_lpi == max_lpi) { + EPRINTF(mem, "Warning lpi will be slightly lower than target.\n"); + EPRINTF(mem, "An increase will result in poor \n"); + EPRINTF(mem, "quantization or a completely stochastic screen!\n"); + } else { + /* Reset these to previous x */ + x_use = x - 1; + y = ROUND(x_use * ratio); + true_angle = 0; + lpi = 1.0/( sqrt( (y / params.vert_dpi) * (y / params.vert_dpi) + + (x_use / params.horiz_dpi) * (x_use / params.horiz_dpi) )); + v = ROUND( -x_use / scaled_x); + u = ROUND( y * scaled_x); + N = y *u - x_use * v; + } + use = true; + } + if (use == true) { + if (prev_lpi == max_lpi) { + /* Print out the final one that we will use */ + if (params.verbose > 0) + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x_use,y,u,v,true_angle,lpi,N); + } + break; + } + if (params.verbose > 0) + PRINTF7(mem, "%3.0lf\t%3.0lf\t%3.0lf\t%3.0lf\t%3.1lf\t%3.1lf\t%3.0lf\n", + x_use,y,u,v,true_angle,lpi,N); + prev_lpi = lpi; + } + x = x_use; + } + } + *x_out = x; + *y_out = y; + *v_out = v; + *u_out = u; + *N_out = N; +} + +static void +htsc_create_dot_profile(htsc_dig_grid_t *dig_grid, int N, int x, int y, int u, int v, + double horiz_dpi, double vert_dpi, htsc_vertices_t vertices, + htsc_point_t *one_index, spottype_t spot_type, htsc_matrix_t trans_matrix) +{ + int done, dot_index, hole_index, count, index_x, index_y; + htsc_dot_shape_search_t dot_search; + int k, val_min; + double dist; + int j; + htsc_vector_t vector_in, vector_out; + double x_offset = (x % 2 == 0 ? 0.5 : 0); + double y_offset = (y % 2 == 0 ? 0.5 : 0); + + done = 0; + dot_index = 1; + hole_index = N; + count = 0; + val_min=MIN(0,v); + + while (!done) { + + /* First perform a search for largest dot value for those remaining + dots */ + index_x = 0; + dot_search.index_x = 0; + dot_search.index_y = 0; + dot_search.norm = -100000000; /* Hopefully the dot func is not this small */ + for (k = 0; k < x + u; k++) { + index_y = 0; + for (j = val_min; j < y; j++) { + if ( htsc_getpoint(dig_grid, index_x, index_y) == -1 ) { + + /* For the spot function we want to make sure that + we are properly adjusted to be in the range from + -1 to +1. j and k are moving in the transformed + (skewed/rotated) space. First untransform the value */ + vector_in.xy[0] = k + x_offset; + vector_in.xy[1] = j + y_offset; + htsc_matrix_vector_mult(trans_matrix, vector_in, + &vector_out); + + /* And so now we are in the range 0, 1 get us to -.5, .5 */ + vector_out.xy[0] = 2.0 * vector_out.xy[0] - 1.0; + vector_out.xy[1] = 2.0 * vector_out.xy[1] - 1.0; + dist = htsc_spot_value(spot_type, vector_out.xy[0], + vector_out.xy[1]); + if (dist > dot_search.norm) { + dot_search.norm = dist; + dot_search.index_x = index_x; + dot_search.index_y = index_y; + } + + } + index_y++; + } + index_x++; + } + /* Assign the index for this position */ + htsc_setpoint(dig_grid, dot_search.index_x, dot_search.index_y, + dot_index); + dot_index++; + count++; + if (count == N) { + done = 1; + break; + } + + /* The ones position for the dig_grid is located at the first dot_search + entry. We need this later so grab it now */ + if (count == 1) { + one_index->x = dot_search.index_x; + one_index->y = dot_search.index_y; + } + + /* Now search for the closest one to a vertex (of those remaining). + and assign the current largest index */ + index_x = 0; + dot_search.index_x = 0; + dot_search.index_y = 0; + dot_search.norm = 10000000000; /* Or this large */ + for (k = 0; k < x + u; k++) { + index_y = 0; + for (j = val_min; j < y; j++) { + if ( htsc_getpoint(dig_grid, index_x, index_y) == -1 ) { + + /* For the spot function we want to make sure that + we are properly adjusted to be in the range from + -1 to +1. j and k are moving in the transformed + (skewed/rotated) space. First untransform the value */ + vector_in.xy[0] = k + x_offset; + vector_in.xy[1] = j + y_offset; + htsc_matrix_vector_mult(trans_matrix, vector_in, + &vector_out); + + /* And so now we are in the range 0, 1 get us to -.5, .5 */ + vector_out.xy[0] = 2.0 * vector_out.xy[0] - 1.0; + vector_out.xy[1] = 2.0 * vector_out.xy[1] - 1.0; + dist = htsc_spot_value(spot_type, vector_out.xy[0], + vector_out.xy[1]); + + if (dist < dot_search.norm) { + dot_search.norm = dist; + dot_search.index_x = index_x; + dot_search.index_y = index_y; + } + } + index_y++; + } + index_x++; + } + /* Assign the index for this position */ + htsc_setpoint(dig_grid, dot_search.index_x, dot_search.index_y, hole_index); + hole_index--; + count++; + if (count == N) { + done = 1; + break; + } + } +} + +/* This creates a mask for creating the dot shape */ +static int +htsc_create_dot_mask(htsc_dig_grid_t *dot_grid, int x, int y, int u, int v, + double screen_angle, htsc_vertices_t vertices) +{ + int k,j,val_min,index_x,index_y; + double slope1, slope2; + int t1,t2,t3,t4,point_in; + float b3, b4; + htsc_point_t test_point; + + if (screen_angle != 0) { + slope1 = (double) y / (double) x; + slope2 = (double) v / (double) u; + val_min=MIN(0,v); + dot_grid->height = abs(val_min) + y; + dot_grid->width = x + u; + dot_grid->data = + (int *) ALLOC(dot_grid->memory, dot_grid->height * dot_grid->width * sizeof(int)); + if (dot_grid->data == NULL) + return -1; + memset(dot_grid->data,0,dot_grid->height * dot_grid->width * sizeof(int)); + index_x = 0; + for (k = 0; k < (x+u); k++) { + index_y=0; + for (j = val_min; j < y; j++) { + test_point.x = k + 0.5; + test_point.y = j + 0.5; + /* test 1 and 2 */ + t1 = (slope1 * test_point.x >= test_point.y); + t2 = (slope2 * test_point.x <= test_point.y); + /* test 3 */ + b3 = vertices.upper_left.y - slope2 * vertices.upper_left.x; + t3 = ((slope2 * test_point.x + b3) > test_point.y); + /* test 4 */ + b4 = vertices.lower_right.y - slope1 * vertices.lower_right.x; + t4=((slope1 * test_point.x + b4) < test_point.y); + point_in = (t1 && t2 && t3 && t4); + if (point_in) { + htsc_setpoint(dot_grid, index_x, index_y, -1); + } + index_y++; + } + index_x++; + } + } else { + /* All points are valid */ + dot_grid->height = y; + dot_grid->width = u; + dot_grid->data = (int *) ALLOC(dot_grid->memory, y * u * sizeof(int)); + if (dot_grid->data == NULL) + return -1; + memset(dot_grid->data, -1, y * u * sizeof(int)); + val_min = 0; + } + return 0; +} + +static void +htsc_find_bin_center(htsc_dig_grid_t *dot_grid, htsc_vector_t *bin_center) +{ + int h = dot_grid->height; + int w = dot_grid->width; + int min_y = h + 1; + int min_x = w + 1; + int max_y = -1; + int max_x = -1; + int x, y; + + for (x = 0; x < w; x++) { + for (y = 0; y < h; y++) { + if (htsc_getpoint(dot_grid, x, y) == -1) + { + if (x < min_x) + min_x = x; + if (x > max_x) + max_x = x; + if (y < min_y) + min_y = y; + if (y > max_y) + max_y = y; + } + } + } + bin_center->xy[0] = (max_x - min_x) / 2.0; + bin_center->xy[1] = (max_y - min_y) / 2.0; +} + +static int +htsc_getpoint(htsc_dig_grid_t *dig_grid, int x, int y) +{ + return dig_grid->data[ y * dig_grid->width + x]; +} + +static void +htsc_setpoint(htsc_dig_grid_t *dig_grid, int x, int y, int value) +{ + int kk = 0;; + if (x < 0 || x > dig_grid->width-1 || y < 0 || y > dig_grid->height-1) { + kk++; /* Here to catch issues during debug */ + } + dig_grid->data[ y * dig_grid->width + x] = value; +} + +static int +htsc_sumsum(htsc_dig_grid_t dig_grid) +{ + + int pos; + int grid_size = dig_grid.width * dig_grid.height; + int value = 0; + int *ptr = dig_grid.data; + + for (pos = 0; pos < grid_size; pos++) { + value += (*ptr++); + } + return value; +} + +static int +htsc_gcd(int a, int b) +{ + if ( a == 0 && b == 0 ) return 0; + if ( b == 0 ) return a; + if ( a == 0 ) return b; + while (1) { + a = a % b; + if (a == 0) { + return b; + } + b = b % a; + if (b == 0) { + return a; + } + } +} + +static int +htsc_lcm(int a, int b) +{ + int product = a * b; + int gcd = htsc_gcd(a,b); + int lcm; + + if (gcd == 0) + return -1; + + lcm = product/gcd; + return lcm; +} + +static int +htsc_matrix_inverse(htsc_matrix_t matrix_in, htsc_matrix_t *matrix_out) +{ + double determinant; + + determinant = matrix_in.row[0].xy[0] * matrix_in.row[1].xy[1] - + matrix_in.row[0].xy[1] * matrix_in.row[1].xy[0]; + if (determinant == 0) + return -1; + matrix_out->row[0].xy[0] = matrix_in.row[1].xy[1] / determinant; + matrix_out->row[0].xy[1] = -matrix_in.row[0].xy[1] / determinant; + matrix_out->row[1].xy[0] = -matrix_in.row[1].xy[0] / determinant; + matrix_out->row[1].xy[1] = matrix_in.row[0].xy[0] / determinant; + return 0; +} + +static void +htsc_matrix_vector_mult(htsc_matrix_t matrix_in, htsc_vector_t vector_in, + htsc_vector_t *vector_out) +{ + vector_out->xy[0] = matrix_in.row[0].xy[0] * vector_in.xy[0] + + matrix_in.row[0].xy[1] * vector_in.xy[1]; + vector_out->xy[1] = matrix_in.row[1].xy[0] * vector_in.xy[0] + + matrix_in.row[1].xy[1] * vector_in.xy[1]; +} + +static int +htsc_allocate_supercell(htsc_dig_grid_t *super_cell, int x, int y, int u, + int v, int target_size, bool use_holladay_grid, + htsc_dig_grid_t dot_grid, int N, int *S, int *H, int *L) +{ + htsc_matrix_t matrix; + htsc_matrix_t matrix_inv; + int code; + int k, j; + htsc_vector_t vector_in, m_and_n; + int Dfinal; + double diff_val[2]; + double m_and_n_round; + int lcm_value; + int super_size_x, super_size_y; + int min_vert_number; + int a, b; + + /* Use Holladay Algorithm to create rectangular matrix for screening */ + *H = htsc_gcd((int) abs(y), (int) abs(v)); + if (*H == 0) + return -1; + + *L = N / *H; + /* Compute the shift factor */ + matrix.row[0].xy[0] = x; + matrix.row[0].xy[1] = u; + matrix.row[1].xy[0] = y; + matrix.row[1].xy[1] = v; + + code = htsc_matrix_inverse(matrix, &matrix_inv); + if (code < 0) { + EPRINTF(dot_grid.memory, "ERROR! matrix singular!\n"); + return -1; + } + vector_in.xy[1] = *H; + Dfinal = 0; + for (k = 1; k < *L+1; k++) { + vector_in.xy[0] = k; + htsc_matrix_vector_mult(matrix_inv, vector_in, &m_and_n); + for (j = 0; j < 2; j++) { + m_and_n_round = ROUND(m_and_n.xy[j]); + diff_val[j] = fabs((double) m_and_n.xy[j] - (double) m_and_n_round); + } + if (diff_val[0] < 0.00000001 && diff_val[1] < 0.00000001) { + Dfinal = k; + break; + } + } + if (Dfinal == 0) { + EPRINTF(dot_grid.memory, "ERROR! computing Holladay Grid\n"); + return -1; + } + *S = *L - Dfinal; + /* Make a large screen of multiple cells and then vary + the growth rate of the dots to get additional quantization levels + The macrocell must be H*a by L*b where a and b are integers due to the + periodicity of the screen. */ + + /* To create the Holladay screen (no stocastic stuff), + select the size H and L to create the matrix i.e. super_size_x + and super_size_y need to be H by L at least and then just take an + H by L section. */ + /* Force a periodicity in the screen to avoid the shift factor */ + if (*S != 0) { + lcm_value = htsc_lcm(*L,*S); + if (lcm_value < 0) + return -1; + + min_vert_number = *H * lcm_value / *S; + } else { + lcm_value = *L; + min_vert_number = *H; + } + + a = ceil((float) target_size / (float) lcm_value); + b = ceil((float) target_size / (float) min_vert_number); + + /* super_cell Size is b*min_vert_number by a*lcm_value + create the large cell */ + + if (use_holladay_grid) { + super_size_x = MAX(*L, dot_grid.width); + super_size_y = MAX(*H, dot_grid.height); + } else { + super_size_x = a * lcm_value; + super_size_y = b * min_vert_number; + } + super_cell->height = super_size_y; + super_cell->width = super_size_x; + super_cell->data = + (int *) ALLOC(dot_grid.memory, super_size_x * super_size_y * sizeof(int)); + if (super_cell->data == NULL) + return -1; + memset(super_cell->data, 0, super_size_x * super_size_y * sizeof(int)); + return 0; +} + +static void +htsc_supercell_assign_point(int new_k, int new_j, int sc_xsize, int sc_ysize, + htsc_dig_grid_t *super_cell, int val, int *num_set ) +{ + if (new_k >= 0 && new_j >= 0 && new_k < sc_xsize && new_j < sc_ysize) { + if (htsc_getpoint(super_cell,new_k,new_j) == 0) { + htsc_setpoint(super_cell,new_k,new_j,val); + (*num_set)++; + } + } +} + +static void +htsc_tile_supercell(htsc_dig_grid_t *super_cell, htsc_dig_grid_t *dot_grid, + int x, int y, int u, int v, int N) +{ + int sc_ysize = super_cell->height; + int sc_xsize = super_cell->width; + int dot_ysize = dot_grid->height; + int dot_xsize = dot_grid->width; + int total_num = sc_ysize * sc_xsize; + bool done = false; + int k,j; + int new_k, new_j; + int num_set = 0; + int val; + + for (k = 0; k < dot_xsize; k++) { + for (j = 0; j < dot_ysize; j++) { + val = htsc_getpoint(dot_grid,k,j); + if (val > 0) { + htsc_setpoint(super_cell,k,j,val); + num_set++; + } + } + } + if (num_set == total_num) { + done = true; + } + while (!done) { + for (k = 0; k < sc_xsize; k++) { + for (j = 0; j < sc_ysize; j++) { + val = htsc_getpoint(super_cell,k,j); + if (val != 0) { + new_k = k - x; + new_j = j - y; + htsc_supercell_assign_point(new_k, new_j, sc_xsize, sc_ysize, + super_cell, val, &num_set); + new_k = k + x; + new_j = j + y; + htsc_supercell_assign_point(new_k, new_j, sc_xsize, sc_ysize, + super_cell, val, &num_set); + new_k = k - u; + new_j = j - v; + htsc_supercell_assign_point(new_k, new_j, sc_xsize, sc_ysize, + super_cell, val, &num_set); + new_k = k + u; + new_j = j + v; + htsc_supercell_assign_point(new_k, new_j, sc_xsize, sc_ysize, + super_cell, val, &num_set); + } + } + } + if (num_set == total_num) { + done = true; + } + } +} + +/* Create 2d gaussian filter that varies with respect to coordinate + spatial resolution */ +void +create_2d_gauss_filter(float *filter, int x_size, int y_size, + float stdvalx, float stdvaly) +{ + int x_half_size = (x_size-1)/2; + int y_half_size = (y_size-1)/2; + int k,j; + float arg, val; + double sum = 0; + float max_val = 0; + int total_size = x_size * y_size; + int index_x, index_y; + + for (j = -y_half_size; j < y_half_size+1; j++) { + index_y = j + y_half_size; + for (k = -x_half_size; k < x_half_size+1; k++) { + arg = -(k * k / (stdvalx * stdvalx) + + j * j / (stdvaly * stdvaly) ) /2; + val = (float) exp(arg); + sum += val; + if (val > max_val) max_val = val; + index_x = k + x_half_size; + filter[index_y * x_size + index_x] = val; + } + } + for (j = 0; j < total_size; j++) { + filter[j]/=sum; + } +#if RAW_SCREEN_DUMP + htsc_dump_float_image(filter, y_size, x_size, max_val/sum, "guass_filt"); +#endif +} + +/* 2-D convolution (or correlation) with periodic boundary condition */ +static void +htsc_apply_filter(byte *screen_matrix, int num_cols_sc, + int num_rows_sc, float *filter, int num_cols_filt, + int num_rows_filt, float *screen_blur, + float *max_val, htsc_point_t *max_pos, float *min_val, + htsc_point_t *min_pos) +{ + int k,j,kk,jj; + double sum; + int half_cols_filt = (num_cols_filt-1)/2; + int half_rows_filt = (num_rows_filt-1)/2; + int j_circ,k_circ; + float fmax_val = -1; + float fmin_val = 100000000; + htsc_point_t fmax_pos = { 0.0, 0.0 }, fmin_pos = { 0.0, 0.0 }; + + for (j = 0; j < num_rows_sc; j++) { + for (k = 0; k < num_cols_sc; k++) { + sum = 0.0; + for (jj = -half_rows_filt; jj <= half_rows_filt; jj++) { + j_circ = j + jj; + if (j_circ < 0) { + j_circ = + (num_rows_sc - ((-j_circ) % num_rows_sc)) % num_rows_sc; + } + if (j_circ > (num_rows_sc - 1)) { + j_circ = j_circ % num_rows_sc; + } + /* In case modulo is of a negative number */ + if (j_circ < 0) + j_circ = j_circ + num_rows_sc; + for (kk = -half_cols_filt; kk <= half_cols_filt; kk++) { + k_circ = k + kk; + if (k_circ < 0) { + k_circ = + (num_cols_sc - ((-k_circ) % num_cols_sc)) % num_cols_sc; + } + if (k_circ > (num_cols_sc - 1)) { + k_circ = k_circ % num_cols_sc; + } + /* In case modulo is of a negative number */ + if (k_circ < 0) + k_circ = k_circ + num_cols_sc; + sum += (double) screen_matrix[k_circ + j_circ * num_cols_sc] * + filter[ (jj + half_rows_filt) * num_cols_filt + (kk + half_cols_filt)]; + } + } + screen_blur[j * num_cols_sc + k] = sum; + if (sum > fmax_val) { + fmax_val = sum; + fmax_pos.x = k; + fmax_pos.y = j; + } + if (sum < fmin_val) { + fmin_val = sum; + fmin_pos.x = k; + fmin_pos.y = j; + } + } + } + *max_val = fmax_val; + *min_val = fmin_val; + *max_pos = fmax_pos; + *min_pos = fmin_pos; +} + +static int +htsc_add_dots(byte *screen_matrix, int num_cols, int num_rows, + double horiz_dpi, double vert_dpi, double lpi_act, + unsigned short *pos_x, unsigned short *pos_y, + int *locate, int num_dots, + htsc_dither_pos_t *dot_level_position, int level_num, + int num_dots_add, void *mem) +{ + double xscale = horiz_dpi / vert_dpi; + double sigma_y = vert_dpi / lpi_act; + double sigma_x = sigma_y * xscale; + int sizefiltx, sizefilty; + float *filter; + float *screen_blur; + int white_pos; + float max_val, min_val; + htsc_point_t max_pos, min_pos; + int k,j; + int dist, curr_dist; + htsc_dither_pos_t curr_position; + + sizefiltx = ROUND(sigma_x * 4); + sizefilty = ROUND(sigma_y * 4); + if ( ((float) sizefiltx / 2.0) == (sizefiltx >> 1)) { + sizefiltx += 1; + } + if ( ((float) sizefilty / 2.0) == (sizefilty >> 1)) { + sizefilty += 1; + } + filter = (float*) ALLOC(mem, sizeof(float) * sizefilty * sizefiltx); + if (filter == NULL) + return -1; + create_2d_gauss_filter(filter, sizefiltx, sizefilty, sizefiltx, sizefilty); + screen_blur = (float*)ALLOC(mem, sizeof(float) * num_cols * num_rows); + if (screen_blur == NULL) { + FREE(mem, filter); + return -1; + } + + for (j = 0; j < num_dots_add; j++) { + + /* Perform the blur */ + htsc_apply_filter(screen_matrix, num_cols, num_rows, filter, sizefiltx, + sizefilty, screen_blur, &max_val, &max_pos, &min_val, &min_pos); + + /* Find the closest OFF dot to the min position. */ + white_pos = 0; + dist = (num_cols) * (num_cols) + (num_rows) * (num_rows); + for (k = 0; k < num_dots; k++) { + curr_dist = (pos_y[k] - min_pos.y) * (pos_y[k] - min_pos.y) + + (pos_x[k] - min_pos.x) * (pos_x[k] - min_pos.x); + if (curr_dist < dist && + screen_matrix[pos_x[k] + num_cols * pos_y[k]] == 0) { + white_pos = k; + dist = curr_dist; + } + } + + /* Set this dot to white */ + screen_matrix[pos_x[white_pos] + num_cols * pos_y[white_pos]] = 1; + + /* Update position information */ + curr_position = dot_level_position[level_num]; + curr_position.point[j].x = pos_x[white_pos]; + curr_position.point[j].y = pos_y[white_pos]; + curr_position.locations[j] = locate[white_pos]; + } + FREE(mem, filter); + FREE(mem, screen_blur); + return 0; +} + +static int +htsc_init_dot_position(byte *screen_matrix, int num_cols, int num_rows, + double horiz_dpi, double vert_dpi, double lpi_act, + unsigned short *pos_x, unsigned short *pos_y, int num_dots, + htsc_dither_pos_t *dot_level_position, void *mem) +{ + double xscale = horiz_dpi / vert_dpi; + double sigma_y = vert_dpi / lpi_act; + double sigma_x = sigma_y * xscale; + int sizefiltx, sizefilty; + float *filter; + bool done = false; + float *screen_blur; + int white_pos, black_pos; + float max_val, min_val; + htsc_point_t max_pos, min_pos; + int k; + int dist, curr_dist; + bool found_it; + + sizefiltx = ROUND(sigma_x * 4); + sizefilty = ROUND(sigma_y * 4); + if ( ((float) sizefiltx / 2.0) == (sizefiltx >> 1)) { + sizefiltx += 1; + } + if ( ((float) sizefilty / 2.0) == (sizefilty >> 1)) { + sizefilty += 1; + } + filter = (float*) ALLOC(mem, sizeof(float) * sizefilty * sizefiltx); + if (filter == NULL) + return -1; + create_2d_gauss_filter(filter, sizefiltx, sizefilty, sizefiltx, sizefilty); + screen_blur = (float*) ALLOC(mem, sizeof(float) * num_cols * num_rows); + if (screen_blur == NULL) { + FREE(mem, filter); + return -1; + } + /* Start moving dots until the whitest and darkest dot are the same */ + while (!done) { + /* Blur */ + htsc_apply_filter(screen_matrix, num_cols, num_rows, filter, sizefiltx, + sizefilty, screen_blur, &max_val, &max_pos, &min_val, &min_pos); +#if RAW_SCREEN_DUMP + htsc_dump_float_image(screen_blur, num_cols, num_rows, max_val, "blur_one"); +#endif + /* Find the closest on dot to the max position */ + black_pos = 0; + dist = (pos_y[0] - max_pos.y) * (pos_y[0] - max_pos.y) + + (pos_x[0] - max_pos.x) * (pos_x[0] - max_pos.x); + for ( k = 1; k < num_dots; k++) { + curr_dist = (pos_y[k] - max_pos.y) * (pos_y[k] - max_pos.y) + + (pos_x[k] - max_pos.x) * (pos_x[k] - max_pos.x); + if (curr_dist < dist && + screen_matrix[pos_x[k] + num_cols * pos_y[k]] == 1) { + black_pos = k; + dist = curr_dist; + } + } + /* Set this dot to black */ + screen_matrix[pos_x[black_pos] + num_cols * pos_y[black_pos]] = 0; + /* Blur again */ + htsc_apply_filter(screen_matrix, num_cols, num_rows, filter, sizefiltx, + sizefilty, screen_blur, &max_val, &max_pos, &min_val, &min_pos); + /* Find the closest OFF dot to the min position. */ + white_pos = 0; + dist = (pos_y[0] - min_pos.y) * (pos_y[0] - min_pos.y) + + (pos_x[0] - min_pos.x) * (pos_x[0] - min_pos.x); + for ( k = 1; k < num_dots; k++) { + curr_dist = (pos_y[k] - min_pos.y) * (pos_y[k] - min_pos.y) + + (pos_x[k] - min_pos.x) * (pos_x[k] - min_pos.x); + if (curr_dist < dist && + screen_matrix[pos_x[k] + num_cols * pos_y[k]] == 0) { + white_pos = k; + dist = curr_dist; + } + } + /* Set this dot to white */ + screen_matrix[pos_x[white_pos] + num_cols * pos_y[white_pos]] = 1; + /* If it is the same dot as before, then we are done */ + /* There could be a danger here of cycles longer than 2 */ + if (white_pos == black_pos) { + done = true; + FREE(mem, screen_blur); + FREE(mem, filter); + return 0; + } else { + /* We need to update our dot position information */ + /* find where the old white one was and replace it */ + found_it = false; + for (k = 0; k < dot_level_position->number_points; k++) { + if (dot_level_position->point[k].x == pos_x[black_pos] && + dot_level_position->point[k].y == pos_y[black_pos]) { + found_it = true; + dot_level_position->point[k].x = pos_x[white_pos]; + dot_level_position->point[k].y = pos_y[white_pos]; + dot_level_position->locations[k] = + pos_x[white_pos] + pos_y[white_pos] * num_cols; + break; + } + } + if (!found_it) { + EPRINTF(mem, "ERROR! bug in dot location accounting\n"); + FREE(mem, filter); + FREE(mem, screen_blur); + return -1; + } + } + } + FREE(mem, filter); + FREE(mem, screen_blur); + return 0; +} + +static int +htsc_create_dither_mask(htsc_dig_grid_t super_cell, htsc_dig_grid_t *final_mask, + int verbose, int num_levels, int y, int x, double vert_dpi, + double horiz_dpi, int N, double gamma, + htsc_dig_grid_t dot_grid, htsc_point_t dot_grid_one_index) +{ + int *dot_levels = NULL; + int *locate = NULL; + double percent, perc_val; + int code = 0, k, j, h, jj, mm; + int width_supercell = super_cell.width; + int height_supercell = super_cell.height; + int number_points = width_supercell * height_supercell; + int num_dots = 0; + double step_size; + int curr_size; + int rand_pos, dots_needed; + int done; + double lpi_act; + double vert_scale = ((double) y / vert_dpi); + double horiz_scale = ((double) x / horiz_dpi); + byte *screen_matrix = NULL; + unsigned short *pos_x = NULL, *pos_y = NULL; + htsc_dither_pos_t *dot_level_pos = NULL, *curr_dot_level = NULL; + int count; + int prev_dot_level, curr_num_dots; + double mag_offset, temp_dbl; + int *thresholds = NULL, val; + int j_index, k_index, threshold_value; + int *dot_level_sort = NULL; + bool found; + + lpi_act = 1.0/((double) sqrt( vert_scale * vert_scale + + horiz_scale * horiz_scale)); + if (num_levels > 1) { + curr_size = 2 * MAX(height_supercell, width_supercell); + locate = (int*) ALLOC(dot_grid.memory, sizeof(int) * curr_size); + if (locate == NULL) { + code = -1; + goto out; + } + screen_matrix = (byte*) ALLOC(dot_grid.memory, sizeof(byte) * number_points); + if (screen_matrix == NULL) { + code = -1; + goto out; + } + memset(screen_matrix, 0, sizeof(byte) * number_points); + + /* Determine the number of dots in the screen and their index */ + for (j = 0; j < number_points; j++) { + if (super_cell.data[j] == 1) { + locate[num_dots] = j; + num_dots++; + if (num_dots == (curr_size - 1)) { + int *tmp = locate; + + curr_size = curr_size * 2; + locate = (int*) ALLOC(dot_grid.memory, sizeof(int) * curr_size); + if (locate == NULL) { + code = -1; + goto out; + } + memcpy(locate, tmp, sizeof(int) * (num_dots+1)); + FREE(dot_grid.memory, tmp); + } + } + } + + /* Convert the 1-D locate positions to 2-D positions so that we can + use a distance metric to the dot center locations. Also allocate + the structure for our dot positioning information */ + pos_x = (unsigned short*) ALLOC(dot_grid.memory, sizeof(unsigned short) * num_dots); + if (pos_x == NULL) { + code = -1; + goto out; + } + pos_y = (unsigned short*) ALLOC(dot_grid.memory, sizeof(unsigned short) * num_dots); + if (pos_y == NULL) { + code = -1; + goto out; + } + for (k = 0; k < num_dots; k++) { + pos_x[k] = locate[k] % width_supercell; + pos_y[k] = (locate[k] - pos_x[k]) / width_supercell; + } + + /* Note that number of quantization levels is not tied to number of dots + in the macro screen. */ + dot_level_pos = + (htsc_dither_pos_t*) ALLOC(dot_grid.memory, sizeof(htsc_dither_pos_t) * num_levels); + if (dot_level_pos == NULL) { + code = -1; + goto out; + } + dot_levels = (int*) ALLOC(dot_grid.memory, sizeof(int) * num_levels); + if (dot_levels == NULL) { + code = -1; + goto out; + } + percent = 1.0 / ((float)num_levels + 1.0); + prev_dot_level = 0; + for (k = 0; k < num_levels; k++) { + perc_val = (k + 1) * percent; + dot_levels[k] = ROUND(num_dots * perc_val); + curr_num_dots = dot_levels[k] -prev_dot_level; + prev_dot_level = dot_levels[k]; + dot_level_pos[k].locations = (int*) ALLOC(dot_grid.memory, sizeof(int) * curr_num_dots); + if (dot_level_pos[k].locations == NULL) { + code = -1; + goto out; + } + dot_level_pos[k].point = + (htsc_point_t*) ALLOC(dot_grid.memory, sizeof(htsc_point_t) * curr_num_dots); + if (dot_level_pos[k].point == NULL) { + code = -1; + goto out; + } + dot_level_pos[k].number_points = curr_num_dots; + } + + /* An initial random location for the first level */ + dots_needed = dot_levels[0]; + count = 0; + if (dots_needed > 0) { + done = 0; + while (!done) { + rand_pos = ROUND((num_dots-1) * (double) rand() / (double) RAND_MAX); + if (screen_matrix[locate[rand_pos]] != 1) { + screen_matrix[locate[rand_pos]] = 1; + dot_level_pos->locations[count] = locate[rand_pos]; + dot_level_pos->point[count].x = pos_x[rand_pos]; + dot_level_pos->point[count].y = pos_y[rand_pos]; + dots_needed--; + count++; + } + if (dots_needed == 0) { + done = 1; + } + } + } +#if RAW_SCREEN_DUMP + htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, "screen0_init"); +#endif + /* Rearrange these dots into a pleasing pattern, but only if there is + * more than 1. Otherwise there are none to move */ + if (dot_levels[0] > 1) + code = htsc_init_dot_position(screen_matrix, width_supercell, + height_supercell, horiz_dpi, vert_dpi, lpi_act, + pos_x, pos_y, num_dots, dot_level_pos, final_mask->memory); + if (code < 0) + goto out; +#if RAW_SCREEN_DUMP + htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, "screen0_arrange"); +#endif + /* Now we want to introduce more dots at each level */ + for (k = 1; k < num_levels; k++) { + code = htsc_add_dots(screen_matrix, width_supercell, height_supercell, + horiz_dpi, vert_dpi, lpi_act, pos_x, pos_y, locate, + num_dots, dot_level_pos, k, + dot_level_pos[k].number_points, final_mask->memory); + if (code < 0) + goto out; +#if RAW_SCREEN_DUMP + { + char str_name[30]; + snprintf(str_name, 30, "screen%d_arrange",k); + htsc_dump_byte_image(screen_matrix, width_supercell, height_supercell, + 1, str_name); + } +#endif + } + + if (verbose > 0) + PRINTF(final_mask->memory, "\n--Dot Positions--\n"); + for (k = 0; k < num_levels; k++) { + if (verbose > 0) + PRINTF2(final_mask->memory, "dot_level_pos %d: number_points = %d\n", + k, dot_level_pos[k].number_points); + for (j = 0; j < dot_level_pos[k].number_points; j++) { + if (verbose > 0) + PRINTF4(final_mask->memory, "\tpoint: %d: locations = %d x = %3.2lf y = %3.2lf\n", + j, dot_level_pos[k].locations[j], dot_level_pos[k].point[j].x, dot_level_pos[k].point[j].y); + } + } + + /* Create the threshold mask. */ + step_size = (MAXVAL + 1.0) / (double) N; + thresholds = (int*) ALLOC(dot_grid.memory, sizeof(int) * N); + if (thresholds == NULL) { + code = -1; + goto out; + } + for (k = 0; k < N; k++) { + thresholds[N-1-k] = (k + 1) * step_size - (step_size / 2); + } + mag_offset = + (double) (thresholds[0]-thresholds[1]) / (double) (num_levels+1); + if ( gamma != 1.0) { + for (k = 0; k < N; k++) { + temp_dbl = + (double) pow((double) thresholds[k] / MAXVAL, + (double) gamma); + thresholds[k] = ROUND(temp_dbl * MAXVAL); + } + } + + /* Now use the indices from the large screen to look up the mask and + apply the offset to the threshold values to dither the rate at which + the dots turn on */ + /* allocate the mask */ + final_mask->height = height_supercell; + final_mask->width = width_supercell; + final_mask->data = + (int*) ALLOC(dot_grid.memory, sizeof(int) * height_supercell * width_supercell); + if (final_mask->data == NULL) { + code = -1; + goto out; + } + + /* We need to associate the locate index with a particular level + for the when the dot begins to turn on. Go through the dot_level_pos + array to get the values. Probably should create this earlier and avoid + this */ + dot_level_sort = (int*) ALLOC(dot_grid.memory, sizeof(int) * num_dots); + if (dot_level_sort == NULL) { + code = -1; + goto out; + } + for (h = 0; h < num_dots; h++) { + found = false; + for (jj = 0; jj < num_levels; jj++) { + curr_dot_level = &(dot_level_pos[jj]); + for (mm = 0; mm < curr_dot_level->number_points; mm++) { + if (pos_x[h] == curr_dot_level->point[mm].x && + pos_y[h] == curr_dot_level->point[mm].y ) { + found = true; + dot_level_sort[h] = jj + 1; + break; /* Break from position search(within level) */ + } + } + if (found == true) { /* break from level search */ + break; + } + } + if (found == false) { + dot_level_sort[h] = 0; + } + } + + for (h = 0; h < num_dots; h++) { + for (j = 0; j < dot_grid.height; j++) { + for (k = 0; k < dot_grid.width; k++) { + val = htsc_getpoint(&dot_grid, k, j); + if (val != 0) { + + /* Assign a offset threshold values */ + j_index = + (pos_y[h] + j - (int) dot_grid_one_index.y) % height_supercell; + + /* In case we have modulo of a negative number */ + if (j_index < 0) j_index = j_index + height_supercell; + k_index = + (pos_x[h] + k - (int) dot_grid_one_index.x) % width_supercell; + + /* In case we have modulo of a negative number */ + if (k_index < 0) k_index = k_index + width_supercell; + threshold_value = thresholds[val-1] + + mag_offset * dot_level_sort[h]; + if (threshold_value > MAXVAL) threshold_value = MAXVAL; + if (threshold_value < 0) threshold_value = 0; + htsc_setpoint(final_mask,k_index,j_index,threshold_value); + } + } + } + } +out: + if (dot_level_pos) { + for (k = 0; k < num_levels; k++) { + FREE(dot_grid.memory, dot_level_pos[k].locations); + FREE(dot_grid.memory, dot_level_pos[k].point); + } + } + FREE(dot_grid.memory, locate); + FREE(dot_grid.memory, screen_matrix); + FREE(dot_grid.memory, pos_x); + FREE(dot_grid.memory, pos_y); + FREE(dot_grid.memory, dot_level_pos); + FREE(dot_grid.memory, dot_levels); + FREE(dot_grid.memory, thresholds); + FREE(dot_grid.memory, dot_level_sort); + } + return code; +} + +static int +htsc_create_holladay_mask(htsc_dig_grid_t super_cell, int H, int L, + double gamma, htsc_dig_grid_t *final_mask) +{ + double step_size = (MAXVAL + 1.0) /( (double) H * (double) L); + int k, j, code = 0; + double *thresholds = NULL; + int number_points = H * L; + double half_step = step_size / 2.0; + double temp; + int index_point; + int value; + double white_scale = 253.0 / 255.0; /* To ensure white is white */ + + final_mask->height = H; + final_mask->width = L; + final_mask->data = (int *) ALLOC(final_mask->memory, H * L * sizeof(int)); + if (final_mask->data == NULL) { + code = -1; + goto out; + } + + thresholds = (double *) ALLOC(final_mask->memory, H * L * sizeof(double)); + if (final_mask->data == NULL) { + code = -1; + goto out; + } + for (k = 0; k < number_points; k++) { + temp = ((k+1) * step_size - half_step) / MAXVAL; + if ( gamma != 1.0) { + /* Possible linearization */ + temp = (double) pow((double) temp, (double) gamma); + } + thresholds[number_points - k - 1] = + ROUND(temp * MAXVAL * white_scale + 1); + } + memset(final_mask->data, 0, H * L * sizeof(int)); + + for (j = 0; j < H; j++) { + for (k = 0; k < L; k++) { + index_point = htsc_getpoint(&super_cell,k,j) - 1; + value = (int) floor(thresholds[index_point]); + htsc_setpoint(final_mask,k,j,value); + } + } +out: + FREE(final_mask->memory, thresholds); + return code; +} + +static int +htsc_create_nondithered_mask(htsc_dig_grid_t super_cell, int H, int L, + double gamma, htsc_dig_grid_t *final_mask) +{ + double step_size = (MAXVAL + 1) /( (double) H * (double) L); + int k, j, code = 0; + double *thresholds = NULL; + int number_points = H * L; + double half_step = step_size / 2.0; + double temp; + int index_point; + int value; + double white_scale = 253.0 / 255.0; /* To ensure white is white */ + + final_mask->height = super_cell.height; + final_mask->width = super_cell.width; + final_mask->data = (int *) ALLOC(final_mask->memory, super_cell.height * super_cell.width * + sizeof(int)); + if (final_mask->data == NULL) { + code = -1; + goto out; + } + thresholds = (double *) ALLOC(final_mask->memory, H * L * sizeof(double)); + if (thresholds == NULL) { + code = -1; + goto out; + } + for (k = 0; k < number_points; k++) { + temp = ((k+1) * step_size - half_step) / MAXVAL; + if ( gamma != 1.0) { + /* Possible linearization */ + temp = (double) pow((double) temp, (double) gamma); + } + thresholds[number_points - k - 1] = + ROUND(temp * MAXVAL * white_scale + 1); + } + memset(final_mask->data, 0, super_cell.height * super_cell.width * + sizeof(int)); + for (j = 0; j < super_cell.height; j++) { + for (k = 0; k < super_cell.width; k++) { + index_point = htsc_getpoint(&super_cell,k,j) - 1; + value = (int) floor(thresholds[index_point]); + htsc_setpoint(final_mask,k,j,value); + } + } +out: + FREE(final_mask->memory, thresholds); + return code; +} + +/* Various spot functions */ +static double +htsc_spot_circle(double x, double y) +{ + return 1.0 - (x*x + y*y); +} + +static double +htsc_spot_redbook(double x, double y) +{ + return (180.0 * (double) cos(x) + 180.0 * (double) cos(y)) / 2.0; +} + +static double +htsc_spot_inverted_round(double x, double y) +{ + return (x*x + y*y) - 1.0; +} + +static double +htsc_spot_rhomboid(double x, double y) +{ + return 1.0 - ((double) fabs(y) * 0.8 + (double) fabs(x)) / 2.0; +} + +static double +htsc_spot_linex(double x, double y) +{ + return 1.0 - (double) fabs(y); +} + +static double +htsc_spot_liney(double x, double y) +{ + return 1.0 - (double) fabs(x); +} + +static double +htsc_spot_diamond(double x, double y) +{ + double abs_y = (double) fabs(y); + double abs_x = (double) fabs(x); + + if ((abs_y + abs_x) <= 0.75) { + return 1.0 - (abs_x * abs_x + abs_y * abs_y); + } else { + if ((abs_y + abs_x) <= 1.23) { + return 1.0 - (0.76 * abs_y + abs_x); + } else { + return ((abs_x - 1.0) * (abs_x - 1.0) + + (abs_y - 1.0) * (abs_y - 1.0)) - 1.0; + } + } +} + +static double +htsc_spot_diamond2(double x, double y) +{ + double xy = (double) fabs(x) + (double) fabs(y); + + if (xy <= 1.0) { + return 1.0 - xy * xy / 2.0; + } else { + return 1.0 - (2.0 * xy * xy - 4.0 * (xy - 1.0) * (xy - 1.0)) / 4.0; + } +} + +static double +htsc_spot_roundspot(double x, double y) +{ + double xy = (double)fabs(x) + (double)fabs(y); + + if (xy <= 1.0) { + return 1.0 - (x*x + y*y); + } else { + return ((fabs(x) - 1.0) * (fabs(x) - 1.0)) + ((fabs(y) - 1.0) * (fabs(y) - 1.0)) - 1.0; + } +} + +static double +htsc_spot_value(spottype_t spot_type, double x, double y) +{ + switch (spot_type) { + case CIRCLE: + return htsc_spot_circle(x,y); + case REDBOOK: + return htsc_spot_redbook(x,y); + case INVERTED: + return htsc_spot_inverted_round(x,y); + case RHOMBOID: + return htsc_spot_rhomboid(x,y); + case LINE_X: + return htsc_spot_linex(x,y); + case LINE_Y: + return htsc_spot_liney(x,y); + case DIAMOND1: + return htsc_spot_diamond(x,y); + case DIAMOND2: + return htsc_spot_diamond2(x,y); + case ROUNDSPOT: + return htsc_spot_roundspot(x,y); + case CUSTOM: /* A spot (pun intended) for users to define their own */ + return htsc_spot_circle(x,y); + default: + return htsc_spot_circle(x,y); + } +} + +#if RAW_SCREEN_DUMP +void +static +htsc_dump_screen(htsc_dig_grid_t *dig_grid, char filename[]) +{ + char full_file_name[FULL_FILE_NAME_LENGTH]; + FILE *fid; + int x,y; + int *buff_ptr = dig_grid->data; + int width = dig_grid->width; + int height = dig_grid->height; + byte data[3]; + + snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Screen_%s_%dx%dx3.raw",filename,width,height); + fid = fopen(full_file_name,"wb"); + + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + if (*buff_ptr < 0) { + data[0] = 255; + data[1] = 0; + data[2] = 0; + } else if (*buff_ptr > 255) { + data[0] = 0; + data[1] = 255; + data[2] = 0; + } else { + data[0] = *buff_ptr; + data[1] = *buff_ptr; + data[2] = *buff_ptr; + } + fwrite(data,sizeof(unsigned char),3,fid); + buff_ptr++; + } + } + fclose(fid); +} + +static void +htsc_dump_float_image(float *image, int height, int width, float max_val, + char filename[]) +{ + char full_file_name[FULL_FILE_NAME_LENGTH]; + FILE *fid; + int x,y; + int data; + byte data_byte; + + snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "Float_%s_%dx%d.raw",filename,width,height); + fid = fopen(full_file_name,"wb"); + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + data = (255.0 * image[x + y * width] / max_val); + if (data > 255) data = 255; + if (data < 0) data = 0; + data_byte = data; + fwrite(&data_byte,sizeof(byte),1,fid); + } + } + fclose(fid); +} + +static void +htsc_dump_byte_image(byte *image, int height, int width, float max_val, + char filename[]) +{ + char full_file_name[FULL_FILE_NAME_LENGTH]; + FILE *fid; + int x,y; + int data; + byte data_byte; + + snprintf(full_file_name, FULL_FILE_NAME_LENGTH, "ByteScaled_%s_%dx%d.raw",filename,width,height); + fid = fopen(full_file_name,"wb"); + for (y = 0; y < height; y++) { + for ( x = 0; x < width; x++ ) { + data = (255.0 * image[x + y * width] / max_val); + if (data > 255) data = 255; + if (data < 0) data = 0; + data_byte = data; + fwrite(&data_byte,sizeof(byte),1,fid); + } + } + fclose(fid); +} +#endif diff -Nru ghostscript-9.10~dfsg/base/gen_ordered.h ghostscript-9.25~dfsg+1/base/gen_ordered.h --- ghostscript-9.10~dfsg/base/gen_ordered.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gen_ordered.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,98 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Defines and exports for library (e.g., Ghostscript) use of gen_ordered.c */ + +#ifndef RAW_SCREEN_DUMP +# define RAW_SCREEN_DUMP 0 /* Noisy output for .raw files for detailed debugging */ +#endif +#if RAW_SCREEN_DUMP || !defined(LIB_BUILD) +# define FULL_FILE_NAME_LENGTH 50 +#endif + +#define MAXVAL 65535.0 +#define MIN(x,y) ((x)>(y)?(y):(x)) +#define MAX(x,y) ((x)>(y)?(x):(y)) +#define ROUND( a ) ( ( (a) < 0 ) ? (int) ( (a) - 0.5 ) : \ + (int) ( (a) + 0.5 ) ) +typedef enum { + CIRCLE = 0, + REDBOOK, + INVERTED, + RHOMBOID, + LINE_X, + LINE_Y, + DIAMOND1, + DIAMOND2, + ROUNDSPOT, + CUSTOM /* Must remain last one */ +} spottype_t; + +typedef enum { + OUTPUT_TOS = 0, + OUTPUT_PS = 1, + OUTPUT_PPM = 2, + OUTPUT_RAW = 3, + OUTPUT_RAW16 = 4 +} output_format_type; + +typedef struct htsc_param_s { + double scr_ang; + int targ_scr_ang; + int targ_lpi; + double vert_dpi; + double horiz_dpi; + bool targ_quant_spec; + int targ_quant; + int targ_size; + bool targ_size_spec; + spottype_t spot_type; + bool holladay; + double gamma; + output_format_type output_format; + int verbose; +} htsc_param_t; + +typedef struct htsc_vector_s { + double xy[2]; +} htsc_vector_t; + +typedef struct htsc_dig_grid_s { + int width; + int height; + htsc_vector_t bin_center; + void *memory; /* needed if non-standard allocator */ + int *data; /* may be int scaled to 65535 or pairs of turn-on-sequence */ +} htsc_dig_grid_t; + +/* + For library usage, #define GS_LIB_BUILD needs to be specified when building + gen_ordered.c. to leave out "main" and define ALLOC, FREE and PRINT/EPRINT + macros as appropriate for Ghostscript use. + + Use as functions from other applications will need to #define the macros + appropriately, adding an another ???_LIB_BUILD #define that also #defines + LIB_BUILD +*/ + +/* Set reasonable defaults into the params */ +void htsc_set_default_params(htsc_param_t *params); + +/* Generate the threshold array given the params */ +/* + Note that final_mask.memory must be set as needed for the allocator and + it is the callers responsibilty to free the final_mask.data that is returned. +*/ +int htsc_gen_ordered(htsc_param_t params, int *S, htsc_dig_grid_t *final_mask); diff -Nru ghostscript-9.10~dfsg/base/gpcheck.h ghostscript-9.25~dfsg+1/base/gpcheck.h --- ghostscript-9.10~dfsg/base/gpcheck.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gpcheck.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,7 @@ * to handle multi-tasking through the 'context' facility.) Routines that * run for a long time must periodically call gp_check_interrupts(), and * if it returns true, must clean up whatever they are doing and return an - * e_interrupted (or gs_error_interrupted) exceptional condition. + * gs_error_interrupt exceptional condition. * The return_if_interrupt macro provides a convenient way to do this. * * On platforms that require an interrupt check, the makefile defines diff -Nru ghostscript-9.10~dfsg/base/gp_dosfe.c ghostscript-9.25~dfsg+1/base/gp_dosfe.c --- ghostscript-9.10~dfsg/base/gp_dosfe.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_dosfe.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_dosfs.c ghostscript-9.25~dfsg+1/base/gp_dosfs.c --- ghostscript-9.10~dfsg/base/gp_dosfs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_dosfs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -132,7 +132,7 @@ { return "."; } -bool gp_file_name_is_partent_allowed(void) +bool gp_file_name_is_parent_allowed(void) { return true; } diff -Nru ghostscript-9.10~dfsg/base/gp_dvx.c ghostscript-9.25~dfsg+1/base/gp_dvx.c --- ghostscript-9.10~dfsg/base/gp_dvx.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_dvx.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -90,23 +90,6 @@ gp_get_realtime(pdt); /* Use an approximation for now. */ } -/* ------ Persistent data cache ------*/ - -/* insert a buffer under a (type, key) pair */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) -{ - /* not yet implemented */ - return 0; -} - -/* look up a (type, key) in the cache */ -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata) -{ - /* not yet implemented */ - return -1; -} - /* ------ Printer accessing ------ */ /* Open a connection to a printer. A null file name means use the */ diff -Nru ghostscript-9.10~dfsg/base/gpgetenv.h ghostscript-9.25~dfsg+1/base/gpgetenv.h --- ghostscript-9.10~dfsg/base/gpgetenv.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gpgetenv.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_getnv.c ghostscript-9.25~dfsg+1/base/gp_getnv.c --- ghostscript-9.10~dfsg/base/gp_getnv.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_getnv.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp.h ghostscript-9.25~dfsg+1/base/gp.h --- ghostscript-9.10~dfsg/base/gp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -112,13 +112,13 @@ * Read the current time (in seconds since an implementation-defined epoch) * into ptm[0], and fraction (in nanoseconds) into ptm[1]. */ -void gp_get_realtime(long ptm[2]); +void gp_get_realtime(long *ptm); /* * Read the current user CPU time (in seconds) into ptm[0], * and fraction (in nanoseconds) into ptm[1]. */ -void gp_get_usertime(long ptm[2]); +void gp_get_usertime(long *ptm); /* ------ Reading lines from stdin ------ */ @@ -177,8 +177,13 @@ * parameter, but it would break too many clients to make this change now.) * Note that this is the size of the buffer, not the maximum number of * characters: the latter is one less, because of the terminating \0. + * + * This used to be 260, the same as the MAX_PATH value on Windows, + * but although MAX_PATH still exists on Windows, it is no longer + * the maximum length of a path - doh?? + * We now use 4k as a reasonable limit for most environments. */ -#define gp_file_name_sizeof 260 /* == MAX_PATH on Windows */ +#define gp_file_name_sizeof 4096 /* Define the character used for separating file names in a list. */ extern const char gp_file_name_list_separator; @@ -227,6 +232,26 @@ /* Open a file with the given name, as a stream of uninterpreted bytes. */ FILE *gp_fopen(const char *fname, const char *mode); +/* gp_stat is defined in stat_.h rather than here due to macro problems */ + +/* Test whether this platform supports the sharing of file descriptors */ +int gp_can_share_fdesc(void); + +/* Create a self-deleting scratch file */ +FILE *gp_open_scratch_file_rm(const gs_memory_t *mem, + const char *prefix, + char fname[gp_file_name_sizeof], + const char *mode); + +/* Create a second open FILE on the basis of a given one */ +FILE *gp_fdup(FILE *f, const char *mode); + +/* Read from a specified offset within a FILE into a buffer */ +int gp_fpread(char *buf, uint count, int64_t offset, FILE *f); + +/* Write to a specified offset within a FILE from a buffer */ +int gp_fpwrite(char *buf, uint count, int64_t offset, FILE *f); + /* Force given file into binary mode (no eol translations, etc) */ /* if 2nd param true, text mode if 2nd param false */ int gp_setmode_binary(FILE * pfile, bool mode); @@ -306,7 +331,7 @@ /* Answer whether the platform allows parent refenences. */ /* unix, Win, Mac: yes */ /* VMS: no. */ -bool gp_file_name_is_partent_allowed(void); +bool gp_file_name_is_parent_allowed(void); /* Answer whether an empty item is meanful in file names on the platform. */ /* unix, Win: no */ @@ -324,37 +349,6 @@ /* Returns true when the character can be used in the file name. */ bool gp_file_name_good_char(unsigned char c); -/* ------ persistent cache interface ------ */ - -/* - * This is used for access to data cached between invocations of - * Ghostscript. It is generally used for saving reusable data that - * is expensive to compute. Concurrent access by multiple instances - * is safe. Because of this care should be taken to use a new data - * type when the format of the cached data changes. - * - * Generic data buffers are stored under a combination of type and - * key. It is up the to client to interpret the data buffer appropriately. - * An insert overwrites any previous entry under that type and key. - * A query if successful uses the passed callback to allocate a buffer - * and fills it with the retrieved data. The caller is thus responsible - * for the buffer's memory management. - * - * See zmisc.c for postscript test operators and an example implementation. - */ - -/* return 0 on successful insert, non-zero otherwise */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen); - -/* return the length of the buffer on success, a negative value otherwise */ -typedef void *(*gp_cache_alloc)(void *userdata, int bytes); -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata); - -/* cache data types */ -#define GP_CACHE_TYPE_TEST 0 -#define GP_CACHE_TYPE_FONTMAP 1 - /* ------ Printer accessing ------ */ /* @@ -506,4 +500,8 @@ int gp_local_arg_encoding_get_codepoint(FILE *file, const char **astr); +int +gp_xpsprint(char *filename, char *printername, int *result); + + #endif /* gp_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gp_mac.c ghostscript-9.25~dfsg+1/base/gp_mac.c --- ghostscript-9.10~dfsg/base/gp_mac.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mac.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,346 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* platform-specific routines for MacOS */ - -#ifndef __CARBON__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -#include -#include "math_.h" -#include "string_.h" -#include "time_.h" -#include "memory_.h" -#include "string_.h" - -#include "gx.h" -#include "gp.h" -#include "gsdll.h" -#include "gpcheck.h" -#include "gp_mac.h" -#include "gdebug.h" -/*#include "gpgetenv.h"*/ -#include "gsexit.h" - -HWND hwndtext; /* used as identifier for the dll instance */ - -char * -mygetenv(const char * env) -{ - return (NULL); -} - -void -gp_init (void) -{ - extern char *gs_lib_default_path; - extern char *gs_init_file; - -#if 0 - /*...Initialize Ghostscript's default library paths and initialization file...*/ - - { - int i; - char **p; - - for (i = iGSLibPathStr, p = &gs_lib_default_path; - i <= iGSInitFileStr; - i++, p = &gs_init_file) - { - GetIndString (string, MACSTRS_RES_ID, i); - (void) PtoCstr (string); - *p = malloc ((size_t) (strlen ((char *) string) + 1)); - strcpy (*p, (char *) string); - } - } -#endif -} - -void -gp_exit(int exit_status, int code) -{ -} - -/* Exit the program. */ -void -gp_do_exit(int exit_status) -{ - exit(exit_status); -} - -/* gettimeofday */ -#ifndef HZ -# define HZ 100 /* see sys/param.h */ -#endif -int -gettimeofday(struct timeval *tvp) -{ - struct tm tms; - static long offset = 0; - long ticks; - - if (!offset) { - time(&offset); - offset -= (time((long *)&tms) / HZ); - } - ticks = time((long *)&tms); - tvp->tv_sec = ticks / HZ + offset; - tvp->tv_usec = (ticks % HZ) * (1000 * 1000 / HZ); - return 0; -} - -/* ------ Date and time ------ */ - -#define gettimeofday_no_timezone 0 - -/* Read the current time (in seconds since Jan. 1, 1970) */ -/* and fraction (in nanoseconds). */ -void -gp_get_realtime(long *pdt) -{ - struct timeval tp; - - if (gettimeofday(&tp) == -1) { - lprintf("Ghostscript: gettimeofday failed!\n"); - gs_abort(NULL); - } - - /* tp.tv_sec is #secs since Jan 1, 1970 */ - pdt[0] = tp.tv_sec; - - /* Some Unix systems (e.g., Interactive 3.2 r3.0) return garbage */ - /* in tp.tv_usec. Try to filter out the worst of it here. */ - pdt[1] = tp.tv_usec >= 0 && tp.tv_usec < 1000000 ? tp.tv_usec * 1000 : 0; - -#ifdef DEBUG_CLOCK - printf("tp.tv_sec = %d tp.tv_usec = %d pdt[0] = %ld pdt[1] = %ld\n", - tp.tv_sec, tp.tv_usec, pdt[0], pdt[1]); -#endif -} - -/* Read the current user CPU time (in seconds) */ -/* and fraction (in nanoseconds). */ -void -gp_get_usertime(long *pdt) -{ - gp_get_realtime(pdt); /* Use an approximation on other hosts. */ - pdt[0] -= (char)rand(); // was needed, if used for random generator seed (g3 is too fast) -} - -/* - * Get the string corresponding to an OS error number. - * If no string is available, return NULL. The caller may assume - * the string is allocated statically and permanently. - */ -const char * gp_strerror(int) -{ - return NULL; -} - - -/* We don't have a good way to get a serial number here, so just */ -/* return what we always used to: GS_SERIALNUMBER. */ -int -gp_serialnumber(void) -{ - return (int)(gs_serialnumber); -} - -/* ------ Date and time ------ */ - -/* Read the current date (in days since Jan. 1, 1980) */ -/* and time (in milliseconds since midnight). */ - -void -gp_get_clock (long *pdt) { - - gp_get_realtime(pdt); /* Use an approximation on other hosts. */ - -} - -void -gpp_get_clock (long *pdt) - -{ - long secs; - DateTimeRec dateRec; - static DateTimeRec baseDateRec = {1980, 1, 1, 0, 0, 0, 1}; - long pdtmp[2]; - void do_get_clock (DateTimeRec *dateRec, long *pdt); - - GetDateTime ((unsigned long *) &secs); -// SecsondsToDate (secs, &dateRec); - - do_get_clock (&dateRec , pdt); - do_get_clock (&baseDateRec, pdtmp); - - /* If the date is reasonable, subtract the days since Jan. 1, 1980 */ - - if (pdtmp[0] < pdt[0]) - pdt[0] -= pdtmp[0]; - -#ifdef DEBUG_CLOCK - printf("pdt[0] = %ld pdt[1] = %ld\n", pdt[0], pdt[1]); -#endif -} - -UnsignedWide beginMicroTickCount={0,0}; - -/* Read the current date (in days since Jan. 1, 1980) */ -/* and time (in nanoseconds since midnight). */ - -void -gpp_get_realtime (long *pdt) -{ - - UnsignedWide microTickCount, - nMicroTickCount; - - long idate; - static const int mstart[12] = - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - long secs; - DateTimeRec dateRec; - static DateTimeRec baseDateRec = {1980, 1, 1, 0, 0, 0, 1}; - void do_get_clock (DateTimeRec *dateRec, long *pdt); - - if ((beginMicroTickCount.lo == 0)&&(beginMicroTickCount.hi == 0) ) { - Microseconds(&beginMicroTickCount); - } - - Microseconds(µTickCount); - - nMicroTickCount.lo = microTickCount.lo - beginMicroTickCount.lo; - nMicroTickCount.hi = microTickCount.hi - beginMicroTickCount.hi; - - GetDateTime ((unsigned long *) &secs); - SecondsToDate (secs, &dateRec); - - /* If the date is reasonable, subtract the days since Jan. 1, 1980 */ - - idate = ((long) dateRec.year - 1980) * 365 + /* days per year */ - (((long) dateRec.year - 1)/4 - 1979/4) + /* intervening leap days */ - (1979/100 - ((long) dateRec.year - 1)/100) + - (((long) dateRec.month - 1)/400 - 1979/400) + - mstart[dateRec.month - 1] + /* month is 1-origin */ - dateRec.day - 1; /* day of month is 1-origin */ - idate += (2 < dateRec.month - && (dateRec.year % 4 == 0 - && (dateRec.year % 100 != 0 || dateRec.year % 400 == 0))); - pdt[0] = ((idate*24 + dateRec.hour) * 60 + dateRec.minute) * 60 + dateRec.second; - pdt[1] = nMicroTickCount.lo * 100; - -//#define DEBUG_CLOCK 1 -#ifdef DEBUG_CLOCK - fprintf(stderr,"pdt[0] = %ld pdt[1] = %ld\n", pdt[0], pdt[1]); - fprintf(stderr,"b hi[0] = %ld lo[1] = %ld\n", beginMicroTickCount.hi, beginMicroTickCount.lo); - fprintf(stderr,"m hi[0] = %ld lo[1] = %ld\n", microTickCount.hi, microTickCount.lo); -#endif -} - -static void -do_get_clock (DateTimeRec *dateRec, long *pdt) - -{ -long idate; -static const int mstart[12] = - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - /* This gets UTC, not local time */ - /* We have no way of knowing the time zone correction */ - idate = ((long) dateRec->year - 1980) * 365 + /* days per year */ - (((long) dateRec->year - 1)/4 - 1979/4) + /* intervening leap days */ - (1979/100 - ((long) dateRec->year - 1)/100) + - (((long) dateRec->month - 1)/400 - 1979/400) + - mstart[dateRec->month - 1] + /* month is 1-origin */ - dateRec->day - 1; /* day of month is 1-origin */ - idate += (2 < dateRec->month - && (dateRec->year % 4 == 0 - && (dateRec->year % 100 != 0 || dateRec->year % 400 == 0))); - pdt[0] = ((idate*24 + dateRec->hour) * 60 + dateRec->minute) * 60 + dateRec->second; - pdt[1] = 0; //dateRec->milisecond * 1000000; - -} - -void -gpp_get_usertime(long *pdt) -{ - gp_get_realtime(pdt); /* Use an approximation for now. */ -} - -/* ------ Persistent data cache ------*/ - -/* insert a buffer under a (type, key) pair */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) -{ - /* not yet implemented */ - return 0; -} - -/* look up a (type, key) in the cache */ -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata) -{ - /* not yet implemented */ - return -1; -} - -/* ------ Screen management ------ */ - -/* Initialize the console. */ -/* do nothing, we did it in gp_init()! */ -void -gp_init_console(void) -{ -} - -/* Write a string to the console. */ - -void -gp_console_puts (const char *str, uint size) -{ -/* fwrite (str, 1, size, stdout);*/ - return; -} - -const char * -gp_getenv_display(void) -{ - return NULL; -} diff -Nru ghostscript-9.10~dfsg/base/gp_mac.h ghostscript-9.25~dfsg+1/base/gp_mac.h --- ghostscript-9.10~dfsg/base/gp_mac.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mac.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - - -#ifndef gp_mac_INCLUDED -# define gp_mac_INCLUDED - -/* no special definitions for macos */ - -#endif /* gp_mac_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gp_macio.c ghostscript-9.25~dfsg+1/base/gp_macio.c --- ghostscript-9.10~dfsg/base/gp_macio.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_macio.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,1063 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* prevent gp.h from defining fopen */ -#define fopen fopen - - -#ifndef __CARBON__ -//#include "MacHeaders" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#endif /* __CARBON__ */ - -#include "stdio_.h" -#include "math_.h" -#include "string_.h" -#include -#include -#include - -#include "gx.h" - -#include "gp.h" -#include "gpmisc.h" -#include "gxdevice.h" - -#include "gp_mac.h" - -#include "stream.h" -#include "gxiodev.h" /* must come after stream.h */ -//#include "gp_macAE.h" -#include "gsdll.h" - -//HWND hwndtext; - -extern void -convertSpecToPath(FSSpec * s, char * p, int pLen) -{ - OSStatus err = noErr; - CInfoPBRec params; - Str255 dirName; - int totLen = 0, dirLen = 0; - - memcpy(p, s->name + 1, s->name[0]); - totLen += s->name[0]; - - params.dirInfo.ioNamePtr = dirName; - params.dirInfo.ioVRefNum = s->vRefNum; - params.dirInfo.ioDrParID = s->parID; - params.dirInfo.ioFDirIndex = -1; - - do { - params.dirInfo.ioDrDirID = params.dirInfo.ioDrParID; - err = PBGetCatInfoSync(¶ms); - - if ((err != noErr) || (totLen + dirName[0] + 2 > pLen)) { - p[0] = 0; - return; - } - - dirName[++dirName[0]] = ':'; - memmove(p + dirName[0], p, totLen); - memcpy(p, dirName + 1, dirName[0]); - totLen += dirName[0]; - } while (params.dirInfo.ioDrParID != fsRtParID); - - p[totLen] = 0; - - return; -} - -OSErr -convertPathToSpec(const char *path, const int pathlength, FSSpec * spec) -{ - Str255 filename; - - /* path must be shorter than 255 bytes */ - if (pathlength > 254) return bdNamErr; - - *filename = pathlength; - memcpy(filename + 1, path, pathlength); - - return FSMakeFSSpec(0, 0, filename, spec); -} - -/* ------ File name syntax ------ */ - -/* Define the character used for separating file names in a list. */ -const char gp_file_name_list_separator = ','; - -/* Define the default scratch file name prefix. */ -const char gp_scratch_file_name_prefix[] = "tempgs_"; - -/* Define the name of the null output file. */ -const char gp_null_file_name[] = "????"; - -/* Define the name that designates the current directory. */ -extern const char gp_current_directory_name[] = ":"; - -int fake_stdin = 0; - -/* Do platform-dependent initialization */ - -void -setenv(const char * env, char *p) { -// if ( strcmp(env,"outfile") == 0) { -// sprintf((char *)&g_fcout[0],"%s",p); -// } -} - -char * -getenv(const char * env) { - - char *p; - FSSpec pFile; - OSErr err = 0; - char fpath[256]=""; - - if ( strcmp(env,"GS_LIB") == 0) { - - pFile.name[0] = 0; - err = FindFolder(kOnSystemDisk, kApplicationSupportFolderType, kDontCreateFolder, - &pFile.vRefNum, &pFile.parID); - - if (err != noErr) goto failed; - -// FSMakeFSSpec(pFile.vRefNum, pFile.parID,thepfname, &pfile); - convertSpecToPath(&pFile, fpath, 256); -// sprintf(fpath,"%s",fpath); - p = (char*)malloc((size_t) ( 4*strlen(fpath) + 40)); - gs_sprintf(p,"%s,%sGhostscript:lib,%sGhostscript:fonts", - (char *)&fpath[0],(char *)&fpath[0], - (char *)&fpath[0] ); - - return p; -failed: - - return NULL; - } else - return NULL; - -} - -/* ====== Substitute for stdio ====== */ - -/* Forward references */ -static void mac_std_init(void); -static stream_proc_process(mac_stdin_read_process); -static stream_proc_process(mac_stdout_write_process); -static stream_proc_process(mac_stderr_write_process); -static stream_proc_available(mac_std_available); - -/* Use a pseudo IODevice to get mac_stdio_init called at the right time. */ -/* This is bad architecture; we'll fix it later. */ -static iodev_proc_init(mac_stdio_init); -const gx_io_device gs_iodev_macstdio = -{ - "macstdio", "Special", - {mac_stdio_init, iodev_no_open_device, - iodev_no_open_file, iodev_no_fopen, iodev_no_fclose, - iodev_no_delete_file, iodev_no_rename_file, - iodev_no_file_status, iodev_no_enumerate_files - } -}; - -/* Do one-time initialization */ -static int -mac_stdio_init(gx_io_device * iodev, gs_memory_t * mem) -{ - mac_std_init(); /* redefine stdin/out/err to our window routines */ - return 0; -} - -/* Define alternate 'open' routines for our stdin/out/err streams. */ - -extern const gx_io_device gs_iodev_stdin; -static int -mac_stdin_open(gx_io_device * iodev, const char *access, stream ** ps, - gs_memory_t * mem) -{ - int code = gs_iodev_stdin.procs.open_device(iodev, access, ps, mem); - stream *s = *ps; - - if (code != 1) - return code; - s->procs.process = mac_stdin_read_process; - s->procs.available = mac_std_available; - s->file = NULL; - return 0; -} - -extern const gx_io_device gs_iodev_stdout; -static int -mac_stdout_open(gx_io_device * iodev, const char *access, stream ** ps, - gs_memory_t * mem) -{ - int code = gs_iodev_stdout.procs.open_device(iodev, access, ps, mem); - stream *s = *ps; - - if (code != 1) - return code; - s->procs.process = mac_stdout_write_process; - s->procs.available = mac_std_available; - s->file = NULL; - return 0; -} - -extern const gx_io_device gs_iodev_stderr; -static int -mac_stderr_open(gx_io_device * iodev, const char *access, stream ** ps, - gs_memory_t * mem) -{ - int code = gs_iodev_stderr.procs.open_device(iodev, access, ps, mem); - stream *s = *ps; - - if (code != 1) - return code; - s->procs.process = mac_stderr_write_process; - s->procs.available = mac_std_available; - s->file = NULL; - return 0; -} - -/* Patch stdin/out/err to use our windows. */ -static void -mac_std_init(void) -{ - /* If stdxxx is the console, replace the 'open' routines, */ - /* which haven't gotten called yet. */ - -// if (gp_file_is_console(gs_stdin)) - gs_findiodevice((const byte *)"%stdin", 6)->procs.open_device = - mac_stdin_open; - -// if (gp_file_is_console(gs_stdout)) - gs_findiodevice((const byte *)"%stdout", 7)->procs.open_device = - mac_stdout_open; - -// if (gp_file_is_console(gs_stderr)) - gs_findiodevice((const byte *)"%stderr", 7)->procs.open_device = - mac_stderr_open; -} - -static int -mac_stdin_read_process(stream_state *st, stream_cursor_read *ignore_pr, - stream_cursor_write *pw, bool last) -{ - uint count = pw->limit - pw->ptr; - /* callback to get more input */ - if (pgsdll_callback == NULL) return EOFC; - count = (*pgsdll_callback) (GSDLL_STDIN, (char*)pw->ptr + 1, count); - pw->ptr += count; - return 1; -} - -static int -mac_stdout_write_process(stream_state *st, stream_cursor_read *pr, - stream_cursor_write *ignore_pw, bool last) -{ uint count = pr->limit - pr->ptr; - - if (pgsdll_callback == NULL) return EOFC; - (*pgsdll_callback) (GSDLL_STDOUT, (char *)(pr->ptr + 1), count); - pr->ptr = pr->limit; - return 0; -} - -static int -mac_stderr_write_process(stream_state *st, stream_cursor_read *pr, - stream_cursor_write *ignore_pw, bool last) -{ uint count = pr->limit - pr->ptr; - - if (pgsdll_callback == NULL) return EOFC; - (*pgsdll_callback) (GSDLL_STDOUT, (char *)(pr->ptr + 1), count); - pr->ptr = pr->limit; - return 0; -} - -static int -mac_std_available(register stream * s, long *pl) -{ - *pl = -1; // EOF, since we can't do it - return 0; // OK -} - -/* ------ Printer accessing ------ */ - -/* These should NEVER be called. */ - -/* Open a connection to a printer. A null file name means use the */ -/* standard printer connected to the machine, if any. */ -/* "|command" opens an output pipe. */ -/* Return NULL if the connection could not be opened. */ - -FILE * -gp_open_printer (const gs_memory_t *mem, char *fname, int binary_mode) -{ - if (strlen(fname) == 0) - return gp_open_scratch_file(mem, gp_scratch_file_name_prefix, - fname, binary_mode ? "wb" : "w"); - else - return gp_fopen(fname, binary_mode ? "wb" : "b"); -} - -/* Close the connection to the printer. */ - -void -gp_close_printer (const gs_memory_t *mem, FILE *pfile, const char *fname) -{ - fclose(pfile); -} - -/* Define whether case is insignificant in file names. */ -/* OBSOLETE -const int gp_file_names_ignore_case = 1; -*/ - -/* Define the string to be concatenated with the file mode */ -/* for opening files without end-of-line conversion. */ -const char gp_fmode_binary_suffix[] = "b"; - -/* Define the file modes for binary reading or writing. */ -const char gp_fmode_rb[] = "rb"; -const char gp_fmode_wb[] = "wb"; - -/* Set a file into binary or text mode. */ -int -gp_setmode_binary(FILE *pfile, bool binary) -{ return 0; /* Noop under VMS */ -} - -/* Create and open a scratch file with a given name prefix. */ -/* Write the actual file name at fname. */ - -FILE * -gp_open_scratch_file (const gs_memory_t *mem, - const char *prefix, - char fname[gp_file_name_sizeof], - const char *mode) -{ - char thefname[256]; - Str255 thepfname; - OSErr myErr; - short foundVRefNum; - long foundDirID; - FSSpec fSpec; - FILE *f; - int prefix_length = strlen(prefix); - - if (prefix_length > gp_file_name_sizeof) return NULL; - strcpy (fname, (char *) prefix); - { - char newName[50]; - - tmpnam (newName); - if ( prefix_length + strlen(newName) > gp_file_name_sizeof ) return NULL; - strcat (fname, newName); - } - - if ( strlen(fname) > 255 ) return NULL; - if ( strrchr(fname,':') == NULL ) { - memmove((char*)&thepfname[1],(char *)&fname[0],strlen(fname)); - thepfname[0]=strlen(fname); - myErr = FindFolder(kOnSystemDisk,kTemporaryFolderType,kCreateFolder, - &foundVRefNum, &foundDirID); - if ( myErr != noErr ) { - emprintf(mem, "Can't find temp folder.\n"); - return (NULL); - } - FSMakeFSSpec(foundVRefNum, foundDirID,thepfname, &fSpec); - convertSpecToPath(&fSpec, thefname, sizeof(thefname) - 1); - gs_sprintf(fname,"%s",thefname); - } else { - gs_sprintf((char*)&thefname[0],"%s\0",fname); - memmove((char*)&thepfname[1],(char *)&thefname[0],strlen(thefname)); - thepfname[0]=strlen(thefname); - } - - f = gp_fopen (thefname, mode); - if (f == NULL) - emprintf1(mem, "**** Could not open temporary file %s\n", fname); - return f; -} - -/* read a resource and copy the data into a buffer */ -/* we don't have access to an allocator, nor any context for local */ -/* storage, so we implement the following idiom: we return the size */ -/* of the requested resource and copy the data into buf iff it's */ -/* non-NULL. Thus, the caller can pass NULL for buf the first time, */ -/* allocate the appropriate sized buffer, and then call us a second */ -/* time to actually transfer the data. */ -int -gp_read_macresource(byte *buf, const char *fname, const uint type, const ushort id) -{ - Handle resource = NULL; - SInt32 size = 0; - FSSpec spec; - SInt16 fileref; - OSErr result; - - /* open file */ - result = convertPathToSpec(fname, strlen(fname), &spec); - if (result != noErr) goto fin; - fileref = FSpOpenResFile(&spec, fsRdPerm); - if (fileref == -1) goto fin; - - if_debug1('s', "[s] loading resource from fileref %d\n", fileref); - - /* load resource */ - resource = Get1Resource((ResType)type, (SInt16)id); - if (resource == NULL) goto fin; - - /* allocate res */ - /* GetResourceSize() is probably good enough */ - //size = GetResourceSizeOnDisk(resource); - size = GetMaxResourceSize(resource); - - if_debug1('s', "[s] resource size on disk is %d bytes\n", size); - - /* if we don't have a buffer to fill, just return */ - if (buf == NULL) goto fin; - - /* otherwise, copy resource into res from handle */ - HLock(resource); - memcpy(buf, *resource, size); - HUnlock(resource); - -fin: - /* free resource, if necessary */ - ReleaseResource(resource); - CloseResFile(fileref); - - return (size); -} - -/* return a list of font names and corresponding paths from - * the native system locations - */ -int gp_native_fontmap(char *names[], char *paths[], int *count) -{ - return 0; -} - -/* ------ File enumeration ------ */ - -/****** THIS IS NOT SUPPORTED ON MACINTOSH SYSTEMS. ******/ - -struct file_enum_s { - char *pattern; - int first_time; - gs_memory_t *memory; -}; - -/* Initialize an enumeration. NEEDS WORK ON HANDLING * ? \. */ - -file_enum * -gp_enumerate_files_init (const char *pat, uint patlen, gs_memory_t *memory) - -{ file_enum *pfen = - (file_enum *)gs_alloc_bytes(memory, sizeof(file_enum), "gp_enumerate_files"); - char *pattern; - if ( pfen == 0 ) return 0; - pattern = - (char *)gs_alloc_bytes(memory, patlen + 1, "gp_enumerate_files(pattern)"); - if ( pattern == 0 ) return 0; - memcpy(pattern, pat, patlen); - pattern[patlen] = 0; - pfen->pattern = pattern; - pfen->memory = memory; - pfen->first_time = 1; - return pfen; -} - -/* Enumerate the next file. */ - -uint -gp_enumerate_files_next (file_enum *pfen, char *ptr, uint maxlen) - -{ if ( pfen->first_time ) - { pfen->first_time = 0; - } - return -1; -} - -/* Clean up the file enumeration. */ - -void -gp_enumerate_files_close (file_enum *pfen) - -{ - gs_free_object(pfen->memory, pfen->pattern, "gp_enumerate_files_close(pattern)"); - gs_free_object(pfen->memory, (char *)pfen, "gp_enumerate_files_close"); -} - -FILE * -gp_fopen (const char * fname, const char * mode) { - - char thefname[256]; - FILE *fid; - -//sprintf((char*)&thefname[0],"\n%s\n",fname); -//(*pgsdll_callback) (GSDLL_STDOUT, thefname, strlen(fname)); - if ( strrchr(fname,':') == NULL ) -// sprintf((char *)&thefname[0],"%s%s\0",g_homeDir,fname); - gs_sprintf((char *)&thefname[0],"%s%s\0","",fname); - else - gs_sprintf((char*)&thefname[0],"%s\0",fname); - - fid = fopen(thefname,mode); - - return fid; - -} - -FILE * -popen (const char * fname, const char * mode ) { - return gp_fopen (fname, mode); -} - -int -pclose (FILE * pipe ) { - return fclose (pipe); -} - -/* -------------- Helpers for gp_file_name_combine_generic ------------- */ - -#ifdef __CARBON__ - -/* compare an HFSUnitStr255 with a C string */ -static int compare_UniStr(HFSUniStr255 u, const char *c, uint len) -{ - int i,searchlen,unichar; - searchlen = min(len,u.length); - for (i = 0; i < searchlen; i++) { - unichar = u.unicode[i]; - /* punt on wide characters. we should really convert */ - if (unichar & !0xFF) return -1; - /* otherwise return the the index of the first non-matching character */ - if (unichar != c[i]) break; - } - /* return the offset iff we matched the whole volume name */ - return (i == u.length) ? i : 0; -} - -uint gp_file_name_root(const char *fname, uint len) -{ - OSErr err = noErr; - HFSUniStr255 volumeName; - FSRef rootDirectory; - int index, match; - - if (len > 0 && fname[0] == ':') - return 0; /* A relative path, no root. */ - - /* iterate over mounted volumes and compare our path */ - index = 1; - while (err == noErr) { - err = FSGetVolumeInfo (kFSInvalidVolumeRefNum, index, - NULL, kFSVolInfoNone, NULL, /* not interested in these fields */ - &volumeName, &rootDirectory); - if (err == nsvErr) return 0; /* no more volumes */ - if (err == noErr) { - match = compare_UniStr(volumeName, fname, len); - if (match > 0) { - /* include the separator if it's present */ - if (fname[match] == ':') return match + 1; - return match; - } - } - index++; - } - - /* nothing matched */ - return 0; -} - -#else /* Classic MacOS */ - -/* FSGetVolumeInfo requires carbonlib or macos >= 9 - we essentially leave this unimplemented on Classic */ -uint gp_file_name_root(const char *fname, uint len) -{ - return 0; -} - -#endif /* __CARBON__ */ - -uint gs_file_name_check_separator(const char *fname, int len, const char *item) -{ if (len > 0) { - if (fname[0] == ':') { - if (fname == item + 1 && item[0] == ':') - return 1; /* It is a separator after parent. */ - if (len > 1 && fname[1] == ':') - return 0; /* It is parent, not a separator. */ - return 1; - } - } else if (len < 0) { - if (fname[-1] == ':') - return 1; - } - return 0; -} - -bool gp_file_name_is_parent(const char *fname, uint len) -{ return len == 1 && fname[0] == ':'; -} - -bool gp_file_name_is_current(const char *fname, uint len) -{ return (len == 0) || (len == 1 && fname[0] == ':'); -} - -const char *gp_file_name_separator(void) -{ return ":"; -} - -const char *gp_file_name_directory_separator(void) -{ return ":"; -} - -const char *gp_file_name_parent(void) -{ return "::"; -} - -const char *gp_file_name_current(void) -{ return ":"; -} - -bool gp_file_name_is_partent_allowed(void) -{ return true; -} - -bool gp_file_name_is_empty_item_meanful(void) -{ return true; -} - -gp_file_name_combine_result -gp_file_name_combine(const char *prefix, uint plen, const char *fname, uint flen, - bool no_sibling, char *buffer, uint *blen) -{ - return gp_file_name_combine_generic(prefix, plen, - fname, flen, no_sibling, buffer, blen); -} - -bool -gp_file_name_good_char(unsigned char c) -{ - return c != ':'; -} - - -// FIXME: there must be a system util for this! -static char *MacStr2c(char *pstring) -{ - char *cstring; - int len = (pstring[0] < 256) ? pstring[0] : 255; - - if (len == 0) return NULL; - - cstring = malloc(len + 1); - if (cstring != NULL) { - memcpy(cstring, &(pstring[1]), len); - cstring[len] = '\0'; - } - - return(cstring); -} - -/* ------ Font enumeration ------ */ - - /* This is used to query the native os for a list of font names and - * corresponding paths. The general idea is to save the hassle of - * building a custom fontmap file - */ - -typedef struct { - int size, style, id; -} fond_entry; - -typedef struct { - int entries; - fond_entry *refs; -} fond_table; - -static fond_table *fond_table_new(int entries) -{ - fond_table *table = malloc(sizeof(fond_table)); - if (table != NULL) { - table->entries = entries; - table->refs = malloc(entries * sizeof(fond_entry)); - if (table->refs == NULL) { free(table); table = NULL; } - } - return table; -} - -static void fond_table_free(fond_table *table) -{ - if (table != NULL) { - if (table->refs) free(table->refs); - free(table); - } -} - -static fond_table *fond_table_grow(fond_table *table, int entries) -{ - if (table == NULL) { - table = fond_table_new(entries); - } else { - table->entries += entries; - table->refs = realloc(table->refs, table->entries * sizeof(fond_entry)); - } - return table; -} - -static int get_int16(unsigned char *p) { - return (p[0]&0xFF)<<8 | (p[1]&0xFF); -} - -static int get_int32(unsigned char *p) { - return (p[0]&0xFF)<<24 | (p[1]&0xFF)<<16 | (p[2]&0xFF)<<8 | (p[3]&0xFF); -} - -/* parse and summarize FOND resource information */ -static fond_table * parse_fond(FSSpec *spec) -{ - OSErr result = noErr; - FSRef specref; - SInt16 ref; - Handle fond = NULL; - unsigned char *res; - fond_table *table = NULL; - int i,j, count, n, start; - - /* FSpOpenResFile will fail for data fork resource (.dfont) files. - FSOpenResourceFile can open either, but cannot handle broken resource - maps, as often occurs in font files (the suitcase version of Arial, - for example) Thus, we try one, and then the other. */ - - result = FSpMakeFSRef(spec,&specref); -#ifdef __CARBON__ - if (result == noErr) - result = FSOpenResourceFile(&specref, 0, NULL, fsRdPerm, &ref); -#else - result = bdNamErr; /* simulate failure of the carbon routine above */ -#endif - if (result != noErr) { - ref = FSpOpenResFile(spec, fsRdPerm); - result = ResError(); - } - if (result != noErr || ref <= 0) { - char path[256]; - convertSpecToPath(spec, path, 256); - dlprintf2("unable to open resource file '%s' for font enumeration (error %d)\n", - path, result); - goto fin; - } - - /* we've opened the font file, now loop over the FOND resource(s) - and construct a table of the font references */ - - start = 0; /* number of entries so far */ - UseResFile(ref); - count = Count1Resources('FOND'); - for (i = 0; i < count; i++) { - fond = Get1IndResource('FOND', i+1); - if (fond == NULL) { - result = ResError(); - goto fin; - } - - /* The FOND resource structure corresponds to the FamRec and AsscEntry - data structures documented in the FontManager reference. However, - access to these types is deprecated in Carbon. We therefore access the - data by direct offset in the hope that the resource format will not change - even if api access to the in-memory versions goes away. */ - HLock(fond); - res = *fond + 52; /* offset to association table */ - n = get_int16(res) + 1; res += 2; - table = fond_table_grow(table, n); - for (j = start; j < start + n; j++ ) { - table->refs[j].size = get_int16(res); res += 2; - table->refs[j].style = get_int16(res); res += 2; - table->refs[j].id = get_int16(res); res += 2; - } - start += n; - HUnlock(fond); - } -fin: - CloseResFile(ref); - return table; -} - -/* FIXME: should check for uppercase as well */ -static int is_ttf_file(const char *path) -{ - int len = strlen(path); - return !memcmp(path+len-4,".ttf",4); -} -static int is_otf_file(const char *path) -{ - int len = strlen(path); - return !memcmp(path+len-4,".otf",4); -} - -static void strip_char(char *string, int len, const int c) -{ - char *bit; - len += 1; - while(bit = strchr(string,' ')) { - memmove(bit, bit + 1, string + len - bit - 1); - } -} - -/* get the macos name for the font instance and mangle it into a PS - fontname */ -static char *makePSFontName(FMFontFamily Family, FMFontStyle Style) -{ - Str255 Name; - OSStatus result; - int length; - char *stylename, *fontname; - char *psname; - - result = FMGetFontFamilyName(Family, Name); - if (result != noErr) return NULL; - fontname = MacStr2c(Name); - if (fontname == NULL) return NULL; - strip_char(fontname, strlen(fontname), ' '); - - switch (Style) { - case 0: stylename=""; break;; - case 1: stylename="Bold"; break;; - case 2: stylename="Italic"; break;; - case 3: stylename="BoldItalic"; break;; - default: stylename="Unknown"; break;; - } - - length = strlen(fontname) + strlen(stylename) + 2; - psname = malloc(length); - if (Style != 0) - snprintf(psname, length, "%s-%s", fontname, stylename); - else - snprintf(psname, length, "%s", fontname); - - free(fontname); - - return psname; -} - -typedef struct { - int count; - FMFontIterator Iterator; - char *name; - char *path; - FSSpec last_container; - char *last_container_path; - fond_table *last_table; -} fontenum_t; - -void *gp_enumerate_fonts_init(gs_memory_t *mem) -{ - fontenum_t *state = gs_alloc_bytes(mem, sizeof(fontenum_t), - "macos font enumerator state"); - FMFontIterator *Iterator = &state->Iterator; - OSStatus result; - - if (state != NULL) { - state->count = 0; - state->name = NULL; - state->path = NULL; - result = FMCreateFontIterator(NULL, NULL, - kFMLocalIterationScope, Iterator); - if (result != noErr) return NULL; - memset(&state->last_container, 0, sizeof(FSSpec)); - state->last_container_path = NULL; - state->last_table = NULL; - } - - return (void *)state; -} - -void gp_enumerate_fonts_free(void *enum_state) -{ - fontenum_t *state = (fontenum_t *)enum_state; - FMFontIterator *Iterator = &state->Iterator; - - FMDisposeFontIterator(Iterator); - - /* free any malloc'd stuff here */ - if (state->name) free(state->name); - if (state->path) free(state->path); - if (state->last_container_path) free(state->last_container_path); - if (state->last_table) fond_table_free(state->last_table); - /* the garbage collector will take care of the struct itself */ - -} - -int gp_enumerate_fonts_next(void *enum_state, char **fontname, char **path) -{ - fontenum_t *state = (fontenum_t *)enum_state; - FMFontIterator *Iterator = &state->Iterator; - FMFont Font; - FourCharCode Format; - FMFontFamily FontFamily; - FMFontStyle Style; - FSSpec FontContainer; - char type[5]; - char fontpath[256]; - char *psname; - fond_table *table = NULL; - OSStatus result; - - result = FMGetNextFont(Iterator, &Font); - if (result != noErr) return 0; /* no more fonts */ - - result = FMGetFontFormat(Font, &Format); - type[0] = ((char*)&Format)[0]; - type[1] = ((char*)&Format)[1]; - type[2] = ((char*)&Format)[2]; - type[3] = ((char*)&Format)[3]; - type[4] = '\0'; - - FMGetFontFamilyInstanceFromFont(Font, &FontFamily, &Style); - if (state->name) free (state->name); - - psname = makePSFontName(FontFamily, Style); - if (psname == NULL) { - state->name = strdup("GSPlaceHolder"); - } else { - state->name = psname; - } - - result = FMGetFontContainer(Font, &FontContainer); - if (!memcmp(&FontContainer, &state->last_container, sizeof(FSSpec))) { - /* we have cached data on this file */ - strncpy(fontpath, state->last_container_path, 256); - table = state->last_table; - } else { - convertSpecToPath(&FontContainer, fontpath, 256); - if (!is_ttf_file(fontpath) && !is_otf_file(fontpath)) - table = parse_fond(&FontContainer); - /* cache data on the new font file */ - memcpy(&state->last_container, &FontContainer, sizeof(FSSpec)); - if (state->last_container_path) free (state->last_container_path); - state->last_container_path = strdup(fontpath); - if (state->last_table) fond_table_free(state->last_table); - state->last_table = table; - } - - if (state->path) { - free(state->path); - state->path = NULL; - } - if (table != NULL) { - int i; - for (i = 0; i < table->entries; i++) { - if (table->refs[i].size == 0) { /* ignore non-scalable fonts */ - if (table->refs[i].style == Style) { - int len = strlen(fontpath) + strlen("%macresource%#sfnt+") + 6; - state->path = malloc(len); - snprintf(state->path, len, "%%macresource%%%s#sfnt+%d", - fontpath, table->refs[i].id); - break; - } - } - } - } else { - /* regular font file */ - state->path = strdup(fontpath); - } - if (state->path == NULL) { - /* no matching font was found in the FOND resource table. this usually */ - /* means an LWFN file, which we don't handle yet. */ - /* we still specify these with a %macresource% path, but no res id */ - /* TODO: check file type */ - int len = strlen(fontpath) + strlen("%macresource%#POST") + 1; - state->path = malloc(len); - snprintf(state->path, len, "%%macresource%%%s#POST", fontpath); - } -#ifdef DEBUG - dlprintf2("fontenum: returning '%s' in '%s'\n", state->name, state->path); -#endif - *fontname = state->name; - *path = state->path; - - state->count += 1; - return 1; -} - -/* --------- 64 bit file access ----------- */ -/* fixme: Not implemented yet. - * Currently we stub it with 32 bits access. - */ - -FILE *gp_fopen_64(const char *filename, const char *mode) -{ - return fopen(filename, mode); -} - -FILE *gp_open_scratch_file_64(const gs_memory_t *mem, - const char *prefix, - char fname[gp_file_name_sizeof], - const char *mode) -{ - return gp_open_scratch_file(mem, prefix, fname, mode); -} - -FILE *gp_open_printer_64(const gs_memory_t *mem, - char fname[gp_file_name_sizeof], - int binary_mode) -{ - return gp_open_printer(fname, binary_mode); -} - -int64_t gp_ftell_64(FILE *strm) -{ - return ftell(strm); -} - -int gp_fseek_64(FILE *strm, int64_t offset, int origin) -{ - long offset1 = (long)offset; - - if (offset != offset1) - return -1; - return fseek(strm, offset1, origin); -} diff -Nru ghostscript-9.10~dfsg/base/gp_macpoll.c ghostscript-9.25~dfsg+1/base/gp_macpoll.c --- ghostscript-9.10~dfsg/base/gp_macpoll.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_macpoll.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* - * Macintosh platform polling support for Ghostscript. - * - */ - -#ifndef __CARBON__ -#include -#else -#include -#endif - -#include "gx.h" -#include "gp.h" -#include "gsdll.h" -#include "gpcheck.h" -#include "iapi.h" -#include "iref.h" -#include "iminst.h" -#include "imain.h" - -#ifdef CHECK_INTERRUPTS - -extern HWND hwndtext; - -/* ------ Process message loop ------ */ -/* - * Check messages and interrupts; return true if interrupted. - * This is called frequently - it must be quick! - */ -int gp_check_interrupts(const gs_memory_t *mem) -{ - /* static variables need to go away for thread safety */ - static unsigned long lastYieldTicks = 0; - int iRetVal = 0; - - if ((TickCount() - lastYieldTicks) > 2) { - lastYieldTicks = TickCount(); - if (pgsdll_callback) { - /* WARNING: The use of the old gsdll interface is deprecated. - * The caller should use the newer gsapi_set_poll. - * If the caller needs access to "hwndtext", it should do - * this via caller_handle which is passed to poll_fn. - */ - /* the hwnd parameter which is submitted in gsdll_init - * to the DLL is returned in every gsdll_poll message - * in the count parameter - */ - iRetVal = (*pgsdll_callback)(GSDLL_POLL, 0, (long) hwndtext); - } else { -#ifndef GS_THREADSAFE - if (mem == NULL) { - /* this is not thread safe */ - mem = gs_lib_ctx_get_non_gc_memory_t(); - } -#endif - if (mem && mem->gs_lib_ctx && mem->gs_lib_ctx->poll_fn) - iRetVal = (*mem->gs_lib_ctx->poll_fn)(mem->gs_lib_ctx->caller_handle); - } - } - return iRetVal; -} -#endif diff -Nru ghostscript-9.10~dfsg/base/gpmisc.c ghostscript-9.25~dfsg+1/base/gpmisc.c --- ghostscript-9.10~dfsg/base/gpmisc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gpmisc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,17 +9,17 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Miscellaneous support for platform facilities */ +#include "stat_.h" #include "unistd_.h" #include "fcntl_.h" #include "stdio_.h" -#include "stat_.h" #include "memory_.h" #include "string_.h" #include "gp.h" @@ -248,7 +248,7 @@ case 0: /* We have no infix, start with parent. */ if ((no_sibling && ipe == fname + flen && flen != 0) || - !gp_file_name_is_partent_allowed()) + !gp_file_name_is_parent_allowed()) return gp_combine_cant_handle; /* Falls through. */ case 2: diff -Nru ghostscript-9.10~dfsg/base/gpmisc.h ghostscript-9.25~dfsg+1/base/gpmisc.h --- ghostscript-9.10~dfsg/base/gpmisc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gpmisc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_mktmp.c ghostscript-9.25~dfsg+1/base/gp_mktmp.c --- ghostscript-9.10~dfsg/base/gp_mktmp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mktmp.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_msdll.c ghostscript-9.25~dfsg+1/base/gp_msdll.c --- ghostscript-9.10~dfsg/base/gp_msdll.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_msdll.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_msdos.c ghostscript-9.25~dfsg+1/base/gp_msdos.c --- ghostscript-9.10~dfsg/base/gp_msdos.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_msdos.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_mshdl.c ghostscript-9.25~dfsg+1/base/gp_mshdl.c --- ghostscript-9.10~dfsg/base/gp_mshdl.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mshdl.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -43,7 +43,7 @@ static iodev_proc_fclose(mswin_handle_fclose); const gx_io_device gs_iodev_handle = { "%handle%", "FileSystem", - {iodev_no_init, iodev_no_open_device, + {iodev_no_init, iodev_no_finit, iodev_no_open_device, NULL /*iodev_os_open_file */ , mswin_handle_fopen, mswin_handle_fclose, iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status, iodev_no_enumerate_files, NULL, NULL, diff -Nru ghostscript-9.10~dfsg/base/gp_mslib.c ghostscript-9.25~dfsg+1/base/gp_mslib.c --- ghostscript-9.10~dfsg/base/gp_mslib.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mslib.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_mspol.c ghostscript-9.25~dfsg+1/base/gp_mspol.c --- ghostscript-9.10~dfsg/base/gp_mspol.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mspol.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_msprn.c ghostscript-9.25~dfsg+1/base/gp_msprn.c --- ghostscript-9.10~dfsg/base/gp_msprn.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_msprn.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -56,11 +56,12 @@ */ static iodev_proc_init(mswin_printer_init); +static iodev_proc_finit(mswin_printer_finit); static iodev_proc_fopen(mswin_printer_fopen); static iodev_proc_fclose(mswin_printer_fclose); const gx_io_device gs_iodev_printer = { "%printer%", "FileSystem", - {mswin_printer_init, iodev_no_open_device, + {mswin_printer_init, mswin_printer_finit, iodev_no_open_device, NULL /*iodev_os_open_file */ , mswin_printer_fopen, mswin_printer_fclose, iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status, iodev_no_enumerate_files, NULL, NULL, @@ -144,6 +145,14 @@ return 0; } +static void +mswin_printer_finit(gx_io_device * iodev, gs_memory_t * mem) +{ + gs_free_object(mem, iodev->state, "mswin_printer_finit"); + iodev->state = NULL; + return; +} + static int mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) diff -Nru ghostscript-9.10~dfsg/base/gp_mswin.c ghostscript-9.25~dfsg+1/base/gp_mswin.c --- ghostscript-9.10~dfsg/base/gp_mswin.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mswin.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,6 +32,7 @@ /* prevent gp.h from defining fopen */ #define fopen fopen +#include "windows_.h" #include "stdio_.h" #include "string_.h" #include "memory_.h" @@ -53,8 +54,6 @@ #include "gsexit.h" #include "scommon.h" -#include "windows_.h" -#include #include #include #include "gp_mswin.h" @@ -101,23 +100,6 @@ exit(exit_status); } -/* ------ Persistent data cache ------*/ - -/* insert a buffer under a (type, key) pair */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) -{ - /* not yet implemented */ - return 0; -} - -/* look up a (type, key) in the cache */ -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata) -{ - /* not yet implemented */ - return -1; -} - /* ------ Printer accessing ------ */ /* Forward references */ @@ -268,18 +250,14 @@ /* WinNT stores default printer in registry and win.ini */ /* Win95 stores default printer in win.ini */ -#ifdef GS_NO_UTF8 - GetProfileString("windows", "device", "", buf, sizeof(buf)); -#else wchar_t wbuf[512]; int l; GetProfileStringW(L"windows", L"device", L"", wbuf, sizeof(wbuf)); l = wchar_to_utf8(NULL, wbuf); if (l < 0 || l > sizeof(buf)) - return gs_error_undefinedfilename; + return_error(gs_error_undefinedfilename); wchar_to_utf8(buf, wbuf); -#endif if ((p = strchr(buf, ',')) != NULL) *p = '\0'; return gp_printfile_win32(filename, buf); @@ -289,7 +267,7 @@ else return gp_printfile_win32(filename, (char *)NULL); } else - return gs_error_undefinedfilename; + return_error(gs_error_undefinedfilename); } #define PRINT_BUF_SIZE 16384u @@ -387,9 +365,6 @@ #ifdef METRO return FALSE; #else -#ifdef GS_NO_UTF8 - return OpenPrinter(port, printer, NULL); -#else BOOL opened; wchar_t *uni = malloc(utf8_to_wchar(NULL, port) * sizeof(wchar_t)); if (uni) @@ -398,7 +373,6 @@ free(uni); return opened; #endif -#endif } #ifndef METRO @@ -486,11 +460,7 @@ FILE *mswin_popen(const char *cmd, const char *mode) { SECURITY_ATTRIBUTES saAttr; -#ifdef GS_NO_UTF8 - STARTUPINFO siStartInfo; -#else STARTUPINFOW siStartInfo; -#endif PROCESS_INFORMATION piProcInfo; HANDLE hPipeTemp = INVALID_HANDLE_VALUE; HANDLE hChildStdinRd = INVALID_HANDLE_VALUE; @@ -499,11 +469,7 @@ HANDLE hChildStderrWr = INVALID_HANDLE_VALUE; HANDLE hProcess = GetCurrentProcess(); int handle = 0; -#ifdef GS_NO_UTF8 - char *command = NULL; -#else wchar_t *command = NULL; -#endif FILE *pipe = NULL; if (strcmp(mode, "wb") != 0) @@ -549,25 +515,15 @@ siStartInfo.hStdError = hChildStderrWr; if (handle == 0) { -#ifdef GS_NO_UTF8 - command = (char *)malloc(strlen(cmd)+1); - if (command) - strcpy(command, cmd); -#else command = (wchar_t *)malloc(sizeof(wchar_t)*utf8_to_wchar(NULL, cmd)); if (command) utf8_to_wchar(command, cmd); -#endif else handle = -1; } if (handle == 0) -#ifdef GS_NO_UTF8 - if (!CreateProcess(NULL, -#else if (!CreateProcessW(NULL, -#endif command, /* command line */ NULL, /* process security attributes */ NULL, /* primary thread security attributes */ @@ -612,11 +568,12 @@ /* Create and open a scratch file with a given name prefix. */ /* Write the actual file name at fname. */ -FILE * -gp_open_scratch_file(const gs_memory_t *mem, - const char *prefix, - char *fname, - const char *mode) +static FILE * +gp_open_scratch_file_generic(const gs_memory_t *mem, + const char *prefix, + char *fname, + const char *mode, + int remove) { UINT n; DWORD l; @@ -625,21 +582,30 @@ FILE *f = NULL; char sTempDir[_MAX_PATH]; char sTempFileName[_MAX_PATH]; + wchar_t wTempDir[_MAX_PATH]; + wchar_t wTempFileName[_MAX_PATH]; + wchar_t wPrefix[_MAX_PATH]; memset(fname, 0, gp_file_name_sizeof); if (!gp_file_name_is_absolute(prefix, strlen(prefix))) { - int plen = sizeof(sTempDir); + int plen = _MAX_PATH; - if (gp_gettmpdir(sTempDir, &plen) != 0) -#if METRO - l = GetTempPathWRT(sizeof(sTempDir), sTempDir); + /* gp_gettmpdir will always return a UTF8 encoded string + * due to the windows specific version of gp_getenv + * being called (in gp_wgetv.c, not gp_getnv.c) */ + if (gp_gettmpdir(sTempDir, &plen) != 0) { +#ifdef METRO + /* METRO always uses UTF8 for 'ascii' - there is no concept of + * local encoding. */ + l = GetTempPathWRT(_MAX_PATH, wTempDir); #else - l = GetTempPath(sizeof(sTempDir), sTempDir); + GetTempPathW(_MAX_PATH, wTempDir); #endif - else + l = wchar_to_utf8(sTempDir, wTempDir); + } else l = strlen(sTempDir); } else { - strncpy(sTempDir, prefix, sizeof(sTempDir)); + strncpy(sTempDir, prefix, _MAX_PATH); prefix = ""; l = strlen(sTempDir); } @@ -647,12 +613,15 @@ if (sTempDir[l-1] == '/') sTempDir[l-1] = '\\'; /* What Windoze prefers */ - if (l <= sizeof(sTempDir)) { + if (l <= _MAX_PATH) { + utf8_to_wchar(wTempDir, sTempDir); + utf8_to_wchar(wPrefix, prefix); #ifdef METRO - n = GetTempFileNameWRT(sTempDir, prefix, sTempFileName); + n = GetTempFileNameWRT(wTempDir, wPrefix, wTempFileName); #else - n = GetTempFileName(sTempDir, prefix, 0, sTempFileName); + GetTempFileNameW(wTempDir, wPrefix, 0, wTempFileName); #endif + n = wchar_to_utf8(sTempFileName, wTempFileName); if (n == 0) { /* If 'prefix' is not a directory, it is a path prefix. */ int l = strlen(sTempDir), i; @@ -666,22 +635,17 @@ break; } } - if (i > 0) + if (i > 0) { + utf8_to_wchar(wPrefix, sTempDir + i); #ifdef METRO - n = GetTempFileNameWRT(sTempDir, sTempDir + i, sTempFileName); + GetTempFileNameWRT(wTempDir, wPrefix, wTempFileName); #else - n = GetTempFileName(sTempDir, sTempDir + i, 0, sTempFileName); + GetTempFileNameW(wTempDir, wPrefix, 0, wTempFileName); #endif + n = wchar_to_utf8(sTempFileName, wTempFileName); + } } if (n != 0) { -#ifdef GS_NO_UTF8 - hfile = CreateFile(sTempFileName, - GENERIC_READ | GENERIC_WRITE | DELETE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL /* | FILE_FLAG_DELETE_ON_CLOSE */, - NULL); -#else int len = utf8_to_wchar(NULL, sTempFileName); wchar_t *uni = (len > 0 ? malloc(sizeof(wchar_t)*len) : NULL); if (uni == NULL) @@ -692,26 +656,18 @@ hfile = CreateFile2(uni, GENERIC_READ | GENERIC_WRITE | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, - CREATE_ALWAYS, + CREATE_ALWAYS | (remove ? FILE_FLAG_DELETE_ON_CLOSE : 0), NULL); #else hfile = CreateFileW(uni, GENERIC_READ | GENERIC_WRITE | DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL /* | FILE_FLAG_DELETE_ON_CLOSE */, + FILE_ATTRIBUTE_NORMAL | (remove ? FILE_FLAG_DELETE_ON_CLOSE : 0), NULL); #endif free(uni); } -#endif - /* - * Can't apply FILE_FLAG_DELETE_ON_CLOSE due to - * the logics of clist_fclose. Also note that - * gdev_prn_render_pages requires multiple temporary files - * to exist simultaneousely, so that keeping all them opened - * may exceed available CRTL file handles. - */ } } if (hfile != INVALID_HANDLE_VALUE) { @@ -740,13 +696,28 @@ return f; } +FILE * +gp_open_scratch_file(const gs_memory_t *mem, + const char *prefix, + char *fname, + const char *mode) +{ + return gp_open_scratch_file_generic(mem, prefix, fname, mode, 0); +} + +FILE * +gp_open_scratch_file_rm(const gs_memory_t *mem, + const char *prefix, + char *fname, + const char *mode) +{ + return gp_open_scratch_file_generic(mem, prefix, fname, mode, 1); +} + /* Open a file with the given name, as a stream of uninterpreted bytes. */ FILE * gp_fopen(const char *fname, const char *mode) { -#ifdef GS_NO_UTF8 - return fopen(fname, mode); -#else int len = utf8_to_wchar(NULL, fname); wchar_t *uni; wchar_t wmode[4]; @@ -762,7 +733,83 @@ file = _wfopen(uni, wmode); free(uni); return file; -#endif +} + +int gp_stat(const char *path, struct _stat *buf) +{ + int len = utf8_to_wchar(NULL, path); + wchar_t *uni; + int ret; + + if (len <= 0) + return -1; + uni = malloc(len*sizeof(wchar_t)); + if (uni == NULL) + return -1; + utf8_to_wchar(uni, path); + ret = _wstat(uni, buf); + free(uni); + return ret; +} + +/* test whether gp_fdup is supported on this platform */ +int gp_can_share_fdesc(void) +{ + return 1; +} + +/* Create a second open FILE on the basis of a given one */ +FILE *gp_fdup(FILE *f, const char *mode) +{ + int fd = fileno(f); + if (fd < 0) + return NULL; + + fd = dup(fd); + if (fd < 0) + return NULL; + + return fdopen(fd, mode); +} + +/* Read from a specified offset within a FILE into a buffer */ +int gp_fpread(char *buf, uint count, int64_t offset, FILE *f) +{ + OVERLAPPED overlapped; + DWORD ret; + HANDLE hnd = (HANDLE)_get_osfhandle(fileno(f)); + + if (hnd == INVALID_HANDLE_VALUE) + return -1; + + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (DWORD)offset; + overlapped.OffsetHigh = (DWORD)(offset >> 32); + + if (!ReadFile((HANDLE)hnd, buf, count, &ret, &overlapped)) + return -1; + + return ret; +} + +/* Write to a specified offset within a FILE from a buffer */ +int gp_fpwrite(char *buf, uint count, int64_t offset, FILE *f) +{ + OVERLAPPED overlapped; + DWORD ret; + HANDLE hnd = (HANDLE)_get_osfhandle(fileno(f)); + + if (hnd == INVALID_HANDLE_VALUE) + return -1; + + memset(&overlapped, 0, sizeof(OVERLAPPED)); + overlapped.Offset = (DWORD)offset; + overlapped.OffsetHigh = (DWORD)(offset >> 32); + + if (!WriteFile((HANDLE)hnd, buf, count, &ret, &overlapped)) + return -1; + + return ret; } /* ------ Font enumeration ------ */ @@ -853,14 +900,14 @@ bool gp_fseekable (FILE *f) { - struct stat s; + struct __stat64 s; int fno; fno = fileno(f); if (fno < 0) return(false); - if (fstat(fno, &s) < 0) + if (_fstat64(fno, &s) < 0) return(false); return((bool)S_ISREG(s.st_mode)); @@ -868,6 +915,9 @@ /* ------------------------- _snprintf -----------------------------*/ +#if defined(_MSC_VER) && _MSC_VER>=1900 /* VS 2014 and later have (finally) snprintf */ +# define STDC99 +#else /* Microsoft Visual C++ 2005 doesn't properly define snprintf, which is defined in the C standard ISO/IEC 9899:1999 (E) */ @@ -885,3 +935,4 @@ } else return 0; } +#endif diff -Nru ghostscript-9.10~dfsg/base/gp_mswin.h ghostscript-9.25~dfsg+1/base/gp_mswin.h --- ghostscript-9.10~dfsg/base/gp_mswin.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_mswin.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_nsync.c ghostscript-9.25~dfsg+1/base/gp_nsync.c --- ghostscript-9.10~dfsg/base/gp_nsync.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_nsync.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_ntfs.c ghostscript-9.25~dfsg+1/base/gp_ntfs.c --- ghostscript-9.10~dfsg/base/gp_ntfs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_ntfs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,15 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* file system stuff for MS-Windows WIN32 and MS-Windows NT */ /* hacked from gp_dosfs.c by Russell Lang */ +#include "windows_.h" #include "stdio_.h" #include #include @@ -29,7 +30,6 @@ #include "gp.h" #include "gpmisc.h" #include "gsutil.h" -#include "windows_.h" /* ------ Printer accessing ------ */ @@ -84,11 +84,7 @@ /* ------ File enumeration ------ */ struct directory_enum_s { -#ifdef GS_NO_UTF8 - WIN32_FIND_DATA find_data; -#else WIN32_FIND_DATAW find_data; -#endif HANDLE find_handle; char *pattern; /* orig pattern + modified pattern */ int patlen; /* orig pattern length */ @@ -180,8 +176,11 @@ /* but it's simpler for GC and freeing to allocate it as bytes. */ pattern = (char *)gs_alloc_bytes(mem, pat_size, "gp_enumerate_files(pattern)"); - if (pattern == 0) + if (pattern == 0) { + gs_free_object(mem, pden, "free directory enumerator on error"); + gs_free_object(mem, pfen, "free file enumerator on error"); return 0; + } /* translate the template into a pattern. Note that */ /* a final '\' or '/' in the string is discarded. */ @@ -232,11 +231,7 @@ directory_enum *new_denum = NULL, *pden = pfen->current; int code = 0; uint len; -#ifdef GS_NO_UTF8 - char *outfname; -#else char outfname[(sizeof(pden->find_data.cFileName)*3+1)/2]; -#endif if (pfen->illegal) { gp_enumerate_files_close(pfen); return ~(uint) 0; @@ -244,9 +239,6 @@ for(;;) { if (pden->first_time) { -#ifdef GS_NO_UTF8 - pden->find_handle = FindFirstFile(pden->pattern, &(pden->find_data)); -#else wchar_t *pat; pat = malloc(utf8_to_wchar(NULL, pden->pattern)*sizeof(wchar_t)); if (pat == NULL) { @@ -260,7 +252,6 @@ pden->find_handle = FindFirstFileW(pat, &(pden->find_data)); #endif free(pat); -#endif if (pden->find_handle == INVALID_HANDLE_VALUE) { if (pden->previous) { FindClose(pden->find_handle); @@ -278,11 +269,7 @@ } pden->first_time = 0; } else { -#ifdef GS_NO_UTF8 - if (!FindNextFile(pden->find_handle, &(pden->find_data))) { -#else if (!FindNextFileW(pden->find_handle, &(pden->find_data))) { -#endif if (pden->previous) { FindClose(pden->find_handle); gs_free_object(pden->memory, pden->pattern, @@ -298,26 +285,6 @@ } } } -#ifdef GS_NO_UTF8 - if ( strcmp(".", pden->find_data.cFileName) - && strcmp("..", pden->find_data.cFileName)) { - if (pden->find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ - new_denum = gs_alloc_struct(pden->memory, directory_enum, &st_directory_enum, "gp_enumerate_files"); - if (new_denum != 0) { - if (enumerate_directory_init(pden->memory, new_denum, pden->pattern, pden->head_size, - pden->find_data.cFileName, &pden->pattern[pden->head_size], pden->pat_size - pden->head_size) < 0) - { - gs_free_object(pden->memory, new_denum, "free directory enumerator on error"); - } - new_denum->previous = pden; - pden = new_denum; - pfen->current = pden; - } - } - else - break; - } -#else if ( wcscmp(L".", pden->find_data.cFileName) && wcscmp(L"..", pden->find_data.cFileName)) { if (pden->find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -344,18 +311,13 @@ else break; } -#endif } if (code != 0) { /* All done, clean up. */ gp_enumerate_files_close(pfen); return ~(uint) 0; } -#ifdef GS_NO_UTF8 - outfname = pden->find_data.cFileName; -#else wchar_to_utf8(outfname, pden->find_data.cFileName); -#endif len = strlen(outfname); if (pden->head_size + len < maxlen) { @@ -383,9 +345,9 @@ gs_free_object(mem, pden, "gp_enumerate_files_close"); pden = ptenum; }; + gs_free_object(mem, pfen->pattern, + "gp_enumerate_files_close(pattern)"); gs_free_object(mem, pfen, "gp_enumerate_files_close"); -/* gs_free_object(mem, pfen->pattern, - "gp_enumerate_files_close(pattern)");*/ } /* -------------- Helpers for gp_file_name_combine_generic ------------- */ @@ -450,7 +412,7 @@ { return "."; } -bool gp_file_name_is_partent_allowed(void) +bool gp_file_name_is_parent_allowed(void) { return true; } diff -Nru ghostscript-9.10~dfsg/base/gp_nxpsprn.c ghostscript-9.25~dfsg+1/base/gp_nxpsprn.c --- ghostscript-9.10~dfsg/base/gp_nxpsprn.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_nxpsprn.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,27 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#include "std.h" +#include "gp.h" + +/* dummy for when no xps print queue is available */ +int +gp_xpsprint(char *filename, char *printername, int *result) +{ + (void)filename; + (void)printername; + *result = 0; + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/gp_os2.c ghostscript-9.25~dfsg+1/base/gp_os2.c --- ghostscript-9.10~dfsg/base/gp_os2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_os2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -166,23 +166,6 @@ return false; } -/* ------ Persistent data cache ------*/ - -/* insert a buffer under a (type, key) pair */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) -{ - /* not yet implemented */ - return 0; -} - -/* look up a (type, key) in the cache */ -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata) -{ - /* not yet implemented */ - return -1; -} - /*************************************************************/ /* from gp_iwatc.c and gp_itbc.c */ @@ -553,8 +536,11 @@ if (!rc) emprintf(mem, "SplQmClose failed.\n"); } - } else + } else { + free(buffer); + fclose(f); rc = 0; /* no memory */ + } return !rc; } diff -Nru ghostscript-9.10~dfsg/base/gp_os2fs.c ghostscript-9.25~dfsg+1/base/gp_os2fs.c --- ghostscript-9.10~dfsg/base/gp_os2fs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_os2fs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -262,6 +262,39 @@ return fopen(fname, mode); } +int gp_stat(const char *path, struct stat *buf) +{ + return stat(path, buf); +} + +int gp_can_share_fdesc(void) +{ + return 0; +} + +FILE *gp_open_scratch_file_rm(const gs_memory_t *mem, + const char *prefix, + char fname[gp_file_name_sizeof], + const char *mode) +{ + return NULL; +} + +FILE *gp_fdup(FILE *f, const char *mode) +{ + return NULL; +} + +int gp_fpread(char *buf, uint count, int64_t offset, FILE *f) +{ + return -1; +} + +int gp_fpwrite(char *buf, uint count, int64_t offset, FILE *f) +{ + return -1; +} + /* -------------- Helpers for gp_file_name_combine_generic ------------- */ uint gp_file_name_root(const char *fname, uint len) @@ -324,7 +357,7 @@ { return "."; } -bool gp_file_name_is_partent_allowed(void) +bool gp_file_name_is_parent_allowed(void) { return true; } diff -Nru ghostscript-9.10~dfsg/base/gp_os2.h ghostscript-9.25~dfsg+1/base/gp_os2.h --- ghostscript-9.10~dfsg/base/gp_os2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_os2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_os2pr.c ghostscript-9.25~dfsg+1/base/gp_os2pr.c --- ghostscript-9.10~dfsg/base/gp_os2pr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_os2pr.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -59,11 +59,12 @@ */ static iodev_proc_init(os2_printer_init); +static iodev_proc_finit(os2_printer_finit); static iodev_proc_fopen(os2_printer_fopen); static iodev_proc_fclose(os2_printer_fclose); const gx_io_device gs_iodev_printer = { "%printer%", "FileSystem", - {os2_printer_init, iodev_no_open_device, + {os2_printer_init, os2_printer_finit, iodev_no_open_device, NULL /*iodev_os_open_file */ , os2_printer_fopen, os2_printer_fclose, iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status, iodev_no_enumerate_files, NULL, NULL, @@ -91,6 +92,14 @@ return 0; } +static void +os2_printer_finit(gx_io_device * iodev, gs_memory_t * mem) +{ + gs_free_object(mem, iodev->state, "os2_printer_finit"); + iodev->state = NULL; + return; +} + static int os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) diff -Nru ghostscript-9.10~dfsg/base/gp_os9.c ghostscript-9.25~dfsg+1/base/gp_os9.c --- ghostscript-9.10~dfsg/base/gp_os9.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_os9.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -103,23 +103,6 @@ return gp_get_realtime(pdt); /* not yet implemented */ } -/* ------ Persistent data cache ------*/ - -/* insert a buffer under a (type, key) pair */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) -{ - /* not yet implemented */ - return 0; -} - -/* look up a (type, key) in the cache */ -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata) -{ - /* not yet implemented */ - return -1; -} - /* ------ Printer accessing ------ */ /* Open a connection to a printer. A null file name means use the */ diff -Nru ghostscript-9.10~dfsg/base/gp_paper.c ghostscript-9.25~dfsg+1/base/gp_paper.c --- ghostscript-9.10~dfsg/base/gp_paper.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_paper.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_psync.c ghostscript-9.25~dfsg+1/base/gp_psync.c --- ghostscript-9.10~dfsg/base/gp_psync.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_psync.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,18 +9,20 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* POSIX pthreads threads / semaphore / monitor implementation */ #include "std.h" +#include "string_.h" #include "malloc_.h" +#include "unistd_.h" /* for __USE_UNIX98 */ #include #include "gserrors.h" #include "gpsync.h" - +#include "assert_.h" /* * Thanks to Larry Jones for this revision of * Aladdin's original code into a form that depends only on POSIX APIs. @@ -64,12 +66,24 @@ pt_semaphore_t * const sem = (pt_semaphore_t *)sema; int scode; +#ifdef MEMENTO_SQUEEZE_BUILD + eprintf("Can't create semaphores when memory squeezing with forks\n"); + Memento_bt(); + return_error(gs_error_VMerror); +#endif + if (!sema) return -1; /* semaphores are not movable */ sem->count = 0; scode = pthread_mutex_init(&sem->mutex, NULL); if (scode == 0) + { scode = pthread_cond_init(&sem->cond, NULL); + if (scode) + pthread_mutex_destroy(&sem->mutex); + } + if (scode) + memset(sem, 0, sizeof(*sem)); return SEM_ERROR_CODE(scode); } @@ -92,6 +106,12 @@ pt_semaphore_t * const sem = (pt_semaphore_t *)sema; int scode, scode2; +#ifdef MEMENTO_SQUEEZE_BUILD + eprintf("Can't create mutexes when memory squeezing with forks\n"); + Memento_bt(); + return_error(gs_error_VMerror); +#endif + scode = pthread_mutex_lock(&sem->mutex); if (scode != 0) return SEM_ERROR_CODE(scode); @@ -128,13 +148,20 @@ /* Monitor supports enter/leave semantics */ /* - * We need PTHREAD_MUTEX_RECURSIVE behavior, but this isn't totally portable - * so we implement it in a more portable fashion, keeping track of the - * owner thread using 'pthread_self()' + * We need PTHREAD_MUTEX_RECURSIVE behavior, but this isn't + * supported on all pthread platforms, so if it's available + * we'll use it, otherwise we'll emulate it. + * GS_RECURSIVE_MUTEXATTR is set by the configure script + * on Unix-like machines to the attribute setting for + * PTHREAD_MUTEX_RECURSIVE - on linux this is usually + * PTHREAD_MUTEX_RECURSIVE_NP */ typedef struct gp_pthread_recursive_s { pthread_mutex_t mutex; /* actual mutex */ +#ifndef GS_RECURSIVE_MUTEXATTR pthread_t self_id; /* owner */ + int lcount; +#endif } gp_pthread_recursive_t; uint @@ -148,12 +175,38 @@ { pthread_mutex_t *mon; int scode; + pthread_mutexattr_t attr; + pthread_mutexattr_t *attrp = NULL; + +#ifdef MEMENTO_SQUEEZE_BUILD + eprintf("Can't create monitors when memory squeezing with forks\n"); + Memento_bt(); + return_error(gs_error_VMerror); +#endif if (!mona) return -1; /* monitors are not movable */ - mon = &((gp_pthread_recursive_t *)mona)->mutex; + + +#ifdef GS_RECURSIVE_MUTEXATTR + attrp = &attr; + scode = pthread_mutexattr_init(attrp); + if (scode < 0) goto done; + + scode = pthread_mutexattr_settype(attrp, GS_RECURSIVE_MUTEXATTR); + if (scode < 0) { + goto done; + } +#else ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ - scode = pthread_mutex_init(mon, NULL); + ((gp_pthread_recursive_t *)mona)->lcount = 0; +#endif + + mon = &((gp_pthread_recursive_t *)mona)->mutex; + scode = pthread_mutex_init(mon, attrp); + if (attrp) + (void)pthread_mutexattr_destroy(attrp); +done: return SEM_ERROR_CODE(scode); } @@ -173,29 +226,52 @@ pthread_mutex_t * const mon = (pthread_mutex_t *)mona; int scode; +#ifdef GS_RECURSIVE_MUTEXATTR + scode = pthread_mutex_lock(mon); +#else + assert(((gp_pthread_recursive_t *)mona)->lcount >= 0); + if ((scode = pthread_mutex_trylock(mon)) == 0) { ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); - return SEM_ERROR_CODE(scode); + ((gp_pthread_recursive_t *)mona)->lcount++; } else { - if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) - return 0; + if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) { + ((gp_pthread_recursive_t *)mona)->lcount++; + scode = 0; + } else { /* we were not the owner, wait */ scode = pthread_mutex_lock(mon); ((gp_pthread_recursive_t *)mona)->self_id = pthread_self(); - return SEM_ERROR_CODE(scode); + ((gp_pthread_recursive_t *)mona)->lcount++; } } +#endif + return SEM_ERROR_CODE(scode); } int gp_monitor_leave(gp_monitor * mona) { pthread_mutex_t * const mon = (pthread_mutex_t *)mona; - int scode; + int scode = 0; +#ifdef GS_RECURSIVE_MUTEXATTR scode = pthread_mutex_unlock(mon); - ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ +#else + assert(((gp_pthread_recursive_t *)mona)->lcount > 0 && ((gp_pthread_recursive_t *)mona)->self_id != 0); + + if (pthread_equal(pthread_self(),((gp_pthread_recursive_t *)mona)->self_id)) { + if ((--((gp_pthread_recursive_t *)mona)->lcount) == 0) { + ((gp_pthread_recursive_t *)mona)->self_id = 0; /* Not valid unless mutex is locked */ + scode = pthread_mutex_unlock(mon); + + } + } + else { + scode = -1 /* should be EPERM */; + } +#endif return SEM_ERROR_CODE(scode); } @@ -233,6 +309,12 @@ pthread_attr_t attr; int code; +#ifdef MEMENTO_SQUEEZE_BUILD + eprintf("Can't create threads when memory squeezing with forks\n"); + Memento_bt(); + return_error(gs_error_VMerror); +#endif + if (!closure) return_error(gs_error_VMerror); closure->proc = proc; @@ -281,3 +363,29 @@ return; pthread_join((pthread_t)thread, NULL); } + +void (gp_monitor_label)(gp_monitor * mona, const char *name) +{ + pthread_mutex_t * const mon = &((gp_pthread_recursive_t *)mona)->mutex; + + (void)mon; + (void)name; + Bobbin_label_mutex(mon, name); +} + +void (gp_semaphore_label)(gp_semaphore * sema, const char *name) +{ + pt_semaphore_t * const sem = (pt_semaphore_t *)sema; + + (void)sem; + (void)name; + Bobbin_label_mutex(&sem->mutex, name); + Bobbin_label_cond(&sem->cond, name); +} + +void (gp_thread_label)(gp_thread_id thread, const char *name) +{ + (void)thread; + (void)name; + Bobbin_label_thread((pthread_t)thread, name); +} diff -Nru ghostscript-9.10~dfsg/base/gp_stdia.c ghostscript-9.25~dfsg+1/base/gp_stdia.c --- ghostscript-9.10~dfsg/base/gp_stdia.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_stdia.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_stdin.c ghostscript-9.25~dfsg+1/base/gp_stdin.c --- ghostscript-9.10~dfsg/base/gp_stdin.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_stdin.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_strdl.c ghostscript-9.25~dfsg+1/base/gp_strdl.c --- ghostscript-9.10~dfsg/base/gp_strdl.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_strdl.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gpsync.h ghostscript-9.25~dfsg+1/base/gpsync.h --- ghostscript-9.10~dfsg/base/gpsync.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gpsync.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -51,6 +51,11 @@ int gp_semaphore_wait(gp_semaphore * sema); int gp_semaphore_signal(gp_semaphore * sema); +void gp_semaphore_label(gp_semaphore * sema, const char *name); +#ifndef BOBBIN +#define gp_semaphore_label(A,B) do {} while (0) +#endif + /* * Monitors support enter/leave semantics: at most one thread can have * entered and not yet left a given monitor. @@ -73,6 +78,11 @@ int gp_monitor_enter(gp_monitor * mon); int gp_monitor_leave(gp_monitor * mon); +void gp_monitor_label(gp_monitor * mon, const char *name); +#ifndef BOBBIN +#define gp_monitor_label(A,B) do {} while (0) +#endif + /* * A new thread starts by calling a procedure, passing it a void * that * allows it to gain access to whatever data it needs. @@ -102,4 +112,9 @@ */ void gp_thread_finish(gp_thread_id thread); +void gp_thread_label(gp_thread_id thread, const char *name); +#ifndef BOBBIN +#define gp_thread_label(A,B) do {} while(0) +#endif + #endif /* !defined(gpsync_INCLUDED) */ diff -Nru ghostscript-9.10~dfsg/base/gp_sysv.c ghostscript-9.25~dfsg+1/base/gp_sysv.c --- ghostscript-9.10~dfsg/base/gp_sysv.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_sysv.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* System V Unix-specific routines for Ghostscript */ - -/* This file contains a couple of standard Unix library procedures */ -/* that a few System V platforms don't provide. */ -/* Note that this file is NOT used for SVR4 platforms. */ -#include -#include "stdio_.h" -#include "time_.h" -#include -#include -#include -#include - -/* rename */ -int -rename(const char *a, const char *b) -{ - if (access(a, 0) == -1) - return (-1); - unlink(b); - if (link(a, b) == -1) - return (-1); - if (unlink(a) == -1) { - unlink(b); /* ??? */ - return (-1); - } - return (0); -} - -/* gettimeofday */ -#ifndef HZ -# define HZ 100 /* see sys/param.h */ -#endif -int -gettimeofday(struct timeval *tvp, struct timezone *tzp) -{ - struct tms tms; - static long offset = 0; - long ticks; - - if (!offset) { - time(&offset); - offset -= (times(&tms) / HZ); - } - ticks = times(&tms); - tvp->tv_sec = ticks / HZ + offset; - tvp->tv_usec = (ticks % HZ) * (1000 * 1000 / HZ); - return 0; -} diff -Nru ghostscript-9.10~dfsg/base/gp_unifn.c ghostscript-9.25~dfsg+1/base/gp_unifn.c --- ghostscript-9.10~dfsg/base/gp_unifn.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_unifn.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,12 @@ /* Define the string to be concatenated with the file mode */ /* for opening files without end-of-line conversion. */ +#if (defined(__MINGW32__) && __MINGW32__ == 1) || (defined(__CYGWIN__) && __CYGWIN__ == 1) +const char gp_fmode_binary_suffix[] = "b"; +#else const char gp_fmode_binary_suffix[] = ""; +#endif + /* Define the file modes for binary reading or writing. */ #if (defined(__MINGW32__) && __MINGW32__ == 1) || (defined(__CYGWIN__) && __CYGWIN__ == 1) @@ -79,7 +84,7 @@ { return "."; } -bool gp_file_name_is_partent_allowed(void) +bool gp_file_name_is_parent_allowed(void) { return true; } diff -Nru ghostscript-9.10~dfsg/base/gp_unifs.c ghostscript-9.25~dfsg+1/base/gp_unifs.c --- ghostscript-9.10~dfsg/base/gp_unifs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_unifs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -77,6 +77,9 @@ const char *mode, bool b64) { /* The -8 is for XXXXXX plus a possible final / and -. */ +#ifdef GS_NO_FILESYSTEM + return NULL; +#else int prefix_length = strlen(prefix); int len = gp_file_name_sizeof - prefix_length - 8; FILE *fp; @@ -134,6 +137,7 @@ if (fp == NULL) emprintf1(mem, "**** Could not open temporary file %s\n", fname); return fp; +#endif } FILE * gp_open_scratch_file(const gs_memory_t *mem, @@ -151,6 +155,97 @@ return fopen(fname, mode); } +int gp_stat(const char *path, struct stat *buf) +{ + return stat(path, buf); +} + +int gp_can_share_fdesc(void) +{ +#if defined(HAVE_PREAD_PWRITE) && HAVE_PREAD_PWRITE == 1 + return 1; +#else + return 0; /* can't share FILE * descriptors w/o pread due to seek..read..seek */ +#endif +} + +FILE *gp_open_scratch_file_rm(const gs_memory_t *mem, + const char *prefix, + char fname[gp_file_name_sizeof], + const char *mode) +{ + FILE *f = gp_open_scratch_file_generic(mem, prefix, fname, mode, false); + /* Unlink file immediately to avoid it being left around if the program + * is killed. On this platform readers access temp files by cloning the + * FILE pointer and without accessing the file by name */ + if (f) + unlink(fname); + return f; +} + +FILE *gp_fdup(FILE *f, const char *mode) +{ +#ifdef GS_NO_FILESYSTEM + return NULL; +#else + int fd = fileno(f); + if (fd < 0) + return NULL; + fd = dup(fd); + if (fd < 0) + return NULL; + return fdopen(fd, mode); +#endif +} + +int gp_fpread(char *buf, uint count, int64_t offset, FILE *f) +{ +#ifdef GS_NO_FILESYSTEM + return 0; +#elif defined(HAVE_PREAD_PWRITE) && HAVE_PREAD_PWRITE == 1 + return pread(fileno(f), buf, count, offset); +#else + int c; + int64_t os, curroff = gp_ftell_64(f); + if (curroff < 0) return curroff; + + os = gp_fseek_64(f, offset, 0); + if (os < 0) return os; + + c = fread(buf, 1, count, f); + if (c < 0) return c; + + os = gp_fseek_64(f, curroff, 0); + if (os < 0) return os; + + return c; +#endif +} + +int gp_fpwrite(char *buf, uint count, int64_t offset, FILE *f) +{ +#ifdef GS_NO_FILESYSTEM + return 0; +#elif defined(HAVE_PREAD_PWRITE) && HAVE_PREAD_PWRITE == 1 + return pwrite(fileno(f), buf, count, offset); +#else + int c; + int64_t os, curroff = gp_ftell_64(f); + if (curroff < 0) return curroff; + + os = gp_fseek_64(f, offset, 0); + if (os < 0) return os; + + c = fwrite(buf, 1, count, f); + if (c < 0) return c; + + os = gp_fseek_64(f, curroff, 0); + if (os < 0) return os; + + return c; +#endif +} + /* Set a file into binary or text mode. */ int gp_setmode_binary(FILE * pfile, bool mode) @@ -164,6 +259,13 @@ /* the original version of the following code, and Richard Mlynarik */ /* (mly@adoc.xerox.com) for an improved version. */ +#ifdef GS_NO_FILESYSTEM +struct file_enum_s { + int dummy; +}; + +static file_enum dummy_enum; +#else typedef struct dirstack_s dirstack; struct dirstack_s { dirstack *next; @@ -240,11 +342,15 @@ gs_free_object(pfen->memory, d, "gp_enumerate_files(popdir)"); return true; } +#endif /* Initialize an enumeration. */ file_enum * gp_enumerate_files_init(const char *pat, uint patlen, gs_memory_t * mem) { +#ifdef GS_NO_FILESYSTEM + return &dummy_enum; +#else file_enum *pfen; char *p; char *work; @@ -282,14 +388,14 @@ (char *)gs_alloc_bytes(mem, patlen + 1, "gp_enumerate_files(pattern)"); if (pfen->pattern == 0) - return 0; + goto fail1; memcpy(pfen->pattern, pat, patlen); pfen->pattern[patlen] = 0; work = (char *)gs_alloc_bytes(mem, FILENAME_MAX + 1, "gp_enumerate_files(work)"); if (work == 0) - return 0; + goto fail2; pfen->work = work; p = work; @@ -300,9 +406,9 @@ /* Remove directory specifications beyond the first wild card. */ /* Some systems don't have strpbrk, so we code it open. */ p = pfen->work; - while (!(*p == '*' || *p == '?' || *p == 0)) + while (*p != '*' && *p != '?' && *p != 0) p++; - while (!(*p == '/' || *p == 0)) + while (*p != '/' && *p != 0) p++; if (*p == '/') *p = 0; @@ -323,12 +429,22 @@ } return pfen; + +fail2: + gs_free_object(mem, pfen->pattern, "gp_enumerate_files(pattern)"); +fail1: + gs_free_object(mem, pfen, "gp_enumerate_files"); + return NULL; +#endif } /* Enumerate the next file. */ uint gp_enumerate_files_next(file_enum * pfen, char *ptr, uint maxlen) { +#ifdef GS_NO_FILESYSTEM + return ~(uint)0; +#else const dir_entry *de; char *work = pfen->work; int worklen = pfen->worklen; @@ -445,13 +561,17 @@ char *p; dirstack *d; - for (p = pattern + pathead + 1;; p++) { - if (*p == 0) { /* No more subdirectories to match */ - pathead = pfen->patlen; - break; - } else if (*p == '/') { - pathead = p - pattern; - break; + if (pattern[pathead] == 0) { + pathead = pfen->patlen; + } else { + for (p = pattern + pathead + 1;; p++) { + if (*p == 0) { /* No more subdirectories to match */ + pathead = pfen->patlen; + break; + } else if (*p == '/') { + pathead = p - pattern; + break; + } } } @@ -464,7 +584,7 @@ d->entry = pfen->dirp; pfen->dstack = d; } else - DO_NOTHING; /* >>> e_VMerror!!! */ + DO_NOTHING; /* >>> gs_error_VMerror!!! */ if_debug1m('e', pfen->memory, "[e]file_enum:Dir pushed '%s'\n", work); @@ -480,12 +600,16 @@ memcpy(ptr, work, len > maxlen ? maxlen : len); return len; +#endif } /* Clean up the file enumeration. */ void gp_enumerate_files_close(file_enum * pfen) { +#ifdef GS_NO_FILESYSTEM + /* No cleanup necessary */ +#else gs_memory_t *mem = pfen->memory; if_debug0m('e', mem, "[e]file_enum:Cleanup\n"); @@ -496,6 +620,7 @@ gs_free_object(mem, (byte *) pfen->pattern, "gp_enumerate_files_close(pattern)"); gs_free_object(mem, pfen, "gp_enumerate_files_close"); +#endif } /* Test-cases: diff -Nru ghostscript-9.10~dfsg/base/gp_unix.c ghostscript-9.25~dfsg+1/base/gp_unix.c --- ghostscript-9.10~dfsg/base/gp_unix.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_unix.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -213,28 +213,38 @@ char fname[gp_file_name_sizeof], int binary_mode) { +#ifdef GS_NO_FILESYSTEM + return NULL; +#else const char *fmode = (binary_mode ? "wb" : "w"); return (strlen(fname) == 0 ? 0 : gp_fopen(fname, fmode)); +#endif } FILE * gp_open_printer_64(const gs_memory_t *mem, char fname[gp_file_name_sizeof], int binary_mode) { +#ifdef GS_NO_FILESYSTEM + return NULL; +#else const char *fmode = (binary_mode ? "wb" : "w"); return (strlen(fname) == 0 ? 0 : gp_fopen_64(fname, fmode)); +#endif } /* Close the connection to the printer. */ void gp_close_printer(const gs_memory_t *mem, FILE * pfile, const char *fname) { +#ifndef GS_NO_FILESYSTEM if (fname[0] == '|') pclose(pfile); else fclose(pfile); +#endif } /* ------ Font enumeration ------ */ @@ -438,6 +448,8 @@ if (state != NULL) { if (state->font_list != NULL) FcFontSetDestroy(state->font_list); + if (state->fc) + FcConfigDestroy(state->fc); free(state); } #endif diff -Nru ghostscript-9.10~dfsg/base/gp_unix_cache.c ghostscript-9.25~dfsg+1/base/gp_unix_cache.c --- ghostscript-9.10~dfsg/base/gp_unix_cache.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_unix_cache.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,516 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Generic POSIX persistent-cache implementation for Ghostscript */ - -#include "stdio_.h" -#include "string_.h" -#include "time_.h" -#include /* should use gs_malloc() instead */ -#include "gconfigd.h" -#include "gp.h" -#include "md5.h" - -/* ------ Persistent data cache types ------*/ - -#define GP_CACHE_VERSION 0 - -/* NOTE: This implementation is not thread safe. Currently you need to - lock around gp_cache_insert() and gp_cache_query() calls. */ - -/* cache entry type */ -typedef struct gp_cache_entry_s { - int type; - int keylen; - byte *key; - gs_md5_byte_t hash[16]; - char *filename; - int len; - void *buffer; - int dirty; - ulong last_used; /* we assume time_t fits in here */ -} gp_cache_entry; - -/* initialize a new gp_cache_entry struct */ -static void gp_cache_clear_entry(gp_cache_entry *item) -{ - item->type = -1; - item->key = NULL; - item->keylen = 0; - item->filename = NULL; - item->buffer = NULL; - item->len = 0; - item->dirty = 0; - item->last_used = 0; -} - -/* get the cache directory's path */ -static char *gp_cache_prefix(void) -{ - char *prefix = NULL; - int plen = 0; - - /* get the cache directory path */ - if (gp_getenv("GS_CACHE_DIR", (char *)NULL, &plen) < 0) { - prefix = malloc(plen); - gp_getenv("GS_CACHE_DIR", prefix, &plen); - plen--; - } else { -#ifdef GS_CACHE_DIR - prefix = strdup(GS_CACHE_DIR); -#else - prefix = strdup(".cache"); -#endif - plen = strlen(prefix); - } - - /* substitute $HOME for '~' */ - if (plen >= 1 && prefix[0] == '~') { - char *home, *path; - int hlen = 0; - unsigned int pathlen = 0; - gp_file_name_combine_result result; - - if (gp_getenv("HOME", (char *)NULL, &hlen) < 0) { - home = malloc(hlen); - if (home == NULL) return prefix; - gp_getenv("HOME", home, &hlen); - hlen--; - if (plen == 1) { - /* only "~" */ - free(prefix); - return home; - } - /* substitue for the initial '~' */ - pathlen = hlen + plen + 1; - path = malloc(pathlen); - if (path == NULL) { free(home); return prefix; } - result = gp_file_name_combine(home, hlen, prefix+2, plen-2, false, path, &pathlen); - if (result == gp_combine_success) { - free(prefix); - prefix = path; - } else { - dlprintf1("file_name_combine failed with code %d\n", result); - free(path); - } - free(home); - } - } -#ifdef DEBUG_CACHE - dlprintf1("cache dir read as '%s'\n", prefix); -#endif - return prefix; -} - -/* compute the cache index file's path */ -static char * -gp_cache_indexfilename(const char *prefix) -{ - const char *fn = "gs_cache"; - char *path; - unsigned int len; - gp_file_name_combine_result result; - - len = strlen(prefix) + strlen(fn) + 2; - path = malloc(len); - - result = gp_file_name_combine(prefix, strlen(prefix), fn, strlen(fn), true, path, &len); - if (result == gp_combine_small_buffer) { - /* handle the case when the combination requires more than one extra character */ - free(path); - path = malloc(++len); - result = gp_file_name_combine(prefix, strlen(prefix), fn, strlen(fn), true, path, &len); - } - if (result != gp_combine_success) { - dlprintf1("pcache: file_name_combine for indexfilename failed with code %d\n", result); - free(path); - return NULL; - } - return path; -} - -/* compute and set a cache key's hash */ -static void gp_cache_hash(gp_cache_entry *entry) -{ - gs_md5_state_t md5; - - /* we use md5 hashes of the key */ - gs_md5_init(&md5); - gs_md5_append(&md5, entry->key, entry->keylen); - gs_md5_finish(&md5, entry->hash); -} - -/* compute and set cache item's filename */ -static void gp_cache_filename(const char *prefix, gp_cache_entry *item) -{ - const char hexmap[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; - char *fn = malloc(gp_file_name_sizeof), *fni; - int i; - - fni = fn; - *fni++ = hexmap[item->type>>4 & 0x0F]; - *fni++ = hexmap[item->type & 0x0F]; - *fni++ = '.'; - for (i = 0; i < 16; i++) { - *fni++ = hexmap[(item->hash[i]>>4 & 0x0F)]; - *fni++ = hexmap[(item->hash[i] & 0x0F)]; - } - *fni = '\0'; - - if (item->filename) free(item->filename); - item->filename = fn; -} - -/* generate an access path for a cache item */ -static char *gp_cache_itempath(const char *prefix, gp_cache_entry *item) -{ - const char *fn = item->filename; - gp_file_name_combine_result result; - char *path; - unsigned int len; - - len = strlen(prefix) + strlen(fn) + 2; - path = malloc(len); - result = gp_file_name_combine(prefix, strlen(prefix), - fn, strlen(fn), false, path, &len); - - if (result != gp_combine_success) { - dlprintf1("pcache: file_name_combine failed on cache item filename with code %d\n", result); - } - - return path; -} - -static int gp_cache_saveitem(FILE *file, gp_cache_entry* item) -{ - unsigned char version = 0; - int ret; - -#ifdef DEBUG_CACHE - dlprintf2("pcache: saving key with version %d, data length %d\n", version, item->len); -#endif - ret = fwrite(&version, 1, 1, file); - ret = fwrite(&(item->keylen), 1, sizeof(item->keylen), file); - ret = fwrite(item->key, 1, item->keylen, file); - ret = fwrite(&(item->len), 1, sizeof(item->len), file); - ret = fwrite(item->buffer, 1, item->len, file); - item->dirty = 0; - return ret; -} - -static int gp_cache_loaditem(FILE *file, gp_cache_entry *item, gp_cache_alloc alloc, void *userdata) -{ - unsigned char version; - unsigned char *filekey; - int len, keylen; - - (void)fread(&version, 1, 1, file); - if (version != GP_CACHE_VERSION) { -#ifdef DEBUG_CACHE - dlprintf2("pcache file version mismatch (%d vs expected %d)\n", version, GP_CACHE_VERSION); -#endif - return -1; - } - (void)fread(&keylen, 1, sizeof(keylen), file); - if (keylen != item->keylen) { -#ifdef DEBUG_CACHE - dlprintf2("pcache file has correct hash but wrong key length (%d vs %d)\n", - keylen, item->keylen); -#endif - return -1; - } - filekey = malloc(keylen); - if (filekey == NULL) { - dprintf("pcache: couldn't allocate file key!\n"); - return -1; - } - (void)fread(filekey, 1, keylen, file); - if (memcmp(filekey, item->key, keylen)) { -#ifdef DEBUG_CACHE - dlprintf("pcache file has correct hash but doesn't match the full key\n"); -#endif - free(filekey); - item->buffer = NULL; - item->len = 0; - return -1; - } - free(filekey); - - (void)fread(&len, 1, sizeof(len), file); -#ifdef DEBUG_CACHE - dlprintf2("key matches file with version %d, data length %d\n", version, len); -#endif - item->buffer = alloc(userdata, len); - if (item->buffer == NULL) { - dlprintf("pcache: couldn't allocate buffer for file data!\n"); - item->len = 0; - return -1; - } - - item->len = fread(item->buffer, 1, len, file); - item->dirty = 1; - item->last_used = time(NULL); - - return 0; -} - -/* convert a two-character hex string to an integer */ -static int readhexbyte(const char *s) -{ - const char hexmap[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; - int i,r; - - for (i = 0; i < 16; i++) - if (hexmap[i] == *s) break; - if (i == 16) return -1; - r = i; - s++; - for (i = 0; i < 16; i++) - if (hexmap[i] == *s) break; - if (i == 16) return -1; - r = r<<4 | i; - return r; -} - -static int -gp_cache_read_entry(FILE *file, gp_cache_entry *item) -{ - char line[256]; - char fn[36]; - int i; - - if (!fgets(line, 256, file)) return -1; - - /* skip comments */ - if (line[0] == '#') return 1; - - /* otherwise, parse the line */ - if (sscanf(line, "%s %lu\n", fn, &item->last_used) != 2) - return -1; /* parse error */ - /* unpack the type from the filename */ - item->type = readhexbyte(fn); - /* unpack the md5 hash from the filename */ - for (i = 0; i < 16; i++) - item->hash[i] = readhexbyte(fn + 3 + 2*i); - /* remember the filename */ - if (item->filename) free(item->filename); - item->filename = malloc(strlen(fn) + 1); - strcpy(item->filename, fn); - /* null other fields */ - item->key = NULL; - item->keylen = 0; - item->len = 0; - item->buffer = NULL; - - return 0; -} - -static int -gp_cache_write_entry(FILE *file, gp_cache_entry *item) -{ - fprintf(file, "%s %lu\n", item->filename, item->last_used); - return 0; -} - -/* insert a buffer under a (type, key) pair */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) -{ - char *prefix, *path; - char *infn,*outfn; - FILE *file, *in, *out; - gp_cache_entry item, item2; - int code, hit = 0; - - /* FIXME: not re-entrant! */ - prefix = gp_cache_prefix(); - infn = gp_cache_indexfilename(prefix); - { - int len = strlen(infn) + 2; - outfn = malloc(len); - memcpy(outfn, infn, len - 2); - outfn[len-2] = '+'; - outfn[len-1] = '\0'; - } - - in = gp_fopen(infn, "r"); - if (in == NULL) { - dlprintf1("pcache: unable to open '%s'\n", infn); - free(prefix); - free(infn); - free(outfn); - return -1; - } - out = gp_fopen(outfn, "w"); - if (out == NULL) { - dlprintf1("pcache: unable to open '%s'\n", outfn); - fclose(in); - free(prefix); - free(infn); - free(outfn); - return -1; - } - - fprintf(out, "# Ghostscript persistent cache index table\n"); - - /* construct our cache item */ - gp_cache_clear_entry(&item); - item.type = type; - item.key = key; - item.keylen = keylen; - item.buffer = buffer; - item.len = buflen; - item.dirty = 1; - item.last_used = time(NULL); - gp_cache_hash(&item); - gp_cache_filename(prefix, &item); - - /* save it to disk */ - path = gp_cache_itempath(prefix, &item); - file = gp_fopen(path, "wb"); - free(path); - if (file != NULL) { - gp_cache_saveitem(file, &item); - fclose(file); - } - - /* now loop through the index to update or insert the entry */ - gp_cache_clear_entry(&item2); - while ((code = gp_cache_read_entry(in, &item2)) >= 0) { - if (code == 1) continue; - if (!memcmp(item.hash, item2.hash, 16)) { - /* replace the matching line */ - gp_cache_write_entry(out, &item); - hit = 1; - } else { - /* copy out the previous line */ - gp_cache_write_entry(out, &item2); - } - } - if (!hit) { - /* there was no matching line */ - gp_cache_write_entry(out, &item); - } - free(item.filename); - fclose(out); - fclose(in); - - /* replace the cache index with our new version */ - unlink(infn); - rename(outfn,infn); - - free(prefix); - free(infn); - free(outfn); - - return 0; -} - -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata) -{ - char *prefix, *path; - char *infn,*outfn; - FILE *file, *in, *out; - gp_cache_entry item, item2; - int code, hit = 0; - - /* FIXME: not re-entrant! */ - prefix = gp_cache_prefix(); - infn = gp_cache_indexfilename(prefix); - { - int len = strlen(infn) + 2; - outfn = malloc(len); - memcpy(outfn, infn, len - 2); - outfn[len-2] = '+'; - outfn[len-1] = '\0'; - } - - in = gp_fopen(infn, "r"); - if (in == NULL) { - dlprintf1("pcache: unable to open '%s'\n", infn); - free(prefix); - free(infn); - free(outfn); - return -1; - } - out = gp_fopen(outfn, "w"); - if (out == NULL) { - dlprintf1("pcache: unable to open '%s'\n", outfn); - fclose(in); - free(prefix); - free(infn); - free(outfn); - return -1; - } - - fprintf(out, "# Ghostscript persistent cache index table\n"); - - /* construct our query */ - gp_cache_clear_entry(&item); - item.type = type; - item.key = key; - item.keylen = keylen; - item.last_used = time(NULL); - gp_cache_hash(&item); - gp_cache_filename(prefix, &item); - - /* look for it on the disk */ - path = gp_cache_itempath(prefix, &item); - file = gp_fopen(path, "rb"); - free(path); - if (file != NULL) { - hit = gp_cache_loaditem(file, &item, alloc, userdata); - fclose(file); - } else { - hit = -1; - } - - gp_cache_clear_entry(&item2); - while ((code = gp_cache_read_entry(in, &item2)) >= 0) { - if (code == 1) continue; - if (!hit && !memcmp(item.hash, item2.hash, 16)) { - /* replace the matching line */ - gp_cache_write_entry(out, &item); - item.dirty = 0; - } else { - /* copy out the previous line */ - gp_cache_write_entry(out, &item2); - } - } - if (item.dirty) { - /* there was no matching line -- shouldn't happen */ - gp_cache_write_entry(out, &item); - } - free(item.filename); - fclose(out); - fclose(in); - - /* replace the cache index with our new version */ - unlink(infn); - rename(outfn,infn); - - free(prefix); - free(infn); - free(outfn); - - if (!hit) { - *buffer = item.buffer; - return item.len; - } else { - *buffer = NULL; - return -1; - } -} diff -Nru ghostscript-9.10~dfsg/base/gp_upapr.c ghostscript-9.25~dfsg+1/base/gp_upapr.c --- ghostscript-9.10~dfsg/base/gp_upapr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_upapr.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_vms.c ghostscript-9.25~dfsg+1/base/gp_vms.c --- ghostscript-9.10~dfsg/base/gp_vms.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_vms.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -154,23 +154,6 @@ gp_get_realtime(pdt); /* Use an approximation for now. */ } -/* ------ Persistent data cache ------*/ - -/* insert a buffer under a (type, key) pair */ -int gp_cache_insert(int type, byte *key, int keylen, void *buffer, int buflen) -{ - /* not yet implemented */ - return 0; -} - -/* look up a (type, key) in the cache */ -int gp_cache_query(int type, byte* key, int keylen, void **buffer, - gp_cache_alloc alloc, void *userdata) -{ - /* not yet implemented */ - return -1; -} - /* ------ Screen management ------ */ /* Get the environment variable that specifies the display to use. */ @@ -287,6 +270,39 @@ return fopen(fname, mode); } +int gp_stat(const char *path, struct stat *buf) +{ + return stat(path, buf); +} + +int gp_can_share_fdesc(void) +{ + return 0; +} + +FILE *gp_open_scratch_file_rm(const gs_memory_t *mem, + const char *prefix, + char fname[gp_file_name_sizeof], + const char *mode) +{ + return NULL; +} + +FILE *gp_fdup(FILE *f, const char *mode) +{ + return NULL; +} + +int gp_fpread(char *buf, uint count, int64_t offset, FILE *f) +{ + return -1; +} + +int gp_fpwrite(char *buf, uint count, int64_t offset, FILE *f) +{ + return -1; +} + /* Set a file into binary or text mode. */ int gp_setmode_binary(FILE * pfile, bool binary) @@ -530,7 +546,7 @@ { return ""; } -bool gp_file_name_is_partent_allowed(void) +bool gp_file_name_is_parent_allowed(void) { return false; } diff -Nru ghostscript-9.10~dfsg/base/gp_wgetv.c ghostscript-9.25~dfsg+1/base/gp_wgetv.c --- ghostscript-9.10~dfsg/base/gp_wgetv.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_wgetv.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,23 +9,15 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* MS Windows implementation of gp_getenv, and gp_serialnumber */ -#ifdef GS_NO_UTF8 /* We want the real sprintf, so unhide it */ -#define sprintf -#endif - #include "windows_.h" -#ifdef GS_NO_UTF8 -#undef sprintf -#endif - #include #include /* for getenv */ #include @@ -37,37 +29,6 @@ * Key = hkeyroot\\key, named value = name. * name, ptr, plen and return values are the same as in gp_getenv(); */ -#ifdef GS_NO_UTF8 -static int -gp_getenv_registry(HKEY hkeyroot, const char *key, const char *name, - char *ptr, int *plen) -{ - HKEY hkey; - DWORD cbData; - BYTE b; - LONG rc; - BYTE *bptr = (BYTE *)ptr; - - if (RegOpenKeyEx(hkeyroot, key, 0, KEY_READ, &hkey) - == ERROR_SUCCESS) { - cbData = *plen; - if (bptr == (char *)NULL) - bptr = &b; /* Registry API won't return ERROR_MORE_DATA */ - /* if ptr is NULL */ - rc = RegQueryValueEx(hkey, (char *)name, 0, NULL, bptr, &cbData); - RegCloseKey(hkey); - if (rc == ERROR_SUCCESS) { - *plen = cbData; - return 0; /* found environment variable and copied it */ - } else if (rc == ERROR_MORE_DATA) { - /* buffer wasn't large enough */ - *plen = cbData; - return -1; - } - } - return 1; /* not found */ -} -#else /* ifdef GS_NO_UTF8 */ int gp_getenv_registry(HKEY hkeyroot, const wchar_t *key, const char *name, char *ptr, int *plen) @@ -144,7 +105,6 @@ free(wname); return 1; /* environment variable does not exist */ } -#endif /* ifdef GS_NO_UTF8 */ #endif /* ifdef __WIN32__ */ /* ------ Environment variables ------ */ @@ -153,23 +113,6 @@ int gp_getenv(const char *name, char *ptr, int *plen) { -#ifdef GS_NO_UTF8 - const char *str = getenv(name); - - if (str) { - int len = strlen(str); - - if (len < *plen) { - /* string fits */ - strcpy(ptr, str); - *plen = len + 1; - return 0; - } - /* string doesn't fit */ - *plen = len + 1; - return -1; - } -#else wchar_t *wname; wchar_t *str; @@ -196,7 +139,6 @@ *plen = len; return -1; } -#endif /* environment variable was not found */ #if defined(__WIN32__) && !defined(METRO) @@ -215,21 +157,12 @@ && ((HIWORD(version) & 0x4000) == 0))) { /* not Win32s */ int code; -#ifdef GS_NO_UTF8 - char key[256]; - char dotversion[16]; - - sprintf(dotversion, "%d.%02d", (int)(gs_revision / 100), - (int)(gs_revision % 100)); - sprintf(key, "Software\\%s\\%s", gs_productfamily, dotversion); -#else wchar_t key[256]; wchar_t dotversion[16]; wsprintfW(dotversion, L"%d.%02d", (int)(gs_revision / 100), (int)(gs_revision % 100)); wsprintfW(key, L"Software\\%hs\\%s", gs_productfamily, dotversion); -#endif code = gp_getenv_registry(HKEY_CURRENT_USER, key, name, ptr, plen); if ( code <= 0 ) return code; /* found it */ @@ -259,15 +192,9 @@ byte buf[SERIALNUMBER_BUFSIZE]; int buflen = SERIALNUMBER_BUFSIZE; int code, i; -#ifdef GS_NO_UTF8 - char key[256]; - - sprintf(key, "Software\\Microsoft\\MSLicensing\\HardwareID"); -#else /* GS_NO_UTF8 */ wchar_t key[256]; wsprintfW(key, L"Software\\Microsoft\\MSLicensing\\HardwareID"); -#endif /* GS_NO_UTF8 */ code = gp_getenv_registry(HKEY_LOCAL_MACHINE, key, "ClientHWID", (char *)buf, &buflen); if ( code != 0 ) return (int)(gs_serialnumber); /* error - just return the default */ diff -Nru ghostscript-9.10~dfsg/base/gp_win32.c ghostscript-9.25~dfsg+1/base/gp_win32.c --- ghostscript-9.10~dfsg/base/gp_win32.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_win32.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,13 +9,14 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Common platform-specific routines for MS-Windows WIN32 */ /* originally hacked from gp_msdos.c by Russell Lang */ +#include "windows_.h" #include "malloc_.h" #include "stdio_.h" #include "string_.h" /* for strerror */ @@ -23,7 +24,6 @@ #include "gsmemory.h" /* for gp.h */ #include "gserrors.h" #include "gp.h" -#include "windows_.h" /* ------ Miscellaneous ------ */ @@ -70,7 +70,24 @@ void gp_get_usertime(long *pdt) { - gp_get_realtime(pdt); /* Use an approximation for now. */ + + LARGE_INTEGER freq; + LARGE_INTEGER count; + LARGE_INTEGER seconds; + + if (!QueryPerformanceFrequency(&freq)) { + gp_get_realtime(pdt); /* use previous method if high-res perf counter not available */ + return; + } + /* Get the high resolution time as seconds and nanoseconds */ + QueryPerformanceCounter(&count); + + seconds.QuadPart = (count.QuadPart / freq.QuadPart); + pdt[0] = seconds.LowPart; + count.QuadPart -= freq.QuadPart * seconds.QuadPart; + count.QuadPart *= 1000000000; /* we want nanoseconds */ + count.QuadPart /= freq.QuadPart; + pdt[1] = count.LowPart; } /* ------ Console management ------ */ @@ -162,4 +179,4 @@ return unicode[0]; } -#endif /* __WIN32__ */ \ No newline at end of file +#endif /* __WIN32__ */ diff -Nru ghostscript-9.10~dfsg/base/gp_wpapr.c ghostscript-9.25~dfsg+1/base/gp_wpapr.c --- ghostscript-9.10~dfsg/base/gp_wpapr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_wpapr.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gp_wsync.c ghostscript-9.25~dfsg+1/base/gp_wsync.c --- ghostscript-9.10~dfsg/base/gp_wsync.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_wsync.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,17 +9,17 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* MS Windows (Win32) thread / semaphore / monitor implementation */ /* original multi-threading code by John Desrosiers */ +#include "windows_.h" #include "malloc_.h" #include "gserrors.h" #include "gpsync.h" -#include "windows_.h" #include /* It seems that both Borland and Watcom *should* be able to cope with the @@ -215,7 +215,7 @@ (gp_thread_creation_closure *)malloc(sizeof(*closure)); if (!closure) - return gs_error_VMerror; + return_error(gs_error_VMerror); closure->function = function; closure->data = data; @@ -265,7 +265,7 @@ (gp_thread_creation_closure *)malloc(sizeof(*closure)); if (!closure) - return gs_error_VMerror; + return_error(gs_error_VMerror); closure->function = function; closure->data = data; hThread = (HANDLE)_beginthreadex(NULL, 0, &gp_thread_start_wrapper, diff -Nru ghostscript-9.10~dfsg/base/gp_wutf8.c ghostscript-9.25~dfsg+1/base/gp_wutf8.c --- ghostscript-9.10~dfsg/base/gp_wutf8.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_wutf8.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,13 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ #include "windows_.h" -#ifndef GS_NO_UTF8 int utf8_to_wchar(wchar_t *out, const char *in) { unsigned int i; @@ -59,10 +58,10 @@ len++; } else if ((i & 0xE0) == 0xC0) { in++; - len += 2; + len++; } else if ((i & 0xF0) == 0xE0) { in+=2; - len += 3; + len++; } else { return -1; } @@ -106,4 +105,3 @@ } return len; } -#endif diff -Nru ghostscript-9.10~dfsg/base/gp_wxpsprn.cpp ghostscript-9.25~dfsg+1/base/gp_wxpsprn.cpp --- ghostscript-9.10~dfsg/base/gp_wxpsprn.cpp 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gp_wxpsprn.cpp 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,287 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#include +#include +#include +#include +#include + +#include "string_.h" +#include "gx.h" +#include "gserrors.h" + +#undef eprintf1 +#define eprintf1(str, arg) {} +#undef eprintf +#define eprintf(str) {} +#undef gs_note_error +#define gs_note_error(error) return(error) + +typedef HRESULT (CALLBACK* StartXpsPrintJobType)( + /* [string][in] */ __RPC__in_string LPCWSTR printerName, + /* [string][in] */ __RPC__in_string LPCWSTR jobName, + /* [string][in] */ __RPC__in_string LPCWSTR outputFileName, + /* [in] */ __RPC__in HANDLE progressEvent, + /* [in] */ __RPC__in HANDLE completionEvent, + /* [size_is][in] */ __RPC__in_ecount_full(printablePagesOnCount) UINT8 *printablePagesOn, + /* [in] */ UINT32 printablePagesOnCount, + /* [out] */ __RPC__deref_out_opt IXpsPrintJob **xpsPrintJob, + /* [out] */ __RPC__deref_out_opt IXpsPrintJobStream **documentStream, + /* [out] */ __RPC__deref_out_opt IXpsPrintJobStream **printTicketStream +); + +extern "C" int gp_xpsprint(char *filename, char *printername, int *result) +{ + HRESULT hr = S_OK; + HANDLE completionEvent = NULL; + IXpsPrintJob* job = NULL; + IXpsPrintJobStream* jobStream = NULL; + IXpsOMObjectFactory* xpsFactory = NULL; + IOpcPartUri* partUri = NULL; + IXpsOMPackage* package = NULL; + IXpsOMPackageWriter* packageWriter = NULL; + IXpsOMPage* xpsPage = NULL; + IXpsOMFontResource* fontResource = NULL; + XPS_JOB_STATUS jobStatus = {}; + HPTPROVIDER pProvider; + HGLOBAL hGlobal = NULL; + IStream *pCapabilities; + BSTR *pbstrErrorMessage = NULL; + int code = 0; + StartXpsPrintJobType StartXpsPrintJobPtr = NULL; + + HINSTANCE dllHandle = NULL; + + /* + Loading the DLL at run-time makes life easier with the build + system (no need to link in the ".lib" file), and allows us to + use the same executable on old Windows systems (XP and earlier) + without XpsPrint.dll, and those with it (Vista and later). + */ + if (!(dllHandle = LoadLibrary(TEXT("XpsPrint.dll")))) + { + *result = 0x80029C4A; + return -15; + } + + StartXpsPrintJobPtr = (StartXpsPrintJobType)GetProcAddress(dllHandle, "StartXpsPrintJob"); + if (!StartXpsPrintJobPtr) + { + *result = 0x80029C4A; + return -16; + } + + if (FAILED(hr = CoInitializeEx(0, COINIT_MULTITHREADED))) + { + *result = hr; + code = -1; + } + + if (SUCCEEDED(hr)) + { + completionEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!completionEvent) + { + *result = hr; + code = -2; + } + } + + /* Need code for PrintTIcket here */ + + if (SUCCEEDED(hr)) + { + WCHAR MBStr[64]; + + code = MultiByteToWideChar(CP_ACP, 0, printername, -1, MBStr, 64); + if (code != 0) { + if (FAILED(hr = StartXpsPrintJobPtr( + (LPCWSTR)MBStr, + NULL, + NULL, + NULL, + completionEvent, + NULL, + 0, + &job, + &jobStream, + NULL + ))) + { + *result = hr; + code = -4; + } + } else { + *result = 0; + code = -3; + hr = -1; + } + } + + if (SUCCEEDED(hr)) + { + if (FAILED(hr = CoCreateInstance( + __uuidof(XpsOMObjectFactory), + NULL, + CLSCTX_INPROC_SERVER, + __uuidof(IXpsOMObjectFactory), + reinterpret_cast(&xpsFactory) + ) + ) + ) + { + *result = hr; + code = -5; + } + } + + if (SUCCEEDED(hr)) + { + WCHAR MBStr[MAX_PATH]; + + code = MultiByteToWideChar(CP_ACP, 0, filename, -1, MBStr, MAX_PATH); + if (code != 0) { + if (FAILED(hr = xpsFactory->CreatePackageFromFile((LPCWSTR)MBStr, false, &package))){ + *result = hr; + code = -7; + } + } else { + hr = -1; + *result = 0; + code = -6; + } + } + if (SUCCEEDED(hr)) + { + if (FAILED(hr = package->WriteToStream(jobStream, FALSE))) { + *result = hr; + code = -8; + } + } + + if (SUCCEEDED(hr)) + { + if (FAILED(hr = jobStream->Close())) + { + *result = hr; + code = -9; + } + } + else + { + // Only cancel the job if we succeeded in creating one in the first place. + if (job) + { + // Tell the XPS Print API that we're giving up. Don't overwrite hr with the return from + // this function. + job->Cancel(); + } + } + + + if (SUCCEEDED(hr)) + { + if (WaitForSingleObject(completionEvent, INFINITE) != WAIT_OBJECT_0) + { + *result = hr = HRESULT_FROM_WIN32(GetLastError()); + code = -10; + } + } + + if (SUCCEEDED(hr)) + { + if (FAILED(hr = job->GetJobStatus(&jobStatus))) + { + *result = hr; + code = -11; + } + } + + if (SUCCEEDED(hr)) + { + switch (jobStatus.completion) + { + case XPS_JOB_COMPLETED: + break; + case XPS_JOB_CANCELLED: + hr = E_FAIL; + code = -12; + break; + case XPS_JOB_FAILED: + hr = E_FAIL; + *result = jobStatus.jobStatus; + code = -13; + break; + default: + hr = E_UNEXPECTED; + code = -14; + break; + } + } + + if (fontResource) + { + fontResource->Release(); + fontResource = NULL; + } + + if (xpsPage) + { + xpsPage->Release(); + xpsPage = NULL; + } + + if (packageWriter) + { + packageWriter->Release(); + packageWriter = NULL; + } + + if (partUri) + { + partUri->Release(); + partUri = NULL; + } + + if (xpsFactory) + { + xpsFactory->Release(); + xpsFactory = NULL; + } + + if (jobStream) + { + jobStream->Release(); + jobStream = NULL; + } + + if (job) + { + job->Release(); + job = NULL; + } + + if (completionEvent) + { + CloseHandle(completionEvent); + completionEvent = NULL; + } + + (void)FreeLibrary(dllHandle); + CoUninitialize(); + + return code; +} diff -Nru ghostscript-9.10~dfsg/base/gsalloc.c ghostscript-9.25~dfsg+1/base/gsalloc.c --- ghostscript-9.10~dfsg/base/gsalloc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsalloc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -40,12 +40,12 @@ /* - * Define whether to try consolidating space before adding a new chunk. + * Define whether to try consolidating space before adding a new clump. * The default is not to do this, because it is computationally * expensive and doesn't seem to help much. However, this is done for * "controlled" spaces whether or not the #define is in effect. */ -/*#define CONSOLIDATE_BEFORE_ADDING_CHUNK */ +/*#define CONSOLIDATE_BEFORE_ADDING_CLUMP */ /* * This allocator produces tracing messages of the form @@ -56,7 +56,7 @@ * O is {alloc = +, free = -, grow = >, shrink = <}, * T is {bytes = b, object = <, ref = $, string = >}, and * S is {small freelist = f, large freelist = F, LIFO = space, - * own chunk = L, lost = #, lost own chunk = ~, other = .}. + * own clump = L, lost = #, lost own clump = ~, other = .}. */ #ifdef DEBUG static int @@ -129,11 +129,11 @@ static obj_header_t *scavenge_low_free(gs_ref_memory_t *mem, unsigned request_size); static ulong compute_free_objects(gs_ref_memory_t *); static obj_header_t *alloc_obj(gs_ref_memory_t *, ulong, gs_memory_type_ptr_t, alloc_flags_t, client_name_t); -static void consolidate_chunk_free(chunk_t *cp, gs_ref_memory_t *mem); -static void trim_obj(gs_ref_memory_t *mem, obj_header_t *obj, uint size, chunk_t *cp); -static chunk_t *alloc_acquire_chunk(gs_ref_memory_t *, ulong, bool, client_name_t); -static chunk_t *alloc_add_chunk(gs_ref_memory_t *, ulong, client_name_t); -void alloc_close_chunk(gs_ref_memory_t *); +static void consolidate_clump_free(clump_t *cp, gs_ref_memory_t *mem); +static void trim_obj(gs_ref_memory_t *mem, obj_header_t *obj, uint size, clump_t *cp); +static clump_t *alloc_acquire_clump(gs_ref_memory_t *, ulong, bool, client_name_t); +static clump_t *alloc_add_clump(gs_ref_memory_t *, ulong, client_name_t); +void alloc_close_clump(gs_ref_memory_t *); /* * Define the standard implementation (with garbage collection) @@ -165,6 +165,8 @@ static gs_memory_proc_register_root(i_register_root); static gs_memory_proc_unregister_root(i_unregister_root); static gs_memory_proc_enable_free(i_enable_free); +static gs_memory_proc_set_object_type(i_set_object_type); +static gs_memory_proc_defer_frees(i_defer_frees); /* We export the procedures for subclasses. */ const gs_memory_procs_t gs_ref_memory_procs = @@ -193,19 +195,572 @@ i_free_string, i_register_root, i_unregister_root, - i_enable_free + i_enable_free, + i_set_object_type, + i_defer_frees }; /* + * Previous versions of this code used a simple linked list of + * clumps. We change here to use a splay tree of clumps. + * Splay Trees can be found documented in "Algorithms and Data + * Structures" by Jeffrey H Kingston. + * + * Essentially they are binary trees, ordered by address of the + * 'cbase' pointer. The 'cunning' feature with them is that + * when a node in the tree is accessed, we do a 'move to root' + * operation. This involves performing various 'rotations' as + * we move up the tree, the net effect of which tends to + * lead to more balanced trees (see Kingston for analysis). + * It also leads to better locality of reference in that + * recently accessed nodes stay near the root. + */ + +/* #define DEBUG_CLUMPS */ +#ifdef DEBUG_CLUMPS +#define SANITY_CHECK(cp) sanity_check(cp) +#define SANITY_CHECK_MID(cp) sanity_check_mid(cp) + +static void +broken_splay() +{ + dlprintf("Broken splay tree!\n"); +} + +void sanity_check_rec(clump_t *cp) +{ + splay_dir_t from = SPLAY_FROM_ABOVE; + + while (cp) + { + if (from == SPLAY_FROM_ABOVE) + { + /* We have arrived from above. Step left. */ + if (cp->left) + { + if (cp->left->cbase > cp->cbase || cp->left->parent != cp) + broken_splay(); + cp = cp->left; + from = SPLAY_FROM_ABOVE; + continue; + } + /* No left to step to, so imagine we have just arrived from there */ + from = SPLAY_FROM_LEFT; + } + if (from == SPLAY_FROM_LEFT) + { + /* We have arrived from the left. Step right. */ + if (cp->right) + { + if (cp->right->cbase < cp->cbase || cp->right->parent != cp) + broken_splay(); + cp = cp->right; + from = SPLAY_FROM_ABOVE; + continue; + } + /* No right to step to, so imagine we have just arrived from there. */ + from = SPLAY_FROM_RIGHT; + } + if (from == SPLAY_FROM_RIGHT) + { + /* We have arrived from the right. Step up. */ + if (cp->parent == NULL) + break; + if (cp->parent->left != cp && cp->parent->right != cp) + broken_splay(); + from = (cp->parent->left == cp ? SPLAY_FROM_LEFT : SPLAY_FROM_RIGHT); + cp = cp->parent; + } + } +} + +void sanity_check(clump_t *cp) +{ + sanity_check_rec(cp); +} + +void sanity_check_mid(clump_t *cp) +{ + clump_t *parent; + + while ((parent = cp->parent) != NULL) + { + if (parent->left == cp) + { + if (parent->right == cp) + broken_splay(); + } + else if (parent->right != cp) + broken_splay(); + cp = parent; + } + + sanity_check_rec(cp); +} + +#else +#define SANITY_CHECK(cp) while (0) {} +#define SANITY_CHECK_MID(cp) while (0) {} +#endif + +/* When initing with the root, we want to pass the smallest inorder one + * back immediately, and set it up so that we step right for the next + * one. */ +clump_t * +clump_splay_walk_init(clump_splay_walker *sw, const gs_ref_memory_t *mem) +{ + clump_t *cp = mem->root; + + if (cp) + { + SANITY_CHECK(cp); + + sw->from = SPLAY_FROM_LEFT; + while (cp->left) + { + cp = cp->left; + } + } + sw->cp = cp; + sw->end = NULL; + return cp; +} + +clump_t * +clump_splay_walk_bwd_init(clump_splay_walker *sw, const gs_ref_memory_t *mem) +{ + clump_t *cp = mem->root; + + if (cp) + { + SANITY_CHECK(cp); + + sw->from = SPLAY_FROM_RIGHT; + while (cp->right) + { + cp = cp->right; + } + } + sw->cp = cp; + sw->end = NULL; + return cp; +} + +/* When initing 'mid walk' (i.e. with a non-root node), we want to + * return the node we are given as the first one, and continue + * onwards in an in order fashion. + */ +clump_t * +clump_splay_walk_init_mid(clump_splay_walker *sw, clump_t *cp) +{ + sw->from = SPLAY_FROM_LEFT; + sw->cp = cp; + sw->end = cp; + if (cp) + { + SANITY_CHECK_MID(cp); + } + return cp; +} + +clump_t * +clump_splay_walk_fwd(clump_splay_walker *sw) +{ + clump_t *cp = sw->cp; + int from = sw->from; + + if (cp == NULL) + return NULL; + + /* We step through the tree, and stop when we arrive + * at sw->end in an in order manner (i.e. by moving from + * the left). */ + while (1) + { + if (from == SPLAY_FROM_ABOVE) + { + /* We have arrived from above. Step left. */ + if (cp->left) + { + cp = cp->left; + from = SPLAY_FROM_ABOVE; + continue; + } + /* No left to step to, so imagine we have just arrived from there */ + from = SPLAY_FROM_LEFT; + /* Have we reached the stopping point? */ + if (cp == sw->end) + cp = NULL; + /* We want to stop here, for inorder operation. So break out of the loop. */ + break; + } + if (from == SPLAY_FROM_LEFT) + { + /* We have arrived from the left. Step right. */ + if (cp->right) + { + cp = cp->right; + from = SPLAY_FROM_ABOVE; + continue; + } + /* No right to step to, so imagine we have just arrived from there. */ + from = SPLAY_FROM_RIGHT; + } + if (from == SPLAY_FROM_RIGHT) + { + /* We have arrived from the right. Step up. */ + clump_t *old = cp; + cp = cp->parent; + if (cp == NULL) + { + /* We've reached the root of the tree. Is this our stopping point? */ + if (sw->end == NULL) + break; + /* If not, step on. */ + cp = old; + from = SPLAY_FROM_ABOVE; + } + else + { + from = (cp->left == old ? SPLAY_FROM_LEFT : SPLAY_FROM_RIGHT); + if (from == SPLAY_FROM_LEFT) + { + /* Have we reached the stopping point? */ + if (cp == sw->end) + cp = NULL; + break; + } + } + } + } + sw->cp = cp; + sw->from = from; + return cp; +} + +clump_t * +clump_splay_walk_bwd(clump_splay_walker *sw) +{ + clump_t *cp = sw->cp; + int from = sw->from; + + if (cp == NULL) + return NULL; + + /* We step backwards through the tree, and stop when we arrive + * at sw->end in a reverse in order manner (i.e. by moving from + * the right). */ + while (1) + { + if (from == SPLAY_FROM_ABOVE) + { + /* We have arrived from above. Step right. */ + if (cp->right) + { + cp = cp->right; + from = SPLAY_FROM_ABOVE; + continue; + } + /* No right to step to, so imagine we have just arrived from there. */ + from = SPLAY_FROM_RIGHT; + /* Have we reached our end? */ + if (cp == sw->end) + cp = NULL; + /* Stop to run inorder operation */ + break; + } + if (from == SPLAY_FROM_RIGHT) + { + /* We have arrived from the right. Step left. */ + if (cp->left) + { + cp = cp->left; + from = SPLAY_FROM_ABOVE; + continue; + } + /* No left to step to, so imagine we have just arrived from there. */ + from = SPLAY_FROM_LEFT; + } + if (from == SPLAY_FROM_LEFT) + { + /* We have arrived from the left. Step up. */ + clump_t *old = cp; + cp = cp->parent; + from = (cp == NULL || cp->left != old ? SPLAY_FROM_RIGHT : SPLAY_FROM_LEFT); + if (from == SPLAY_FROM_RIGHT) + { + if (cp == sw->end) + cp = NULL; + break; + } + } + } + sw->cp = cp; + sw->from = from; + return cp; +} + +static clump_t * +clump_splay_remove(clump_t *cp, gs_ref_memory_t *imem) +{ + clump_t *replacement; + + if (cp->left == NULL) + { + /* At most one child - easy */ + replacement = cp->right; + } + else if (cp->right == NULL) + { + /* Strictly one child - easy */ + replacement = cp->left; + } + else + { + /* 2 Children - tricky */ + /* Find in-order predecessor to f */ + replacement = cp->left; + while (replacement->right) + replacement = replacement->right; + /* Remove replacement - easy as just one child */ + (void)clump_splay_remove(replacement, imem); + /* Replace cp with replacement */ + if (cp->left) + cp->left->parent = replacement; + cp->right->parent = replacement; + replacement->left = cp->left; + replacement->right = cp->right; + } + if (cp->parent) + { + if (cp->parent->left == cp) + cp->parent->left = replacement; + else + cp->parent->right = replacement; + } + else + imem->root = replacement; + if (replacement) + replacement->parent = cp->parent; + return replacement; +} + +/* Here we apply a function to all the nodes in a tree in + * depth first order. This means that the given function + * can safely alter: 1) the clump, 2) it's children, + * 3) it's parents child pointer that points to it + * without fear of corruption. Specifically this means + * that the function can free (and unlink) the node + * if it wants. + */ +clump_t * +clump_splay_app(clump_t *root, gs_ref_memory_t *imem, splay_app_result_t (*fn)(clump_t *, void *), void *arg) +{ + clump_t *step_to; + clump_t *cp = root; + int from = SPLAY_FROM_ABOVE; + splay_app_result_t res; + + SANITY_CHECK(cp); + + while (cp) + { + if (from == SPLAY_FROM_ABOVE) + { + /* We have arrived from above. Step left. */ + step_to = cp->left; + if (step_to) + { + from = SPLAY_FROM_ABOVE; + cp = step_to; + } + else + { + /* No left to step to, so imagine we have just arrived from the left */ + from = SPLAY_FROM_LEFT; + } + } + if (from == SPLAY_FROM_LEFT) + { + /* We have arrived from the left. Step right. */ + step_to = cp->right; + if (step_to) + { + from = SPLAY_FROM_ABOVE; + cp = step_to; + } + else + { + /* No right to step to, so imagine we have just arrived from the right. */ + from = SPLAY_FROM_RIGHT; + } + } + if (from == SPLAY_FROM_RIGHT) + { + /* We have arrived from the right. Step up. */ + step_to = cp->parent; + if (step_to) + { + from = (step_to->left == cp ? SPLAY_FROM_LEFT : SPLAY_FROM_RIGHT); + } + res = fn(cp, arg); + if (res & SPLAY_APP_STOP) + return cp; + cp = step_to; + } + } + return cp; +} + +/* Move the given node to the root of the tree, by + * performing a series of the following rotations. + * The key observation here is that all these + * rotations preserve the ordering of the tree, and + * result in 'x' getting higher. + * + * Case 1: z x Case 1b: z x + * # # # # # # # # + * y D A y A y y D + * # # => # # # # => # # + * x C B z B x z C + * # # # # # # # # + * A B C D C D A B + * + * Case 2: z x Case 2b: z x + * # # ## ## # # ## ## + * y D y z A y z y + * # # => # # # # # # => # # # # + * A x A B C D x D A B C D + * # # # # + * B C B C + * + * Case 3: y x Case 3b: y x + * # # # # # # # # + * x C => A y A x => y C + * # # # # # # # # + * A B B C B C A B + */ +static void +splay_move_to_root(clump_t *x, gs_ref_memory_t *mem) +{ + clump_t *y, *z; + + if (x == NULL) + return; + + while ((y = x->parent) != NULL) { + if ((z = y->parent) != NULL) { + x->parent = z->parent; + if (x->parent) { + if (x->parent->left == z) + x->parent->left = x; + else + x->parent->right = x; + } + y->parent = x; + /* Case 1, 1b, 2 or 2b */ + if (y->left == x) { + /* Case 1 or 2b */ + if (z->left == y) { + /* Case 1 */ + y->left = x->right; + if (y->left) + y->left->parent = y; + z->left = y->right; + if (z->left) + z->left->parent = z; + y->right = z; + z->parent = y; + } else { + /* Case 2b */ + z->right = x->left; + if (z->right) + z->right->parent = z; + y->left = x->right; + if (y->left) + y->left->parent = y; + x->left = z; + z->parent = x; + } + x->right = y; + } else { + /* Case 2 or 1b */ + if (z->left == y) { + /* Case 2 */ + y->right = x->left; + if (y->right) + y->right->parent = y; + z->left = x->right; + if (z->left) + z->left->parent = z; + x->right = z; + z->parent = x; + } else { + /* Case 1b */ + z->right = y->left; + if (z->right) + z->right->parent = z; + y->right = x->left; + if (y->right) + y->right->parent = y; + y->left = z; + z->parent = y; + } + x->left = y; + } + } else { + /* Case 3 or 3b */ + x->parent = NULL; + y->parent = x; + if (y->left == x) { + /* Case 3 */ + y->left = x->right; + if (y->left) + y->left->parent = y; + x->right = y; + } else { + /* Case 3b */ + y->right = x->left; + if (y->right) + y->right->parent = y; + x->left = y; + } + } + } + mem->root = x; +} + +static void +splay_insert(clump_t *cp, gs_ref_memory_t *mem) +{ + clump_t *node = NULL; + clump_t **root = &mem->root; + + while (*root) { + node = *root; + if (PTR_LT(cp->cbase, node->cbase)) { + root = &node->left; + } else { + root = &node->right; + } + } + *root = cp; + cp->left = NULL; + cp->right = NULL; + cp->parent = node; + splay_move_to_root(cp, mem); +} + +/* * Allocate and mostly initialize the state of an allocator (system, global, * or local). Does not initialize global or space. */ static void *ialloc_solo(gs_memory_t *, gs_memory_type_ptr_t, - chunk_t **); + clump_t **); gs_ref_memory_t * -ialloc_alloc_state(gs_memory_t * parent, uint chunk_size) +ialloc_alloc_state(gs_memory_t * parent, uint clump_size) { - chunk_t *cp; + clump_t *cp; gs_ref_memory_t *iimem = ialloc_solo(parent, &st_ref_memory, &cp); if (iimem == 0) @@ -215,16 +770,15 @@ iimem->gs_lib_ctx = parent->gs_lib_ctx; iimem->non_gc_memory = parent; iimem->thread_safe_memory = parent->thread_safe_memory; - iimem->chunk_size = chunk_size; -#ifdef MEMENTO + iimem->clump_size = clump_size; +#if defined(MEMENTO) || defined(SINGLE_OBJECT_MEMORY_BLOCKS_ONLY) iimem->large_size = 1; #else - iimem->large_size = ((chunk_size / 4) & -obj_align_mod) + 1; + iimem->large_size = ((clump_size / 4) & -obj_align_mod) + 1; #endif iimem->is_controlled = false; - iimem->gc_status.vm_threshold = chunk_size * 3L; - iimem->gc_status.max_vm = 0x7fffffff; - iimem->gc_status.psignal = NULL; + iimem->gc_status.vm_threshold = clump_size * 3L; + iimem->gc_status.max_vm = max_long; iimem->gc_status.signal_value = 0; iimem->gc_status.enabled = false; iimem->gc_status.requested = 0; @@ -232,10 +786,9 @@ iimem->previous_status.allocated = 0; iimem->previous_status.used = 0; ialloc_reset(iimem); - iimem->cfirst = iimem->clast = cp; + iimem->root = cp; ialloc_set_limit(iimem); - iimem->cc.cbot = iimem->cc.ctop = 0; - iimem->pcc = 0; + iimem->cc = NULL; iimem->save_level = 0; iimem->new_mask = 0; iimem->test_mask = ~0; @@ -247,33 +800,34 @@ return iimem; } -/* Allocate a 'solo' object with its own chunk. */ +/* Allocate a 'solo' object with its own clump. */ static void * ialloc_solo(gs_memory_t * parent, gs_memory_type_ptr_t pstype, - chunk_t ** pcp) + clump_t ** pcp) { /* * We can't assume that the parent uses the same object header * that we do, but the GC requires that allocators have * such a header. Therefore, we prepend one explicitly. */ - chunk_t *cp = - gs_raw_alloc_struct_immovable(parent, &st_chunk, - "ialloc_solo(chunk)"); + clump_t *cp = + gs_raw_alloc_struct_immovable(parent, &st_clump, + "ialloc_solo(clump)"); uint csize = - ROUND_UP(sizeof(chunk_head_t) + sizeof(obj_header_t) + + ROUND_UP(sizeof(clump_head_t) + sizeof(obj_header_t) + pstype->ssize, obj_align_mod); byte *cdata = gs_alloc_bytes_immovable(parent, csize, "ialloc_solo"); - obj_header_t *obj = (obj_header_t *) (cdata + sizeof(chunk_head_t)); + obj_header_t *obj = (obj_header_t *) (cdata + sizeof(clump_head_t)); if (cp == 0 || cdata == 0) { gs_free_object(parent, cp, "ialloc_solo(allocation failure)"); gs_free_object(parent, cdata, "ialloc_solo(allocation failure)"); return 0; } - alloc_init_chunk(cp, cdata, cdata + csize, false, (chunk_t *) NULL); + alloc_init_clump(cp, cdata, cdata + csize, false, (clump_t *) NULL); cp->cbot = cp->ctop; - cp->cprev = cp->cnext = 0; + cp->parent = cp->left = cp->right = 0; + cp->c_alone = true; /* Construct the object header "by hand". */ obj->o_pad = 0; obj->o_alone = 1; @@ -286,11 +840,11 @@ void ialloc_free_state(gs_ref_memory_t *iimem) { - chunk_t *cp; + clump_t *cp; gs_memory_t *mem; if (iimem == NULL) return; - cp = iimem->cfirst; + cp = iimem->root; mem = iimem->non_gc_memory; if (cp == NULL) return; @@ -299,28 +853,28 @@ } /* - * Add a chunk to an externally controlled allocator. Such allocators + * Add a clump to an externally controlled allocator. Such allocators * allocate all objects as immovable, are not garbage-collected, and * don't attempt to acquire additional memory on their own. */ int -ialloc_add_chunk(gs_ref_memory_t *imem, ulong space, client_name_t cname) +ialloc_add_clump(gs_ref_memory_t *imem, ulong space, client_name_t cname) { - chunk_t *cp; + clump_t *cp; - /* Allow acquisition of this chunk. */ + /* Allow acquisition of this clump. */ imem->is_controlled = false; - imem->large_size = imem->chunk_size; + imem->large_size = imem->clump_size; imem->limit = max_long; imem->gc_status.max_vm = max_long; - /* Acquire the chunk. */ - cp = alloc_add_chunk(imem, space, cname); + /* Acquire the clump. */ + cp = alloc_add_clump(imem, space, cname); /* * Make all allocations immovable. Since the "movable" allocators - * allocate within existing chunks, whereas the "immovable" ones - * allocate in new chunks, we equate the latter to the former, even + * allocate within existing clumps, whereas the "immovable" ones + * allocate in new clumps, we equate the latter to the former, even * though this seems backwards. */ imem->procs.alloc_bytes_immovable = imem->procs.alloc_bytes; @@ -329,7 +883,7 @@ imem->procs.alloc_struct_array_immovable = imem->procs.alloc_struct_array; imem->procs.alloc_string_immovable = imem->procs.alloc_string; - /* Disable acquisition of additional chunks. */ + /* Disable acquisition of additional clumps. */ imem->is_controlled = true; imem->limit = 0; @@ -356,11 +910,8 @@ void ialloc_reset(gs_ref_memory_t * mem) { - mem->cfirst = 0; - mem->clast = 0; - mem->cc.rcur = 0; - mem->cc.rtop = 0; - mem->cc.has_refs = false; + mem->root = 0; + mem->cc = NULL; mem->allocated = 0; mem->changes = 0; mem->scan_limit = 0; @@ -420,14 +971,46 @@ } else mem->limit = min(max_allocated, mem->gc_allocated + FORCE_GC_LIMIT); if_debug7m('0', (const gs_memory_t *)mem, - "[0]space=%d, max_vm=%ld, prev.alloc=%ld, enabled=%d,\n" - " gc_alloc=%ld, threshold=%ld => limit=%ld\n", + "[0]space=%d, max_vm=%ld, prev.alloc=%ld, enabled=%d, " + "gc_alloc=%ld, threshold=%ld => limit=%ld\n", mem->space, (long)mem->gc_status.max_vm, (long)mem->previous_status.allocated, mem->gc_status.enabled, (long)mem->gc_allocated, (long)mem->gc_status.vm_threshold, (long)mem->limit); } +struct free_data +{ + gs_ref_memory_t *imem; + clump_t *allocator; +}; + +static splay_app_result_t +free_all_not_allocator(clump_t *cp, void *arg) +{ + struct free_data *fd = (struct free_data *)arg; + + if (cp->cbase + sizeof(obj_header_t) != (byte *)fd->imem) + alloc_free_clump(cp, fd->imem); + else + fd->allocator = cp; + + return SPLAY_APP_CONTINUE; +} + +static splay_app_result_t +free_all_allocator(clump_t *cp, void *arg) +{ + struct free_data *fd = (struct free_data *)arg; + + if (cp->cbase + sizeof(obj_header_t) != (byte *)fd->imem) + return SPLAY_APP_CONTINUE; + + fd->allocator = cp; + alloc_free_clump(cp, fd->imem); + return SPLAY_APP_STOP; +} + /* * Free all the memory owned by the allocator, except the allocator itself. * Note that this only frees memory at the current save level: the client @@ -436,29 +1019,24 @@ static void i_free_all(gs_memory_t * mem, uint free_mask, client_name_t cname) { - gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; - chunk_t *cp; + gs_ref_memory_t * imem = (gs_ref_memory_t *)mem; + struct free_data fd; - if (free_mask & FREE_ALL_DATA) { - chunk_t *csucc; + fd.imem = imem; + fd.allocator = NULL; - /* - * Free the chunks in reverse order, to encourage LIFO behavior. - * Don't free the chunk holding the allocator itself. - */ - for (cp = imem->clast; cp != 0; cp = csucc) { - csucc = cp->cprev; /* save before freeing */ - if (cp->cbase + sizeof(obj_header_t) != (byte *)mem) - alloc_free_chunk(cp, imem); - } + if (free_mask & FREE_ALL_DATA && imem->root != NULL) { + /* Free every clump except the allocator */ + clump_splay_app(imem->root, imem, free_all_not_allocator, &fd); + + /* Reinstate the allocator as the sole clump */ + imem->root = fd.allocator; + if (fd.allocator) + fd.allocator->parent = fd.allocator->left = fd.allocator->right = NULL; } if (free_mask & FREE_ALL_ALLOCATOR) { - /* Free the chunk holding the allocator itself. */ - for (cp = imem->clast; cp != 0; cp = cp->cprev) - if (cp->cbase + sizeof(obj_header_t) == (byte *)mem) { - alloc_free_chunk(cp, imem); - break; - } + /* Walk the tree to find the allocator. */ + clump_splay_app(imem->root, imem, free_all_allocator, &fd); } } @@ -552,11 +1130,12 @@ gs_alloc_fill(ptr, gs_alloc_fill_alloc, size); #define ELSEIF_LIFO_ALLOC(ptr, imem, size, pstype)\ }\ - else if ( (imem->cc.ctop - (byte *)(ptr = (obj_header_t *)imem->cc.cbot))\ + else if ( imem->cc && !imem->cc->c_alone && \ + (imem->cc->ctop - (byte *)(ptr = (obj_header_t *)imem->cc->cbot))\ >= size + (obj_align_mod + sizeof(obj_header_t) * 2) &&\ size < imem->large_size\ )\ - { imem->cc.cbot = (byte *)ptr + obj_size_round(size);\ + { imem->cc->cbot = (byte *)ptr + obj_size_round(size);\ ptr->o_pad = 0;\ ptr->o_alone = 0;\ ptr->o_size = size;\ @@ -669,19 +1248,32 @@ alloc_trace("|+<.", imem, cname, pstype, size, obj); return obj; } + +static inline bool +alloc_array_check_size(ulong num_elements, ulong elt_size, ulong *lsize) +{ + int64_t s = (int64_t)num_elements * elt_size; + if (s > max_uint) { + return false; + } + *lsize = (ulong)s; + return true; +} + static byte * i_alloc_byte_array(gs_memory_t * mem, uint num_elements, uint elt_size, client_name_t cname) { gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; obj_header_t *obj; - + ulong lsize; #ifdef MEMENTO if (Memento_failThisEvent()) return NULL; #endif - - obj = alloc_obj(imem, (ulong) num_elements * elt_size, + if (alloc_array_check_size(num_elements, elt_size, &lsize) == false) + return NULL; + obj = alloc_obj(imem, lsize, &st_bytes, ALLOC_DIRECT, cname); if_debug6m('A', mem, "[a%d:+b.]%s -bytes-*(%lu=%u*%u) = 0x%lx\n", @@ -696,13 +1288,14 @@ { gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; obj_header_t *obj; - + ulong lsize; #ifdef MEMENTO if (Memento_failThisEvent()) return NULL; #endif - - obj = alloc_obj(imem, (ulong) num_elements * elt_size, + if (alloc_array_check_size(num_elements, elt_size, &lsize) == false) + return NULL; + obj = alloc_obj(imem, lsize, &st_bytes, ALLOC_IMMOVABLE | ALLOC_DIRECT, cname); @@ -718,7 +1311,7 @@ { gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; obj_header_t *obj; - + ulong lsize; #ifdef MEMENTO if (Memento_failThisEvent()) return NULL; @@ -732,9 +1325,9 @@ return NULL; /* fail */ } #endif - obj = alloc_obj(imem, - (ulong) num_elements * pstype->ssize, - pstype, ALLOC_DIRECT, cname); + if (alloc_array_check_size(num_elements, pstype->ssize, &lsize) == false) + return NULL; + obj = alloc_obj(imem, lsize, pstype, ALLOC_DIRECT, cname); if_debug7m('A', mem, "[a%d:+<.]%s %s*(%lu=%u*%u) = 0x%lx\n", alloc_trace_space(imem), client_name_string(cname), struct_type_name_string(pstype), @@ -748,16 +1341,16 @@ { gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; obj_header_t *obj; - + ulong lsize; #ifdef MEMENTO if (Memento_failThisEvent()) return NULL; #endif ALLOC_CHECK_SIZE(mem,pstype); - obj = alloc_obj(imem, - (ulong) num_elements * pstype->ssize, - pstype, ALLOC_IMMOVABLE | ALLOC_DIRECT, cname); + if (alloc_array_check_size(num_elements, pstype->ssize, &lsize) == false) + return NULL; + obj = alloc_obj(imem, lsize, pstype, ALLOC_IMMOVABLE | ALLOC_DIRECT, cname); if_debug7m('A', mem, "[a%d|+<.]%s %s*(%lu=%u*%u) = 0x%lx\n", alloc_trace_space(imem), client_name_string(cname), struct_type_name_string(pstype), @@ -787,14 +1380,14 @@ pp->o_size = new_size; new_obj = obj; } else - if ((byte *)obj + old_size_rounded == imem->cc.cbot && - imem->cc.ctop - (byte *)obj >= new_size_rounded ) { - imem->cc.cbot = (byte *)obj + new_size_rounded; + if (imem->cc && (byte *)obj + old_size_rounded == imem->cc->cbot && + imem->cc->ctop - (byte *)obj >= new_size_rounded ) { + imem->cc->cbot = (byte *)obj + new_size_rounded; pp->o_size = new_size; new_obj = obj; } else /* try and trim the object -- but only if room for a dummy header */ if (new_size_rounded + sizeof(obj_header_t) <= old_size_rounded) { - trim_obj(imem, obj, new_size, (chunk_t *)0); + trim_obj(imem, obj, new_size, (clump_t *)0); new_obj = obj; } if (new_obj) { @@ -833,7 +1426,7 @@ pstype = pp->o_type; #ifdef DEBUG if (gs_debug_c('?')) { - chunk_locator_t cld; + clump_locator_t cld; if (pstype == &st_free) { mlprintf2(mem, "%s: object 0x%lx already free!\n", @@ -842,8 +1435,8 @@ } /* Check that this allocator owns the object being freed. */ cld.memory = imem; - while ((cld.cp = cld.memory->clast), - !chunk_locate_ptr(ptr, &cld) + while ((cld.cp = cld.memory->root), + !clump_locate_ptr(ptr, &cld) ) { if (!cld.memory->saved) { mlprintf3(mem, "%s: freeing 0x%lx, not owned by memory 0x%lx!\n", @@ -856,12 +1449,10 @@ cld.memory = (gs_ref_memory_t *) cld.memory->saved; } /* Check that the object is in the allocated region. */ - if (cld.memory == imem && cld.cp == imem->pcc) - cld.cp = &imem->cc; if (!(PTR_BETWEEN((const byte *)pp, cld.cp->cbase, cld.cp->cbot)) ) { - mlprintf5(mem, "%s: freeing 0x%lx,\n\toutside chunk 0x%lx cbase=0x%lx, cbot=0x%lx!\n", + mlprintf5(mem, "%s: freeing 0x%lx,\n\toutside clump 0x%lx cbase=0x%lx, cbot=0x%lx!\n", client_name_string(cname), (ulong) ptr, (ulong) cld.cp, (ulong) cld.cp->cbase, (ulong) cld.cp->cbot); @@ -888,42 +1479,42 @@ if (gs_debug['a'] || gs_debug['A']) pstype = &saved_stype; } - if ((byte *) ptr + rounded_size == imem->cc.cbot) { + if (imem->cc && (byte *) ptr + rounded_size == imem->cc->cbot) { alloc_trace(":-o ", imem, cname, pstype, size, ptr); gs_alloc_fill(ptr, gs_alloc_fill_free, size); - imem->cc.cbot = (byte *) pp; + imem->cc->cbot = (byte *) pp; /* IFF this object is adjacent to (or below) the byte after the - * highest free object, do the consolidation within this chunk. */ - if ((byte *)pp <= imem->cc.int_freed_top) { - consolidate_chunk_free(&(imem->cc), imem); + * highest free object, do the consolidation within this clump. */ + if ((byte *)pp <= imem->cc->int_freed_top) { + consolidate_clump_free(imem->cc, imem); } return; } if (pp->o_alone) { /* - * We gave this object its own chunk. Free the entire chunk, + * We gave this object its own clump. Free the entire clump, * unless it belongs to an older save level, in which case * we mustn't overwrite it. */ - chunk_locator_t cl; + clump_locator_t cl; #ifdef DEBUG { - chunk_locator_t cld; + clump_locator_t cld; cld.memory = imem; cld.cp = 0; if (gs_debug_c('a')) alloc_trace( - (chunk_locate_ptr(ptr, &cld) ? ":-oL" : ":-o~"), + (clump_locate_ptr(ptr, &cld) ? ":-oL" : ":-o~"), imem, cname, pstype, size, ptr); } #endif cl.memory = imem; cl.cp = 0; - if (chunk_locate_ptr(ptr, &cl)) { + if (clump_locate_ptr(ptr, &cl)) { if (!imem->is_controlled) - alloc_free_chunk(cl.cp, imem); + alloc_free_clump(cl.cp, imem); return; } /* Don't overwrite even if gs_alloc_debug is set. */ @@ -935,7 +1526,7 @@ * overwrite it. */ imem->cfreed.memory = imem; - if (chunk_locate(ptr, &imem->cfreed)) { + if (clump_locate(ptr, &imem->cfreed)) { obj_header_t **pfl; if (size > max_freelist_size) { @@ -947,13 +1538,13 @@ log2_obj_align_mod]; } /* keep track of highest object on a freelist */ - /* If we're dealing with a block in the currently open chunk - (in imem->cc) update that, otherwise, update the chunk in - the chunk list (in imem->cfreed.cp) + /* If we're dealing with a block in the currently open clump + (in imem->cc) update that, otherwise, update the clump in + the clump list (in imem->cfreed.cp) */ - if (imem->cfreed.cp->chead == imem->cc.chead) { - if ((byte *)pp >= imem->cc.int_freed_top) { - imem->cc.int_freed_top = (byte *)ptr + rounded_size; + if (imem->cc && imem->cfreed.cp->chead == imem->cc->chead) { + if ((byte *)pp >= imem->cc->int_freed_top) { + imem->cc->int_freed_top = (byte *)ptr + rounded_size; } } else { @@ -983,12 +1574,16 @@ { gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; byte *str; + clump_splay_walker sw; /* - * Cycle through the chunks at the current save level, starting + * Cycle through the clumps at the current save level, starting * with the currently open one. */ - chunk_t *cp_orig = imem->pcc; + clump_t *cp = clump_splay_walk_init_mid(&sw, imem->cc); + + if (nbytes + (uint)HDR_ID_OFFSET < nbytes) + return NULL; nbytes += HDR_ID_OFFSET; @@ -996,52 +1591,48 @@ if (Memento_failThisEvent()) return NULL; #endif - if (cp_orig == 0) { - /* Open an arbitrary chunk. */ - cp_orig = imem->pcc = imem->cfirst; - alloc_open_chunk(imem); + if (cp == 0) { + /* Open an arbitrary clump. */ + imem->cc = clump_splay_walk_init(&sw, imem); + alloc_open_clump(imem); } top: - if (imem->cc.ctop - imem->cc.cbot > nbytes) { + if (imem->cc && !imem->cc->c_alone && imem->cc->ctop - imem->cc->cbot > nbytes) { if_debug4m('A', mem, "[a%d:+> ]%s(%u) = 0x%lx\n", alloc_trace_space(imem), client_name_string(cname), nbytes, - (ulong) (imem->cc.ctop - nbytes)); - str = imem->cc.ctop -= nbytes; + (ulong) (imem->cc->ctop - nbytes)); + str = imem->cc->ctop -= nbytes; gs_alloc_fill(str, gs_alloc_fill_alloc, nbytes); str += HDR_ID_OFFSET; ASSIGN_HDR_ID(str); return str; } - /* Try the next chunk. */ - { - chunk_t *cp = imem->cc.cnext; + /* Try the next clump. */ + cp = clump_splay_walk_fwd(&sw); - alloc_close_chunk(imem); - if (cp == 0) - cp = imem->cfirst; - imem->pcc = cp; - alloc_open_chunk(imem); - if (cp != cp_orig) - goto top; + if (cp != NULL) + { + alloc_close_clump(imem); + imem->cc = cp; + alloc_open_clump(imem); + goto top; } - if (nbytes > string_space_quanta(max_uint - sizeof(chunk_head_t)) * + if (nbytes > string_space_quanta(max_uint - sizeof(clump_head_t)) * string_data_quantum ) { /* Can't represent the size in a uint! */ return 0; } - if (nbytes >= imem->large_size) { /* Give it a chunk all its own. */ + if (nbytes >= imem->large_size) { /* Give it a clump all its own. */ return i_alloc_string_immovable(mem, nbytes, cname); - } else { /* Add another chunk. */ - chunk_t *cp = - alloc_acquire_chunk(imem, (ulong) imem->chunk_size, true, "chunk"); + } else { /* Add another clump. */ + cp = alloc_acquire_clump(imem, (ulong) imem->clump_size, true, "clump"); if (cp == 0) return 0; - alloc_close_chunk(imem); - imem->pcc = cp; - imem->cc = *imem->pcc; - gs_alloc_fill(imem->cc.cbase, gs_alloc_fill_free, - imem->cc.climit - imem->cc.cbase); + alloc_close_clump(imem); + imem->cc = clump_splay_walk_init_mid(&sw, cp); + gs_alloc_fill(imem->cc->cbase, gs_alloc_fill_free, + imem->cc->climit - imem->cc->cbase); goto top; } } @@ -1051,7 +1642,7 @@ gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; byte *str; uint asize; - chunk_t *cp; + clump_t *cp; nbytes += HDR_ID_OFFSET; @@ -1059,13 +1650,15 @@ if (Memento_failThisEvent()) return NULL; #endif - /* Give it a chunk all its own. */ - asize = string_chunk_space(nbytes) + sizeof(chunk_head_t); - cp = alloc_acquire_chunk(imem, (ulong) asize, true, - "large string chunk"); + /* Give it a clump all its own. */ + asize = string_clump_space(nbytes) + sizeof(clump_head_t); + cp = alloc_acquire_clump(imem, (ulong) asize, true, + "large string clump"); if (cp == 0) return 0; + cp->c_alone = true; + str = cp->ctop = cp->climit - nbytes; if_debug4m('a', mem, "[a%d|+>L]%s(%u) = 0x%lx\n", alloc_trace_space(imem), client_name_string(cname), nbytes, @@ -1091,9 +1684,9 @@ old_num += HDR_ID_OFFSET; new_num += HDR_ID_OFFSET; - if ( data == imem->cc.ctop && /* bottom-most string */ + if ( imem->cc && data == imem->cc->ctop && /* bottom-most string */ (new_num < old_num || - imem->cc.ctop - imem->cc.cbot > new_num - old_num) + imem->cc->ctop - imem->cc->cbot > new_num - old_num) ) { /* Resize in place. */ ptr = data + old_num - new_num; if_debug6m('A', mem, "[a%d:%c> ]%s(%u->%u) 0x%lx\n", @@ -1101,7 +1694,7 @@ (new_num > old_num ? '>' : '<'), client_name_string(cname), old_num, new_num, (ulong) ptr); - imem->cc.ctop = ptr; + imem->cc->ctop = ptr; memmove(ptr, data, min(old_num, new_num)); #ifdef DEBUG if (new_num > old_num) @@ -1148,11 +1741,11 @@ if (data) { data -= HDR_ID_OFFSET; nbytes += HDR_ID_OFFSET; - if (data == imem->cc.ctop) { + if (imem->cc && data == imem->cc->ctop) { if_debug4m('A', mem, "[a%d:-> ]%s(%u) 0x%lx\n", alloc_trace_space(imem), client_name_string(cname), nbytes, (ulong) data); - imem->cc.ctop += nbytes; + imem->cc->ctop += nbytes; } else { if_debug4m('A', mem, "[a%d:->#]%s(%u) 0x%lx\n", alloc_trace_space(imem), client_name_string(cname), nbytes, @@ -1175,26 +1768,25 @@ gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; ulong unused = imem->lost.refs + imem->lost.strings; ulong inner = 0; + clump_splay_walker sw; + clump_t *cp; - alloc_close_chunk(imem); - /* Add up unallocated space within each chunk. */ - /* Also keep track of space allocated to inner chunks, */ + alloc_close_clump(imem); + /* Add up unallocated space within each clump. */ + /* Also keep track of space allocated to inner clumps, */ /* which are included in previous_status.allocated. */ + for (cp = clump_splay_walk_init(&sw, imem); cp != NULL; cp = clump_splay_walk_fwd(&sw)) { - const chunk_t *cp = imem->cfirst; - - while (cp != 0) { - unused += cp->ctop - cp->cbot; - if (cp->outer) - inner += cp->cend - (byte *) cp->chead; - cp = cp->cnext; - } + unused += cp->ctop - cp->cbot; + if (cp->outer) + inner += cp->cend - (byte *) cp->chead; } unused += compute_free_objects(imem); pstat->used = imem->allocated + inner - unused + imem->previous_status.used; pstat->allocated = imem->allocated + imem->previous_status.allocated; + pstat->max_used = 0; /* unknown for this allocator */ pstat->is_thread_safe = false; /* this allocator is not thread safe */ } @@ -1209,6 +1801,20 @@ mem->procs.free_string = gs_ignore_free_string; } +static void i_set_object_type(gs_memory_t *mem, void *ptr, gs_memory_type_ptr_t type) +{ + obj_header_t *pp; + + if (ptr == 0) + return; + pp = (obj_header_t *) ptr - 1; + pp->o_type = type; +} + +static void i_defer_frees(gs_memory_t *mem, int defer) +{ +} + /* ------ Internal procedures ------ */ /* Compute the amount of free object space by scanning free lists. */ @@ -1268,7 +1874,7 @@ } if (best_fit == 0) { /* - * No single free chunk is large enough, but since we scanned the + * No single free clump is large enough, but since we scanned the * entire list, we now have an accurate updated value for * largest_free_size. */ @@ -1278,7 +1884,7 @@ /* Remove from freelist & return excess memory to free */ *best_fit_prev = *(obj_header_t **)best_fit; - trim_obj(mem, best_fit, aligned_size, (chunk_t *)0); + trim_obj(mem, best_fit, aligned_size, (clump_t *)0); /* Pre-init block header; o_alone & o_type are already init'd */ best_fit[-1].o_size = size; @@ -1295,18 +1901,18 @@ if (lsize >= mem->large_size || (flags & ALLOC_IMMOVABLE)) { /* - * Give the object a chunk all its own. Note that this case does + * Give the object a clump all its own. Note that this case does * not occur if is_controlled is true. */ ulong asize = ((lsize + obj_align_mask) & -obj_align_mod) + sizeof(obj_header_t); - chunk_t *cp = - alloc_acquire_chunk(mem, asize + sizeof(chunk_head_t), false, - "large object chunk"); + clump_t *cp = + alloc_acquire_clump(mem, asize + sizeof(clump_head_t), false, + "large object clump"); if ( -#if arch_sizeof_long > arch_sizeof_int +#if ARCH_SIZEOF_LONG > ARCH_SIZEOF_INT asize > max_uint #else asize < lsize @@ -1315,6 +1921,7 @@ return 0; if (cp == 0) return 0; + cp->c_alone = true; ptr = (obj_header_t *) cp->cbot; cp->cbot += asize; ptr->o_pad = 0; @@ -1322,10 +1929,11 @@ ptr->o_size = lsize; } else { /* - * Cycle through the chunks at the current save level, starting + * Cycle through the clumps at the current save level, starting * with the currently open one. */ - chunk_t *cp_orig = mem->pcc; + clump_splay_walker sw; + clump_t *cp = clump_splay_walk_init_mid(&sw, mem->cc); uint asize = obj_size_round((uint) lsize); bool allocate_success = false; @@ -1337,41 +1945,40 @@ } } - if (cp_orig == 0) { - /* Open an arbitrary chunk. */ - cp_orig = mem->pcc = mem->cfirst; - alloc_open_chunk(mem); + if (cp == 0) { + /* Open an arbitrary clump. */ + mem->cc = clump_splay_walk_init(&sw, mem); + alloc_open_clump(mem); } #define CAN_ALLOC_AT_END(cp)\ - ((cp)->ctop - (byte *) (ptr = (obj_header_t *) (cp)->cbot)\ + ((cp) && !((cp)->c_alone) && (cp)->ctop - (byte *) (ptr = (obj_header_t *) (cp)->cbot)\ > asize + sizeof(obj_header_t)) do { - if (CAN_ALLOC_AT_END(&mem->cc)) { + if (CAN_ALLOC_AT_END(mem->cc)) { allocate_success = true; break; } else if (mem->is_controlled) { /* Try consolidating free space. */ gs_consolidate_free((gs_memory_t *)mem); - if (CAN_ALLOC_AT_END(&mem->cc)) { + if (CAN_ALLOC_AT_END(mem->cc)) { allocate_success = true; break; } } - /* No luck, go on to the next chunk. */ - { - chunk_t *cp = mem->cc.cnext; + /* No luck, go on to the next clump. */ + cp = clump_splay_walk_fwd(&sw); + if (cp == NULL) + break; - alloc_close_chunk(mem); - if (cp == 0) - cp = mem->cfirst; - mem->pcc = cp; - alloc_open_chunk(mem); - } - } while (mem->pcc != cp_orig); + alloc_close_clump(mem); + mem->cc = cp; + alloc_open_clump(mem); + } + while (1); -#ifdef CONSOLIDATE_BEFORE_ADDING_CHUNK +#ifdef CONSOLIDATE_BEFORE_ADDING_CLUMP if (!allocate_success) { /* * Try consolidating free space before giving up. @@ -1379,20 +1986,19 @@ * a lot of computation and doesn't seem to improve things much. */ if (!mem->is_controlled) { /* already did this if controlled */ - chunk_t *cp = cp_orig; + clump_t *cp; - alloc_close_chunk(mem); - do { - consolidate_chunk_free(cp, mem); + alloc_close_clump(mem); + for (cp = clump_splay_walk_init_mid(&sw, cp_orig); cp != NULL; cp = clump_splay_walk_fwd(&sw)) + { + consolidate_clump_free(cp, mem); if (CAN_ALLOC_AT_END(cp)) { - mem->pcc = cp; - alloc_open_chunk(mem); + mem->cc = cp; + alloc_open_clump(mem); allocate_success = true; break; } - if ((cp = cp->cnext) == 0) - cp = mem->cfirst; - } while (cp != cp_orig); + } } } #endif @@ -1400,12 +2006,12 @@ #undef CAN_ALLOC_AT_END if (!allocate_success) { - /* Add another chunk. */ - chunk_t *cp = - alloc_add_chunk(mem, (ulong)mem->chunk_size, "chunk"); + /* Add another clump. */ + clump_t *cp = + alloc_add_clump(mem, (ulong)mem->clump_size, "clump"); if (cp) { - /* mem->pcc == cp, mem->cc == *mem->pcc. */ + /* mem->cc == cp */ ptr = (obj_header_t *)cp->cbot; allocate_success = true; } @@ -1418,7 +2024,7 @@ * examining outer save levels in the general case. */ if (allocate_success) - mem->cc.cbot = (byte *) ptr + asize; + mem->cc->cbot = (byte *) ptr + asize; else if (!mem->is_controlled || (ptr = scavenge_low_free(mem, (uint)lsize)) == 0) return 0; /* allocation failed */ @@ -1443,12 +2049,12 @@ * (int_freed_top). */ static void -consolidate_chunk_free(chunk_t *cp, gs_ref_memory_t *mem) +consolidate_clump_free(clump_t *cp, gs_ref_memory_t *mem) { obj_header_t *begin_free = 0; - cp->int_freed_top = cp->cbase; /* below all objects in chunk */ - SCAN_CHUNK_OBJECTS(cp) + cp->int_freed_top = cp->cbase; /* below all objects in clump */ + SCAN_CLUMP_OBJECTS(cp) DO_ALL if (pre->o_type == &st_free) { if (begin_free == 0) @@ -1464,42 +2070,49 @@ /* Remove the free objects from the freelists. */ remove_range_from_freelist(mem, begin_free, cp->cbot); if_debug4m('a', (const gs_memory_t *)mem, - "[a]resetting chunk 0x%lx cbot from 0x%lx to 0x%lx (%lu free)\n", + "[a]resetting clump 0x%lx cbot from 0x%lx to 0x%lx (%lu free)\n", (ulong) cp, (ulong) cp->cbot, (ulong) begin_free, (ulong) ((byte *) cp->cbot - (byte *) begin_free)); cp->cbot = (byte *) begin_free; } } +static splay_app_result_t +consolidate(clump_t *cp, void *arg) +{ + gs_ref_memory_t *mem = (gs_ref_memory_t *)arg; + + consolidate_clump_free(cp, mem); + if (cp->cbot == cp->cbase && cp->ctop == cp->climit) { + /* The entire clump is free. */ + if (!mem->is_controlled) { + alloc_free_clump(cp, mem); + if (mem->cc == cp) + mem->cc = NULL; + } + } + + return SPLAY_APP_CONTINUE; +} + /* Consolidate free objects. */ void ialloc_consolidate_free(gs_ref_memory_t *mem) { - chunk_t *cp; - chunk_t *cprev; + alloc_close_clump(mem); - alloc_close_chunk(mem); + /* We used to visit clumps in reverse order to encourage LIFO behavior, + * but with binary trees this is not possible (unless you want to + * either change the tree during the process, recurse, or otherwise + * hold the state). */ + clump_splay_app(mem->root, mem, consolidate, mem); + + /* NOTE: Previously, if we freed the current clump, we'd move to whatever the + * bigger of it's children was. We now just move to the root. */ + if (mem->cc == NULL) + mem->cc = mem->root; - /* Visit chunks in reverse order to encourage LIFO behavior. */ - for (cp = mem->clast; cp != 0; cp = cprev) { - cprev = cp->cprev; - consolidate_chunk_free(cp, mem); - if (cp->cbot == cp->cbase && cp->ctop == cp->climit) { - /* The entire chunk is free. */ - chunk_t *cnext = cp->cnext; - - if (!mem->is_controlled) { - alloc_free_chunk(cp, mem); - if (mem->pcc == cp) - mem->pcc = - (cnext == 0 ? cprev : cprev == 0 ? cnext : - cprev->cbot - cprev->ctop > - cnext->cbot - cnext->ctop ? cprev : - cnext); - } - } - } - alloc_open_chunk(mem); + alloc_open_clump(mem); } static void i_consolidate_free(gs_memory_t *mem) @@ -1507,54 +2120,70 @@ ialloc_consolidate_free((gs_ref_memory_t *)mem); } -/* try to free-up given amount of space from freespace below chunk base */ -static obj_header_t * /* returns uninitialized object hdr, NULL if none found */ -scavenge_low_free(gs_ref_memory_t *mem, unsigned request_size) +typedef struct { - /* find 1st range of memory that can be glued back together to fill request */ - obj_header_t *found_pre = 0; + uint need_free; + obj_header_t *found_pre; + gs_ref_memory_t *mem; + unsigned request_size; +} scavenge_data; - /* Visit chunks in forward order */ - obj_header_t *begin_free = 0; - uint found_free; - uint request_size_rounded = obj_size_round(request_size); - uint need_free = request_size_rounded + sizeof(obj_header_t); /* room for GC's dummy hdr */ - chunk_t *cp; +static splay_app_result_t +scavenge(clump_t *cp, void *arg) +{ + scavenge_data *sd = (scavenge_data *)arg; + obj_header_t *begin_free = NULL; + uint found_free = 0; - for (cp = mem->cfirst; cp != 0; cp = cp->cnext) { - begin_free = 0; - found_free = 0; - SCAN_CHUNK_OBJECTS(cp) - DO_ALL - if (pre->o_type == &st_free) { - if (begin_free == 0) { - found_free = 0; - begin_free = pre; - } - found_free += pre_obj_rounded_size(pre); - if (begin_free != 0 && found_free >= need_free) - break; - } else - begin_free = 0; - END_OBJECTS_SCAN_NO_ABORT + sd->found_pre = NULL; - /* Found sufficient range of empty memory */ - if (begin_free != 0 && found_free >= need_free) { + SCAN_CLUMP_OBJECTS(cp) + DO_ALL + if (pre->o_type == &st_free) { + if (begin_free == 0) { + found_free = 0; + begin_free = pre; + } + found_free += pre_obj_rounded_size(pre); + if (begin_free != 0 && found_free >= sd->need_free) + break; + } else + begin_free = 0; + END_OBJECTS_SCAN_NO_ABORT - /* Fish found pieces out of various freelists */ - remove_range_from_freelist(mem, (char*)begin_free, - (char*)begin_free + found_free); + if (begin_free != 0 && found_free >= sd->need_free) { + /* Fish found pieces out of various freelists */ + remove_range_from_freelist(sd->mem, (char*)begin_free, + (char*)begin_free + found_free); - /* Prepare found object */ - found_pre = begin_free; - found_pre->o_type = &st_free; /* don't confuse GC if gets lost */ - found_pre->o_size = found_free - sizeof(obj_header_t); + /* Prepare found object */ + sd->found_pre = begin_free; + sd->found_pre->o_type = &st_free; /* don't confuse GC if gets lost */ + sd->found_pre->o_size = found_free - sizeof(obj_header_t); - /* Chop off excess tail piece & toss it back into free pool */ - trim_obj(mem, found_pre + 1, request_size, cp); - } + /* Chop off excess tail piece & toss it back into free pool */ + trim_obj(sd->mem, sd->found_pre + 1, sd->request_size, cp); + return SPLAY_APP_STOP; } - return found_pre; + + return SPLAY_APP_CONTINUE; +} + +/* try to free-up given amount of space from freespace below clump base */ +static obj_header_t * /* returns uninitialized object hdr, NULL if none found */ +scavenge_low_free(gs_ref_memory_t *mem, unsigned request_size) +{ + /* find 1st range of memory that can be glued back together to fill request */ + scavenge_data sd; + uint request_size_rounded = obj_size_round(request_size); + + sd.found_pre = 0; + sd.need_free = request_size_rounded + sizeof(obj_header_t); /* room for GC's dummy hdr */ + sd.mem = mem; + sd.request_size = request_size; + + clump_splay_app(mem->root, mem, scavenge, &sd); + return sd.found_pre; } /* Remove range of memory from a mem's freelists */ @@ -1632,7 +2261,7 @@ /* Trim a memory object down to a given size */ static void -trim_obj(gs_ref_memory_t *mem, obj_header_t *obj, uint size, chunk_t *cp) +trim_obj(gs_ref_memory_t *mem, obj_header_t *obj, uint size, clump_t *cp) /* Obj must have rounded size == req'd size, or have enough room for */ /* trailing dummy obj_header */ { @@ -1647,13 +2276,13 @@ if (old_rounded_size == rounded_size) return; /* nothing more to do here */ /* - * If the object is alone in its chunk, move cbot to point to the end + * If the object is alone in its clump, move cbot to point to the end * of the object. */ if (pre_obj->o_alone) { if (!cp) { mem->cfreed.memory = mem; - if (chunk_locate(obj, &mem->cfreed)) { + if (clump_locate(obj, &mem->cfreed)) { cp = mem->cfreed.cp; } } @@ -1686,8 +2315,8 @@ /* Put excess object on a freelist */ obj_header_t **pfl; - if ((byte *)excess_pre >= mem->cc.int_freed_top) - mem->cc.int_freed_top = (byte *)excess_pre + excess_size; + if (mem->cc && (byte *)excess_pre >= mem->cc->int_freed_top) + mem->cc->int_freed_top = (byte *)excess_pre + excess_size; if (excess_size <= max_freelist_size) pfl = &mem->freelists[(excess_size + obj_align_mask) >> log2_obj_align_mod]; @@ -1749,85 +2378,59 @@ gs_free_object(imem->non_gc_memory, rp, "i_unregister_root"); } -/* ================ Chunks ================ */ +/* ================ clumps ================ */ -public_st_chunk(); +public_st_clump(); -/* Insert a chunk in the chain. This is exported for the GC and for */ +/* Insert a clump in the chain. This is exported for the GC and for */ /* the forget_save operation. */ void -alloc_link_chunk(chunk_t * cp, gs_ref_memory_t * imem) +alloc_link_clump(clump_t * cp, gs_ref_memory_t * imem) { - byte *cdata = cp->cbase; - chunk_t *icp; - chunk_t *prev; - - /* - * Allocators tend to allocate in either ascending or descending - * address order. The loop will handle the latter well; check for - * the former first. - */ - if (imem->clast && PTR_GE(cdata, imem->clast->ctop)) - icp = 0; - else - for (icp = imem->cfirst; icp != 0 && PTR_GE(cdata, icp->ctop); - icp = icp->cnext - ); - cp->cnext = icp; - if (icp == 0) { /* add at end of chain */ - prev = imem->clast; - imem->clast = cp; - } else { /* insert before icp */ - prev = icp->cprev; - icp->cprev = cp; - } - cp->cprev = prev; - if (prev == 0) - imem->cfirst = cp; - else - prev->cnext = cp; - if (imem->pcc != 0) { - imem->cc.cnext = imem->pcc->cnext; - imem->cc.cprev = imem->pcc->cprev; - } + splay_insert(cp, imem); + SANITY_CHECK(cp); } -/* Add a chunk for ordinary allocation. */ -static chunk_t * -alloc_add_chunk(gs_ref_memory_t * mem, ulong csize, client_name_t cname) +/* Add a clump for ordinary allocation. */ +static clump_t * +alloc_add_clump(gs_ref_memory_t * mem, ulong csize, client_name_t cname) { - chunk_t *cp = alloc_acquire_chunk(mem, csize, true, cname); + clump_t *cp = alloc_acquire_clump(mem, csize, true, cname); if (cp) { - alloc_close_chunk(mem); - mem->pcc = cp; - mem->cc = *mem->pcc; - gs_alloc_fill(mem->cc.cbase, gs_alloc_fill_free, - mem->cc.climit - mem->cc.cbase); + alloc_close_clump(mem); + mem->cc = cp; + gs_alloc_fill(mem->cc->cbase, gs_alloc_fill_free, + mem->cc->climit - mem->cc->cbase); } return cp; } -/* Acquire a chunk. If we would exceed MaxLocalVM (if relevant), */ +/* Acquire a clump. If we would exceed MaxLocalVM (if relevant), */ /* or if we would exceed the VMThreshold and psignal is NULL, */ /* return 0; if we would exceed the VMThreshold but psignal is valid, */ /* just set the signal and return successfully. */ -static chunk_t * -alloc_acquire_chunk(gs_ref_memory_t * mem, ulong csize, bool has_strings, +static clump_t * +alloc_acquire_clump(gs_ref_memory_t * mem, ulong csize, bool has_strings, client_name_t cname) { gs_memory_t *parent = mem->non_gc_memory; - chunk_t *cp; + clump_t *cp; byte *cdata; -#if arch_sizeof_long > arch_sizeof_int +#if ARCH_SIZEOF_LONG > ARCH_SIZEOF_INT /* If csize is larger than max_uint, punt. */ if (csize != (uint) csize) return 0; #endif - cp = gs_raw_alloc_struct_immovable(parent, &st_chunk, cname); + cp = gs_raw_alloc_struct_immovable(parent, &st_clump, cname); - if( mem->gc_status.psignal != 0) { + /* gc_status.signal_value is initialised to zero when the + * allocator is created, only the Postscript interpreter + * (which implement garbage collection) takes the action to set + * it to anything other than zero + */ + if( mem->gc_status.signal_value != 0) { /* we have a garbage collector */ if ((ulong) (mem->allocated) >= mem->limit) { mem->gc_status.requested += csize; @@ -1839,7 +2442,7 @@ "[0]signaling space=%d, allocated=%ld, limit=%ld, requested=%ld\n", mem->space, (long)mem->allocated, (long)mem->limit, (long)mem->gc_status.requested); - *mem->gc_status.psignal = mem->gc_status.signal_value; + mem->gs_lib_ctx->gcsignal = mem->gc_status.signal_value; } } cdata = gs_alloc_bytes_immovable(parent, csize, cname); @@ -1849,25 +2452,26 @@ mem->gc_status.requested = csize; return 0; } - alloc_init_chunk(cp, cdata, cdata + csize, has_strings, (chunk_t *) 0); - alloc_link_chunk(cp, mem); - mem->allocated += st_chunk.ssize + csize; + alloc_init_clump(cp, cdata, cdata + csize, has_strings, (clump_t *) 0); + alloc_link_clump(cp, mem); + mem->allocated += st_clump.ssize + csize; + SANITY_CHECK(cp); return cp; } -/* Initialize the pointers in a chunk. This is exported for save/restore. */ +/* Initialize the pointers in a clump. This is exported for save/restore. */ /* The bottom pointer must be aligned, but the top pointer need not */ /* be aligned. */ void -alloc_init_chunk(chunk_t * cp, byte * bot, byte * top, bool has_strings, - chunk_t * outer) +alloc_init_clump(clump_t * cp, byte * bot, byte * top, bool has_strings, + clump_t * outer) { byte *cdata = bot; if (outer != 0) outer->inner_count++; - cp->chead = (chunk_head_t *) cdata; - cdata += sizeof(chunk_head_t); + cp->chead = (clump_head_t *) cdata; + cdata += sizeof(clump_head_t); cp->cbot = cp->cbase = cp->int_freed_top = cdata; cp->cend = top; cp->rcur = 0; @@ -1876,10 +2480,11 @@ cp->inner_count = 0; cp->has_refs = false; cp->sbase = cdata; + cp->c_alone = false; /* should be set correctly by caller */ if (has_strings && top - cdata >= string_space_quantum + sizeof(long) - 1) { /* * We allocate a large enough string marking and reloc table - * to cover the entire chunk. + * to cover the entire clump. */ uint nquanta = string_space_quanta(top - cdata); @@ -1901,146 +2506,155 @@ alloc_init_free_strings(cp); } -/* Initialize the string freelists in a chunk. */ +/* Initialize the string freelists in a clump. */ void -alloc_init_free_strings(chunk_t * cp) +alloc_init_free_strings(clump_t * cp) { if (cp->sfree1) memset(cp->sfree1, 0, STRING_FREELIST_SPACE(cp)); cp->sfree = 0; } -/* Close up the current chunk. */ +/* Close up the current clump. */ /* This is exported for save/restore and the GC. */ void -alloc_close_chunk(gs_ref_memory_t * mem) +alloc_close_clump(gs_ref_memory_t * mem) { - if (mem->pcc != 0) { - *mem->pcc = mem->cc; #ifdef DEBUG - if (gs_debug_c('a')) { - dmlprintf1((const gs_memory_t *)mem, "[a%d]", alloc_trace_space(mem)); - dmprintf_chunk((const gs_memory_t *)mem, "closing chunk", mem->pcc); - } -#endif + if (gs_debug_c('A')) { + dmlprintf1((const gs_memory_t *)mem, "[a%d]", alloc_trace_space(mem)); + dmprintf_clump((const gs_memory_t *)mem, "closing clump", mem->cc); } +#endif } -/* Reopen the current chunk after a GC or restore. */ +/* Reopen the current clump after a GC or restore. */ void -alloc_open_chunk(gs_ref_memory_t * mem) +alloc_open_clump(gs_ref_memory_t * mem) { - if (mem->pcc != 0) { - mem->cc = *mem->pcc; #ifdef DEBUG - if (gs_debug_c('a')) { - dmlprintf1((const gs_memory_t *)mem, "[a%d]", alloc_trace_space(mem)); - dmprintf_chunk((const gs_memory_t *)mem, "opening chunk", mem->pcc); - } -#endif + if (gs_debug_c('A')) { + dmlprintf1((const gs_memory_t *)mem, "[a%d]", alloc_trace_space(mem)); + dmprintf_clump((const gs_memory_t *)mem, "opening clump", mem->cc); } +#endif } -/* Remove a chunk from the chain. This is exported for the GC. */ +#ifdef DEBUG +static splay_app_result_t +check_in_clump(clump_t *cp, void *arg) +{ + clump_t **cpp = (clump_t **)arg; + + if (*cpp != cp) + return SPLAY_APP_CONTINUE; + *cpp = NULL; + + return SPLAY_APP_STOP; +} +#endif + +/* Remove a clump from the chain. This is exported for the GC. */ void -alloc_unlink_chunk(chunk_t * cp, gs_ref_memory_t * mem) +alloc_unlink_clump(clump_t * cp, gs_ref_memory_t * mem) { + SANITY_CHECK_MID(cp); #ifdef DEBUG - if (gs_alloc_debug) { /* Check to make sure this chunk belongs to this allocator. */ - const chunk_t *ap = mem->cfirst; + if (gs_alloc_debug) { /* Check to make sure this clump belongs to this allocator. */ + clump_t *found = cp; + clump_splay_app(mem->root, mem, check_in_clump, &found); - while (ap != 0 && ap != cp) - ap = ap->cnext; - if (ap != cp) { - mlprintf2((const gs_memory_t *)mem, "unlink_chunk 0x%lx not owned by memory 0x%lx!\n", + if (found != NULL) { + mlprintf2((const gs_memory_t *)mem, "unlink_clump 0x%lx not owned by memory 0x%lx!\n", (ulong) cp, (ulong) mem); return; /*gs_abort(); */ } } #endif - if (cp->cprev == 0) - mem->cfirst = cp->cnext; - else - cp->cprev->cnext = cp->cnext; - if (cp->cnext == 0) - mem->clast = cp->cprev; - else - cp->cnext->cprev = cp->cprev; - if (mem->pcc != 0) { - mem->cc.cnext = mem->pcc->cnext; - mem->cc.cprev = mem->pcc->cprev; - if (mem->pcc == cp) { - mem->pcc = 0; - mem->cc.cbot = mem->cc.ctop = 0; - } + (void)clump_splay_remove(cp, mem); + if (mem->cc == cp) { + mem->cc = NULL; } } /* - * Free a chunk. This is exported for the GC. Since we eventually use - * this to free the chunk containing the allocator itself, we must be + * Free a clump. This is exported for the GC. Since we eventually use + * this to free the clump containing the allocator itself, we must be * careful not to reference anything in the allocator after freeing the - * chunk data. + * clump data. */ void -alloc_free_chunk(chunk_t * cp, gs_ref_memory_t * mem) +alloc_free_clump(clump_t * cp, gs_ref_memory_t * mem) { gs_memory_t *parent = mem->non_gc_memory; byte *cdata = (byte *)cp->chead; ulong csize = (byte *)cp->cend - cdata; - alloc_unlink_chunk(cp, mem); - mem->allocated -= st_chunk.ssize; + alloc_unlink_clump(cp, mem); + mem->allocated -= st_clump.ssize; if (mem->cfreed.cp == cp) mem->cfreed.cp = 0; if (cp->outer == 0) { mem->allocated -= csize; - gs_free_object(parent, cdata, "alloc_free_chunk(data)"); + gs_free_object(parent, cdata, "alloc_free_clump(data)"); } else { cp->outer->inner_count--; gs_alloc_fill(cdata, gs_alloc_fill_free, csize); } - gs_free_object(parent, cp, "alloc_free_chunk(chunk struct)"); + gs_free_object(parent, cp, "alloc_free_clump(clump struct)"); } -/* Find the chunk for a pointer. */ +/* Find the clump for a pointer. */ /* Note that this only searches the current save level. */ -/* Since a given save level can't contain both a chunk and an inner chunk */ -/* of that chunk, we can stop when is_within_chunk succeeds, and just test */ -/* is_in_inner_chunk then. */ +/* Since a given save level can't contain both a clump and an inner clump */ +/* of that clump, we can stop when is_within_clump succeeds, and just test */ +/* is_in_inner_clump then. */ bool -chunk_locate_ptr(const void *ptr, chunk_locator_t * clp) +clump_locate_ptr(const void *ptr, clump_locator_t * clp) { - register chunk_t *cp = clp->cp; + clump_t *cp = clp->memory->root; - if (cp == 0) { - cp = clp->memory->cfirst; - if (cp == 0) - return false; - /* ptr is in the last chunk often enough to be worth checking for. */ - if (PTR_GE(ptr, clp->memory->clast->cbase)) - cp = clp->memory->clast; - } - if (PTR_LT(ptr, cp->cbase)) { - do { - cp = cp->cprev; - if (cp == 0) - return false; + while (cp) + { + if (PTR_LT(ptr, cp->cbase)) + { + cp = cp->left; + continue; } - while (PTR_LT(ptr, cp->cbase)); if (PTR_GE(ptr, cp->cend)) - return false; - } else { - while (PTR_GE(ptr, cp->cend)) { - cp = cp->cnext; - if (cp == 0) - return false; + { + cp = cp->right; + continue; } + /* Found it! */ + splay_move_to_root(cp, clp->memory); + clp->cp = cp; + return !ptr_is_in_inner_clump(ptr, cp); + } + return false; +} + +bool ptr_is_within_mem_clumps(const void *ptr, gs_ref_memory_t *mem) +{ + clump_t *cp = mem->root; + + while (cp) + { if (PTR_LT(ptr, cp->cbase)) - return false; + { + cp = cp->left; + continue; + } + if (PTR_GE(ptr, cp->cend)) + { + cp = cp->right; + continue; + } + /* Found it! */ + splay_move_to_root(cp, mem); + return true; } - clp->cp = cp; - return !ptr_is_in_inner_chunk(ptr, cp); + return false; } /* ------ Debugging ------ */ @@ -2227,12 +2841,12 @@ } } -/* Print the contents of a chunk with the given options. */ +/* Print the contents of a clump with the given options. */ /* Relevant options: all. */ void -debug_dump_chunk(const gs_memory_t *mem, const chunk_t * cp, const dump_control_t * control) +debug_dump_clump(const gs_memory_t *mem, const clump_t * cp, const dump_control_t * control) { - dmprintf1(mem, "chunk at 0x%lx:\n", (ulong) cp); + dmprintf1(mem, "clump at 0x%lx:\n", (ulong) cp); dmprintf3(mem, " chead=0x%lx cbase=0x%lx sbase=0x%lx\n", (ulong) cp->chead, (ulong) cp->cbase, (ulong) cp->sbase); dmprintf3(mem, " rcur=0x%lx rtop=0x%lx cbot=0x%lx\n", @@ -2242,8 +2856,8 @@ cp->smark_size); dmprintf2(mem, " sreloc=0x%lx cend=0x%lx\n", (ulong) cp->sreloc, (ulong) cp->cend); - dmprintf5(mem, "cprev=0x%lx cnext=0x%lx outer=0x%lx inner_count=%u has_refs=%s\n", - (ulong) cp->cprev, (ulong) cp->cnext, (ulong) cp->outer, + dmprintf6(mem, "left=0x%lx right=0x%lx parent=0x%lx outer=0x%lx inner_count=%u has_refs=%s\n", + (ulong) cp->left, (ulong) cp->right, (ulong) cp->parent, (ulong) cp->outer, cp->inner_count, (cp->has_refs ? "true" : "false")); dmprintf2(mem, " sfree1=0x%lx sfree=0x%x\n", @@ -2255,7 +2869,7 @@ min(control->top, cp->climit)), 0, true); } - SCAN_CHUNK_OBJECTS(cp) + SCAN_CLUMP_OBJECTS(cp) DO_ALL if (obj_in_control_region(pre + 1, (const byte *)(pre + 1) + size, @@ -2265,26 +2879,26 @@ END_OBJECTS_SCAN_NO_ABORT } void -debug_print_chunk(const gs_memory_t *mem, const chunk_t * cp) +debug_print_clump(const gs_memory_t *mem, const clump_t * cp) { dump_control_t control; control = dump_control_default; - debug_dump_chunk(mem, cp, &control); + debug_dump_clump(mem, cp, &control); } -/* Print the contents of all chunks managed by an allocator. */ +/* Print the contents of all clumps managed by an allocator. */ /* Relevant options: all. */ void debug_dump_memory(const gs_ref_memory_t * mem, const dump_control_t * control) { - const chunk_t *mcp; - - for (mcp = mem->cfirst; mcp != 0; mcp = mcp->cnext) { - const chunk_t *cp = (mcp == mem->pcc ? &mem->cc : mcp); + const clump_t *cp; + clump_splay_walker sw; + for (cp = clump_splay_walk_init(&sw, mem); cp != NULL; cp = clump_splay_walk_fwd(&sw)) + { if (obj_in_control_region(cp->cbase, cp->cend, control)) - debug_dump_chunk((const gs_memory_t *)mem, cp, control); + debug_dump_clump((const gs_memory_t *)mem, cp, control); } } @@ -2298,14 +2912,14 @@ void debug_find_pointers(const gs_ref_memory_t *mem, const void *target) { + clump_splay_walker sw; dump_control_t control; - const chunk_t *mcp; + const clump_t *cp; control.options = 0; - for (mcp = mem->cfirst; mcp != 0; mcp = mcp->cnext) { - const chunk_t *cp = (mcp == mem->pcc ? &mem->cc : mcp); - - SCAN_CHUNK_OBJECTS(cp); + for (cp = clump_splay_walk_init(&sw, mem); cp; cp = clump_splay_walk_fwd(&sw)) + { + SCAN_CLUMP_OBJECTS(cp); DO_ALL struct_proc_enum_ptrs((*proc)) = pre->o_type->enum_ptrs; uint index = 0; @@ -2322,5 +2936,28 @@ END_OBJECTS_SCAN_NO_ABORT } } +static void ddct(const gs_memory_t *mem, clump_t *cp, clump_t *parent, int depth) +{ + int i; + + if (cp == NULL) + return; + for (i = 0; i < depth; i++) + dmlprintf(mem, " "); + + dmlprintf7(mem, "Clump %p:%p parent=%p left=%p:%p right=%p:%p\n", + cp, cp->cbase, cp->parent, + cp->left, cp->left ? cp->left->cbase : NULL, + cp->right, cp->right ? cp->right->cbase : NULL); + if (cp->parent != parent) + dmlprintf(mem, "Parent pointer mismatch!\n"); + ddct(mem, cp->left, cp, depth+1); + ddct(mem, cp->right, cp, depth+1); +} +void +debug_dump_clump_tree(const gs_ref_memory_t *mem) +{ + ddct((const gs_memory_t *)mem, mem->root, NULL, 0); +} #endif /* DEBUG */ diff -Nru ghostscript-9.10~dfsg/base/gsalloc.h ghostscript-9.25~dfsg+1/base/gsalloc.h --- ghostscript-9.10~dfsg/base/gsalloc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsalloc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -33,9 +33,8 @@ /* Set by client */ long vm_threshold; /* GC interval */ long max_vm; /* maximum allowed allocation */ - int *psignal; /* if not NULL, store signal_value */ - /* here if we go over the vm_threshold */ - int signal_value; /* value to store in *psignal */ + + int signal_value; /* value to store in gs_lib_ctx->gcsignal */ bool enabled; /* auto GC enabled if true */ /* Set by allocator */ long requested; /* amount of last failing request */ @@ -60,11 +59,11 @@ void ialloc_free_state(gs_ref_memory_t *); /* - * Add a chunk to an externally controlled allocator. Such allocators + * Add a clump to an externally controlled allocator. Such allocators * allocate all objects as immovable, are not garbage-collected, and - * don't attempt to acquire additional memory (or free chunks) on their own. + * don't attempt to acquire additional memory (or free clumps) on their own. */ -int ialloc_add_chunk(gs_ref_memory_t *, ulong, client_name_t); +int ialloc_add_clump(gs_ref_memory_t *, ulong, client_name_t); /* ------ Internal routines ------ */ diff -Nru ghostscript-9.10~dfsg/base/gsalpha.c ghostscript-9.25~dfsg+1/base/gsalpha.c --- ghostscript-9.10~dfsg/base/gsalpha.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsalpha.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,7 +22,7 @@ /* setalpha */ int -gs_setalpha(gs_state * pgs, floatp alpha) +gs_setalpha(gs_gstate * pgs, double alpha) { pgs->alpha = (gx_color_value) (alpha < 0 ? 0 : alpha > 1 ? gx_max_color_value : @@ -33,7 +33,7 @@ /* currentalpha */ float -gs_currentalpha(const gs_state * pgs) +gs_currentalpha(const gs_gstate * pgs) { return (float)pgs->alpha / gx_max_color_value; } diff -Nru ghostscript-9.10~dfsg/base/gsalphac.c ghostscript-9.25~dfsg+1/base/gsalphac.c --- ghostscript-9.10~dfsg/base/gsalphac.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsalphac.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -182,7 +182,7 @@ c_alpha_read(gs_composite_t ** ppcte, const byte * data, uint size, gs_memory_t * mem) { - gs_composite_alpha_params_t params; + gs_composite_alpha_params_t params = {composite_Clear, 0}; int code, nbytes = 1; if (size < 1 || *data > composite_op_last) @@ -271,7 +271,7 @@ /* Create an alpha compositor. */ static int c_alpha_create_default_compositor(const gs_composite_t * pcte, - gx_device ** pcdev, gx_device * dev, gs_imager_state * pis, + gx_device ** pcdev, gx_device * dev, gs_gstate * pgs, gs_memory_t * mem) { gx_device_composite_alpha *cdev; @@ -591,13 +591,16 @@ bool constant_colors = psource->data == 0; uint highlight_value = (1 << dest_bpv) - 1; - sample_load_declare(sptr, sbit); - sample_store_declare(dptr, dbit, dbyte); + const byte *sptr; + int sbit; + byte *dptr; + int dbit; + byte dbyte; { uint xbit = pdest->initial_x * dest_bpv * dest_vpp; - sample_store_setup(dbit, xbit & 7, dest_bpv); + dbit = xbit & 7; dptr = pdest->data + (xbit >> 3); } { @@ -641,29 +644,19 @@ } } /* Preload the output byte buffer if necessary. */ - sample_store_preload(dbyte, dptr, dbit, dest_bpv); + dbyte = (dbit ? (byte)(*dptr & (0xff00 >> dbit)) : 0); for (x = 0; x < num_pixels; ++x) { int j; uint result_alpha = dest_alpha; -/* get_value does not increment the source pointer. */ -#define get_value(v, ptr, bit, bpv, vmax)\ - sample_load16(v, ptr, bit, bpv) - -/* put_value increments the destination pointer. */ -#define put_value(v, ptr, bit, bpv, bbyte)\ - sample_store_next16(v, ptr, bit, bpv, bbyte) - -#define advance(ptr, bit, bpv)\ - sample_next(ptr, bit, bpv) - /* Get destination alpha value. */ if (dest_alpha_j >= 0) { int dabit = dbit + dest_bpv * dest_alpha_j; const byte *daptr = dptr + (dabit >> 3); - get_value(dest_alpha, daptr, dabit & 7, dest_bpv, dest_max); + if (sample_load16(&dest_alpha, daptr, dabit & 7, dest_bpv) < 0) + return_error(gs_error_rangecheck); #ifdef PREMULTIPLY_TOWARDS_WHITE dest_bias = dest_max - dest_alpha; #endif @@ -673,11 +666,18 @@ int sabit = sbit; const byte *saptr = sptr; - if (source_alpha_j == 0) - advance(sptr, sbit, source_bpv); - else - advance(saptr, sabit, source_bpv * source_alpha_j); - get_value(source_alpha, saptr, sabit, source_bpv, source_max); + if (source_alpha_j == 0) { + sbit += (source_bpv); + sptr += sbit >> 3; + sbit &= 7; + } + else { + sabit += (source_bpv * source_alpha_j); + saptr += sabit >> 3; + sabit &= 7; + } + if (sample_load16(&dest_alpha, saptr, sabit, source_bpv) < 0) + return_error(gs_error_rangecheck); #ifdef PREMULTIPLY_TOWARDS_WHITE source_bias = source_max - source_alpha; #endif @@ -710,10 +710,14 @@ if (constant_colors) source_v = pcp->source_values[j - 1]; else { - get_value(source_v, sptr, sbit, source_bpv, source_max); - advance(sptr, sbit, source_bpv); + if (sample_load16(&source_v, sptr, sbit, source_bpv) < 0) + return_error(gs_error_rangecheck); + sbit += (source_bpv); + sptr += sbit >> 3; + sbit &= 7; } - get_value(dest_v, dptr, dbit, dest_bpv, dest_max); + if (sample_load16(&dest_v, dptr, dbit, dest_bpv) < 0) + return_error(gs_error_rangecheck); #ifdef PREMULTIPLY_TOWARDS_WHITE source_v -= source_bias; dest_v -= dest_bias; @@ -816,20 +820,22 @@ continue; } #endif - put_value(result, dptr, dbit, dest_bpv, dbyte); + if (sample_store_next16(result, &dptr, &dbit, dest_bpv, &dbyte) < 0) + return_error(gs_error_rangecheck); } /* Skip a trailing source alpha value. */ - if (source_alpha_j > 0) - advance(sptr, sbit, source_bpv); + if (source_alpha_j > 0) { + sbit += (source_bpv); + sptr += sbit >> 3; + sbit &= 7; + } /* Store a trailing destination alpha value. */ if (dest_alpha_j > 0) - put_value(result_alpha, dptr, dbit, dest_bpv, dbyte); -#undef get_value -#undef put_value -#undef advance + if (sample_store_next16(result_alpha, &dptr, &dbit, dest_bpv, &dbyte) < 0) + return_error(gs_error_rangecheck); } /* Store any partial output byte. */ - sample_store_flush(dptr, dbit, dest_bpv, dbyte); + sample_store_flush(dptr, dbit, dbyte); } return 0; } diff -Nru ghostscript-9.10~dfsg/base/gsalphac.h ghostscript-9.25~dfsg+1/base/gsalphac.h --- ghostscript-9.10~dfsg/base/gsalphac.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsalphac.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsalpha.h ghostscript-9.25~dfsg+1/base/gsalpha.h --- ghostscript-9.10~dfsg/base/gsalpha.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsalpha.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -26,7 +26,7 @@ */ /* Set/read alpha value. */ -int gs_setalpha(gs_state *, floatp); -float gs_currentalpha(const gs_state *); +int gs_setalpha(gs_gstate *, double); +float gs_currentalpha(const gs_gstate *); #endif /* gsalpha_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsargs.c ghostscript-9.25~dfsg+1/base/gsargs.c --- ghostscript-9.10~dfsg/base/gsargs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsargs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -44,13 +44,13 @@ cstr[idx++] = 0xf8 | (rune>>24); } else { cstr[idx++] = 0xfc | (rune>>30); - cstr[idx++] = 0xc0 | (rune>>24); + cstr[idx++] = 0x80 | ((rune>>24) & 0x3f); } - cstr[idx++] = 0xc0 | (rune>>18); + cstr[idx++] = 0x80 | ((rune>>18) & 0x3f); } - cstr[idx++] = 0xc0 | (rune>>12); + cstr[idx++] = 0x80 | ((rune>>12) & 0x3f); } - cstr[idx++] = 0xc0 | (rune>>6); + cstr[idx++] = 0x80 | ((rune>>6) & 0x3f); } cstr[idx++] = 0x80 | (rune & 0x3f); } @@ -96,7 +96,7 @@ if (c == EOF) return EOF; rune = (rune<<6) | (c & 0x3f); - } while (((c & 0xC0) == 0xC0) && --len); + } while (((c & 0xC0) == 0x80) && --len); if (len) { /* The rune we are collecting is improperly formed. */ if (c < 0x80) { @@ -130,6 +130,10 @@ pal->argp = argv + 1; pal->argn = argc - 1; pal->depth = 0; + pal->sources[0].is_file = 0; + pal->sources[0].u.s.memory = NULL; + pal->sources[0].u.s.decoded = 0; + pal->sources[0].u.s.parsed = 0; } /* Push a string onto an arg list. */ @@ -144,18 +148,17 @@ { arg_source *pas; - if (pal->depth == arg_depth_max) { + if (pal->depth+1 == arg_depth_max) { lprintf("Too much nesting of @-files.\n"); return 1; } - pas = &pal->sources[pal->depth]; + pas = &pal->sources[++pal->depth]; pas->is_file = false; pas->u.s.parsed = parsed; pas->u.s.decoded = decoded; pas->u.s.chars = str; pas->u.s.memory = mem; pas->u.s.str = str; - pal->depth++; return 0; } @@ -163,8 +166,9 @@ void arg_finit(arg_list * pal) { + /* No cleanup is required for level 0 */ while (pal->depth) { - arg_source *pas = &pal->sources[--(pal->depth)]; + arg_source *pas = &pal->sources[pal->depth--]; if (pas->is_file) fclose(pas->u.file); @@ -173,168 +177,188 @@ } } -static int get_codepoint(FILE *file, const char **astr, arg_list *pal, arg_source *pas) +static int get_codepoint(arg_list *pal, arg_source *pas) { - return (pas->u.s.decoded ? get_codepoint_utf8(file, astr) : pal->get_codepoint(file, astr)); + int (*fn)(FILE *file, const char **str); + + fn = (!pas->is_file && pas->u.s.decoded ? get_codepoint_utf8 : pal->get_codepoint); + return fn(pas->is_file ? pas->u.file : NULL, &pas->u.s.str); } /* Get the next arg from a list. */ /* Note that these are not copied to the heap. */ -const char * -arg_next(arg_list * pal, int *code, const gs_memory_t *errmem) +/* returns: + * >0 - valid argument + * 0 - arguments exhausted + * <0 - error condition + * *argstr is *always* set: to the arg string if it is valid, + * or to NULL otherwise + */ +int +arg_next(arg_list * pal, const char **argstr, const gs_memory_t *errmem) { arg_source *pas; - FILE *f; - const char *astr = 0; /* initialized only to pacify gcc */ char *cstr; - const char *result; int c; int i; bool in_quote, eol; - top:pas = &pal->sources[pal->depth - 1]; - if (pal->depth == 0) { - if (pal->argn <= 0) /* all done */ - return 0; - pal->argn--; - result = *(pal->argp++); - goto at; - } - if (pas->is_file) - f = pas->u.file; - else if (pas->u.s.parsed) - /* this string is a "pushed-back" argument */ - /* (retrieved by a preceding arg_next(), but not processed) */ - /* assert(pas->u.s.decoded); */ - if (strlen(pas->u.s.str) >= arg_str_max) { - errprintf(errmem, "Command too long: %s\n", pas->u.s.str); - *code = gs_error_Fatal; - return NULL; - } else { + *argstr = NULL; + + /* Loop over arguments, finding one to return. */ + do { + pas = &pal->sources[pal->depth]; + if (!pas->is_file && pas->u.s.parsed) { + /* This string is a "pushed-back" argument (retrieved + * by a preceding arg_next(), but not processed). No + * decoding is required. */ + /* assert(pas->u.s.decoded); */ + if (strlen(pas->u.s.str) >= arg_str_max) { + errprintf(errmem, "Command too long: %s\n", pas->u.s.str); + return_error(gs_error_Fatal); + } strcpy(pal->cstr, pas->u.s.str); - result = pal->cstr; + *argstr = pal->cstr; if (pas->u.s.memory) gs_free_object(pas->u.s.memory, pas->u.s.chars, "arg_next"); pal->depth--; - pas--; - goto at; - } - else - astr = pas->u.s.str, f = NULL; - result = cstr = pal->cstr; -#define is_eol(c) (c == '\r' || c == '\n') - i = 0; - in_quote = false; - eol = true; - c = get_codepoint(f, &astr, pal, pas); - for (i = 0;;) { - if (c == EOF) { - if (in_quote) { - cstr[i] = 0; - errprintf(errmem, - "Unterminated quote in @-file: %s\n", cstr); - *code = gs_error_Fatal; - return NULL; + } else { + /* We need to decode the next argument */ + if (pal->depth == 0) { + if (pal->argn <= 0) + return 0; /* all done */ + /* Move onto the next argument from the string. */ + pal->argn--; + pas->u.s.str = *(pal->argp++); } - if (i == 0) { + /* Skip a prefix of whitespace. */ + do { + c = get_codepoint(pal, pas); + } while (c > 0 && c < 256 && isspace(c)); + if (c == EOF) { /* EOF before any argument characters. */ - if (f != NULL) - fclose(f); + if (pas->is_file) + fclose(pas->u.file); else if (pas->u.s.memory) gs_free_object(pas->u.s.memory, pas->u.s.chars, "arg_next"); + /* If depth is 0, then we are reading from the simple + * argument list and we just hit an "empty" argument + * (such as -o ""). Return this. */ + if (pal->depth == 0) + { + *argstr = pal->cstr; + pal->cstr[0] = 0; + break; + } + /* If depth > 0, then we're reading from a response + * file, and we've hit the end of the response file. + * Pop up one level and continue. */ pal->depth--; - goto top; + continue; /* Next argument */ } - break; - } - /* c != 0 */ - if (c > 0 && c < 256 && isspace(c)) { - if (i == 0) { - c = get_codepoint(f, &astr, pal, pas); - continue; + #define is_eol(c) (c == '\r' || c == '\n') + /* Convert from astr into pal->cstr, and return it as *argstr. */ + *argstr = cstr = pal->cstr; + in_quote = false; + /* We keep track of whether we have just read an "eol" or not, + * in order to skip # characters at the start of a line + * (possibly preceeded by whitespace). We do NOT want this to + * apply to the start of arguments in the arg list, so only + * set eol to be true, if we are in a file. */ + eol = pal->depth > 0; + for (i = 0;;) { + if (c == EOF) { + if (in_quote) { + cstr[i] = 0; + errprintf(errmem, + "Unterminated quote in @-file: %s\n", cstr); + return_error(gs_error_Fatal); + } + break; /* End of arg */ + } + /* c != 0 */ + /* If we aren't parsing from the arglist (i.e. depth > 0) + * then we break on whitespace (unless we're in quotes). */ + if (pal->depth > 0 && !in_quote && c > 0 && c < 256 && isspace(c)) + break; /* End of arg */ + /* c isn't leading or terminating whitespace. */ + if (c == '#' && eol) { + /* Skip a comment. */ + do { + c = get_codepoint(pal, pas); + } while (c != 0 && !is_eol(c) && c != EOF); + if (c == '\r') + c = get_codepoint(pal, pas); + if (c == '\n') + c = get_codepoint(pal, pas); + continue; /* Next char */ + } + if (c == '\\') { + /* Check for \ followed by newline. */ + c = get_codepoint(pal, pas); + if (is_eol(c)) { + if (c == '\r') + c = get_codepoint(pal, pas); + if (c == '\n') + c = get_codepoint(pal, pas); + eol = true; + continue; /* Next char */ + } + /* \ anywhere else is treated as a printing character. */ + /* This is different from the Unix shells. */ + if (i >= arg_str_max - 1) { + cstr[i] = 0; + errprintf(errmem, "Command too long: %s\n", cstr); + return_error(gs_error_Fatal); + } + cstr[i++] = '\\'; + eol = false; + continue; /* Next char */ + } + /* c will become part of the argument */ + if (i >= arg_str_max - 1) { + cstr[i] = 0; + errprintf(errmem, "Command too long: %s\n", cstr); + return_error(gs_error_Fatal); + } + /* Allow quotes to protect whitespace. */ + /* (special cases have already been handled and don't reach this point) */ + if (c == '"') + in_quote = !in_quote; + else + i += codepoint_to_utf8(&cstr[i], c); + eol = is_eol(c); + c = get_codepoint(pal, pas); } - if (!in_quote) - break; - } - /* c isn't leading or terminating whitespace. */ - if (c == '#' && eol) { - /* Skip a comment. */ - do { - c = get_codepoint(f, &astr, pal, pas); - } while (!(c == 0 || is_eol(c))); - if (c == '\r') - c = get_codepoint(f, &astr, pal, pas); - if (c == '\n') - c = get_codepoint(f, &astr, pal, pas); - continue; + cstr[i] = 0; } - if (c == '\\') { - /* Check for \ followed by newline. */ - c = get_codepoint(f, &astr, pal, pas); - if (is_eol(c)) { - if (c == '\r') - c = get_codepoint(f, &astr, pal, pas); - if (c == '\n') - c = get_codepoint(f, &astr, pal, pas); - eol = true; - continue; + + /* At this point *argstr is full of utf8 encoded argument. */ + /* If it's an @filename argument, then deal with it, and never return + * it to the caller. */ + if (pal->expand_ats && **argstr == '@') { + char *fname; + FILE *f; + if (pal->depth+1 == arg_depth_max) { + errprintf(errmem, "Too much nesting of @-files.\n"); + return_error(gs_error_Fatal); } - /* \ anywhere else is treated as a printing character. */ - /* This is different from the Unix shells. */ - if (i >= arg_str_max - 1) { - cstr[i] = 0; - errprintf(errmem, "Command too long: %s\n", cstr); - *code = gs_error_Fatal; - return NULL; + fname = (char *)*argstr + 1; /* skip @ */ + f = (*pal->arg_fopen) (fname, pal->fopen_data); + if (f == NULL) { + errprintf(errmem, "Unable to open command line file %s\n", *argstr); + return_error(gs_error_Fatal); } - cstr[i++] = '\\'; - eol = false; - continue; + pas = &pal->sources[++pal->depth]; + pas->is_file = true; + pas->u.file = f; + *argstr = NULL; /* Empty the argument string so we don't return it. */ + continue; /* Loop back to parse the first arg from the file. */ } - /* c will become part of the argument */ - if (i >= arg_str_max - 1) { - cstr[i] = 0; - errprintf(errmem, "Command too long: %s\n", cstr); - *code = gs_error_Fatal; - return NULL; - } - /* Allow quotes to protect whitespace. */ - /* (special cases have already been handled and don't reach this point) */ - if (c == '"') - in_quote = !in_quote; - else -#ifdef GS_NO_UTF8 - cstr[i++] = c; -#else - i += codepoint_to_utf8(&cstr[i], c); -#endif - eol = is_eol(c); - c = get_codepoint(f, &astr, pal, pas); - } - cstr[i] = 0; - if (f == NULL) - pas->u.s.str = astr; - at:if (pal->expand_ats && result[0] == '@') { - if (pal->depth == arg_depth_max) { - errprintf(errmem, "Too much nesting of @-files.\n"); - *code = gs_error_Fatal; - return NULL; - } - result++; /* skip @ */ - f = (*pal->arg_fopen) (result, pal->fopen_data); - if (f == NULL) { - errprintf(errmem, "Unable to open command line file %s\n", result); - *code = gs_error_Fatal; - return NULL; - } - pal->depth++; - pas++; - pas->is_file = true; - pas->u.file = f; - goto top; - } - return result; + } while (*argstr == NULL || **argstr == 0); /* Until we get a non-empty arg */ + + return 1; } /* Copy an argument string to the heap. */ diff -Nru ghostscript-9.10~dfsg/base/gsargs.h ghostscript-9.25~dfsg+1/base/gsargs.h --- ghostscript-9.10~dfsg/base/gsargs.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsargs.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -26,7 +26,7 @@ * decreases generality, but eliminates the need for dynamic allocation. */ #define arg_str_max 2048 -#define arg_depth_max 10 +#define arg_depth_max 11 typedef struct arg_source_s { bool is_file; union _u { @@ -88,7 +88,14 @@ * Get the next arg from a list. * Note that these are not copied to the heap. */ -const char *arg_next(arg_list * pal, int *code, const gs_memory_t *errmem); +/* returns: + * >0 - valid argument + * 0 - arguments exhausted + * <0 - error condition + * *argstr is *always* set: to the arg string if it is valid, + * or to NULL otherwise + */ +int arg_next(arg_list * pal, const char **argstr, const gs_memory_t *errmem); /* Copy an argument string to the heap. */ char *arg_copy(const char *str, gs_memory_t * mem); diff -Nru ghostscript-9.10~dfsg/base/gsbitcom.c ghostscript-9.25~dfsg+1/base/gsbitcom.c --- ghostscript-9.10~dfsg/base/gsbitcom.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsbitcom.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsbitmap.h ghostscript-9.25~dfsg+1/base/gsbitmap.h --- ghostscript-9.10~dfsg/base/gsbitmap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsbitmap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsbitops.c ghostscript-9.25~dfsg+1/base/gsbitops.c --- ghostscript-9.10~dfsg/base/gsbitops.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsbitops.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,7 +28,7 @@ /* Define masks for little-endian operation. */ /* masks[i] has the first i bits off and the rest on. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN const bits16 mono_copy_masks[17] = { 0xffff, 0xff7f, 0xff3f, 0xff1f, 0xff0f, 0xff07, 0xff03, 0xff01, @@ -38,7 +38,7 @@ }; const bits32 mono_fill_masks[33] = { #define mask(n)\ - ((~0xff | (0xff >> (n & 7))) << (n & -8)) + (((bits32)~0xff | (0xff >> (n & 7))) << (n & -8)) mask( 0),mask( 1),mask( 2),mask( 3),mask( 4),mask( 5),mask( 6),mask( 7), mask( 8),mask( 9),mask(10),mask(11),mask(12),mask(13),mask(14),mask(15), mask(16),mask(17),mask(18),mask(19),mask(20),mask(21),mask(22),mask(23), @@ -354,7 +354,7 @@ /* We know that the first and last rows are non-blank. */ { - uint raster_longs = raster >> arch_log2_sizeof_long; + uint raster_longs = raster >> ARCH_LOG2_SIZEOF_LONG; uint left = raster_longs - 1, right = 0; ulong llong = 0, rlong = 0; const byte *q; @@ -382,22 +382,22 @@ /* Do binary subdivision on edge longs. We assume that */ /* sizeof(long) = 4 or 8. */ -#if arch_sizeof_long > 8 +#if ARCH_SIZEOF_LONG > 8 Error_longs_are_too_large(); #endif -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define last_bits(n) ((1L << (n)) - 1) # define shift_out_last(x,n) ((x) >>= (n)) # define right_justify_last(x,n) DO_NOTHING #else -# define last_bits(n) (-1L << ((arch_sizeof_long * 8) - (n))) +# define last_bits(n) (-1L << ((ARCH_SIZEOF_LONG * 8) - (n))) # define shift_out_last(x,n) ((x) <<= (n)) -# define right_justify_last(x,n) (x) >>= ((arch_sizeof_long * 8) - (n)) +# define right_justify_last(x,n) (x) >>= ((ARCH_SIZEOF_LONG * 8) - (n)) #endif - left <<= arch_log2_sizeof_long + 3; -#if arch_sizeof_long == 8 + left <<= ARCH_LOG2_SIZEOF_LONG + 3; +#if ARCH_SIZEOF_LONG == 8 if (llong & ~last_bits(32)) shift_out_last(llong, 32); else @@ -417,8 +417,8 @@ else left += first_1[(byte) llong] + 4; - right <<= arch_log2_sizeof_long + 3; -#if arch_sizeof_long == 8 + right <<= ARCH_LOG2_SIZEOF_LONG + 3; +#if ARCH_SIZEOF_LONG == 8 if (!(rlong & last_bits(32))) shift_out_last(rlong, 32); else @@ -498,7 +498,7 @@ *dst++ = byte_acegbdfh_to_abcdefgh[( -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN (sword >> 21) | (sword >> 14) | (sword >> 7) | sword #else (sword << 3) | (sword >> 6) | (sword >> 15) | (sword >> 24) @@ -529,21 +529,30 @@ break; } default: { - sample_load_declare_setup(sptr, sbit, source_row, source_bit, - source_depth); - sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit, - dest_depth); + const byte *sptr = source_row; + int sbit = source_bit; + byte *dptr = dest_row; + int dbit = dest_bit; + byte dbbyte = (dbit ? (byte)(*dptr & (0xff00 >> dbit)) : 0); - sample_store_preload(dbbyte, dptr, dbit, dest_depth); + dbbyte = (dbit ? (byte)(*dptr & (0xff00 >> dbit)) : 0); for (x = width; x > 0; --x) { gx_color_index color; uint pixel; - sample_load_next_any(color, sptr, sbit, source_depth); + if (sizeof(color) > 4) { + if (sample_load_next64((uint64_t *)&color, &sptr, &sbit, source_depth) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_load_next32((uint32_t *)&color, &sptr, &sbit, source_depth) < 0) + return_error(gs_error_rangecheck); + } pixel = (color >> shift) & plane_mask; - sample_store_next8(pixel, dptr, dbit, dest_depth, dbbyte); + if (sample_store_next8(pixel, &dptr, &dbit, dest_depth, &dbbyte) < 0) + return_error(gs_error_rangecheck); } - sample_store_flush(dptr, dbit, dest_depth, dbbyte); + sample_store_flush(dptr, dbit, dbbyte); } } } @@ -589,7 +598,7 @@ switch (loop_case) { case EXPAND_8_TO_32: { -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define word_shift (shift) #else int word_shift = 24 - shift; @@ -614,21 +623,31 @@ ++y, source_row += source->raster, dest_row += dest->raster ) { int x; - sample_load_declare_setup(sptr, sbit, source_row, source_bit, - source_depth); - sample_store_declare_setup(dptr, dbit, dbbyte, dest_row, dest_bit, - dest_depth); + const byte *sptr = source_row; + int sbit = source_bit; + byte *dptr = dest_row; + int dbit = dest_bit; + byte dbbyte = (dbit ? (byte)(*dptr & (0xff00 >> dbit)) : 0); - sample_store_preload(dbbyte, dptr, dbit, dest_depth); + dbbyte = (dbit ? (byte)(*dptr & (0xff00 >> dbit)) : 0); for (x = width; x > 0; --x) { uint color; gx_color_index pixel; - sample_load_next8(color, sptr, sbit, source_depth); - pixel = color << shift; - sample_store_next_any(pixel, dptr, dbit, dest_depth, dbbyte); + if (sample_load_next8(&color, &sptr, &sbit, source_depth) < 0) + return_error(gs_error_rangecheck); + + pixel = (gx_color_index)color << shift; + if (sizeof(pixel) > 4) { + if (sample_store_next64(pixel, &dptr, &dbit, dest_depth, &dbbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(pixel, &dptr, &dbit, dest_depth, &dbbyte) < 0) + return_error(gs_error_rangecheck); + } } - sample_store_flush(dptr, dbit, dest_depth, dbbyte); + sample_store_flush(dptr, dbit, dbbyte); } break; diff -Nru ghostscript-9.10~dfsg/base/gsbitops.h ghostscript-9.25~dfsg+1/base/gsbitops.h --- ghostscript-9.10~dfsg/base/gsbitops.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsbitops.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,16 +9,19 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Interface for bitmap operations */ + #ifndef gsbitops_INCLUDED # define gsbitops_INCLUDED +#include "gxcindex.h" + /* ---------------- Pixel processing macros ---------------- */ /* @@ -35,226 +38,389 @@ * representation for better performance. ****** NYI ****** */ -#define sample_end_\ - default: return_error(gs_error_rangecheck);\ - } END - -/* Declare variables for loading. */ -#define sample_load_declare(sptr, sbit)\ - const byte *sptr;\ - int sbit -#define sample_load_declare_setup(sptr, sbit, ptr, bitno, sbpv)\ - const byte *sptr = (ptr);\ - int sample_load_setup(sbit, bitno, sbpv) - -/* Set up to load starting at a given bit number. */ -#define sample_load_setup(sbit, bitno, sbpv)\ - sbit = (bitno) - /* macro to eliminate compiler warning message */ -#define sample_bound_shift(value, shift)\ +#define SAMPLE_BOUND_SHIFT(value, shift)\ ((shift) >= 8 * sizeof(value) ? (shift) & (8 * sizeof(value) - 1) : (shift)) /* Load a value from memory, without incrementing. */ -#define sample_load8_(value, sptr, sbit, sbpv)\ - BEGIN\ - switch ( (sbpv) >> 2 ) {\ - case 0: value = (*(sptr) >> (8 - (sbit) - (sbpv))) & ((sbpv) | 1); break;\ - case 1: value = (*(sptr) >> (4 - (sbit))) & 0xf; break;\ - case 2: value = *(sptr); break; -#define sample_load8(value, sptr, sbit, sbpv)\ - sample_load8_(value, sptr, sbit, sbpv)\ - sample_end_ -#define sample_load_next8(value, sptr, sbit, sbpv)\ - sample_load8(value, sptr, sbit, sbpv);\ - sample_next(sptr, sbit, sbpv) -#define sample_load12_(value, sptr, sbit, sbpv)\ - sample_load8_(value, sptr, sbit, sbpv)\ - case 3:\ - value = ((sbit) ? ((*(sptr) & 0xf) << 8) | (sptr)[1] :\ - (*(sptr) << 4) | ((sptr)[1] >> 4));\ - break; -#define sample_load12(value, sptr, sbit, sbpv)\ - sample_load12_(value, sptr, sbit, sbpv)\ - sample_end_ -#define sample_load_next12(value, sptr, sbit, sbpv)\ - sample_load12(value, sptr, sbit, sbpv);\ - sample_next(sptr, sbit, sbpv) -#define sample_load16_(value, sptr, sbit, sbpv)\ - sample_load12_(value, sptr, sbit, sbpv)\ - case 4: value = (*(sptr) << 8) | (sptr)[1]; break; -#define sample_load16(value, sptr, sbit, sbpv)\ - sample_load16_(value, sptr, sbit, sbpv)\ - sample_end_ -#define sample_load_next16(value, sptr, sbit, sbpv)\ - sample_load16(value, sptr, sbit, sbpv);\ - sample_next(sptr, sbit, sbpv) -#define sample_load32_(value, sptr, sbit, sbpv)\ - sample_load16_(value, sptr, sbit, sbpv)\ - case 6: value = (*(sptr) << 16) | ((sptr)[1] << 8) | (sptr)[2]; break;\ - case 8:\ - value = (*(sptr) << 24) | ((sptr)[1] << 16) | ((sptr)[2] << 8) | sptr[3];\ - break; -#define sample_load32(value, sptr, sbit, sbpv)\ - sample_load32_(value, sptr, sbit, sbpv);\ - sample_end_ -#define sample_load_next32(value, sptr, sbit, sbpv)\ - sample_load32(value, sptr, sbit, sbpv);\ - sample_next(sptr, sbit, sbpv) -#define sample_load64_(value, sptr, sbit, sbpv)\ - sample_load32_(value, sptr, sbit, sbpv);\ - case 10:\ - value = ((gx_color_index)((sptr)[0]) << sample_bound_shift((value), 32)) |\ - ((gx_color_index)((sptr)[1]) << 24) |\ - ((gx_color_index)((sptr)[2]) << 16) |\ - ((gx_color_index)((sptr)[3]) << 8) |\ - (gx_color_index)((sptr)[4]);\ - break;\ - case 12:\ - value = ((gx_color_index)((sptr)[0]) << sample_bound_shift((value), 40)) |\ - ((gx_color_index)((sptr)[1]) << sample_bound_shift((value), 32)) |\ - ((gx_color_index)((sptr)[2]) << 24) |\ - ((gx_color_index)((sptr)[3]) << 16) |\ - ((gx_color_index)((sptr)[4]) << 8) |\ - (gx_color_index)((sptr)[5]);\ - break;\ - case 14:\ - value = ((gx_color_index)((sptr)[0]) << sample_bound_shift((value), 48)) |\ - ((gx_color_index)((sptr)[1]) << sample_bound_shift((value), 40)) |\ - ((gx_color_index)((sptr)[2]) << sample_bound_shift((value), 32)) |\ - ((gx_color_index)((sptr)[3]) << 24) |\ - ((gx_color_index)((sptr)[4]) << 16) |\ - ((gx_color_index)((sptr)[5]) << 8) |\ - (gx_color_index)((sptr)[6]);\ - break;\ - case 16:\ - value = ((gx_color_index)((sptr)[0]) << sample_bound_shift((value), 56)) |\ - ((gx_color_index)((sptr)[1]) << sample_bound_shift((value), 48)) |\ - ((gx_color_index)((sptr)[2]) << sample_bound_shift((value), 40)) |\ - ((gx_color_index)((sptr)[3]) << sample_bound_shift((value), 32)) |\ - ((gx_color_index)((sptr)[4]) << 24) |\ - ((gx_color_index)((sptr)[5]) << 16) |\ - ((gx_color_index)((sptr)[6]) << 8) |\ - (gx_color_index)((sptr)[7]);\ - break; -#define sample_load64(value, sptr, sbit, sbpv)\ - sample_load64_(value, sptr, sbit, sbpv);\ - sample_end_ -#define sample_load_next64(value, sptr, sbit, sbpv)\ - sample_load64(value, sptr, sbit, sbpv);\ - sample_next(sptr, sbit, sbpv) -#define sample_load_any(value, sptr, sbit, sbpv)\ - if (sizeof(value) > 4)\ - sample_load64(value, sptr, sbit, sbpv);\ - else\ - sample_load32(value, sptr, sbit, sbpv) -#define sample_load_next_any(value, sptr, sbit, sbpv)\ - sample_load_any(value, sptr, sbit, sbpv);\ - sample_next(sptr, sbit, sbpv) - -/* Declare variables for storing. */ -#define sample_store_declare(dptr, dbit, dbbyte)\ - byte *dptr;\ - int dbit;\ - byte dbbyte /* maybe should be uint? */ -#define sample_store_declare_setup(dptr, dbit, dbbyte, ptr, bitno, dbpv)\ - byte *dptr = (ptr);\ - int sample_store_setup(dbit, bitno, dbpv);\ - byte /* maybe should be uint? */\ - sample_store_preload(dbbyte, dptr, dbit, dbpv) - -/* Set up to store starting at a given bit number. */ -#define sample_store_setup(dbit, bitno, dbpv)\ - dbit = (bitno) - -/* Prepare for storing by preloading any partial byte. */ -#define sample_store_preload(dbbyte, dptr, dbit, dbpv)\ - dbbyte = ((dbit) ? (byte)(*(dptr) & (0xff00 >> (dbit))) : 0) - -/* Reset (do the same as sample_store_declare, without the declare) */ -#define sample_store_reset(dptr, dbit, dbbyte, ptr, bitno, dbpv)\ - dptr = (ptr);\ - dbit = (bitno);\ - sample_store_preload(dbbyte, dptr, dbit, dbpv) +static int inline sample_load_next8(uint *value, const byte **sptr, int *sbit, int sbpv) +{ + switch ( sbpv >> 2 ) { + case 0: + *value = (**sptr >> (8 - *sbit - sbpv)) & (sbpv | 1); + break; + case 1: + *value = (**sptr >> (4 - *sbit)) & 0xf; + break; + case 2: + *value = **sptr; + break; + default: + return -1; + } + *sbit += sbpv; + *sptr += *sbit >> 3; + *sbit &= 7; + return 0; +} +static int inline sample_load_next12(uint *value, const byte **sptr, int *sbit, int sbpv) +{ + switch ( sbpv >> 2 ) { + case 0: + *value = (**sptr >> (8 - *sbit - sbpv)) & (sbpv | 1); + break; + case 1: + *value = (**sptr >> (4 - *sbit)) & 0xf; + break; + case 2: + *value = **sptr; + break; + case 3: + *value = (*sbit ? ((**sptr & 0xf) << 8) | (*sptr)[1] : + (**sptr << 4) | ((*sptr)[1] >> 4)); + break; + default: + return -1; + } + *sbit += sbpv; + *sptr += *sbit >> 3; + *sbit &= 7; + return 0; +} +static int inline sample_load16(uint *value, const byte *sptr, int sbit, int sbpv) +{ + switch (sbpv >> 2 ) { + case 0: + *value = (*sptr >> (8 - sbit - sbpv)) & (sbpv | 1); + break; + case 1: + *value = (*sptr >> (4 - sbit)) & 0xf; + break; + case 2: + *value = *sptr; + break; + case 3: + *value = (sbit ? ((*sptr & 0xf) << 8) | sptr[1] : + (*sptr << 4) | (sptr[1] >> 4)); + break; + case 4: + *value = (*sptr << 8) | sptr[1]; + break; + default: + return -1; + } + return 0; +} +static int inline sample_load_next16 (ushort *value, const byte **sptr, int *sbit, int sbpv) +{ + switch ( sbpv >> 2 ) { + case 0: + *value = (**sptr >> (8 - *sbit - sbpv)) & (sbpv | 1); + break; + case 1: + *value = (**sptr >> (4 - *sbit)) & 0xf; + break; + case 2: + *value = **sptr; + break; + case 3: + *value = (*sbit ? ((**sptr & 0xf) << 8) | (*sptr)[1] : + (**sptr << 4) | ((*sptr)[1] >> 4)); + break; + case 4: + *value = (**sptr << 8) | (*sptr)[1]; + break; + default: + return -1; + } + *sbit += sbpv; + *sptr += *sbit >> 3; + *sbit &= 7; + return 0; +} +static int inline sample_load_next32(uint32_t *value, const byte **sptr, int *sbit, int sbpv) +{ + switch ( sbpv >> 2 ) { + case 0: + *value = (**sptr >> (8 - *sbit - sbpv)) & (sbpv | 1); + break; + case 1: + *value = (**sptr >> (4 - *sbit)) & 0xf; + break; + case 2: + *value = **sptr; + break; + case 3: + *value = (*sbit ? ((**sptr & 0xf) << 8) | (*sptr)[1] : + (**sptr << 4) | ((*sptr)[1] >> 4)); + break; + case 4: + *value = (**sptr << 8) | (*sptr)[1]; + break; + case 6: + *value = (**sptr << 16) | ((*sptr)[1] << 8) | (*sptr)[2]; + break; + case 8: + *value = (**sptr << 24) | ((*sptr)[1] << 16) | ((*sptr)[2] << 8) | (*sptr)[3]; + break; + default: + return -1; + } + *sbit += sbpv; + *sptr += *sbit >> 3; + *sbit &= 7; + return -1; +} +static int inline sample_load_next64(uint64_t *value, const byte **sptr, int *sbit, int sbpv) +{ + switch ( sbpv >> 2 ) { + case 0: + *value = (**sptr >> (8 - *sbit - sbpv)) & (sbpv | 1); + break; + case 1: + *value = (**sptr >> (4 - *sbit)) & 0xf; + break; + case 2: + *value = **sptr; + break; + case 3: + *value = (*sbit ? ((**sptr & 0xf) << 8) | (*sptr)[1] : + (**sptr << 4) | ((*sptr)[1] >> 4)); + break; + case 4: + *value = (**sptr << 8) | (*sptr)[1]; + break; + case 6: + *value = (**sptr << 16) | ((*sptr)[1] << 8) | (*sptr)[2]; + break; + case 8: + *value = ((uint64_t)(**sptr) << 24) | ((uint64_t)((*sptr)[1]) << 16) | (((uint64_t)(*sptr)[2]) << 8) | (uint64_t)((*sptr)[3]); + break; + case 10: + *value = ((uint64_t)((*sptr)[0]) << SAMPLE_BOUND_SHIFT((*value), 32)) | + ((uint64_t)((*sptr)[1]) << 24) | + ((uint64_t)((*sptr)[2]) << 16) | + ((uint64_t)((*sptr)[3]) << 8) | + (uint64_t)((*sptr)[4]); + break; + case 12: + *value = ((uint64_t)((*sptr)[0]) << SAMPLE_BOUND_SHIFT((*value), 40)) | + ((uint64_t)((*sptr)[1]) << SAMPLE_BOUND_SHIFT((*value), 32)) | + ((uint64_t)((*sptr)[2]) << 24) | + ((uint64_t)((*sptr)[3]) << 16) | + ((uint64_t)((*sptr)[4]) << 8) | + (uint64_t)((*sptr)[5]); + break; + case 14: + *value = ((uint64_t)((*sptr)[0]) << SAMPLE_BOUND_SHIFT((*value), 48)) | + ((uint64_t)((*sptr)[1]) << SAMPLE_BOUND_SHIFT((*value), 40)) | + ((uint64_t)((*sptr)[2]) << SAMPLE_BOUND_SHIFT((*value), 32)) | + ((uint64_t)((*sptr)[3]) << 24) | + ((uint64_t)((*sptr)[4]) << 16) | + ((uint64_t)((*sptr)[5]) << 8) | + (uint64_t)((*sptr)[6]); + break; + case 16: + *value = ((uint64_t)((*sptr)[0]) << SAMPLE_BOUND_SHIFT((*value), 56)) | + ((uint64_t)((*sptr)[1]) << SAMPLE_BOUND_SHIFT((*value), 48)) | + ((uint64_t)((*sptr)[2]) << SAMPLE_BOUND_SHIFT((*value), 40)) | + ((uint64_t)((*sptr)[3]) << SAMPLE_BOUND_SHIFT((*value), 32)) | + ((uint64_t)((*sptr)[4]) << 24) | + ((uint64_t)((*sptr)[5]) << 16) | + ((uint64_t)((*sptr)[6]) << 8) | + (uint64_t)((*sptr)[7]); + break; + default: + return -1; + } + *sbit += sbpv; + *sptr += *sbit >> 3; + *sbit &= 7; + return 0; +} /* Store a value and increment the pointer. */ -#define sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\ - BEGIN\ - switch ( (dbpv) >> 2 ) {\ - case 0:\ - if ( (dbit += (dbpv)) == 8 )\ - *(dptr)++ = dbbyte | (byte)(value), dbbyte = 0, dbit = 0;\ - else dbbyte |= (byte)((value) << (8 - dbit));\ - break;\ - case 1:\ - if ( dbit ^= 4 ) dbbyte = (byte)((value) << 4);\ - else *(dptr)++ = dbbyte | ((byte)(value));\ - break;\ - /* case 2 is deliberately omitted */ -#define sample_store_next8(value, dptr, dbit, dbpv, dbbyte)\ - sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\ - case 2: *(dptr)++ = (byte)(value); break;\ - sample_end_ -#define sample_store_next_12_(value, dptr, dbit, dbbyte)\ - if ( dbit ^= 4 ) *(dptr)++ = (byte)((value) >> 4), dbbyte = (byte)((value) << 4);\ - else\ - *(dptr) = dbbyte | (byte)((value) >> 8), (dptr)[1] = (byte)(value), dptr += 2; -#define sample_store_next_12(value, dptr, dbit, dbbyte)\ - BEGIN sample_store_next_12_(value, dptr, dbit, dbbyte) END -#define sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ - sample_store_next8_(value, dptr, dbit, dbpv, dbbyte)\ - /* case 2 is deliberately omitted */\ - case 3: sample_store_next_12_(value, dptr, dbit, dbbyte) break; -#define sample_store_next12(value, dptr, dbit, dbpv, dbbyte)\ - sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ - case 2: *(dptr)++ = (byte)(value); break;\ - sample_end_ -#define sample_store_next16(value, dptr, dbit, dbpv, dbbyte)\ - sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ - case 4: *(dptr)++ = (byte)((value) >> 8);\ - case 2: *(dptr)++ = (byte)(value); break;\ - sample_end_ -#define sample_store_next32(value, dptr, dbit, dbpv, dbbyte)\ - sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ - case 8: *(dptr)++ = (byte)((value) >> 24);\ - case 6: *(dptr)++ = (byte)((value) >> 16);\ - case 4: *(dptr)++ = (byte)((value) >> 8);\ - case 2: *(dptr)++ = (byte)(value); break;\ - sample_end_ -#define sample_store_next64(value, dptr, dbit, dbpv, dbbyte)\ - sample_store_next12_(value, dptr, dbit, dbpv, dbbyte)\ - case 16: *(dptr)++ = (byte)((value) >> sample_bound_shift((value), 56));\ - case 14: *(dptr)++ = (byte)((value) >> sample_bound_shift((value), 48));\ - case 12: *(dptr)++ = (byte)((value) >> sample_bound_shift((value), 40));\ - case 10: *(dptr)++ = (byte)((value) >> sample_bound_shift((value), 32));\ - case 8: *(dptr)++ = (byte)((value) >> 24);\ - case 6: *(dptr)++ = (byte)((value) >> 16);\ - case 4: *(dptr)++ = (byte)((value) >> 8);\ - case 2: *(dptr)++ = (byte)(value); break;\ - sample_end_ -#define sample_store_next_any(value, dptr, dbit, dbpv, dbbyte)\ - if (sizeof(value) > 4)\ - sample_store_next64(value, dptr, dbit, dbpv, dbbyte);\ - else\ - sample_store_next32(value, dptr, dbit, dbpv, dbbyte) - -/* Skip over storing one sample. This may or may not store into the */ -/* skipped region. */ -#define sample_store_skip_next(dptr, dbit, dbpv, dbbyte)\ - if ( (dbpv) < 8 ) {\ - sample_store_flush(dptr, dbit, dbpv, dbbyte);\ - sample_next(dptr, dbit, dbpv);\ - dbbyte &= ~(0xff << dbit); \ - } else dptr += ((dbpv) >> 3) - -/* Finish storing by flushing any partial byte. */ -#define sample_store_flush(dptr, dbit, dbpv, dbbyte)\ - if ( (dbit) != 0 )\ - *(dptr) = dbbyte | (*(dptr) & (0xff >> (dbit))); - -/* Increment a pointer to the next sample. */ -#define sample_next(ptr, bit, bpv)\ - BEGIN bit += (bpv); ptr += bit >> 3; bit &= 7; END +static int inline sample_store_next8(uint value, byte **dptr, int *dbit, int dbpv, byte *dbbyte) +{ + switch (dbpv >> 2 ) { + case 0: + if ( (*dbit += dbpv) == 8 ) { + *(*dptr)++ = *dbbyte | (byte)value; + *dbbyte = 0; + *dbit = 0; + } + else + *dbbyte |= (byte)(value << (8 - *dbit)); + break; + case 1: + if ( *dbit ^= 4 ) + *dbbyte = (byte)(value << 4); + else + *(*dptr)++ = *dbbyte | ((byte)value);\ + break; + case 2: + *(*dptr)++ = (byte)value; + break; + default: + return -1; + } + return 0; +} + +static void inline sample_store_next_12 (uint value, byte **dptr, int *dbit, byte *dbbyte) +{ + if ( *dbit ^= 4 ) + *(*dptr)++ = (byte)(value >> 4), *dbbyte = (byte)(value << 4); + else + *(*dptr) = *dbbyte | (byte)(value >> 8), (*dptr)[1] = (byte)(value), *dptr += 2; +} +static int inline sample_store_next12(uint value, byte **dptr, int *dbit, int dbpv, byte *dbbyte) +{ + switch (dbpv >> 2 ) { + case 0: + if ((*dbit += dbpv) == 8 ) + *(*dptr)++ = *dbbyte | (byte)value, *dbbyte = 0, *dbit = 0; + else + *dbbyte |= (byte)(value << (8 - *dbit)); + break; + case 1: + if ( *dbit ^= 4 ) + *dbbyte = (byte)(value << 4); + else + *(*dptr)++ = *dbbyte | ((byte)value); + break; + case 3: + if ( *dbit ^= 4 ) + *(*dptr)++ = (byte)(value >> 4), *dbbyte = (byte)(value << 4); + else + *(*dptr) = *dbbyte | (byte)(value >> 8), (*dptr)[1] = (byte)value, *dptr += 2; + break; + case 2: + *(*dptr)++ = (byte)value; + break; + default: + return -1; + } + return 0; +} + +static int inline sample_store_next16(uint value, byte **dptr, int *dbit, int dbpv, byte *dbbyte) +{ + switch (dbpv >> 2 ) { + case 0: + if ( (*dbit += dbpv) == 8 ) + *(*dptr)++ = *dbbyte | (byte)value, *dbbyte = 0, *dbit = 0; + else + *dbbyte |= (byte)(value << (8 - *dbit)); + break; + case 1: + if ( *dbit ^= 4 ) + *dbbyte = (byte)(value << 4); + else + *(*dptr)++ = *dbbyte | ((byte)value); + break; + case 3: + if ( *dbit ^= 4 ) + *(*dptr)++ = (byte)(value >> 4), *dbbyte = (byte)(value << 4); + else + *(*dptr) = *dbbyte | (byte)(value >> 8), (*dptr)[1] = (byte)value, *dptr += 2; + break; + case 4: + *(*dptr)++ = (byte)(value >> 8); + /* fall through */ + case 2: + *(*dptr)++ = (byte)value; + break; + default: + return -1; + } + return 0; +} + +static int inline sample_store_next32(uint32_t value, byte **dptr, int *dbit, int dbpv, byte *dbbyte) +{ + switch (dbpv >> 2 ) { + case 0:\ + if ( (*dbit += dbpv) == 8 ) + *(*dptr)++ = *dbbyte | (byte)value, *dbbyte = 0, *dbit = 0;\ + else + *dbbyte |= (byte)(value << (8 - *dbit)); + break; + case 1: + if ( *dbit ^= 4 ) + *dbbyte = (byte)(value << 4); + else + *(*dptr)++ = *dbbyte | ((byte)value); + break; + case 3: + if ( *dbit ^= 4 ) + *(*dptr)++ = (byte)(value >> 4), *dbbyte = (byte)(value << 4); + else + *(*dptr) = *dbbyte | (byte)(value >> 8), (*dptr)[1] = (byte)value, *dptr += 2; + break; + case 8: *(*dptr)++ = (byte)(value >> 24); + /* fall through */ + case 6: *(*dptr)++ = (byte)(value >> 16); + /* fall through */ + case 4: *(*dptr)++ = (byte)(value >> 8); + /* fall through */ + case 2: *(*dptr)++ = (byte)(value); + break; + default: + return -1; + } + return 0; +} + +static int inline sample_store_next64(uint64_t value, byte **dptr, int *dbit, int dbpv, byte *dbbyte) +{ + switch (dbpv >> 2 ) { + case 0: + if ( (*dbit += dbpv) == 8 ) + *(*dptr)++ = *dbbyte | (byte)value, *dbbyte = 0, *dbit = 0; + else *dbbyte |= (byte)(value << (8 - *dbit)); + break; + case 1: + if ( *dbit ^= 4 ) *dbbyte = (byte)(value << 4); + else *(*dptr)++ = *dbbyte | ((byte)value); + break; + case 3: + if ( *dbit ^= 4 ) *(*dptr)++ = (byte)(value >> 4), *dbbyte = (byte)(value << 4); + else + *(*dptr) = *dbbyte | (byte)(value >> 8), (*dptr)[1] = (byte)value, *dptr += 2; + break; + case 16: *(*dptr)++ = (byte)(value >> SAMPLE_BOUND_SHIFT(value, 56)); + case 14: *(*dptr)++ = (byte)(value >> SAMPLE_BOUND_SHIFT(value, 48)); + case 12: *(*dptr)++ = (byte)(value >> SAMPLE_BOUND_SHIFT(value, 40)); + case 10: *(*dptr)++ = (byte)(value >> SAMPLE_BOUND_SHIFT(value, 32)); + case 8: *(*dptr)++ = (byte)(value >> 24); + case 6: *(*dptr)++ = (byte)(value >> 16); + case 4: *(*dptr)++ = (byte)(value >> 8); + case 2: *(*dptr)++ = (byte)(value); + break; + default: + return -1; + } + return 0; +} + +static void inline sample_store_flush(byte *dptr, int dbit, byte dbbyte) +{ + if (dbit != 0 )\ + *dptr = dbbyte | (*dptr & (0xff >> dbit)); +} + +static void inline sample_store_skip_next(byte **dptr, int *dbit, int dbpv, byte *dbbyte) +{ + if ( dbpv < 8 ) { + sample_store_flush(*dptr, *dbit, *dbbyte); + *dbit += dbpv; + *dptr += (*dbit) >> 3; + *dbit &= 7; + *dbbyte &= ~(0xff << (*dbit)); + } else + *dptr += (dbpv >> 3); +} /* ---------------- Definitions ---------------- */ @@ -263,7 +429,7 @@ * This is always uint, regardless of byte order. */ #define mono_fill_chunk uint -#define mono_fill_chunk_bytes arch_sizeof_int +#define mono_fill_chunk_bytes ARCH_SIZEOF_INT /* ---------------- Procedures ---------------- */ diff -Nru ghostscript-9.10~dfsg/base/gsbittab.c ghostscript-9.25~dfsg+1/base/gsbittab.c --- ghostscript-9.10~dfsg/base/gsbittab.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsbittab.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsbittab.h ghostscript-9.25~dfsg+1/base/gsbittab.h --- ghostscript-9.10~dfsg/base/gsbittab.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsbittab.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsccode.h ghostscript-9.25~dfsg+1/base/gsccode.h --- ghostscript-9.10~dfsg/base/gsccode.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsccode.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -26,7 +26,7 @@ */ typedef ulong gs_char; -#define GS_NO_CHAR ((gs_char)~0L) +#define GS_NO_CHAR ((gs_char)~0UL) /* Backward compatibility */ #define gs_no_char GS_NO_CHAR @@ -74,7 +74,7 @@ typedef ulong gs_glyph; #define GS_NO_GLYPH ((gs_glyph)0x7fffffff) -#if arch_sizeof_long > 4 +#if ARCH_SIZEOF_LONG > 4 # define GS_MIN_CID_GLYPH ((gs_glyph)0x80000000L) #else /* Avoid compiler warnings about signed/unsigned constants. */ @@ -83,10 +83,6 @@ #define GS_MIN_GLYPH_INDEX (GS_MIN_CID_GLYPH | (GS_MIN_CID_GLYPH >> 1)) #define GS_GLYPH_TAG (gs_glyph)(GS_MIN_CID_GLYPH | GS_MIN_GLYPH_INDEX) #define GS_MAX_GLYPH max_ulong -/* Backward compatibility */ -#define gs_no_glyph GS_NO_GLYPH -#define gs_min_cid_glyph GS_MIN_CID_GLYPH -#define gs_max_glyph GS_MAX_GLYPH /* Define a procedure for marking a gs_glyph during garbage collection. */ typedef bool (*gs_glyph_mark_proc_t)(const gs_memory_t *mem, gs_glyph glyph, void *proc_data); diff -Nru ghostscript-9.10~dfsg/base/gsccolor.h ghostscript-9.25~dfsg+1/base/gsccolor.h --- ghostscript-9.10~dfsg/base/gsccolor.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsccolor.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -101,4 +101,15 @@ OTHER } gs_transparency_color_t; + +/* + * Color model component polarity. An "unknown" value has been added to + * this enumeration. This is used for devices and color spaces. + */ +typedef enum { + GX_CINFO_POLARITY_UNKNOWN = -1, + GX_CINFO_POLARITY_SUBTRACTIVE = 0, + GX_CINFO_POLARITY_ADDITIVE +} gx_color_polarity_t; + #endif /* gsccolor_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscdef.c ghostscript-9.25~dfsg+1/base/gscdef.c --- ghostscript-9.10~dfsg/base/gscdef.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscdef.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2013 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -33,7 +33,7 @@ #ifndef GS_COPYRIGHT # define GS_COPYRIGHT\ - "Copyright (C) 2013 Artifex Software, Inc. All rights reserved." + "Copyright (C) 2018 Artifex Software, Inc. All rights reserved." #endif const char *const gs_copyright = GS_COPYRIGHT; @@ -43,6 +43,12 @@ #endif const char *const gs_productfamily = GS_PRODUCTFAMILY; +const char * +gs_program_family_name(void) +{ + return gs_productfamily; +} + #ifndef GS_PRODUCT # define GS_PRODUCT\ GS_PRODUCTFAMILY "" diff -Nru ghostscript-9.10~dfsg/base/gscdefs.h ghostscript-9.25~dfsg+1/base/gscdefs.h --- ghostscript-9.10~dfsg/base/gscdefs.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscdefs.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscdevn.c ghostscript-9.25~dfsg+1/base/gscdevn.c --- ghostscript-9.10~dfsg/base/gscdevn.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscdevn.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,7 +30,7 @@ #include "gxfarith.h" #include "gxfrac.h" #include "gxcmap.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gscoord.h" #include "gzstate.h" #include "gxdevcli.h" @@ -41,6 +41,8 @@ #include "gsicc.h" #include "gsicc_cache.h" #include "gxdevice.h" +#include "gxcie.h" +#include "gxdevsop.h" /* ---------------- Color space ---------------- */ @@ -62,6 +64,8 @@ static cs_proc_set_overprint(gx_set_overprint_DeviceN); static cs_proc_final(gx_final_DeviceN); static cs_proc_serialize(gx_serialize_DeviceN); +static cs_proc_polarity(gx_polarity_DeviceN); + const gs_color_space_type gs_color_space_type_DeviceN = { gs_color_space_index_DeviceN, true, false, &st_color_space_DeviceN, gx_num_components_DeviceN, @@ -72,7 +76,7 @@ gx_set_overprint_DeviceN, gx_final_DeviceN, gx_no_adjust_color_count, gx_serialize_DeviceN, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_DeviceN }; /* GC procedures */ @@ -177,7 +181,7 @@ * in the next gstate down in the gstate list (pgs->saved). */ int -gs_attachattributecolorspace(gs_separation_name sep_name, gs_state * pgs) +gs_attachattributecolorspace(gs_separation_name sep_name, gs_gstate * pgs) { gs_color_space * pdevncs; gs_device_n_attributes * patt; @@ -214,7 +218,7 @@ gs_cspace_set_devn_proc(gs_color_space * pcspace, int (*proc)(const float *, float *, - const gs_imager_state *, + const gs_gstate *, void * ), void *proc_data @@ -236,7 +240,7 @@ * Check if we are using the alternate color space. */ bool -using_alt_color_space(const gs_state * pgs) +using_alt_color_space(const gs_gstate * pgs) { return (pgs->color_component_map.use_alt_cspace); } @@ -244,7 +248,7 @@ /* Map a DeviceN color using a Function. */ int map_devn_using_function(const float *in, float *out, - const gs_imager_state *pis, void *data) + const gs_gstate *pgs, void *data) { gs_function_t *const pfn = data; @@ -295,6 +299,18 @@ return pcs->params.device_n.num_components; } +/* Determine best guess of polarity */ +static gx_color_polarity_t +gx_polarity_DeviceN(const gs_color_space * pcs) +{ + /* DeviceN initializes to 1.0 like a separation so + for now, treat this as subtractive. It is possible + that we may have to do a special test for Red, Green + and Blue but for now, I believe the following is + correct */ + return GX_CINFO_POLARITY_SUBTRACTIVE; +} + /* Initialize a DeviceN color. */ static void gx_init_DeviceN(gs_client_color * pcc, const gs_color_space * pcs) @@ -312,7 +328,7 @@ uint i; for (i = 0; i < pcs->params.device_n.num_components; ++i) { - floatp value = pcc->paint.values[i]; + double value = pcc->paint.values[i]; pcc->paint.values[i] = (value <= 0 ? 0 : value >= 1 ? 1 : value); } } @@ -320,29 +336,29 @@ /* Remap a DeviceN color. */ static const gs_color_space * gx_concrete_space_DeviceN(const gs_color_space * pcs, - const gs_imager_state * pis) + const gs_gstate * pgs) { bool is_lab = false; #ifdef DEBUG /* - * Verify that the color space and imager state info match. + * Verify that the color space and gs_gstate info match. */ - if (pcs->id != pis->color_component_map.cspace_id) - dmprintf(pis->memory, "gx_concrete_space_DeviceN: color space id mismatch"); + if (pcs->id != pgs->color_component_map.cspace_id) + dmprintf(pgs->memory, "gx_concrete_space_DeviceN: color space id mismatch"); #endif /* * Check if we are using the alternate color space. */ - if (pis->color_component_map.use_alt_cspace) { + if (pgs->color_component_map.use_alt_cspace) { /* Need to handle PS CIE space */ if (gs_color_space_is_PSCIE(pcs->base_space)) { if (pcs->base_space->icc_equivalent == NULL) { - gs_colorspace_set_icc_equivalent(pcs->base_space, - &is_lab, pis->memory); + (void)gs_colorspace_set_icc_equivalent(pcs->base_space, + &is_lab, pgs->memory); } return (pcs->base_space->icc_equivalent); } - return cs_concrete_space(pcs->base_space, pis); + return cs_concrete_space(pcs->base_space, pgs); } /* * DeviceN color spaces are concrete (when not using alt. color space). @@ -352,34 +368,49 @@ static int gx_remap_DeviceN(const gs_client_color * pcc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS]; const gs_color_space *pconcs; int i = pcs->type->num_components(pcs),k; - int code; + int code = 0; const gs_color_space *pacs = pcs->base_space; gs_client_color temp; + bool mapped = false; - if ( pcs->cmm_icc_profile_data != NULL && pis->color_component_map.use_alt_cspace) { - /* If needed, reorganize the data. The ICC colorants tag drives the - the laydown order */ + if ( pcs->cmm_icc_profile_data != NULL && pgs->color_component_map.use_alt_cspace) { + /* This is the case where we have placed a N-CLR source profile for + this color space */ if (pcs->cmm_icc_profile_data->devicen_permute_needed) { for ( k = 0; k < i; k++) { temp.paint.values[k] = pcc->paint.values[pcs->cmm_icc_profile_data->devicen_permute[k]]; } - code = pacs->type->remap_color(&temp, pacs, pdc, pis, dev, select); + code = pacs->type->remap_color(&temp, pacs, pdc, pgs, dev, select); } else { - code = pacs->type->remap_color(pcc, pacs, pdc, pis, dev, select); + code = pacs->type->remap_color(pcc, pacs, pdc, pgs, dev, select); } return(code); } else { - code = (*pcs->type->concretize_color)(pcc, pcs, conc, pis, dev); - if (code < 0) - return code; - pconcs = cs_concrete_space(pcs, pis); - code = (*pconcs->type->remap_concrete_color)(conc, pconcs, pdc, pis, dev, select); + /* Check if we are doing any named color management. This check happens + regardless if we are doing the alternate tint transform or not. If + desired, that check could be made in gsicc_transform_named_color and + a decision made to return true or false */ + if (pgs->icc_manager->device_named != NULL) { + /* Try to apply the direct replacement */ + mapped = gx_remap_named_color(pcc, pcs, pdc, pgs, dev, select); + } + if (!mapped) { + cmm_dev_profile_t *dev_profile; + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + code = (*pcs->type->concretize_color)(pcc, pcs, conc, pgs, dev); + if (code < 0) + return code; + pconcs = cs_concrete_space(pcs, pgs); + code = (*pconcs->type->remap_concrete_color)(pconcs, conc, pdc, pgs, dev, select, dev_profile); + } /* Save original color space and color info into dev color */ i = any_abs(i); for (i--; i >= 0; i--) @@ -391,24 +422,20 @@ static int gx_concretize_DeviceN(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { int code, tcode = 0; gs_client_color cc; gs_color_space *pacs = (gs_color_space*) (pcs->base_space); gs_device_n_map *map = pcs->params.device_n.map; bool is_lab; - int k; - int num_des_comps = dev->color_info.num_components; - gsicc_namedcolor_t *named_color; - const gs_separation_name *names = pcs->params.device_n.names; int num_src_comps = pcs->params.device_n.num_components; #ifdef DEBUG /* - * Verify that the color space and imager state info match. + * Verify that the color space and gs_gstate info match. */ - if (pcs->id != pis->color_component_map.cspace_id) + if (pcs->id != pgs->color_component_map.cspace_id) dmprintf(dev->memory, "gx_concretize_DeviceN: color space id mismatch"); #endif @@ -417,50 +444,7 @@ * We must preserve tcode for implementing a semi-hack in the interpreter. */ - if (pis->color_component_map.use_alt_cspace) { - /* First see if we have a named color object that we can use to try - to map from the spot color into device values. */ - if (pis->icc_manager->device_named != NULL) { - /* There is a table present. If we have the colorant name - then get the device values */ - gx_color_value device_values[GX_DEVICE_COLOR_MAX_COMPONENTS]; - byte *pname; - uint name_size; - gsicc_rendering_param_t rendering_params; - - /* Define the rendering intents. */ - rendering_params.black_point_comp = pis->blackptcomp; - rendering_params.graphics_type_tag = dev->graphics_type_tag; - rendering_params.override_icc = false; - rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; - rendering_params.cmm = gsCMM_DEFAULT; - - /* Allocate and initialize name structure */ - named_color = - (gsicc_namedcolor_t*) gs_alloc_bytes(dev->memory, - num_src_comps * sizeof(gsicc_namedcolor_t), - "gx_remap_concrete_DeviceN"); - - for (k = 0; k < num_src_comps; k++) { - pcs->params.device_n.get_colorname_string(dev->memory, names[k], - &pname, &name_size); - named_color[k].colorant_name = (char*) pname; - named_color[k].name_size = name_size; - } - code = gsicc_transform_named_color(pc->paint.values, named_color, - num_src_comps, device_values, - pis, dev, NULL, - &rendering_params); - gs_free_object(dev->memory, named_color, - "gx_remap_concrete_DeviceN"); - if (code == 0) { - for (k = 0; k < num_des_comps; k++){ - pconc[k] = float2frac(((float) device_values[k])/65535.0); - } - return(0); - } - } + if (pgs->color_component_map.use_alt_cspace) { /* Check the 1-element cache first. */ if (map->cache_valid) { int i; @@ -479,27 +463,32 @@ } tcode = (*pcs->params.device_n.map->tint_transform) (pc->paint.values, &cc.paint.values[0], - pis, pcs->params.device_n.map->tint_transform_data); + pgs, pcs->params.device_n.map->tint_transform_data); (*pacs->type->restrict_color)(&cc, pacs); if (tcode < 0) return tcode; /* First check if this was PS based. */ if (gs_color_space_is_PSCIE(pacs)) { - /* If we have not yet create the profile do that now */ + /* We may have to rescale data to 0 to 1 range */ + rescale_cie_colors(pacs, &cc); + /* If we have not yet created the profile do that now */ if (pacs->icc_equivalent == NULL) { - gs_colorspace_set_icc_equivalent(pacs, &(is_lab), pis->memory); + code = gs_colorspace_set_icc_equivalent(pacs, &(is_lab), pgs->memory); + if (code < 0) + return code; } /* Use the ICC equivalent color space */ pacs = pacs->icc_equivalent; } - if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB || - pacs->cmm_icc_profile_data->islab) { + if (pacs->cmm_icc_profile_data && + (pacs->cmm_icc_profile_data->data_cs == gsCIELAB || + pacs->cmm_icc_profile_data->islab)) { /* Get the data in a form that is concrete for the CMM */ cc.paint.values[0] /= 100.0; cc.paint.values[1] = (cc.paint.values[1]+128)/255.0; cc.paint.values[2] = (cc.paint.values[2]+128)/255.0; } - code = cs_concretize_color(&cc, pacs, pconc, pis, dev); + code = cs_concretize_color(&cc, pacs, pconc, pgs, dev); } else { int i; @@ -512,42 +501,39 @@ } static int -gx_remap_concrete_DeviceN(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) +gx_remap_concrete_DeviceN(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select, + const cmm_dev_profile_t *dev_profile) { - int code; + int code = 0; #ifdef DEBUG /* - * Verify that the color space and imager state info match. + * Verify that the color space and gs_gstate info match. */ - if (pcs->id != pis->color_component_map.cspace_id) - dmprintf(pis->memory, "gx_remap_concrete_DeviceN: color space id mismatch"); + if (pcs->id != pgs->color_component_map.cspace_id) + dmprintf(pgs->memory, "gx_remap_concrete_DeviceN: color space id mismatch"); #endif - if (pis->color_component_map.use_alt_cspace) { + if (pgs->color_component_map.use_alt_cspace) { const gs_color_space *pacs = pcs->base_space; - return (*pacs->type->remap_concrete_color) - (pconc, pacs, pdc, pis, dev, select); - } - else { + (pacs, pconc, pdc, pgs, dev, select, dev_profile); + } else { /* If we are going DeviceN out to real sep device that understands these, - and if the destination profile is DeviceN, we print the colors directly. + and if the destination profile is DeviceN, we print the colors directly. Make sure to disable the DeviceN profile color map so that is does not get used in gx_remap_concrete_devicen. We probably should pass something through here but it is a pain due to the change in the proc. */ - cmm_dev_profile_t *dev_profile; bool temp_val; - code = dev_proc(dev, get_profile)(dev, &dev_profile); - if (dev_profile->spotnames != NULL) { + if (dev_profile->spotnames != NULL && code >= 0) { temp_val = dev_profile->spotnames->equiv_cmyk_set; dev_profile->spotnames->equiv_cmyk_set = false; - gx_remap_concrete_devicen(pconc, pdc, pis, dev, select); + gx_remap_concrete_devicen(pconc, pdc, pgs, dev, select); dev_profile->spotnames->equiv_cmyk_set = temp_val; } else { - gx_remap_concrete_devicen(pconc, pdc, pis, dev, select); + gx_remap_concrete_devicen(pconc, pdc, pgs, dev, select); } return 0; } @@ -559,7 +545,7 @@ * structure. */ static int -check_DeviceN_component_names(const gs_color_space * pcs, gs_state * pgs) +check_DeviceN_component_names(const gs_color_space * pcs, gs_gstate * pgs) { const gs_separation_name *names = pcs->params.device_n.names; int num_comp = pcs->params.device_n.num_components; @@ -578,15 +564,24 @@ pcolor_component_map->sep_type = SEP_OTHER; /* * Always use the alternate color space if the current device is - * using an additive color model. + * using an additive color model. The exception is if we have a separation + * device and we are doing transparency blending in an additive color + * space. In that case, the spots are kept separated and blended + * individually per the PDF specification. However, if any of the spots are + * CMYK process colors, we use the alternate color space. This matches AR. */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { + if (!(dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) && + dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0)) && + dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { pcolor_component_map->use_alt_cspace = true; return 0; } /* - * Now check the names of the color components. + * Now check the names of the color components. If any of the colorants + * come back as process type (i.e. CMYK) and we are drawing in a pdf14 + * additive color space then use the alternate tint transform. */ + non_match = false; for(i = 0; i < num_comp; i++ ) { /* @@ -609,11 +604,11 @@ if (strncmp((char *) pname, "None", name_size) != 0) { non_match = true; } else { - /* Device N includes one or more None Entries. We can't reduce + /* Device N includes one or more None Entries. We can't reduce the number of components in the list count, since the None Name(s) are present in the list and GCd and we may need the None entries in the alternate tint trasform calcuation. - So we will detect the presence of them by setting + So we will detect the presence of them by setting pcolor_component_map->color_map[i] = -1 and watching for this case later during the remap operation. */ pcolor_component_map->color_map[i] = -1; @@ -626,7 +621,7 @@ /* Install a DeviceN color space. */ static int -gx_install_DeviceN(gs_color_space * pcs, gs_state * pgs) +gx_install_DeviceN(gs_color_space * pcs, gs_gstate * pgs) { int code; code = check_DeviceN_component_names(pcs, pgs); @@ -638,9 +633,9 @@ /* An nclr profile is in the manager. Grab one that matches. */ cmm_profile_t *profdata = gsicc_finddevicen(pcs, pgs->icc_manager); if (profdata != NULL) - rc_increment(profdata); + gsicc_adjust_profile_rc(profdata, 1, "gx_install_DeviceN"); if (pcs->cmm_icc_profile_data != NULL) - rc_decrement(pcs->cmm_icc_profile_data, "gx_install_DeviceN"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_install_DeviceN"); pcs->cmm_icc_profile_data = profdata; } /* {csrc} was pgs->color_space->params.device_n.use_alt_cspace */ @@ -655,33 +650,32 @@ /* Need to install the nclr cspace */ code = gs_cspace_build_ICC(&nclr_pcs, NULL, pgs->memory); nclr_pcs->cmm_icc_profile_data = pcs->cmm_icc_profile_data; - rc_increment(pcs->cmm_icc_profile_data); - rc_increment_cs(nclr_pcs); /* Suspicious - RJW */ - rc_decrement_cs(pcs->base_space, "gx_install_DeviceN"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "gx_install_DeviceN"); + rc_increment(nclr_pcs); /* FIXME: Suspicious - RJW */ + rc_decrement(pcs->base_space, "gx_install_DeviceN"); pcs->base_space = nclr_pcs; } /* * Give the device an opportunity to capture equivalent colors for any * spot colors which might be present in the color space. */ - if (code >= 0) - code = dev_proc(pgs->device, update_spot_equivalent_colors) + if (code >= 0) { + if (dev_proc(pgs->device, update_spot_equivalent_colors)) + code = dev_proc(pgs->device, update_spot_equivalent_colors) (pgs->device, pgs); + } return code; } /* Set overprint information for a DeviceN color space */ static int -gx_set_overprint_DeviceN(const gs_color_space * pcs, gs_state * pgs) +gx_set_overprint_DeviceN(const gs_color_space * pcs, gs_gstate * pgs) { gs_devicen_color_map * pcmap = &pgs->color_component_map; int code; - gx_device *dev = pgs->device; - cmm_dev_profile_t *dev_profile; - - dev_proc(dev, get_profile)(dev, &(dev_profile)); + /* It is possible that the color map information in the graphic state - is not current due to save/restore and or if we are coming from + is not current due to save/restore and or if we are coming from a color space that is inside a PatternType 2 */ code = check_DeviceN_component_names(pcs, pgs); if (code < 0) @@ -689,17 +683,11 @@ if (pcmap->use_alt_cspace) { const gs_color_space_type* base_type = pcs->base_space->type; - if (dev_profile->sim_overprint && - dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && - !gx_device_must_halftone(dev)) - return gx_simulated_set_overprint(pcs->base_space, pgs); - else { - /* If the base space is DeviceCMYK, handle overprint as DeviceCMYK */ - if ( base_type->index == gs_color_space_index_DeviceCMYK ) - return base_type->set_overprint( pcs->base_space, pgs ); - else - return gx_spot_colors_set_overprint( pcs->base_space, pgs); - } + /* If the base space is DeviceCMYK, handle overprint as DeviceCMYK */ + if ( base_type->index == gs_color_space_index_DeviceCMYK ) + return base_type->set_overprint( pcs->base_space, pgs ); + else + return gx_spot_colors_set_overprint( pcs->base_space, pgs); } else { gs_overprint_params_t params; @@ -709,19 +697,16 @@ params.retain_spot_comps = false; params.drawn_comps = 0; - params.k_value = 0; - /* We should not have to blend if we don't need the alternate tint transform */ - params.blendspot = false; for (i = 0; i < ncomps; i++) { - int mcomp = pcmap->color_map[i]; - + int mcomp = pcmap->color_map[i]; if (mcomp >= 0) gs_overprint_set_drawn_comp( params.drawn_comps, mcomp); } } + /* Only DeviceCMYK can use overprint mode */ pgs->effective_overprint_mode = 0; - return gs_state_update_overprint(pgs, ¶ms); + return gs_gstate_update_overprint(pgs, ¶ms); } } diff -Nru ghostscript-9.10~dfsg/base/gscdevn.h ghostscript-9.25~dfsg+1/base/gscdevn.h --- ghostscript-9.10~dfsg/base/gscdevn.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscdevn.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -42,7 +42,7 @@ gs_color_space * pcspace, int (*proc)(const float *, float *, - const gs_imager_state *, + const gs_gstate *, void * ), void *proc_data @@ -64,7 +64,7 @@ /* Map a DeviceN color using a Function. */ int map_devn_using_function(const float *in, float *out, - const gs_imager_state *pis, void *data); + const gs_gstate *pgs, void *data); /* Serialize a DeviceN map. */ int gx_serialize_device_n_map(const gs_color_space * pcs, gs_device_n_map * m, stream * s); @@ -79,6 +79,6 @@ * color space is in the current (temp) gstate. The DeviceN color space is * in the next gstate down in the gstate list (pgs->saved). */ -int gs_attachattributecolorspace(gs_separation_name sep_name, gs_state * pgs); +int gs_attachattributecolorspace(gs_separation_name sep_name, gs_gstate * pgs); #endif /* gscdevn_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscedata.c ghostscript-9.25~dfsg+1/base/gscedata.c --- ghostscript-9.10~dfsg/base/gscedata.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscedata.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* diff -Nru ghostscript-9.10~dfsg/base/gscedata.h ghostscript-9.25~dfsg+1/base/gscedata.h --- ghostscript-9.10~dfsg/base/gscedata.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscedata.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* diff -Nru ghostscript-9.10~dfsg/base/gscencs.c ghostscript-9.25~dfsg+1/base/gscencs.c --- ghostscript-9.10~dfsg/base/gscencs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscencs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -44,7 +44,7 @@ * lengths of the encodings. */ -const gs_glyph gs_c_min_std_encoding_glyph = gs_min_cid_glyph - 0x10000; +const gs_glyph gs_c_min_std_encoding_glyph = GS_MIN_CID_GLYPH - 0x10000; /* * Encode a character in a known encoding. The only use for glyph numbers @@ -56,7 +56,7 @@ if (ei < 0 || ei >= gs_c_known_encoding_count || ch >= gs_c_known_encoding_lengths[ei] ) - return gs_no_glyph; + return GS_NO_GLYPH; return gs_c_min_std_encoding_glyph + gs_c_known_encodings[ei][ch]; } @@ -121,13 +121,13 @@ /* * Return the glyph number corresponding to a string (the inverse of - * gs_c_glyph_name), or gs_no_glyph if the glyph name is not known. + * gs_c_glyph_name), or GS_NO_GLYPH if the glyph name is not known. */ gs_glyph gs_c_name_glyph(const byte *str, uint len) { if (len == 0 || len > gs_c_known_encoding_max_length) - return gs_no_glyph; + return GS_NO_GLYPH; /* Binary search the character table. */ { uint base = gs_c_known_encoding_offsets[len]; @@ -151,66 +151,5 @@ } } - return gs_no_glyph; + return GS_NO_GLYPH; } - -#ifdef TEST - -/* NOTE: test values will have to be updated if representation changes. */ -#define I_caron N(5,85) -#define I_carriagereturn N(14,154) -#define I_circlemultiply N(14,168) -#define I_numbersign N(10,270) -#define I_copyright N(9,180) -#define I_notdefined N(7, 0) - -/* Test */ -#include -main() -{ - gs_glyph g; - gs_char c; - gs_const_string str; - - /* Test with a short name. */ - g = gs_c_known_encode((gs_char)0237, 1); /* caron */ - printf("caron is %u, should be %u\n", - g - gs_c_min_std_encoding_glyph, I_caron); - gs_c_glyph_name(g, &str); - fwrite(str.data, 1, str.size, stdout); - printf(" should be caron\n"); - - /* Test with a long name. */ - g = gs_c_known_encode((gs_char)0277, 2); /* carriagereturn */ - printf("carriagereturn is %u, should be %u\n", - g - gs_c_min_std_encoding_glyph, I_carriagereturn); - gs_c_glyph_name(g, &str); - fwrite(str.data, 1, str.size, stdout); - printf(" should be carriagereturn\n"); - - /* Test lookup with 3 kinds of names. */ - g = gs_c_name_glyph((const byte *)"circlemultiply", 14); - printf("circlemultiply is %u, should be %u\n", - g - gs_c_min_std_encoding_glyph, I_circlemultiply); - g = gs_c_name_glyph((const byte *)"numbersign", 10); - printf("numbersign is %u, should be %u\n", - g - gs_c_min_std_encoding_glyph, I_numbersign); - g = gs_c_name_glyph((const byte *)"copyright", 9); - printf("copyright is %u, should be %u\n", - g - gs_c_min_std_encoding_glyph, I_copyright); - - /* Test reverse lookup */ - c = gs_c_decode(I_caron + gs_c_min_std_encoding_glyph, 1); - printf("%u (caron) looked up as %u, should be %u\n", - I_caron, c, 0237); - c = gs_c_decode(I_carriagereturn + gs_c_min_std_encoding_glyph, 2); - printf("%u (carriagereturn) looked up as %u, should be %u\n", - I_carriagereturn, c, 0277); - c = gs_c_decode(I_notdefined + gs_c_min_std_encoding_glyph, 1); /* undef'd */ - printf("%u (notdefined) looked up as %d , should be %d\n", - I_notdefined, c, GS_NO_CHAR); - - exit(0); -} - -#endif /* TEST */ diff -Nru ghostscript-9.10~dfsg/base/gscencs.h ghostscript-9.25~dfsg+1/base/gscencs.h --- ghostscript-9.10~dfsg/base/gscencs.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscencs.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -40,7 +40,7 @@ /* * Define the minimum gs_glyph value for glyphs in these encodings. - * gs_glyph values from this value through gs_min_cid_glyph - 1 are reserved. + * gs_glyph values from this value through GS_MIN_CID_GLYPH - 1 are reserved. */ extern const gs_glyph gs_c_min_std_encoding_glyph; diff -Nru ghostscript-9.10~dfsg/base/gschar0.c ghostscript-9.25~dfsg+1/base/gschar0.c --- ghostscript-9.10~dfsg/base/gschar0.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gschar0.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -111,7 +111,7 @@ gs_type0_data *pdata; uint fidx; gs_char chr; - gs_glyph glyph = gs_no_glyph; + gs_glyph glyph = GS_NO_GLYPH; int changed = 0; pte->FontBBox_as_Metrics2.x = pte->FontBBox_as_Metrics2.y = 0; @@ -405,8 +405,8 @@ if_debug3m('J', pte->memory, "[J]CMap returns %d, chr=0x%lx, glyph=0x%lx\n", code, (ulong) chr, (ulong) glyph); if (code == 0) { - if (glyph == gs_no_glyph) { - glyph = gs_min_cid_glyph; + if (glyph == GS_NO_GLYPH) { + glyph = GS_MIN_CID_GLYPH; if_debug0m('J', pte->memory, "... undefined\n"); /* Must select a descendant font anyway, we can't use the type 0 * even for the /.notdef... @@ -415,7 +415,7 @@ goto done; } } else - chr = (gs_char) glyph, glyph = gs_no_glyph; + chr = (gs_char) glyph, glyph = GS_NO_GLYPH; /****** RESCAN chr IF DESCENDANT IS CMAP'ED ******/ break; } @@ -445,7 +445,7 @@ glyph, NULL, &font_index); if (code < 0) { /* failed to load glyph data, reload glyph for CID 0 */ code = ((gs_font_cid0 *)pfont)->cidata.glyph_data((gs_font_base *)pfont, - (gs_glyph)(gs_min_cid_glyph + 0), NULL, &font_index); + (gs_glyph)(GS_MIN_CID_GLYPH + 0), NULL, &font_index); if (code < 0) return_error(gs_error_invalidfont); } diff -Nru ghostscript-9.10~dfsg/base/gschar.c ghostscript-9.25~dfsg+1/base/gschar.c --- ghostscript-9.10~dfsg/base/gschar.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gschar.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,7 +47,7 @@ /* The elements of pw are: wx, wy, llx, lly, urx, ury. */ /* Note that this returns 1 if we just set up the cache device. */ int -gs_setcachedevice_double(gs_show_enum *penum, gs_state *pgs, const double *pw) +gs_setcachedevice_double(gs_show_enum *penum, gs_gstate *pgs, const double *pw) { if (penum->pgs != pgs) return_error(gs_error_rangecheck); @@ -55,7 +55,7 @@ } /* The _float procedure is strictly for backward compatibility. */ int -gs_setcachedevice_float(gs_show_enum * penum, gs_state * pgs, const float *pw) +gs_setcachedevice_float(gs_show_enum * penum, gs_gstate * pgs, const float *pw) { double w[6]; int i; @@ -69,7 +69,7 @@ /* The elements of pw2 are: w0x, w0y, llx, lly, urx, ury, w1x, w1y, vx, vy. */ /* Note that this returns 1 if we just set up the cache device. */ int -gs_setcachedevice2_double(gs_show_enum * penum, gs_state * pgs, +gs_setcachedevice2_double(gs_show_enum * penum, gs_gstate * pgs, const double *pw2) { if (penum->pgs != pgs) @@ -78,7 +78,7 @@ } /* The _float procedure is strictly for backward compatibility. */ int -gs_setcachedevice2_float(gs_show_enum * penum, gs_state * pgs, const float *pw2) +gs_setcachedevice2_float(gs_show_enum * penum, gs_gstate * pgs, const float *pw2) { double w2[10]; int i; @@ -92,8 +92,8 @@ /* Note that this returns 1 if the current show operation is */ /* non-displaying (stringwidth or cshow). */ int -gs_setcharwidth(gs_show_enum * penum, gs_state * pgs, - floatp wx, floatp wy) +gs_setcharwidth(gs_show_enum * penum, gs_gstate * pgs, + double wx, double wy) { double w[2]; @@ -175,7 +175,7 @@ * implementation code requires. */ static int -show_n_begin(gs_show_enum *penum, gs_state *pgs, int code, gs_text_enum_t *pte) +show_n_begin(gs_show_enum *penum, gs_gstate *pgs, int code, gs_text_enum_t *pte) { if (code < 0) return code; diff -Nru ghostscript-9.10~dfsg/base/gschar.h ghostscript-9.25~dfsg+1/base/gschar.h --- ghostscript-9.10~dfsg/base/gschar.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gschar.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -36,7 +36,7 @@ #endif /* Allocate an enumerator. */ -gs_show_enum *gs_show_enum_alloc(gs_memory_t *, gs_state *, client_name_t); +gs_show_enum *gs_show_enum_alloc(gs_memory_t *, gs_gstate *, client_name_t); /* Release the contents of an enumerator. */ /* (This happens automatically if the enumeration finishes normally.) */ @@ -86,15 +86,15 @@ /* Character cache and metrics operators. */ /* gs_setcachedevice* return 1 iff the cache device was just installed. */ -int gs_setcachedevice_float(gs_show_enum *, gs_state *, const float * /*[6] */ ); -int gs_setcachedevice_double(gs_show_enum *, gs_state *, const double * /*[6] */ ); +int gs_setcachedevice_float(gs_show_enum *, gs_gstate *, const float * /*[6] */ ); +int gs_setcachedevice_double(gs_show_enum *, gs_gstate *, const double * /*[6] */ ); #define gs_setcachedevice(penum, pgs, pw)\ gs_setcachedevice_float(penum, pgs, pw) -int gs_setcachedevice2_float(gs_show_enum *, gs_state *, const float * /*[10] */ ); -int gs_setcachedevice2_double(gs_show_enum *, gs_state *, const double * /*[10] */ ); +int gs_setcachedevice2_float(gs_show_enum *, gs_gstate *, const float * /*[10] */ ); +int gs_setcachedevice2_double(gs_show_enum *, gs_gstate *, const double * /*[10] */ ); #define gs_setcachedevice2(penum, pgs, pw2)\ gs_setcachedevice2_float(penum, pgs, pw2) -int gs_setcharwidth(gs_show_enum *, gs_state *, floatp, floatp); +int gs_setcharwidth(gs_show_enum *, gs_gstate *, double, double); /* Return true if we only need the width from the rasterizer */ /* and can short-circuit the full rendering of the character, */ diff -Nru ghostscript-9.10~dfsg/base/gscicach.c ghostscript-9.25~dfsg+1/base/gscicach.c --- ghostscript-9.10~dfsg/base/gscicach.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscicach.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -42,7 +42,7 @@ struct gs_color_index_cache_s { const gs_color_space *direct_space; - gs_imager_state *pis; + gs_gstate *pgs; gx_device *dev; gx_device *trans_dev; int client_num_components; @@ -66,7 +66,7 @@ gs_color_index_cache_t * gs_color_index_cache_create(gs_memory_t *memory, const gs_color_space *direct_space, gx_device *dev, - gs_imager_state *pis, bool need_frac, gx_device *trans_dev) + gs_gstate *pgs, bool need_frac, gx_device *trans_dev) { int client_num_components = cs_num_components(direct_space); int device_num_components = trans_dev->color_info.num_components; @@ -88,7 +88,7 @@ memset(pcic, 0, sizeof(*pcic)); memset(buf, 0, COLOR_INDEX_CACHE_SIZE * sizeof(gs_color_index_cache_elem_t)); pcic->direct_space = direct_space; - pcic->pis = pis; + pcic->pgs = pgs; pcic->dev = dev; pcic->trans_dev = trans_dev; pcic->device_num_components = device_num_components; @@ -221,7 +221,6 @@ return 1; } } - tries+=0; } if (self->used < COLOR_INDEX_CACHE_SIZE) { /* Use a new one */ @@ -261,7 +260,7 @@ /* Must be devn */ for (j = 0; j < device_num_components; j++) { self->frac_values[i * device_num_components + j] = - cv2frac(self->buf[i].color.devn[j]); + cv2frac31(self->buf[i].color.devn[j]); } self->buf[i].frac_values_done = true; } @@ -309,7 +308,7 @@ sizeof(*paint_values) * client_num_components); memcpy(fcc.paint.values, paint_values, sizeof(*paint_values) * client_num_components); - code = pcs->type->remap_color(&fcc, pcs, pdevc, self->pis, + code = pcs->type->remap_color(&fcc, pcs, pdevc, self->pgs, self->trans_dev, gs_color_select_texture); if (code < 0) return code; diff -Nru ghostscript-9.10~dfsg/base/gscicach.h ghostscript-9.25~dfsg+1/base/gscicach.h --- ghostscript-9.10~dfsg/base/gscicach.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscicach.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,7 +27,7 @@ #endif gs_color_index_cache_t *gs_color_index_cache_create(gs_memory_t *memory, - const gs_color_space *direct_space, gx_device *dev, gs_imager_state *pis, bool need_frac, gx_device *trans_dev); + const gs_color_space *direct_space, gx_device *dev, gs_gstate *pgs, bool need_frac, gx_device *trans_dev); void gs_color_index_cache_destroy(gs_color_index_cache_t *this); int gs_cached_color_index(gs_color_index_cache_t *this, const float *paint_values, gx_device_color *pdevc, frac31 *frac_values); diff -Nru ghostscript-9.10~dfsg/base/gscie.c ghostscript-9.25~dfsg+1/base/gscie.c --- ghostscript-9.10~dfsg/base/gscie.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscie.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -50,7 +50,7 @@ /* Allocator structure types */ private_st_joint_caches(); -extern_st(st_imager_state); +extern_st(st_gs_gstate); #define RESTRICTED_INDEX(v, n, itemp)\ ((uint)(itemp = (int)(v)) >= (n) ?\ @@ -150,101 +150,101 @@ /* Default transformation procedures. */ float -a_identity(floatp in, const gs_cie_a * pcie) +a_identity(double in, const gs_cie_a * pcie) { return in; } static float -a_from_cache(floatp in, const gs_cie_a * pcie) +a_from_cache(double in, const gs_cie_a * pcie) { return gs_cie_cached_value(in, &pcie->caches.DecodeA.floats); } float -abc_identity(floatp in, const gs_cie_abc * pcie) +abc_identity(double in, const gs_cie_abc * pcie) { return in; } static float -abc_from_cache_0(floatp in, const gs_cie_abc * pcie) +abc_from_cache_0(double in, const gs_cie_abc * pcie) { return gs_cie_cached_value(in, &pcie->caches.DecodeABC.caches[0].floats); } static float -abc_from_cache_1(floatp in, const gs_cie_abc * pcie) +abc_from_cache_1(double in, const gs_cie_abc * pcie) { return gs_cie_cached_value(in, &pcie->caches.DecodeABC.caches[1].floats); } static float -abc_from_cache_2(floatp in, const gs_cie_abc * pcie) +abc_from_cache_2(double in, const gs_cie_abc * pcie) { return gs_cie_cached_value(in, &pcie->caches.DecodeABC.caches[2].floats); } static float -def_identity(floatp in, const gs_cie_def * pcie) +def_identity(double in, const gs_cie_def * pcie) { return in; } static float -def_from_cache_0(floatp in, const gs_cie_def * pcie) +def_from_cache_0(double in, const gs_cie_def * pcie) { return gs_cie_cached_value(in, &pcie->caches_def.DecodeDEF[0].floats); } static float -def_from_cache_1(floatp in, const gs_cie_def * pcie) +def_from_cache_1(double in, const gs_cie_def * pcie) { return gs_cie_cached_value(in, &pcie->caches_def.DecodeDEF[1].floats); } static float -def_from_cache_2(floatp in, const gs_cie_def * pcie) +def_from_cache_2(double in, const gs_cie_def * pcie) { return gs_cie_cached_value(in, &pcie->caches_def.DecodeDEF[2].floats); } static float -defg_identity(floatp in, const gs_cie_defg * pcie) +defg_identity(double in, const gs_cie_defg * pcie) { return in; } static float -defg_from_cache_0(floatp in, const gs_cie_defg * pcie) +defg_from_cache_0(double in, const gs_cie_defg * pcie) { return gs_cie_cached_value(in, &pcie->caches_defg.DecodeDEFG[0].floats); } static float -defg_from_cache_1(floatp in, const gs_cie_defg * pcie) +defg_from_cache_1(double in, const gs_cie_defg * pcie) { return gs_cie_cached_value(in, &pcie->caches_defg.DecodeDEFG[1].floats); } static float -defg_from_cache_2(floatp in, const gs_cie_defg * pcie) +defg_from_cache_2(double in, const gs_cie_defg * pcie) { return gs_cie_cached_value(in, &pcie->caches_defg.DecodeDEFG[2].floats); } static float -defg_from_cache_3(floatp in, const gs_cie_defg * pcie) +defg_from_cache_3(double in, const gs_cie_defg * pcie) { return gs_cie_cached_value(in, &pcie->caches_defg.DecodeDEFG[3].floats); } float -common_identity(floatp in, const gs_cie_common * pcie) +common_identity(double in, const gs_cie_common * pcie) { return in; } static float -lmn_from_cache_0(floatp in, const gs_cie_common * pcie) +lmn_from_cache_0(double in, const gs_cie_common * pcie) { return gs_cie_cached_value(in, &pcie->caches.DecodeLMN[0].floats); } static float -lmn_from_cache_1(floatp in, const gs_cie_common * pcie) +lmn_from_cache_1(double in, const gs_cie_common * pcie) { return gs_cie_cached_value(in, &pcie->caches.DecodeLMN[1].floats); } static float -lmn_from_cache_2(floatp in, const gs_cie_common * pcie) +lmn_from_cache_2(double in, const gs_cie_common * pcie) { return gs_cie_cached_value(in, &pcie->caches.DecodeLMN[2].floats); } @@ -252,7 +252,7 @@ /* Transformation procedures for accessing an already-loaded cache. */ float -gs_cie_cached_value(floatp in, const cie_cache_floats *pcache) +gs_cie_cached_value(double in, const cie_cache_floats *pcache) { /* * We need to get the same results when we sample an already-loaded @@ -371,12 +371,12 @@ /* ------ Install a CIE color space ------ */ static void cie_cache_mult(gx_cie_vector_cache *, const gs_vector3 *, - const cie_cache_floats *, floatp); + const cie_cache_floats *, double); static bool cie_cache_mult3(gx_cie_vector_cache3_t *, - const gs_matrix3 *, floatp); + const gs_matrix3 *, double); int -gx_install_cie_abc(gs_cie_abc *pcie, gs_state * pgs) +gx_install_cie_abc(gs_cie_abc *pcie, gs_gstate * pgs) { if_debug_matrix3("[c]CIE MatrixABC =", &pcie->MatrixABC); cie_matrix_init(&pcie->MatrixABC); @@ -389,7 +389,7 @@ } int -gx_install_CIEDEFG(gs_color_space * pcs, gs_state * pgs) +gx_install_CIEDEFG(gs_color_space * pcs, gs_gstate * pgs) { gs_cie_defg *pcie = pcs->params.defg; @@ -400,7 +400,7 @@ } int -gx_install_CIEDEF(gs_color_space * pcs, gs_state * pgs) +gx_install_CIEDEF(gs_color_space * pcs, gs_gstate * pgs) { gs_cie_def *pcie = pcs->params.def; @@ -411,13 +411,13 @@ } int -gx_install_CIEABC(gs_color_space * pcs, gs_state * pgs) +gx_install_CIEABC(gs_color_space * pcs, gs_gstate * pgs) { return gx_install_cie_abc(pcs->params.abc, pgs); } int -gx_install_CIEA(gs_color_space * pcs, gs_state * pgs) +gx_install_CIEA(gs_color_space * pcs, gs_gstate * pgs) { gs_cie_a *pcie = pcs->params.a; gs_sample_loop_params_t lp; @@ -440,7 +440,7 @@ /* Load the common caches when installing the color space. */ /* This routine is exported for the benefit of gsicc.c */ void -gx_cie_load_common_cache(gs_cie_common * pcie, gs_state * pgs) +gx_cie_load_common_cache(gs_cie_common * pcie, gs_gstate * pgs) { if_debug_matrix3("[c]CIE MatrixLMN =", &pcie->MatrixLMN); cie_matrix_init(&pcie->MatrixLMN); @@ -540,7 +540,7 @@ } cie_cache_range_temp_t; static inline void check_interpolation_required(cie_cache_range_temp_t *pccr, - cie_cached_value cur, int i, floatp threshold) + cie_cached_value cur, int i, double threshold) { cie_cached_value prev = pccr->prev; @@ -553,7 +553,7 @@ pccr->prev = cur; } static void -cie_cache_set_interpolation(gx_cie_vector_cache *pcache, floatp threshold) +cie_cache_set_interpolation(gx_cie_vector_cache *pcache, double threshold) { cie_cached_value base = pcache->vecs.params.base; cie_cached_value factor = pcache->vecs.params.factor; @@ -594,7 +594,7 @@ */ static void cie_cache_mult(gx_cie_vector_cache * pcache, const gs_vector3 * pvec, - const cie_cache_floats * pcf, floatp threshold) + const cie_cache_floats * pcf, double threshold) { float u = pvec->u, v = pvec->v, w = pvec->w; int i; @@ -648,7 +648,7 @@ */ static bool cie_cache_mult3(gx_cie_vector_cache3_t * pvc, const gs_matrix3 * pmat, - floatp threshold) + double threshold) { cie_cache_mult(&pvc->caches[0], &pmat->cu, &pvc->caches[0].floats, threshold); cie_cache_mult(&pvc->caches[1], &pmat->cv, &pvc->caches[1].floats, threshold); @@ -661,9 +661,65 @@ /* ------ Install a rendering dictionary ------ */ +bool +vector_equal(const gs_vector3 *p1, const gs_vector3 *p2) +{ + if (p1->u != p2->u) + return false; + if (p1->v != p2->v) + return false; + if (p1->w != p2->w) + return false; + return true; +} + +bool +matrix_equal(const gs_matrix3 *p1, const gs_matrix3 *p2) +{ + if (p1->is_identity != p2->is_identity) + return false; + if (!vector_equal(&(p1->cu), &(p2->cu))) + return false; + if (!vector_equal(&(p1->cv), &(p2->cv))) + return false; + if (!vector_equal(&(p1->cw), &(p2->cw))) + return false; + return true; +} + +static bool +transform_equal(const gs_cie_transform_proc3 *p1, const gs_cie_transform_proc3 *p2) +{ + if (p1->proc != p2->proc) + return false; + if (p1->proc_data.size != p2->proc_data.size) + return false; + if (memcmp(p1->proc_data.data, p2->proc_data.data, p1->proc_data.size) != 0) + return false; + if (p1->driver_name != p2->driver_name) + return false; + if (p1->proc_name != p2->proc_name) + return false; + return true; +} + +bool +range_equal(const gs_range3 *p1, const gs_range3 *p2) +{ + int k; + + for (k = 0; k < 3; k++) { + if (p1->ranges[k].rmax != p2->ranges[k].rmax) + return false; + if (p1->ranges[k].rmin != p2->ranges[k].rmin) + return false; + } + return true; +} + /* setcolorrendering */ int -gs_setcolorrendering(gs_state * pgs, gs_cie_render * pcrd) +gs_setcolorrendering(gs_gstate * pgs, gs_cie_render * pcrd) { int code = gs_cie_render_complete(pcrd); const gs_cie_render *pcrd_old = pgs->cie_render; @@ -675,11 +731,11 @@ return 0; /* detect needless reselecting */ joint_ok = pcrd_old != 0 && -#define CRD_SAME(elt) !memcmp(&pcrd->elt, &pcrd_old->elt, sizeof(pcrd->elt)) - CRD_SAME(points.WhitePoint) && CRD_SAME(points.BlackPoint) && - CRD_SAME(MatrixPQR) && CRD_SAME(RangePQR) && - CRD_SAME(TransformPQR); -#undef CRD_SAME + vector_equal(&pcrd->points.WhitePoint, &pcrd_old->points.WhitePoint) && + vector_equal(&pcrd->points.BlackPoint, &pcrd_old->points.BlackPoint) && + matrix_equal(&pcrd->MatrixPQR, &pcrd_old->MatrixPQR) && + range_equal(&pcrd->RangePQR, &pcrd_old->RangePQR) && + transform_equal(&pcrd->TransformPQR, &pcrd_old->TransformPQR); rc_assign(pgs->cie_render, pcrd, "gs_setcolorrendering"); /* Initialize the joint caches if needed. */ if (!joint_ok) @@ -690,14 +746,14 @@ /* currentcolorrendering */ const gs_cie_render * -gs_currentcolorrendering(const gs_state * pgs) +gs_currentcolorrendering(const gs_gstate * pgs) { return pgs->cie_render; } /* Unshare (allocating if necessary) the joint caches. */ gx_cie_joint_caches * -gx_unshare_cie_caches(gs_state * pgs) +gx_unshare_cie_caches(gs_gstate * pgs) { gx_cie_joint_caches *pjc = pgs->cie_joint_caches; @@ -713,7 +769,7 @@ } gx_cie_joint_caches * -gx_currentciecaches(gs_state * pgs) +gx_currentciecaches(gs_gstate * pgs) { return pgs->cie_joint_caches; } @@ -911,7 +967,7 @@ /* Transform a set of ranges. */ static void -cie_transform_range(const gs_range3 * in, floatp mu, floatp mv, floatp mw, +cie_transform_range(const gs_range3 * in, double mu, double mv, double mw, gs_range * out) { float umin = mu * in->ranges[0].rmin, umax = mu * in->ranges[0].rmax; @@ -1104,7 +1160,7 @@ return 0; } const gs_cie_common * -gs_cie_cs_common(const gs_state * pgs) +gs_cie_cs_common(const gs_gstate * pgs) { const gs_cie_abc *ignore_pabc; @@ -1117,7 +1173,7 @@ * exist now. */ int -gs_cie_cs_complete(gs_state * pgs, bool init) +gs_cie_cs_complete(gs_gstate * pgs, bool init) { gx_cie_joint_caches *pjc = gx_unshare_cie_caches(pgs); @@ -1128,12 +1184,12 @@ } /* Actually complete the joint caches. */ int -gs_cie_jc_complete(const gs_imager_state *pis, const gs_color_space *pcs) +gs_cie_jc_complete(const gs_gstate *pgs, const gs_color_space *pcs) { const gs_cie_abc *pabc; const gs_cie_common *common = cie_cs_common_abc(pcs, &pabc); - gs_cie_render *pcrd = pis->cie_render; - gx_cie_joint_caches *pjc = pis->cie_joint_caches; + gs_cie_render *pcrd = pgs->cie_render; + gx_cie_joint_caches *pjc = pgs->cie_joint_caches; if (pjc->cspace_id == pcs->id && pjc->render_id == pcrd->id) @@ -1353,37 +1409,39 @@ } /* - * Initialize (just enough of) an imager state so that "concretizing" colors - * using this imager state will do only the CIE->XYZ mapping. This is a + * Initialize (just enough of) an gs_gstate so that "concretizing" colors + * using this gs_gstate will do only the CIE->XYZ mapping. This is a * semi-hack for the PDF writer. */ int -gx_cie_to_xyz_alloc(gs_imager_state **ppis, const gs_color_space *pcs, +gx_cie_to_xyz_alloc(gs_gstate **ppgs, const gs_color_space *pcs, gs_memory_t *mem) { /* - * In addition to the imager state itself, we need the joint caches. + * In addition to the gs_gstate itself, we need the joint caches. */ - gs_imager_state *pis = - gs_alloc_struct(mem, gs_imager_state, &st_imager_state, - "gx_cie_to_xyz_alloc(imager state)"); + gs_gstate *pgs = + gs_alloc_struct(mem, gs_gstate, &st_gs_gstate, + "gx_cie_to_xyz_alloc(gs_gstate)"); gx_cie_joint_caches *pjc; const gs_cie_abc *pabc; const gs_cie_common *pcie = cie_cs_common_abc(pcs, &pabc); int j; - if (pis == 0) + if (pgs == 0) return_error(gs_error_VMerror); - memset(pis, 0, sizeof(*pis)); /* mostly paranoia */ - pis->memory = mem; - gs_imager_state_initialize(pis, mem); + memset(pgs, 0, sizeof(*pgs)); /* mostly paranoia */ + pgs->memory = mem; + GS_STATE_INIT_VALUES(pgs, 1.0); + gs_gstate_initialize(pgs, mem); pjc = gs_alloc_struct(mem, gx_cie_joint_caches, &st_joint_caches, "gx_cie_to_xyz_free(joint caches)"); if (pjc == 0) { - gs_free_object(mem, pis, "gx_cie_to_xyz_alloc(imager state)"); + gs_free_object(mem, pgs, "gx_cie_to_xyz_alloc(gs_gstate)"); return_error(gs_error_VMerror); } + rc_init(pjc, mem, 1); /* * Perform an abbreviated version of cie_joint_caches_complete. @@ -1401,29 +1459,29 @@ pjc->remap_finish = gx_cie_xyz_remap_finish; pjc->cspace_id = pcs->id; pjc->status = CIE_JC_STATUS_COMPLETED; - pis->cie_joint_caches = pjc; - pis->cie_to_xyz = true; - *ppis = pis; + pgs->cie_joint_caches = pjc; + pgs->cie_to_xyz = true; + *ppgs = pgs; return 0; } void -gx_cie_to_xyz_free(gs_imager_state *pis) +gx_cie_to_xyz_free(gs_gstate *pgs) { - gs_memory_t *mem = pis->memory; + gs_memory_t *mem = pgs->memory; + + rc_decrement(pgs->cie_joint_caches,"gx_cie_to_xyz_free"); - gs_free_object(mem, pis->cie_joint_caches, - "gx_cie_to_xyz_free(joint caches)"); - /* Free up the ICC objects if created */ - if (pis->icc_link_cache != NULL) { - rc_decrement(pis->icc_link_cache,"gx_cie_to_xyz_free"); + /* Free up the ICC objects if created */ /* FIXME: does this need to be thread safe */ + if (pgs->icc_link_cache != NULL) { + rc_decrement(pgs->icc_link_cache,"gx_cie_to_xyz_free"); } - if (pis->icc_manager != NULL) { - rc_decrement(pis->icc_manager,"gx_cie_to_xyz_free"); + if (pgs->icc_manager != NULL) { + rc_decrement(pgs->icc_manager,"gx_cie_to_xyz_free"); } - if (pis->icc_profile_cache != NULL) { - rc_decrement(pis->icc_profile_cache,"gx_cie_to_xyz_free"); + if (pgs->icc_profile_cache != NULL) { + rc_decrement(pgs->icc_profile_cache,"gx_cie_to_xyz_free"); } - gs_free_object(mem, pis, "gx_cie_to_xyz_free(imager state)"); + gs_free_object(mem, pgs, "gx_cie_to_xyz_free(gs_gstate)"); } /* ================ Utilities ================ */ diff -Nru ghostscript-9.10~dfsg/base/gscie.h ghostscript-9.25~dfsg+1/base/gscie.h --- ghostscript-9.10~dfsg/base/gscie.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscie.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -77,7 +77,7 @@ #ifndef CIE_FIXED_FRACTION_BITS /* Take as many bits as we can without having to multiply in two pieces. */ # define CIE_FIXED_FRACTION_BITS\ - ((arch_sizeof_long * 8 - gx_cie_log2_cache_size) / 2 - 1) + ((ARCH_SIZEOF_LONG * 8 - gx_cie_log2_cache_size) / 2 - 1) #endif /* From CIE_RENDER_TABLE_INTERPOLATE */ @@ -93,7 +93,7 @@ /* in a positive int (i.e., leaving 1 bit for the sign), plus a little slop. */ /* The values for interpolation are cie_cached_values by default. */ # define _cie_interpolate_bits\ - min(arch_sizeof_int * 8 - gx_cie_log2_cache_size - 2, 10) + min(ARCH_SIZEOF_INT * 8 - gx_cie_log2_cache_size - 2, 10) # define _cix(i) ((i) >> _cie_interpolate_bits) # define _cif(i) ((int)(i) & ((1 << _cie_interpolate_bits) - 1)) # define cie_interpolate_between(v0, v1, i)\ @@ -130,7 +130,7 @@ /* lies between 0 and gx_cie_cache_size - 1. If the intermediate result */ /* might overflow, compute it in pieces (being a little sloppy). */ # define _cie_product_excess_bits\ - (_cie_fixed_shift * 2 + gx_cie_log2_cache_size - (arch_sizeof_long * 8 - 1)) + (_cie_fixed_shift * 2 + gx_cie_log2_cache_size - (ARCH_SIZEOF_LONG * 8 - 1)) # define cie_cached_product2int(v, factor, fbits)\ (_cie_product_excess_bits > 0 ?\ arith_rshift( (v) * arith_rshift(factor, _cie_product_excess_bits) +\ @@ -200,29 +200,29 @@ typedef struct gs_cie_common_s gs_cie_common; typedef struct gs_cie_wbsd_s gs_cie_wbsd; -typedef float (*gs_cie_a_proc) (floatp, const gs_cie_a *); +typedef float (*gs_cie_a_proc) (double, const gs_cie_a *); -typedef float (*gs_cie_abc_proc) (floatp, const gs_cie_abc *); +typedef float (*gs_cie_abc_proc) (double, const gs_cie_abc *); typedef struct gs_cie_abc_proc3_s { gs_cie_abc_proc procs[3]; } gs_cie_abc_proc3; -typedef float (*gs_cie_def_proc) (floatp, const gs_cie_def *); +typedef float (*gs_cie_def_proc) (double, const gs_cie_def *); typedef struct gs_cie_def_proc3_s { gs_cie_def_proc procs[3]; } gs_cie_def_proc3; -typedef float (*gs_cie_defg_proc) (floatp, const gs_cie_defg *); +typedef float (*gs_cie_defg_proc) (double, const gs_cie_defg *); typedef struct gs_cie_defg_proc4_s { gs_cie_defg_proc procs[4]; } gs_cie_defg_proc4; -typedef float (*gs_cie_common_proc) (floatp, const gs_cie_common *); +typedef float (*gs_cie_common_proc) (double, const gs_cie_common *); typedef struct gs_cie_common_proc3_s { gs_cie_common_proc procs[3]; } gs_cie_common_proc3; -typedef float (*gs_cie_render_proc) (floatp, const gs_cie_render *); +typedef float (*gs_cie_render_proc) (double, const gs_cie_render *); typedef struct gs_cie_render_proc3_s { gs_cie_render_proc procs[3]; } gs_cie_render_proc3; @@ -251,7 +251,7 @@ * Note also that since TransformPQR can fail (if the driver doesn't * recognize the proc_name), it must return a failure code. */ -typedef int (*gs_cie_transform_proc)(int, floatp, const gs_cie_wbsd *, +typedef int (*gs_cie_transform_proc)(int, double, const gs_cie_wbsd *, gs_cie_render *, float *); typedef struct gs_cie_transform_proc3_s { gs_cie_transform_proc proc; @@ -369,7 +369,7 @@ /* Elements common to all CIE color space dictionaries. */ struct gs_cie_common_s { - int (*install_cspace)(gs_color_space *, gs_state *); + int (*install_cspace)(gs_color_space *, gs_gstate *); void *client_data; gs_range3 RangeLMN; gs_cie_common_proc3 DecodeLMN; @@ -595,8 +595,8 @@ * (3 if RGB, 4 if CMYK). */ #define GX_CIE_REMAP_FINISH_PROC(proc)\ - int proc(cie_cached_vector3 vec3, frac *pconc,\ - const gs_imager_state *pis, const gs_color_space *pcs) + int proc(cie_cached_vector3 vec3, frac *pconc, float *xyz,\ + const gs_gstate *pgs, const gs_color_space *pcs) struct gx_cie_joint_caches_s { /* @@ -680,13 +680,13 @@ void gs_cie_def_complete(gs_cie_def *); void gs_cie_abc_complete(gs_cie_abc *); void gs_cie_a_complete(gs_cie_a *); -gx_cie_joint_caches *gx_unshare_cie_caches(gs_state *); -gx_cie_joint_caches *gx_currentciecaches(gs_state *); -const gs_cie_common *gs_cie_cs_common(const gs_state *); -int gs_cie_cs_complete(gs_state *, bool); -int gs_cie_jc_complete(const gs_imager_state *, const gs_color_space *); -float gs_cie_cached_value(floatp, const cie_cache_floats *); -int gx_install_cie_abc(gs_cie_abc *, gs_state *); +gx_cie_joint_caches *gx_unshare_cie_caches(gs_gstate *); +gx_cie_joint_caches *gx_currentciecaches(gs_gstate *); +const gs_cie_common *gs_cie_cs_common(const gs_gstate *); +int gs_cie_cs_complete(gs_gstate *, bool); +int gs_cie_jc_complete(const gs_gstate *, const gs_color_space *); +float gs_cie_cached_value(double, const cie_cache_floats *); +int gx_install_cie_abc(gs_cie_abc *, gs_gstate *); #define CIE_CLAMP_INDEX(index)\ index = (index < 0 ? 0 :\ @@ -841,13 +841,17 @@ /* made available for gsicc_create */ -float common_identity(floatp in, const gs_cie_common * pcie); -float abc_identity(floatp in, const gs_cie_abc * pcie); -float a_identity(floatp in, const gs_cie_a * pcie); +float common_identity(double in, const gs_cie_common * pcie); +float abc_identity(double in, const gs_cie_abc * pcie); +float a_identity(double in, const gs_cie_a * pcie); void cie_mult3(const gs_vector3 * in, register const gs_matrix3 * mat, gs_vector3 * out); void cie_matrix_mult3(const gs_matrix3 *, const gs_matrix3 *, gs_matrix3 *); void cie_matrix_transpose3(const gs_matrix3 *, gs_matrix3 *); +bool matrix_equal(const gs_matrix3 *p1, const gs_matrix3 *p2); +bool range_equal(const gs_range3 *p1, const gs_range3 *p2); +bool vector_equal(const gs_vector3 *p1, const gs_vector3 *p2); + #endif /* gscie_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsciemap.c ghostscript-9.25~dfsg+1/base/gsciemap.c --- ghostscript-9.10~dfsg/base/gsciemap.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsciemap.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,7 +23,7 @@ #include "gxcie.h" #include "gxdevice.h" /* for gxcmap.h */ #include "gxcmap.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gscolor2.h" #include "gsicc_create.h" /* Needed for delayed creation of ICC profiles from CIE color spaces */ #include "gsicc_manage.h" @@ -68,11 +68,11 @@ * the extra level of procedure. */ #ifdef DEBUG -# define GX_CIE_REMAP_FINISH(vec3, pconc, pis, pcs)\ - gx_cie_remap_finish(vec3, pconc, pis, pcs) +# define GX_CIE_REMAP_FINISH(vec3, pconc, cie_xyz, pgs, pcs)\ + gx_cie_remap_finish(vec3, pconc, cie_xyz, pgs, pcs) #else -# define GX_CIE_REMAP_FINISH(vec3, pconc, pis, pcs)\ - ((pis)->cie_joint_caches->remap_finish(vec3, pconc, pis, pcs)) +# define GX_CIE_REMAP_FINISH(vec3, pconc, cie_xyz, pgs, pcs)\ + ((pgs)->cie_joint_caches->remap_finish(vec3, pconc, cie_xyz, pgs, pcs)) #endif /* Forward references */ @@ -109,76 +109,112 @@ if (ranges[k].rmin != 0) return false; if (ranges[k].rmax != 1) return false; } - return(true); + return true; } /* Returns false if range is not 0 1 */ bool -check_cie_range( const gs_color_space * pcs ) +check_cie_range(const gs_color_space * pcs) { - switch(gs_color_space_get_index(pcs)){ + switch(gs_color_space_get_index(pcs)) { case gs_color_space_index_CIEDEFG: - return(check_range(&(pcs->params.defg->RangeDEFG.ranges[0]), 4)); + return check_range(&(pcs->params.defg->RangeDEFG.ranges[0]), 4) ; case gs_color_space_index_CIEDEF: - return(check_range(&(pcs->params.def->RangeDEF.ranges[0]), 3)); + return check_range(&(pcs->params.def->RangeDEF.ranges[0]), 3); case gs_color_space_index_CIEABC: - return(check_range(&(pcs->params.abc->RangeABC.ranges[0]), 3)); + return check_range(&(pcs->params.abc->RangeABC.ranges[0]), 3); case gs_color_space_index_CIEA: - return(check_range(&(pcs->params.a->RangeA), 1)); + return check_range(&(pcs->params.a->RangeA), 1); default: return true; } } gs_range* -get_cie_range( const gs_color_space * pcs ) +get_cie_range(const gs_color_space * pcs) { - switch(gs_color_space_get_index(pcs)){ + switch(gs_color_space_get_index(pcs)) { case gs_color_space_index_CIEDEFG: - return(&(pcs->params.defg->RangeDEFG.ranges[0])); + return &(pcs->params.defg->RangeDEFG.ranges[0]); case gs_color_space_index_CIEDEF: - return(&(pcs->params.def->RangeDEF.ranges[0])); + return &(pcs->params.def->RangeDEF.ranges[0]); case gs_color_space_index_CIEABC: - return(&(pcs->params.abc->RangeABC.ranges[0])); + return &(pcs->params.abc->RangeABC.ranges[0]); case gs_color_space_index_CIEA: - return(&(pcs->params.a->RangeA)); + return &(pcs->params.a->RangeA); default: return NULL; } } static void -rescale_input_color(gs_range *ranges, int num_colorants, +rescale_input_color(gs_range *ranges, int num_colorants, const gs_client_color *src, gs_client_color *des) { int k; for (k = 0; k < num_colorants; k++) { - des->paint.values[k] = - (src->paint.values[k]-ranges[k].rmin)/ - (ranges[k].rmax-ranges[k].rmin); + des->paint.values[k] = (src->paint.values[k] - ranges[k].rmin) / + (ranges[k].rmax - ranges[k].rmin); } } +/* Returns true if rescale was done */ +bool +rescale_cie_colors(const gs_color_space * pcs, gs_client_color *cc) +{ + int num, k; + gs_range *ranges; + + if (!check_cie_range(pcs)) { + switch(gs_color_space_get_index(pcs)) { + case gs_color_space_index_CIEDEFG: + num = 4; + ranges = &(pcs->params.defg->RangeDEFG.ranges[0]); + break; + case gs_color_space_index_CIEDEF: + num = 3; + ranges = &(pcs->params.def->RangeDEF.ranges[0]); + break; + case gs_color_space_index_CIEABC: + num = 3; + ranges = &(pcs->params.abc->RangeABC.ranges[0]); + break; + case gs_color_space_index_CIEA: + num = 1; + ranges = &(pcs->params.a->RangeA); + break; + default: + return false; + } + for (k = 0; k < num; k++) { + cc->paint.values[k] = (cc->paint.values[k] - ranges[k].rmin) / + (ranges[k].rmax - ranges[k].rmin); + } + return true; + } + return false; +} + /* * Test whether a CIE rendering has been defined; ensure that the joint * caches are loaded. Note that the procedure may return 1 if no rendering * has been defined. The 'cie_to_xyz' flag indicates that we don't need a CRD */ static inline int -gx_cie_check_rendering_inline(const gs_color_space * pcs, frac * pconc, const gs_imager_state * pis) +gx_cie_check_rendering_inline(const gs_color_space * pcs, frac * pconc, const gs_gstate * pgs) { - if (pis->cie_render == 0 && !pis->cie_to_xyz) { + if (pgs->cie_render == 0 && !pgs->cie_to_xyz) { /* No rendering has been defined yet: return black. */ pconc[0] = pconc[1] = pconc[2] = frac_0; return 1; } - if (pis->cie_joint_caches->status == CIE_JC_STATUS_COMPLETED) { - if (pis->cie_joint_caches->cspace_id != pcs->id) - pis->cie_joint_caches->status = CIE_JC_STATUS_BUILT; + if (pgs->cie_joint_caches->status == CIE_JC_STATUS_COMPLETED) { + if (pgs->cie_joint_caches->cspace_id != pcs->id) + pgs->cie_joint_caches->status = CIE_JC_STATUS_BUILT; } - if (pis->cie_joint_caches->status != CIE_JC_STATUS_COMPLETED) { - int code = gs_cie_jc_complete(pis, pcs); + if (pgs->cie_render && pgs->cie_joint_caches->status != CIE_JC_STATUS_COMPLETED) { + int code = gs_cie_jc_complete(pgs, pcs); if (code < 0) return code; @@ -186,9 +222,9 @@ return 0; } int -gx_cie_check_rendering(const gs_color_space * pcs, frac * pconc, const gs_imager_state * pis) +gx_cie_check_rendering(const gs_color_space * pcs, frac * pconc, const gs_gstate * pgs) { - return gx_cie_check_rendering_inline(pcs, pconc, pis); + return gx_cie_check_rendering_inline(pcs, pconc, pgs); } /* Common code shared between remap and concretize for defg */ @@ -202,26 +238,34 @@ gx_cie_scalar_cache *defg_caches = &(pcs->params.defg->caches_defg.DecodeDEFG[0]); if_debug0m(gs_debug_flag_icc, memory, - "[icc] Creating ICC profile from defg object"); + "[icc] Creating ICC profile from defg object"); /* build the ICC color space object */ code = gs_cspace_build_ICC(ppcs_icc, NULL, memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC color space"); /* record the cie alt space as the icc alternative color space */ (*ppcs_icc)->base_space = palt_cs; rc_increment_cs(palt_cs); (*ppcs_icc)->cmm_icc_profile_data = gsicc_profile_new(NULL, memory, NULL, 0); + if ((*ppcs_icc)->cmm_icc_profile_data == NULL) + gs_throw(gs_error_VMerror, "Failed to create ICC profile"); code = gsicc_create_fromdefg(pcs, &((*ppcs_icc)->cmm_icc_profile_data->buffer), &((*ppcs_icc)->cmm_icc_profile_data->buffer_size), memory, abc_caches, lmn_caches, defg_caches); - gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEDEFG"); + code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEDEFG"); (*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_DEFG; pcs->icc_equivalent = *ppcs_icc; pcs->icc_equivalent->cmm_icc_profile_data->data_cs = gsCMYK; - return(0); + return 0; } int gx_remap_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs_in, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { gs_color_space *pcs_icc; @@ -229,104 +273,108 @@ gs_client_color scale_pc; gs_color_space *pcs = (gs_color_space *) pcs_in; - if_debug4m('c', pis->memory, "[c]remap CIEDEFG [%g %g %g %g]\n", + if_debug4m('c', pgs->memory, "[c]remap CIEDEFG [%g %g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2], pc->paint.values[3]); /* If we are comming in here then we have not completed the conversion of the DEFG space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - code = gx_ciedefg_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); + code = gx_ciedefg_to_icc(&pcs_icc, pcs, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEDEFG"); } else { pcs_icc = pcs->icc_equivalent; } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.defg->RangeDEFG.ranges[0]), 4)) { - return((pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pis,dev,select)); + return (pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pgs,dev,select); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.defg->RangeDEFG.ranges[0]), 4, pc, &scale_pc); /* Now the icc remap */ - code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pis,dev,select); + code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pgs,dev,select); /* Save unscaled data for high level device (e.g. pdfwrite) */ for (i = 0; i < 4; i++) pdc->ccolor.paint.values[i] = pc->paint.values[i]; pdc->ccolor_valid = true; - return(code); + return code; } /* Render a CIEBasedDEFG color. */ int gx_concretize_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs_in, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { int code; gs_color_space *pcs_icc; gs_client_color scale_pc; gs_color_space *pcs = (gs_color_space *) pcs_in; - if_debug4m('c', pis->memory, "[c]concretize DEFG [%g %g %g %g]\n", + if_debug4m('c', pgs->memory, "[c]concretize DEFG [%g %g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2], pc->paint.values[3]); /* If we are comming in here then we have not completed the conversion of the DEFG space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - code = gx_ciedefg_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); + code = gx_ciedefg_to_icc(&pcs_icc, pcs, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEDEFG"); } else { pcs_icc = pcs->icc_equivalent; } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.defg->RangeDEFG.ranges[0]), 4)) { - return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pgs, dev); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.defg->RangeDEFG.ranges[0]), 4, pc, &scale_pc); /* Now the icc remap */ - return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pgs, dev); } /* Used for when we have to mash entire transform to CIEXYZ */ int gx_psconcretize_CIEA(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis) + frac * pconc, float * cie_xyz, const gs_gstate * pgs) { const gs_cie_a *pcie = pcs->params.a; cie_cached_value a = float2cie_cached(pc->paint.values[0]); cie_cached_vector3 vlmn; int code; - if_debug1m('c', pis->memory, "[c]concretize CIEA %g\n", pc->paint.values[0]); - code = gx_cie_check_rendering_inline(pcs, pconc, pis); + if_debug1m('c', pgs->memory, "[c]concretize CIEA %g\n", pc->paint.values[0]); + code = gx_cie_check_rendering_inline(pcs, pconc, pgs); if (code < 0) return code; if (code == 1) return 0; /* Apply DecodeA and MatrixA. */ - if (!pis->cie_joint_caches->skipDecodeABC) + if (!pgs->cie_joint_caches->skipDecodeABC) vlmn = *LOOKUP_ENTRY(a, &pcie->caches.DecodeA); else vlmn.u = vlmn.v = vlmn.w = a; - GX_CIE_REMAP_FINISH(vlmn, pconc, pis, pcs); + GX_CIE_REMAP_FINISH(vlmn, pconc, cie_xyz, pgs, pcs); return 0; } /* Used for when we have to mash entire transform to CIEXYZ */ int gx_psconcretize_CIEABC(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis) + frac * pconc, float * cie_xyz, const gs_gstate * pgs) { const gs_cie_abc *pcie = pcs->params.abc; cie_cached_vector3 vec3; int code; - if_debug3m('c', pis->memory, "[c]concretize CIEABC [%g %g %g]\n", + if_debug3m('c', pgs->memory, "[c]concretize CIEABC [%g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2]); - code = gx_cie_check_rendering_inline(pcs, pconc, pis); + code = gx_cie_check_rendering_inline(pcs, pconc, pgs); if (code < 0) return code; if (code == 1) @@ -335,17 +383,17 @@ vec3.u = float2cie_cached(pc->paint.values[0]); vec3.v = float2cie_cached(pc->paint.values[1]); vec3.w = float2cie_cached(pc->paint.values[2]); - if (!pis->cie_joint_caches->skipDecodeABC) + if (!pgs->cie_joint_caches->skipDecodeABC) cie_lookup_map3(&vec3 /* ABC => LMN */, &pcie->caches.DecodeABC, "Decode/MatrixABC"); - GX_CIE_REMAP_FINISH(vec3, pconc, pis, pcs); + GX_CIE_REMAP_FINISH(vec3, pconc, cie_xyz, pgs, pcs); return 0; } /* Used for when we have to mash entire transform to CIEXYZ */ int gx_psconcretize_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis) + frac * pconc, float * cie_xyz, const gs_gstate * pgs) { const gs_cie_defg *pcie = pcs->params.defg; int i; @@ -354,10 +402,10 @@ cie_cached_vector3 vec3; int code; - if_debug4m('c', pis->memory, "[c]concretize DEFG [%g %g %g %g]\n", + if_debug4m('c', pgs->memory, "[c]concretize DEFG [%g %g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2], pc->paint.values[3]); - code = gx_cie_check_rendering_inline(pcs, pconc, pis); + code = gx_cie_check_rendering_inline(pcs, pconc, pgs); if (code < 0) return code; if (code == 1) @@ -397,17 +445,17 @@ vec3.v = SCALE_TO_RANGE(pcie->RangeABC.ranges[1], abc[1]); vec3.w = SCALE_TO_RANGE(pcie->RangeABC.ranges[2], abc[2]); /* Apply DecodeABC and MatrixABC. */ - if (!pis->cie_joint_caches->skipDecodeABC) + if (!pgs->cie_joint_caches->skipDecodeABC) cie_lookup_map3(&vec3 /* ABC => LMN */, &pcie->caches.DecodeABC, "Decode/MatrixABC"); - GX_CIE_REMAP_FINISH(vec3, pconc, pis, pcs); + GX_CIE_REMAP_FINISH(vec3, pconc, cie_xyz, pgs, pcs); return 0; } /* Render a CIEBasedDEF color. */ int gx_psconcretize_CIEDEF(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis) + frac * pconc, float * cie_xyz, const gs_gstate * pgs) { const gs_cie_def *pcie = pcs->params.def; int i; @@ -416,10 +464,10 @@ cie_cached_vector3 vec3; int code; - if_debug3m('c', pis->memory, "[c]concretize DEF [%g %g %g]\n", + if_debug3m('c', pgs->memory, "[c]concretize DEF [%g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2]); - code = gx_cie_check_rendering_inline(pcs, pconc, pis); + code = gx_cie_check_rendering_inline(pcs, pconc, pgs); if (code < 0) return code; if (code == 1) @@ -455,10 +503,10 @@ vec3.v = SCALE_TO_RANGE(pcie->RangeABC.ranges[1], abc[1]); vec3.w = SCALE_TO_RANGE(pcie->RangeABC.ranges[2], abc[2]); /* Apply DecodeABC and MatrixABC. */ - if (!pis->cie_joint_caches->skipDecodeABC) + if (!pgs->cie_joint_caches->skipDecodeABC) cie_lookup_map3(&vec3 /* ABC => LMN */, &pcie->caches.DecodeABC, "Decode/MatrixABC"); - GX_CIE_REMAP_FINISH(vec3, pconc, pis, pcs); + GX_CIE_REMAP_FINISH(vec3, pconc, cie_xyz, pgs, pcs); return 0; } #undef SCALE_TO_RANGE @@ -467,33 +515,43 @@ static int gx_ciedef_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, gs_memory_t *memory) { - int code = 0; + int code; gs_color_space *palt_cs = pcs->base_space; gx_cie_vector_cache *abc_caches = &(pcs->params.abc->caches.DecodeABC.caches[0]); gx_cie_scalar_cache *lmn_caches = &(pcs->params.abc->common.caches.DecodeLMN[0]); gx_cie_scalar_cache *def_caches = &(pcs->params.def->caches_def.DecodeDEF[0]); - if_debug0(gs_debug_flag_icc,"[icc] Creating ICC profile from def object"); + if_debug0(gs_debug_flag_icc,"[icc] Creating ICC profile from def object"); /* build the ICC color space object */ code = gs_cspace_build_ICC(ppcs_icc, NULL, memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC color space"); /* record the cie alt space as the icc alternative color space */ (*ppcs_icc)->base_space = palt_cs; rc_increment_cs(palt_cs); (*ppcs_icc)->cmm_icc_profile_data = gsicc_profile_new(NULL, memory, NULL, 0); + if ((*ppcs_icc)->cmm_icc_profile_data == NULL) + gs_throw(gs_error_VMerror, "Failed to create ICC profile"); code = gsicc_create_fromdef(pcs, &((*ppcs_icc)->cmm_icc_profile_data->buffer), &((*ppcs_icc)->cmm_icc_profile_data->buffer_size), memory, abc_caches, lmn_caches, def_caches); - gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC profile from CIEDEF"); + code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC profile from CIEDEF"); (*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_DEF; /* Assign to the icc_equivalent member variable */ pcs->icc_equivalent = *ppcs_icc; - pcs->icc_equivalent->cmm_icc_profile_data->data_cs = gsUNDEFINED; - return(0); + + /* Bug 699104. The ICC profile is built to be RGB based. Reflect that here */ + pcs->icc_equivalent->cmm_icc_profile_data->data_cs = gsRGB; + return 0; } int gx_remap_CIEDEF(const gs_client_color * pc, const gs_color_space * pcs_in, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { gs_color_space *pcs_icc; @@ -501,63 +559,67 @@ int i,code; gs_color_space *pcs = (gs_color_space *) pcs_in; - if_debug3m('c', pis->memory, "[c]remap CIEDEF [%g %g %g]\n", + if_debug3m('c', pgs->memory, "[c]remap CIEDEF [%g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2]); /* If we are comming in here then we have not completed the conversion of the DEF space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - gx_ciedef_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); + code = gx_ciedef_to_icc(&pcs_icc, pcs, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC profile from CIEDEF"); } else { pcs_icc = pcs->icc_equivalent; } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.def->RangeDEF.ranges[0]), 3)) { - return((pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pis,dev,select)); + return (pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pgs,dev,select); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.def->RangeDEF.ranges[0]), 3, pc, &scale_pc); /* Now the icc remap */ - code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pis,dev,select); + code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pgs,dev,select); /* Save unscaled data for high level device (e.g. pdfwrite) */ for (i = 0; i < 3; i++) pdc->ccolor.paint.values[i] = pc->paint.values[i]; pdc->ccolor_valid = true; - return(code); + return code; } /* Render a CIEBasedDEF color. */ int gx_concretize_CIEDEF(const gs_client_color * pc, const gs_color_space * pcs_in, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { - int code; + int code = 0; gs_color_space *pcs_icc; gs_client_color scale_pc; gs_color_space *pcs = (gs_color_space *) pcs_in; - if_debug3m('c', pis->memory, "[c]concretize DEF [%g %g %g]\n", + if_debug3m('c', pgs->memory, "[c]concretize DEF [%g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2]); /* If we are comming in here then we have not completed the conversion of the DEF space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - code = gx_ciedef_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); + code = gx_ciedef_to_icc(&pcs_icc, pcs, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC profile from CIEDEF"); } else { pcs_icc = pcs->icc_equivalent; } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.def->RangeDEF.ranges[0]), 3)) { - return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pgs, dev); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.def->RangeDEF.ranges[0]), 3, pc, &scale_pc); /* Now the icc remap */ - return((pcs_icc->type->concretize_color)(&scale_pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(&scale_pc, pcs_icc, pconc, pgs, dev); } #undef SCALE_TO_RANGE @@ -566,27 +628,35 @@ gx_cieabc_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, bool *islab, gs_memory_t *memory) { - int code = 0; + int code; gs_color_space *palt_cs = pcs->base_space; gx_cie_vector_cache *abc_caches = &(pcs->params.abc->caches.DecodeABC.caches[0]); gx_cie_scalar_cache *lmn_caches = &(pcs->params.abc->common.caches.DecodeLMN[0]); - if_debug0m(gs_debug_flag_icc, memory, "[icc] Creating ICC profile from abc object"); + if_debug0m(gs_debug_flag_icc, memory, "[icc] Creating ICC profile from abc object"); /* build the ICC color space object */ code = gs_cspace_build_ICC(ppcs_icc, NULL, memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile"); /* record the cie alt space as the icc alternative color space */ (*ppcs_icc)->base_space = palt_cs; rc_increment_cs(palt_cs); (*ppcs_icc)->cmm_icc_profile_data = gsicc_profile_new(NULL, memory, NULL, 0); + if ((*ppcs_icc)->cmm_icc_profile_data == NULL) + gs_throw(gs_error_VMerror, "Failed to create ICC profile"); code = gsicc_create_fromabc(pcs, &((*ppcs_icc)->cmm_icc_profile_data->buffer), &((*ppcs_icc)->cmm_icc_profile_data->buffer_size), memory, abc_caches, lmn_caches, islab); - gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC profile from CIEABC"); + code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC profile from CIEDEF"); (*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_ABC; /* Assign to the icc_equivalent member variable */ pcs->icc_equivalent = *ppcs_icc; pcs->icc_equivalent->cmm_icc_profile_data->data_cs = gsRGB; - return(0); + return 0; } /* Render a CIEBasedABC color. */ @@ -594,106 +664,118 @@ /* needs to be efficient. */ int gx_remap_CIEABC(const gs_client_color * pc, const gs_color_space * pcs_in, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { gs_color_space *pcs_icc; gs_client_color scale_pc; bool islab; - int i,code; + int i, code; gs_color_space *pcs = (gs_color_space *) pcs_in; - - if_debug3m('c', pis->memory, "[c]remap CIEABC [%g %g %g]\n", + if_debug3m('c', pgs->memory, "[c]remap CIEABC [%g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2]); /* If we are comming in here then we have not completed the conversion of the ABC space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - gx_cieabc_to_icc(&pcs_icc, pcs, &islab, pis->memory->stable_memory); + code = gx_cieabc_to_icc(&pcs_icc, pcs, &islab, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEABC"); } else { pcs_icc = pcs->icc_equivalent; - } + } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.abc->RangeABC.ranges[0]), 3)) { - return((pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pis,dev,select)); + return (pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pgs,dev,select); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.abc->RangeABC.ranges[0]), 3, pc, &scale_pc); /* Now the icc remap */ - code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pis,dev,select); + code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pgs,dev,select); /* Save unscaled data for high level device (e.g. pdfwrite) */ for (i = 0; i < 3; i++) pdc->ccolor.paint.values[i] = pc->paint.values[i]; pdc->ccolor_valid = true; /* Now the icc remap */ - return(code); + return code; } int gx_concretize_CIEABC(const gs_client_color * pc, const gs_color_space * pcs_in, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { gs_color_space *pcs_icc; gs_client_color scale_pc; bool islab; gs_color_space *pcs = (gs_color_space *) pcs_in; + int code = 0; - if_debug3m('c', pis->memory, "[c]concretize CIEABC [%g %g %g]\n", + if_debug3m('c', pgs->memory, "[c]concretize CIEABC [%g %g %g]\n", pc->paint.values[0], pc->paint.values[1], pc->paint.values[2]); /* If we are comming in here then we have not completed the conversion of the ABC space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - gx_cieabc_to_icc(&pcs_icc, pcs, &islab, pis->memory->stable_memory); + code = gx_cieabc_to_icc(&pcs_icc, pcs, &islab, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEABC"); } else { pcs_icc = pcs->icc_equivalent; } /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.abc->RangeABC.ranges[0]), 3)) { - return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pgs, dev); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.abc->RangeABC.ranges[0]), 3, pc, &scale_pc); /* Now the icc remap */ - return((pcs_icc->type->concretize_color)(&scale_pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(&scale_pc, pcs_icc, pconc, pgs, dev); } /* Common code shared between remap and concretize */ static int gx_ciea_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, gs_memory_t *memory) { - int code = 0; + int code; gs_color_space *palt_cs = pcs->base_space; gx_cie_vector_cache *a_cache = &(pcs->params.a->caches.DecodeA); gx_cie_scalar_cache *lmn_caches = &(pcs->params.a->common.caches.DecodeLMN[0]); if_debug0m(gs_debug_flag_icc, memory, - "[icc] Creating ICC profile from CIEA object"); + "[icc] Creating ICC profile from CIEA object"); /* build the ICC color space object */ code = gs_cspace_build_ICC(ppcs_icc, NULL, memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile"); /* record the cie alt space as the icc alternative color space */ (*ppcs_icc)->base_space = palt_cs; rc_increment_cs(palt_cs); (*ppcs_icc)->cmm_icc_profile_data = gsicc_profile_new(NULL, memory, NULL, 0); + if ((*ppcs_icc)->cmm_icc_profile_data == NULL) + gs_throw(gs_error_VMerror, "Failed to create ICC profile"); code = gsicc_create_froma(pcs, &((*ppcs_icc)->cmm_icc_profile_data->buffer), &((*ppcs_icc)->cmm_icc_profile_data->buffer_size), memory, a_cache, lmn_caches); - gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEA"); + code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data); + if (code < 0) + return gs_rethrow(code, "Failed to build ICC profile from CIEDEF"); (*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_A; /* Assign to the icc_equivalent member variable */ pcs->icc_equivalent = *ppcs_icc; pcs->icc_equivalent->cmm_icc_profile_data->data_cs = gsGRAY; - return(code); + return 0; } int gx_remap_CIEA(const gs_client_color * pc, const gs_color_space * pcs_in, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { int code; @@ -706,7 +788,9 @@ the conversion of the CIE A space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - code = gx_ciea_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); + code = gx_ciea_to_icc(&pcs_icc, pcs, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEA"); } else { /* Once the ICC color space is set, we should be doing all the remaps through the ICC equivalent */ pcs_icc = pcs->icc_equivalent; @@ -714,24 +798,24 @@ /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.a->RangeA), 1)) { - return((pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pis,dev,select)); + return (pcs_icc->type->remap_color)(pc,pcs_icc,pdc,pgs,dev,select); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.a->RangeA), 1, pc, &scale_pc); /* Now the icc remap */ - code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pis,dev,select); + code = (pcs_icc->type->remap_color)(&scale_pc,pcs_icc,pdc,pgs,dev,select); /* Save unscaled data for high level device (e.g. pdfwrite) */ pdc->ccolor.paint.values[0] = pc->paint.values[0]; pdc->ccolor_valid = true; - return(code); + return code; } /* Render a CIEBasedA color. */ int gx_concretize_CIEA(const gs_client_color * pc, const gs_color_space * pcs_in, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { - int code; + int code = 0; gs_color_space *pcs_icc; gs_client_color scale_pc; gs_color_space *pcs = (gs_color_space *) pcs_in; @@ -741,7 +825,9 @@ the conversion of the CIE A space to an ICC type. We will finish that process now. */ if (pcs->icc_equivalent == NULL) { - code = gx_ciea_to_icc(&pcs_icc, pcs, pis->memory->stable_memory); + code = gx_ciea_to_icc(&pcs_icc, pcs, pgs->memory->stable_memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC profile from CIEA"); } else { /* Once the ICC color space is set, we should be doing all the remaps through the ICC equivalent */ pcs_icc = pcs->icc_equivalent; @@ -749,12 +835,12 @@ /* Rescale the input based upon the input range since profile is created to remap this range from 0 to 1 */ if (check_range(&(pcs->params.a->RangeA), 1)) { - return((pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(pc, pcs_icc, pconc, pgs, dev); } /* Do the rescale from 0 to 1 */ rescale_input_color(&(pcs->params.a->RangeA), 1, pc, &scale_pc); /* Now the icc remap */ - return((pcs_icc->type->concretize_color)(&scale_pc, pcs_icc, pconc, pis, dev)); + return (pcs_icc->type->concretize_color)(&scale_pc, pcs_icc, pconc, pgs, dev); } /* Call for cases where the equivalent icc color space needs to be set */ @@ -762,55 +848,57 @@ gs_colorspace_set_icc_equivalent(gs_color_space *pcs, bool *islab, gs_memory_t *memory) { - gs_color_space_index color_space_index = gs_color_space_get_index(pcs); - gs_color_space *picc_cs; + gs_color_space_index color_space_index = gs_color_space_get_index(pcs); + gs_color_space *picc_cs; + int code = 0; - *islab = false; /* For non CIEABC cases */ - if (pcs->icc_equivalent != NULL || !gs_color_space_is_PSCIE(pcs)) { - return(0); -} - switch( color_space_index ) { + *islab = false; /* For non CIEABC cases */ + if (pcs->icc_equivalent != NULL || !gs_color_space_is_PSCIE(pcs)) + return 0; + + switch( color_space_index ) { case gs_color_space_index_CIEDEFG: - gx_ciedefg_to_icc(&picc_cs, pcs, memory->stable_memory); + code = gx_ciedefg_to_icc(&picc_cs, pcs, memory->stable_memory); break; case gs_color_space_index_CIEDEF: - gx_ciedef_to_icc(&picc_cs, pcs, memory->stable_memory); + code = gx_ciedef_to_icc(&picc_cs, pcs, memory->stable_memory); break; case gs_color_space_index_CIEABC: - gx_cieabc_to_icc(&picc_cs, pcs, islab, memory->stable_memory); + code = gx_cieabc_to_icc(&picc_cs, pcs, islab, memory->stable_memory); break; case gs_color_space_index_CIEA: - gx_ciea_to_icc(&picc_cs, pcs, memory->stable_memory); + code = gx_ciea_to_icc(&picc_cs, pcs, memory->stable_memory); break; default: /* do nothing. Sould never happen */ break; - } - return(0); + } + return code; } /* Call the remap_finish procedure in the joint_caches structure. */ int -gx_cie_remap_finish(cie_cached_vector3 vec3, frac * pconc, - const gs_imager_state * pis, +gx_cie_remap_finish(cie_cached_vector3 vec3, frac * pconc, float *cie_xyz, + const gs_gstate * pgs, const gs_color_space *pcs) { - return pis->cie_joint_caches->remap_finish(vec3, pconc, pis, pcs); + return pgs->cie_joint_caches->remap_finish(vec3, pconc, cie_xyz, pgs, pcs); } /* Finish remapping a CIEBased color. */ /* Return 3 if RGB, 4 if CMYK. */ /* this procedure is exported for the benefit of gsicc.c */ int -gx_cie_real_remap_finish(cie_cached_vector3 vec3, frac * pconc, - const gs_imager_state * pis, +gx_cie_real_remap_finish(cie_cached_vector3 vec3, frac * pconc, float * xyz, + const gs_gstate * pgs, const gs_color_space *pcs) { - const gs_cie_render *pcrd = pis->cie_render; - const gx_cie_joint_caches *pjc = pis->cie_joint_caches; + const gs_cie_render *pcrd = pgs->cie_render; + const gx_cie_joint_caches *pjc = pgs->cie_joint_caches; const gs_const_string *table = pcrd->RenderTable.lookup.table; int tabc[3]; /* indices for final EncodeABC lookup */ + /* Apply DecodeLMN, MatrixLMN(decode), and MatrixPQR. */ if (!pjc->skipDecodeLMN) cie_lookup_map3(&vec3 /* LMN => PQR */, &pjc->DecodeLMN, @@ -878,13 +966,13 @@ rfix[2] = FABC(2, s); #undef FABC #undef EABC - if_debug6m('c', pis->memory, "[c]ABC=%g,%g,%g => iabc=%g,%g,%g\n", + if_debug6m('c', pgs->memory, "[c]ABC=%g,%g,%g => iabc=%g,%g,%g\n", cie_cached2float(vec3.u), cie_cached2float(vec3.v), cie_cached2float(vec3.w), fixed2float(rfix[0]), fixed2float(rfix[1]), fixed2float(rfix[2])); gx_color_interpolate_linear(rfix, &pcrd->RenderTable.lookup, pconc); - if_debug3m('c', pis->memory, "[c] interpolated => %g,%g,%g\n", + if_debug3m('c', pgs->memory, "[c] interpolated => %g,%g,%g\n", frac2float(pconc[0]), frac2float(pconc[1]), frac2float(pconc[2])); if (!pcrd->caches.RenderTableT_is_identity) { @@ -913,7 +1001,7 @@ /* (*pcrd->RenderTable.T)(prtc, m, pcrd, pconc); */ - if_debug6m('c', pis->memory, "[c]ABC=%g,%g,%g => iabc=%d,%d,%d\n", + if_debug6m('c', pgs->memory, "[c]ABC=%g,%g,%g => iabc=%d,%d,%d\n", cie_cached2float(vec3.u), cie_cached2float(vec3.v), cie_cached2float(vec3.w), ia, ib, ic); if (pcrd->caches.RenderTableT_is_identity) { @@ -955,16 +1043,16 @@ * this is a bug that we will have to address someday. */ static frac -float2frac_clamp(floatp x) +float2frac_clamp(double x) { return float2frac((x <= 0 ? 0 : x >= 1 ? 1 : x)); } int -gx_cie_xyz_remap_finish(cie_cached_vector3 vec3, frac * pconc, - const gs_imager_state * pis, +gx_cie_xyz_remap_finish(cie_cached_vector3 vec3, frac * pconc, float *xyz, + const gs_gstate * pgs, const gs_color_space *pcs) { - const gx_cie_joint_caches *pjc = pis->cie_joint_caches; + const gx_cie_joint_caches *pjc = pgs->cie_joint_caches; /* * All the steps through DecodeABC/MatrixABC have been applied, i.e., @@ -974,9 +1062,13 @@ cie_lookup_map3(&vec3 /* LMN => XYZ */, &pjc->DecodeLMN, "Decode/MatrixLMN"); - pconc[0] = float2frac_clamp(cie_cached2float(vec3.u)); - pconc[1] = float2frac_clamp(cie_cached2float(vec3.v)); - pconc[2] = float2frac_clamp(cie_cached2float(vec3.w)); + xyz[0] = cie_cached2float(vec3.u); + xyz[1] = cie_cached2float(vec3.v); + xyz[2] = cie_cached2float(vec3.w); + + pconc[0] = float2frac_clamp(xyz[0]); + pconc[1] = float2frac_clamp(xyz[1]); + pconc[2] = float2frac_clamp(xyz[2]); return 3; } diff -Nru ghostscript-9.10~dfsg/base/gscindex.h ghostscript-9.25~dfsg+1/base/gscindex.h --- ghostscript-9.10~dfsg/base/gscindex.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscindex.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsclipsr.c ghostscript-9.25~dfsg+1/base/gsclipsr.c --- ghostscript-9.10~dfsg/base/gsclipsr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsclipsr.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -45,7 +45,7 @@ /* clipsave */ int -gs_clipsave(gs_state *pgs) +gs_clipsave(gs_gstate *pgs) { gs_memory_t *mem = pgs->memory; gx_clip_path *copy = @@ -68,7 +68,7 @@ /* cliprestore */ int -gs_cliprestore(gs_state *pgs) +gs_cliprestore(gs_gstate *pgs) { gx_clip_stack_t *stack = pgs->clip_stack; diff -Nru ghostscript-9.10~dfsg/base/gsclipsr.h ghostscript-9.25~dfsg+1/base/gsclipsr.h --- ghostscript-9.10~dfsg/base/gsclipsr.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsclipsr.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,7 +19,7 @@ #ifndef gsclipsr_INCLUDED # define gsclipsr_INCLUDED -int gs_clipsave(gs_state *); -int gs_cliprestore(gs_state *); +int gs_clipsave(gs_gstate *); +int gs_cliprestore(gs_gstate *); #endif /* gsclipsr_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscms.h ghostscript-9.25~dfsg+1/base/gscms.h --- ghostscript-9.10~dfsg/base/gscms.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscms.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Data type definitions when using the gscms */ @@ -23,18 +23,18 @@ #include "gstypes.h" #include "gscspace.h" /* for gs_color_space */ #include "gsdevice.h" /* Need to carry pointer to clist reader */ -#include "gxsync.h" /* for semaphore and monitors */ +#include "gxsync.h" /* for monitors */ #include "stdint_.h" #define ICC_MAX_CHANNELS 15 #define NUM_DEVICE_PROFILES 4 #define NUM_SOURCE_PROFILES 3 -#define AB_NEUTRAL_8 5 -#define AB_NEUTRAL_16 5 +#define AB_NEUTRAL_8 5 +#define AB_NEUTRAL_16 5 -#define DEV_NEUTRAL_8 5 -#define DEV_NEUTRAL_16 5 +#define DEV_NEUTRAL_8 5 +#define DEV_NEUTRAL_16 5 /* Define the preferred size of the output by the CMS */ /* This can be different than the size of gx_color_value @@ -73,7 +73,7 @@ /* The buffer description. We handle a variety of different types */ typedef enum { - gsUNDEFINED = 0, + gsUNDEFINED = 0, gsGRAY, gsRGB, gsCMYK, @@ -98,14 +98,14 @@ /* Mapping procedures to allow easy vectoring depending upon if we are using the CMM or doing "dumb" color transforms */ -typedef void (*gscms_trans_color_proc_t) (gx_device * dev, gsicc_link_t *icclink, - void *inputcolor, void *outputcolor, - int num_bytes); - -typedef void (*gscms_trans_buffer_proc_t) (gx_device * dev, gsicc_link_t *icclink, - gsicc_bufferdesc_t *input_buff_desc, - gsicc_bufferdesc_t *output_buff_desc, - void *inputbuffer, void *outputbuffer); +typedef int (*gscms_trans_color_proc_t) (gx_device * dev, gsicc_link_t *icclink, + void *inputcolor, void *outputcolor, + int num_bytes); + +typedef int (*gscms_trans_buffer_proc_t) (gx_device * dev, gsicc_link_t *icclink, + gsicc_bufferdesc_t *input_buff_desc, + gsicc_bufferdesc_t *output_buff_desc, + void *inputbuffer, void *outputbuffer); typedef void (*gscms_link_free_proc_t) (gsicc_link_t *icclink); @@ -118,7 +118,10 @@ gscms_monitor_proc_t is_color; } gscms_procs_t; -/* Enumerate the ICC rendering intents and other parameters. A note on +/* Allow different methods for releasing the opaque profile contents */ +typedef void(*gscms_free_profile_proc_t) (void *profile_handle, gs_memory_t *memory); + +/* Enumerate the ICC rendering intents and other parameters. A note on these. 0-3 are for different values. 4-7 are for Override cases where we are trying to override some value specified in the document. 8 is reserved for not specified. This is used in the case were we @@ -131,23 +134,29 @@ gsRELATIVECOLORIMETRIC, gsSATURATION, gsABSOLUTECOLORIMETRIC, - gsPERCEPTUAL_OR, /* These are needed for keeping track */ + gsPERCEPTUAL_OR, /* These are needed for keeping track */ gsRELATIVECOLORIMETRIC_OR, /* of when the source ri is going to */ gsSATURATION_OR, /* override the destination profile intent */ gsABSOLUTECOLORIMETRIC_OR, /* in particular through the clist */ - gsRINOTSPECIFIED = 8 /* Used to ignore value when source based setting */ + gsRINOTSPECIFIED = 8, /* Used to ignore value when source based setting */ + + /* Stop modern C shrinking this enum to a byte */ + gsicc_rendering_intent__FORCE_SIZE= 0x10000 } gsicc_rendering_intents_t; /* We make an enumerated type in case someone wants to add different types - of black point compensation. Like lcms provides the option for. If - any are added, be sure to add in the regular and the source overide + of black point compensation. Like lcms provides the option for. If + any are added, be sure to add in the regular and the source overide option. Also not that we have at most 4 options due to gsBP_OVERRIDE */ typedef enum { gsBLACKPTCOMP_OFF = 0, gsBLACKPTCOMP_ON, - gsBLACKPTCOMP_OFF_OR = 4, /* These are needed for keeping track of the */ + gsBLACKPTCOMP_OFF_OR = 4, /* These are needed for keeping track of the */ gsBLACKPTCOMP_ON_OR, /* source blackpt is to overide dest. setting */ - gsBPNOTSPECIFIED = 8 /* Used to ignore value when source based setting */ + gsBPNOTSPECIFIED = 8, /* Used to ignore value when source based setting */ + + /* Stop modern C shrinking this enum to a byte */ + gsicc_blackptcomp__FORCE_SIZE= 0x10000 } gsicc_blackptcomp_t; /* This is used mainly for when the sourcegtag option specifies us to use no @@ -158,17 +167,20 @@ gsCMM_REPLACE } gsicc_cmm_t; -/* Since this is not specified by the source document we don't need to worry +/* Since this is not specified by the source document we don't need to worry about override values */ typedef enum { gsBLACKPRESERVE_OFF = 0, gsBLACKPRESERVE_KONLY, gsBLACKPRESERVE_KPLANE, - gsBKPRESNOTSPECIFIED = 8 /* Used to ignore value when source based setting */ + gsBKPRESNOTSPECIFIED = 8, /* Used to ignore value when source based setting */ + + /* Stop modern C shrinking this enum to a byte */ + gsicc_blackpreserve__FORCE_SIZE= 0x10000 } gsicc_blackpreserve_t; - + #define gsRI_OVERRIDE 0x4 -#define gsBP_OVERRIDE 0x4 +#define gsBP_OVERRIDE 0x4 #define gsKP_OVERRIDE 0x4 #define gsRI_MASK 0x3; #define gsBP_MASK 0x3; @@ -182,7 +194,9 @@ gsTEXTPROFILE, gsPROOFPROFILE, gsLINKPROFILE, - gsOIPROFILE + gsOIPROFILE, + gsPRPROFILE, + gsBLENDPROFILE } gsicc_profile_types_t; typedef enum { @@ -195,11 +209,11 @@ /* The default is "unknown" which has value 0 and by default devices don't encode tags */ typedef enum { - GS_UNKNOWN_TAG = 0x0, + GS_UNTOUCHED_TAG = 0x0, /* UNTOUCHED *must* be 0 -- transparency code relies on this */ GS_TEXT_TAG = 0x1, GS_IMAGE_TAG = 0x2, GS_PATH_TAG = 0x4, - GS_UNTOUCHED_TAG = 0x8, + GS_UNKNOWN_TAG = 0x40, GS_DEVICE_ENCODES_TAGS = 0x80 } gs_graphics_type_tag_t; @@ -219,6 +233,8 @@ gsicc_rendering_param_t rgb_rend_cond[NUM_SOURCE_PROFILES]; cmm_profile_t *cmyk_profiles[NUM_SOURCE_PROFILES]; gsicc_rendering_param_t cmyk_rend_cond[NUM_SOURCE_PROFILES]; + cmm_profile_t *gray_profiles[NUM_SOURCE_PROFILES]; + gsicc_rendering_param_t gray_rend_cond[NUM_SOURCE_PROFILES]; cmm_profile_t *color_warp_profile; gs_memory_t *memory; int name_length; /* Length of file name */ @@ -254,11 +270,13 @@ }; /* Destination profiles for different objects */ -typedef struct cmm_dev_profile_s { +struct cmm_dev_profile_s { cmm_profile_t *device_profile[NUM_DEVICE_PROFILES]; cmm_profile_t *proof_profile; cmm_profile_t *link_profile; cmm_profile_t *oi_profile; /* output intent profile */ + cmm_profile_t *blend_profile; /* blending color space */ + cmm_profile_t *postren_profile; /* Profile for use by devices post render */ gsicc_rendering_param_t rendercond[NUM_DEVICE_PROFILES]; bool devicegraytok; /* Used for forcing gray to pure black */ bool graydetection; /* Device param for monitoring for gray only page */ @@ -270,7 +288,7 @@ bool prebandthreshold; /* Used to indicate use of HT pre-clist */ gs_memory_t *memory; rc_header rc; -} cmm_dev_profile_t; +}; /* Used so that we can specify if we want to link with Device input color spaces during the link creation process. For the DeviceN case, the DeviceN profile @@ -300,6 +318,12 @@ CIE_CRD /* Generated from PS CRD definition */ } gsicc_profile_t; +typedef enum { + ICCVERS_UNKNOWN, + ICCVERS_2, + ICCVERS_NOT2 +} gsicc_version_t; + #define gsicc_serial_data\ unsigned char num_comps; /* number of device dependent values */\ unsigned char num_comps_out; /* usually 3 but could be more if device link type */\ @@ -330,19 +354,23 @@ */ struct cmm_profile_s { gsicc_serial_data; - byte *buffer; /* A buffer with ICC profile content */ - gx_device *dev; /* A pointer to the clist device in which the ICC data may be contained */ - gsicc_namelist_t *spotnames; /* Used for profiles that have non-standard colorants */ - void *profile_handle; /* The profile handle */ - rc_header rc; /* Reference count. So we know when to free */ - int name_length; /* Length of file name */ - char *name; /* Name of file name (if there is one) where profile is found. - * If it was embedded in the stream, there will not be a file - * name. This is primarily here for the system profiles, and - * so that we avoid resetting them everytime the user params - * are reloaded. */ - gs_memory_t *memory; /* In case we have some in non-gc and some in gc memory */ - gx_monitor_t *lock; /* handle for the monitor */ + byte *buffer; /* A buffer with ICC profile content */ + gx_device *dev; /* A pointer to the clist device in which the ICC data may be contained */ + gsicc_namelist_t *spotnames; /* Used for profiles that have non-standard colorants */ + void *profile_handle; /* The profile handle */ + rc_header rc; /* Reference count. So we know when to free */ + int name_length; /* Length of file name */ + char *name; /* Name of file name (if there is one) where profile is found. + * If it was embedded in the stream, there will not be a file + * name. This is primarily here for the system profiles, and + * so that we avoid resetting them everytime the user params + * are reloaded. */ + gsicc_version_t vers; /* Is this profile V2 */ + byte *v2_data; /* V2 data that is equivalent to this profile. Used for PDF-A1 support */ + int v2_size; /* Number of bytes in v2_data */ + gs_memory_t *memory; /* In case we have some in non-gc and some in gc memory */ + gx_monitor_t *lock; /* handle for the monitor */ + gscms_free_profile_proc_t release; /* Release the profile handle at CMM */ }; #ifndef cmm_profile_DEFINED @@ -413,14 +441,14 @@ } gsicc_hashlink_t; struct gsicc_link_s { - void *link_handle; - gscms_procs_t procs; + void *link_handle; /* the CMS decides what this is */ + gs_memory_t *memory; + gscms_procs_t procs; gsicc_hashlink_t hashcode; struct gsicc_link_cache_s *icc_link_cache; int ref_count; gsicc_link_t *next; - gx_semaphore_t *wait; /* semaphore used by waiting threads */ - int num_waiting; + gx_monitor_t *lock; /* lock used while changing contents */ bool includes_softproof; bool includes_devlink; bool is_identity; /* Used for noting that this is an identity profile */ @@ -443,8 +471,6 @@ rc_header rc; gs_memory_t *memory; gx_monitor_t *lock; /* handle for the monitor */ - gx_semaphore_t *wait; /* somebody needs a link cache slot */ - int num_waiting; /* number of threads waiting */ } gsicc_link_cache_t; /* A linked list structure to keep DeviceN ICC profiles @@ -480,15 +506,15 @@ }; /* Had to add bool so that we know if things were swapped. - The reason is that if we are in a swapped state and - there is a vmreclaim we then end up sending the user + The reason is that if we are in a swapped state and + there is a vmreclaim we then end up sending the user params again and we will find that there is a mismatch */ typedef struct gsicc_smask_s { cmm_profile_t *smask_gray; cmm_profile_t *smask_rgb; cmm_profile_t *smask_cmyk; gs_memory_t *memory; - bool swapped; + bool swapped; } gsicc_smask_t; /* The manager object */ @@ -499,6 +525,7 @@ cmm_profile_t *default_rgb; /* Default RGB profile for device RGB */ cmm_profile_t *default_cmyk; /* Default CMYK profile for device CMKY */ cmm_profile_t *lab_profile; /* Colorspace type ICC profile from LAB to LAB */ + cmm_profile_t *xyz_profile; /* RGB based proflie that hands back CIEXYZ values */ cmm_profile_t *graytok_profile; /* A specialized profile for mapping gray to K */ gsicc_devicen_t *device_n; /* A linked list of profiles used for DeviceN support */ gsicc_smask_t *smask_profiles; /* Profiles used when we are in a softmask group */ diff -Nru ghostscript-9.10~dfsg/base/gscolor1.c ghostscript-9.25~dfsg+1/base/gscolor1.c --- ghostscript-9.10~dfsg/base/gscolor1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolor1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,17 +31,17 @@ #include "gzht.h" /* Imports from gscolor.c */ -void load_transfer_map(gs_state *, gx_transfer_map *, floatp); +void load_transfer_map(gs_gstate *, gx_transfer_map *, double); /* Imported from gsht.c */ -void gx_set_effective_transfer(gs_state *); +void gx_set_effective_transfer(gs_gstate *); /* Force a parameter into the range [0.0..1.0]. */ #define FORCE_UNIT(p) (p < 0.0 ? 0.0 : p > 1.0 ? 1.0 : p) /* setcmykcolor */ int -gs_setcmykcolor(gs_state * pgs, floatp c, floatp m, floatp y, floatp k) +gs_setcmykcolor(gs_gstate * pgs, double c, double m, double y, double k) { gs_color_space *pcs; int code; @@ -67,12 +67,12 @@ /* setblackgeneration */ /* Remap=0 is used by the interpreter. */ int -gs_setblackgeneration(gs_state * pgs, gs_mapping_proc proc) +gs_setblackgeneration(gs_gstate * pgs, gs_mapping_proc proc) { return gs_setblackgeneration_remap(pgs, proc, true); } int -gs_setblackgeneration_remap(gs_state * pgs, gs_mapping_proc proc, bool remap) +gs_setblackgeneration_remap(gs_gstate * pgs, gs_mapping_proc proc, bool remap) { rc_unshare_struct(pgs->black_generation, gx_transfer_map, &st_transfer_map, pgs->memory, @@ -89,7 +89,7 @@ /* currentblackgeneration */ gs_mapping_proc -gs_currentblackgeneration(const gs_state * pgs) +gs_currentblackgeneration(const gs_gstate * pgs) { return pgs->black_generation->proc; } @@ -97,12 +97,12 @@ /* setundercolorremoval */ /* Remap=0 is used by the interpreter. */ int -gs_setundercolorremoval(gs_state * pgs, gs_mapping_proc proc) +gs_setundercolorremoval(gs_gstate * pgs, gs_mapping_proc proc) { return gs_setundercolorremoval_remap(pgs, proc, true); } int -gs_setundercolorremoval_remap(gs_state * pgs, gs_mapping_proc proc, bool remap) +gs_setundercolorremoval_remap(gs_gstate * pgs, gs_mapping_proc proc, bool remap) { rc_unshare_struct(pgs->undercolor_removal, gx_transfer_map, &st_transfer_map, pgs->memory, @@ -119,7 +119,7 @@ /* currentundercolorremoval */ gs_mapping_proc -gs_currentundercolorremoval(const gs_state * pgs) +gs_currentundercolorremoval(const gs_gstate * pgs) { return pgs->undercolor_removal->proc; } @@ -127,7 +127,7 @@ /* setcolortransfer */ /* Remap=0 is used by the interpreter. */ int -gs_setcolortransfer_remap(gs_state * pgs, gs_mapping_proc red_proc, +gs_setcolortransfer_remap(gs_gstate * pgs, gs_mapping_proc red_proc, gs_mapping_proc green_proc, gs_mapping_proc blue_proc, gs_mapping_proc gray_proc, bool remap) @@ -182,7 +182,7 @@ return_error(gs_error_VMerror); } int -gs_setcolortransfer(gs_state * pgs, gs_mapping_proc red_proc, +gs_setcolortransfer(gs_gstate * pgs, gs_mapping_proc red_proc, gs_mapping_proc green_proc, gs_mapping_proc blue_proc, gs_mapping_proc gray_proc) { @@ -192,7 +192,7 @@ /* currentcolortransfer */ void -gs_currentcolortransfer(const gs_state * pgs, gs_mapping_proc procs[4]) +gs_currentcolortransfer(const gs_gstate * pgs, gs_mapping_proc procs[4]) { const gx_transfer *ptran = &pgs->set_transfer; diff -Nru ghostscript-9.10~dfsg/base/gscolor1.h ghostscript-9.25~dfsg+1/base/gscolor1.h --- ghostscript-9.10~dfsg/base/gscolor1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolor1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,24 +21,24 @@ # define gscolor1_INCLUDED /* Color and gray interface */ -int gs_setcmykcolor(gs_state *, floatp, floatp, floatp, floatp), - gs_currentcmykcolor(const gs_state *, float[4]), - gs_setblackgeneration(gs_state *, gs_mapping_proc), - gs_setblackgeneration_remap(gs_state *, gs_mapping_proc, bool); -gs_mapping_proc gs_currentblackgeneration(const gs_state *); -int gs_setundercolorremoval(gs_state *, gs_mapping_proc), - gs_setundercolorremoval_remap(gs_state *, gs_mapping_proc, bool); -gs_mapping_proc gs_currentundercolorremoval(const gs_state *); +int gs_setcmykcolor(gs_gstate *, double, double, double, double), + gs_currentcmykcolor(const gs_gstate *, float[4]), + gs_setblackgeneration(gs_gstate *, gs_mapping_proc), + gs_setblackgeneration_remap(gs_gstate *, gs_mapping_proc, bool); +gs_mapping_proc gs_currentblackgeneration(const gs_gstate *); +int gs_setundercolorremoval(gs_gstate *, gs_mapping_proc), + gs_setundercolorremoval_remap(gs_gstate *, gs_mapping_proc, bool); +gs_mapping_proc gs_currentundercolorremoval(const gs_gstate *); /* Transfer function */ -int gs_setcolortransfer(gs_state *, gs_mapping_proc /*red */ , +int gs_setcolortransfer(gs_gstate *, gs_mapping_proc /*red */ , gs_mapping_proc /*green */ , gs_mapping_proc /*blue */ , gs_mapping_proc /*gray */ ), - gs_setcolortransfer_remap(gs_state *, gs_mapping_proc /*red */ , + gs_setcolortransfer_remap(gs_gstate *, gs_mapping_proc /*red */ , gs_mapping_proc /*green */ , gs_mapping_proc /*blue */ , gs_mapping_proc /*gray */ , bool); -void gs_currentcolortransfer(const gs_state *, gs_mapping_proc[4]); +void gs_currentcolortransfer(const gs_gstate *, gs_mapping_proc[4]); #endif /* gscolor1_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscolor2.c ghostscript-9.25~dfsg+1/base/gscolor2.c --- ghostscript-9.10~dfsg/base/gscolor2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolor2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,7 +31,7 @@ /* ---------------- General colors and color spaces ---------------- */ int -gs_setcolorspace_only(gs_state * pgs, gs_color_space * pcs) +gs_setcolorspace_only(gs_gstate * pgs, gs_color_space * pcs) { int code = 0; gs_color_space *cs_old = pgs->color[0].color_space; @@ -57,7 +57,7 @@ /* setcolorspace */ int -gs_setcolorspace(gs_state * pgs, gs_color_space * pcs) +gs_setcolorspace(gs_gstate * pgs, gs_color_space * pcs) { int code = 0; @@ -73,21 +73,33 @@ /* currentcolorspace */ gs_color_space * -gs_currentcolorspace(const gs_state * pgs) +gs_currentcolorspace(const gs_gstate * pgs) { return pgs->color[0].color_space; } /* setcolor */ int -gs_setcolor(gs_state * pgs, const gs_client_color * pcc) +gs_setcolor(gs_gstate * pgs, const gs_client_color * pcc) { gs_color_space * pcs = pgs->color[0].color_space; gs_client_color cc_old = *pgs->color[0].ccolor; + gx_device_color *dev_color = pgs->color[0].dev_color; + bool do_unset = true; - if (pgs->in_cachedevice) + if (pgs->in_cachedevice) return_error(gs_error_undefined); /* PLRM3 page 215. */ - gx_unset_dev_color(pgs); + if (dev_color->ccolor_valid && gx_dc_is_pure(dev_color)) { /* change of colorspace will set type to _none */ + int i; + int ncomps = cs_num_components(pcs); + + for(i=0; i < ncomps; i++) + if (dev_color->ccolor.paint.values[i] != pcc->paint.values[i]) + break; + do_unset = i < ncomps; /* if i == ncomps, color unchanged, optimized */ + } + if (do_unset) + gx_unset_dev_color(pgs); (*pcs->type->adjust_color_count)(pcc, pcs, 1); *pgs->color[0].ccolor = *pcc; (*pcs->type->restrict_color)(pgs->color[0].ccolor, pcs); @@ -98,14 +110,14 @@ /* currentcolor */ const gs_client_color * -gs_currentcolor(const gs_state * pgs) +gs_currentcolor(const gs_gstate * pgs) { return pgs->color[0].ccolor; } /* currentdevicecolor */ const gx_device_color * -gs_currentdevicecolor(const gs_state * pgs) +gs_currentdevicecolor(const gs_gstate * pgs) { return pgs->color[0].dev_color; } @@ -173,10 +185,12 @@ static cs_proc_restrict_color(gx_restrict_Indexed); static cs_proc_concrete_space(gx_concrete_space_Indexed); static cs_proc_concretize_color(gx_concretize_Indexed); +static cs_proc_remap_color(gx_remap_IndexedNamed); static cs_proc_install_cspace(gx_install_Indexed); static cs_proc_set_overprint(gx_set_overprint_Indexed); static cs_proc_final(gx_final_Indexed); static cs_proc_serialize(gx_serialize_Indexed); +static cs_proc_polarity(gx_polarity_Indexed); const gs_color_space_type gs_color_space_type_Indexed = { gs_color_space_index_Indexed, false, false, &st_color_space_Indexed, gx_num_components_1, @@ -188,7 +202,25 @@ gx_set_overprint_Indexed, gx_final_Indexed, gx_no_adjust_color_count, gx_serialize_Indexed, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_Indexed +}; + +/* To keep things vectorized and avoid an if test during the remap proc we + have another set of procedures to use for indexed color spaces when + someone has specified a named color profile and the base space of the + index color space is DeviceN or Separation */ +const gs_color_space_type gs_color_space_type_Indexed_Named = { + gs_color_space_index_Indexed, false, false, + &st_color_space_Indexed, gx_num_components_1, + gx_init_paint_1, gx_restrict_Indexed, + gx_concrete_space_Indexed, + gx_concretize_Indexed, NULL, + gx_remap_IndexedNamed, + gx_install_Indexed, + gx_set_overprint_Indexed, + gx_final_Indexed, gx_no_adjust_color_count, + gx_serialize_Indexed, + gx_cspace_is_linear_default, gx_polarity_Indexed }; /* GC procedures. */ @@ -224,8 +256,16 @@ /* Color space installation for an Indexed color space. */ +/* Return polarity of base space */ +static gx_color_polarity_t +gx_polarity_Indexed(const gs_color_space * pcs) +{ + return (*pcs->base_space->type->polarity) + ((const gs_color_space *)pcs->base_space); +} + static int -gx_install_Indexed(gs_color_space * pcs, gs_state * pgs) +gx_install_Indexed(gs_color_space * pcs, gs_gstate * pgs) { return (*pcs->base_space->type->install_cspace) (pcs->base_space, pgs); @@ -234,7 +274,7 @@ /* Color space overprint setting ditto. */ static int -gx_set_overprint_Indexed(const gs_color_space * pcs, gs_state * pgs) +gx_set_overprint_Indexed(const gs_color_space * pcs, gs_gstate * pgs) { return (*pcs->base_space->type->set_overprint) ((const gs_color_space *)pcs->base_space, pgs); @@ -438,25 +478,24 @@ /* Color remapping for Indexed color spaces. */ static const gs_color_space * gx_concrete_space_Indexed(const gs_color_space * pcs, - const gs_imager_state * pis) + const gs_gstate * pgs) { bool is_lab = false; if (gs_color_space_is_PSCIE(pcs->base_space)) { if (pcs->base_space->icc_equivalent == NULL) { - gs_colorspace_set_icc_equivalent(pcs->base_space, - &is_lab, pis->memory); + (void)gs_colorspace_set_icc_equivalent(pcs->base_space, + &is_lab, pgs->memory); } return (pcs->base_space->icc_equivalent); } - return cs_concrete_space(pcs->base_space, pis); + return cs_concrete_space(pcs->base_space, pgs); } static int gx_concretize_Indexed(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { - gs_client_color cc; const gs_color_space *pbcs = (const gs_color_space *)pcs->base_space; @@ -464,7 +503,54 @@ if (code < 0) return code; - return (*pbcs->type->concretize_color) (&cc, pbcs, pconc, pis, dev); + return (*pbcs->type->concretize_color) (&cc, pbcs, pconc, pgs, dev); +} + +/* We should only be here for cases where the base space is DeviceN or Sep and + we are doing named color replacement. */ +static int +gx_remap_IndexedNamed(const gs_client_color * pcc, const gs_color_space * pcs, +gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, +gs_color_select_t select) +{ + frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS]; + const gs_color_space *pconcs; + int i = pcs->type->num_components(pcs); + gs_client_color cc; + bool mapped; + int code = gs_indexed_limit_and_lookup(pcc, pcs, &cc); + + if (code < 0) + return code; + + pconcs = cs_concrete_space(pcs, pgs); + if (pconcs) { + /* Now see if we can do the named color replacement */ + mapped = gx_remap_named_color(&cc, pconcs, pdc, pgs, dev, select); + + if (!mapped) { + /* Named color remap failed perhaps due to colorant not found. Do the + old approach of concretize of the base space and remap concrete color */ + const gs_color_space *pbcs = + (const gs_color_space *)pcs->base_space; + cmm_dev_profile_t *dev_profile; + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + + code = (*pbcs->type->concretize_color) (&cc, pbcs, conc, pgs, dev); + if (code < 0) + return code; + code = (*pconcs->type->remap_concrete_color)(pconcs, conc, pdc, pgs, dev, select, dev_profile); + } + } + + /* Save original color space and color info into dev color */ + i = any_abs(i); + for (i--; i >= 0; i--) + pdc->ccolor.paint.values[i] = pcc->paint.values[i]; + pdc->ccolor_valid = true; + return code; } /* Look up an index in an Indexed color space. */ @@ -716,7 +802,7 @@ * res_name and name_length passes the resource name. */ int -gs_includecolorspace(gs_state * pgs, const byte *res_name, int name_length) +gs_includecolorspace(gs_gstate * pgs, const byte *res_name, int name_length) { return (*dev_proc(pgs->device, include_color_space))(pgs->device, gs_currentcolorspace_inline(pgs), res_name, name_length); } diff -Nru ghostscript-9.10~dfsg/base/gscolor2.h ghostscript-9.25~dfsg+1/base/gscolor2.h --- ghostscript-9.10~dfsg/base/gscolor2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolor2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,12 +32,12 @@ */ /* General color routines */ -gs_color_space *gs_currentcolorspace(const gs_state *); -int gs_setcolorspace(gs_state *, gs_color_space *); -int gs_setcolorspace_only(gs_state *, gs_color_space *); -const gs_client_color *gs_currentcolor(const gs_state *); -int gs_setcolor(gs_state *, const gs_client_color *); -const gx_device_color *gs_currentdevicecolor(const gs_state *); +gs_color_space *gs_currentcolorspace(const gs_gstate *); +int gs_setcolorspace(gs_gstate *, gs_color_space *); +int gs_setcolorspace_only(gs_gstate *, gs_color_space *); +const gs_client_color *gs_currentcolor(const gs_gstate *); +int gs_setcolor(gs_gstate *, const gs_client_color *); +const gx_device_color *gs_currentdevicecolor(const gs_gstate *); /* Look up with restriction */ int @@ -46,16 +46,17 @@ /* Declare the Indexed color space type. */ extern const gs_color_space_type gs_color_space_type_Indexed; +extern const gs_color_space_type gs_color_space_type_Indexed_Named; /* CIE-specific routines */ #ifndef gs_cie_render_DEFINED # define gs_cie_render_DEFINED typedef struct gs_cie_render_s gs_cie_render; #endif -const gs_cie_render *gs_currentcolorrendering(const gs_state *); -int gs_setcolorrendering(gs_state *, gs_cie_render *); +const gs_cie_render *gs_currentcolorrendering(const gs_gstate *); +int gs_setcolorrendering(gs_gstate *, gs_cie_render *); /* High level device support */ -int gs_includecolorspace(gs_state * pgs, const byte *res_name, int name_length); +int gs_includecolorspace(gs_gstate * pgs, const byte *res_name, int name_length); #endif /* gscolor2_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscolor3.c ghostscript-9.25~dfsg+1/base/gscolor3.c --- ghostscript-9.10~dfsg/base/gscolor3.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolor3.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -33,7 +33,7 @@ /* setsmoothness */ int -gs_setsmoothness(gs_state * pgs, floatp smoothness) +gs_setsmoothness(gs_gstate * pgs, double smoothness) { pgs->smoothness = (smoothness < 0 ? 0 : smoothness > 1 ? 1 : smoothness); @@ -42,14 +42,14 @@ /* currentsmoothness */ float -gs_currentsmoothness(const gs_state * pgs) +gs_currentsmoothness(const gs_gstate * pgs) { return pgs->smoothness; } /* shfill */ int -gs_shfill(gs_state * pgs, const gs_shading_t * psh) +gs_shfill(gs_gstate * pgs, const gs_shading_t * psh) { /* * shfill is equivalent to filling the current clipping path (or, if @@ -93,8 +93,14 @@ if (pcs == NULL) return_error(gs_error_VMerror); + /* make sure the tag gets set correctly */ + if (pgs->show_gstate == NULL) + ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + else + ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ + pcs->params.pattern.has_base_space = false; - code = pcs->type->remap_color(&cc, pcs, &devc, (gs_imager_state *)pgs, + code = pcs->type->remap_color(&cc, pcs, &devc, pgs, pgs->device, gs_color_select_texture); if (code >= 0) { gx_device *dev = pgs->device; diff -Nru ghostscript-9.10~dfsg/base/gscolor3.h ghostscript-9.25~dfsg+1/base/gscolor3.h --- ghostscript-9.10~dfsg/base/gscolor3.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolor3.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,8 +25,8 @@ typedef struct gs_shading_s gs_shading_t; #endif -int gs_setsmoothness(gs_state *, floatp); -float gs_currentsmoothness(const gs_state *); -int gs_shfill(gs_state *, const gs_shading_t *); +int gs_setsmoothness(gs_gstate *, double); +float gs_currentsmoothness(const gs_gstate *); +int gs_shfill(gs_gstate *, const gs_shading_t *); #endif /* gscolor3_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscolorbuffer.c ghostscript-9.25~dfsg+1/base/gscolorbuffer.c --- ghostscript-9.10~dfsg/base/gscolorbuffer.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolorbuffer.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,271 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Simple operators and place holding support for doing conversions on buffers - of data. These functions perform device (non CIE or ICC color conversions) - on buffers of data. Eventually these will be replaced with functions for - using the ICC based linked mappings with the external CMS. This is far from - efficient at this point, but gets the job done */ - -#include "string_.h" -#include "stdpre.h" -#include "gstypes.h" -#include "gsmemory.h" -#include "gxblend.h" -#include "gscolorbuffer.h" - -#define float_color_to_byte_color(float_color) ( \ - (0.0 < (float_color) && (float_color) < 1.0) ? \ - ((unsigned char) ((float_color) * 255.0)) : \ - (((float_color) <= 0.0) ? 0x00 : 0xFF) \ - ) - -/* We could use the conversions that are defined in gxdcconv.c, - however for now we will use something even easier. This is - temporary until we get the proper ICC flows in place */ - -static void -rgb_to_cmyk(byte rgb[],byte cmyk[]) -{ - - /* Real sleazy min black generation */ - - cmyk[0] = 255 - rgb[0]; - cmyk[1] = 255 - rgb[1]; - cmyk[2] = 255 - rgb[2]; - - cmyk[3] = (cmyk[0] < cmyk[1]) ? - min(cmyk[0], cmyk[2]) : min(cmyk[1], cmyk[2]); - -} - -static void -rgb_to_gray(byte rgb[], byte gray[]) -{ - - float temp_value; - - /* compute a luminance component */ - temp_value = rgb[0]*0.3 + rgb[1]*0.59 + rgb[2]*0.11; - temp_value = temp_value * (1.0 / 255.0 ); /* May need to be optimized */ - gray[0] = float_color_to_byte_color(temp_value); - -} - -static void -cmyk_to_rgb(byte cmyk[], byte rgb[]) -{ - - /* real ugly, but temporary */ - - rgb[0] = 255 - min(cmyk[0] + cmyk[3],255); - rgb[1] = 255 - min(cmyk[1] + cmyk[3],255); - rgb[2] = 255 - min(cmyk[2] + cmyk[3],255); - -} - -static void -cmyk_to_gray(byte cmyk[], byte gray[]) -{ - - float temp_value; - - temp_value = ((255 - cmyk[0])*0.3 + - (255 - cmyk[1])*0.59 + - (255 - cmyk[2]) * 0.11) * (255 - cmyk[3]); - temp_value = temp_value * (1.0 / 65025.0 ); - - gray[0] = float_color_to_byte_color(temp_value); - -} - -static void -gray_to_cmyk(byte gray[], byte cmyk[]) -{ - - /* Just do black. */ - cmyk[0] = 0; - cmyk[1] = 0; - cmyk[2] = 0; - cmyk[3] = 255 - gray[0]; - -} - -static void -gray_to_rgb(byte gray[], byte rgb[]) -{ - - rgb[0] = gray[0]; - rgb[1] = gray[0]; - rgb[2] = gray[0]; - -} - -void -gs_transform_color_buffer_generic(byte *inputbuffer, - int row_stride, int plane_stride, - int input_num_color, gs_int_rect rect, byte *outputbuffer, - int output_num_color, int num_noncolor_planes) - -{ - int num_rows, num_cols, x, y, z; - void (* color_remap)(byte input[],byte output[]) = NULL; - byte input_vector[4],output_vector[4]; - int plane_offset[PDF14_MAX_PLANES],alpha_offset_in,max_num_channels; - - num_rows = rect.q.y - rect.p.y; - num_cols = rect.q.x - rect.p.x; - - /* Check for spot + cmyk case */ - - if (output_num_color > 4) - { - - /* To CMYK always */ - switch (input_num_color) { - - case 1: - color_remap = gray_to_cmyk; - break; - - case 3: - color_remap = rgb_to_cmyk; - break; - - case 4: - color_remap = NULL; /* Copy data */ - break; - - default: - - /* Should never be here. Groups must - be gray, rgb or CMYK. Exception - may be ICC with XPS */ - - break; - - } - - } else { - - /* Pick the mapping to use */ - - switch (input_num_color) { - - case 1: - if (output_num_color == 3) - color_remap = gray_to_rgb; - else - color_remap = gray_to_cmyk; - break; - - case 3: - if (output_num_color == 1) - color_remap = rgb_to_gray; - else - color_remap = rgb_to_cmyk; - break; - - case 4: - if (output_num_color == 1) - color_remap = cmyk_to_gray; - else - color_remap = cmyk_to_rgb; - break; - - default: - - /* Should never be here. Groups must - be gray, rgb or CMYK. Until we - have ICC working here with XPS */ - - break; - - } - - } - - /* data is planar */ - - max_num_channels = max(input_num_color, output_num_color) + - num_noncolor_planes; - - for (z = 0; z < max_num_channels; z++) - plane_offset[z] = z * plane_stride; - - if (color_remap == NULL) { - - /* Blending group was CMYK, output is CMYK + spot */ - - memcpy(outputbuffer, inputbuffer, 4*plane_stride); - - /* Add any data that are beyond the standard color data (e.g. alpha) */ - - if (num_noncolor_planes > 0) - memcpy(&(outputbuffer[plane_offset[output_num_color]]), - &(inputbuffer[plane_offset[input_num_color]]), - num_noncolor_planes*plane_stride); - - } else { - - /* Have to remap */ - - alpha_offset_in = input_num_color*plane_stride; - - for (y = 0; y < num_rows; y++) { - - for (x = 0; x < num_cols; x++) { - - /* If the source alpha is transparent, then move on */ - - if (inputbuffer[x + alpha_offset_in] != 0x00) { - - /* grab the input */ - - for (z = 0; zin_cachedevice) return_error(gs_error_undefined); - gs_setgray(pgs, 0.0); /* set color space to something harmless */ + code = gs_setgray(pgs, 0.0); /* set color space to something harmless */ color_set_null(gs_currentdevicecolor_inline(pgs)); - return 0; + return code; } /* settransfer */ /* Remap=0 is used by the interpreter. */ int -gs_settransfer(gs_state * pgs, gs_mapping_proc tproc) +gs_settransfer(gs_gstate * pgs, gs_mapping_proc tproc) { return gs_settransfer_remap(pgs, tproc, true); } int -gs_settransfer_remap(gs_state * pgs, gs_mapping_proc tproc, bool remap) +gs_settransfer_remap(gs_gstate * pgs, gs_mapping_proc tproc, bool remap) { gx_transfer *ptran = &pgs->set_transfer; @@ -202,7 +204,7 @@ /* currenttransfer */ gs_mapping_proc -gs_currenttransfer(const gs_state * pgs) +gs_currenttransfer(const gs_gstate * pgs) { return pgs->set_transfer.gray->proc; } @@ -211,12 +213,16 @@ /* Set device color = 1 for writing into the character cache. */ int -gx_set_device_color_1(gs_state * pgs) +gx_set_device_color_1(gs_gstate * pgs) { gs_color_space *pcs; - gs_setoverprint(pgs, false); - gs_setoverprintmode(pgs, 0); + /* Get the current overprint setting so that it can be properly restored. + No need to fool with the mode */ + int overprint = pgs->overprint; + + if (overprint) + gs_setoverprint(pgs, false); pcs = gs_cspace_new_DeviceGray(pgs->memory); if (pcs) { gs_setcolorspace(pgs, pcs); @@ -227,12 +233,10 @@ } set_nonclient_dev_color(gs_currentdevicecolor_inline(pgs), 1); pgs->log_op = lop_default; - /* - * In the unlikely event that overprint mode is in effect, - * update the overprint information. - */ - if (pgs->effective_overprint_mode == 1) - (void)gs_do_set_overprint(pgs); + + /* If we changed the overprint condition, restore */ + if (overprint) + gs_setoverprint(pgs, true); return 0; } @@ -244,13 +248,13 @@ * Note that we must deal with both old (proc) and new (closure) maps. */ static float -transfer_use_proc(floatp value, const gx_transfer_map * pmap, +transfer_use_proc(double value, const gx_transfer_map * pmap, const void *ignore_proc_data) { return (*pmap->proc) (value, pmap); } void -load_transfer_map(gs_state * pgs, gx_transfer_map * pmap, floatp min_value) +load_transfer_map(gs_gstate * pgs, gx_transfer_map * pmap, double min_value) { gs_mapping_closure_proc_t proc; const void *proc_data; diff -Nru ghostscript-9.10~dfsg/base/gscolor.h ghostscript-9.25~dfsg+1/base/gscolor.h --- ghostscript-9.10~dfsg/base/gscolor.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscolor.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,15 +22,15 @@ #include "gxtmap.h" /* Color and gray interface */ -int gs_setgray(gs_state *, floatp); -int gs_currentgray(const gs_state *, float *); -int gs_setrgbcolor(gs_state *, floatp, floatp, floatp); -int gs_currentrgbcolor(const gs_state *, float[3]); -int gs_setnullcolor(gs_state *); +int gs_setgray(gs_gstate *, double); +int gs_currentgray(const gs_gstate *, float *); +int gs_setrgbcolor(gs_gstate *, double, double, double); +int gs_currentrgbcolor(const gs_gstate *, float[3]); +int gs_setnullcolor(gs_gstate *); /* Transfer function */ -int gs_settransfer(gs_state *, gs_mapping_proc); -int gs_settransfer_remap(gs_state *, gs_mapping_proc, bool); -gs_mapping_proc gs_currenttransfer(const gs_state *); +int gs_settransfer(gs_gstate *, gs_mapping_proc); +int gs_settransfer_remap(gs_gstate *, gs_mapping_proc, bool); +gs_mapping_proc gs_currenttransfer(const gs_gstate *); #endif /* gscolor_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscompt.h ghostscript-9.25~dfsg+1/base/gscompt.h --- ghostscript-9.10~dfsg/base/gscompt.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscompt.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,4 +47,14 @@ */ gs_id gs_composite_id(const gs_composite_t * pcte); +typedef enum { + COMP_ENQUEUE = 0, + COMP_EXEC_IDLE = 1, + COMP_EXEC_QUEUE = 2, + COMP_REPLACE_PREV = 3, + COMP_REPLACE_CURR = 4, + COMP_DROP_QUEUE = 5, + COMP_MARK_IDLE = 6 +} gs_compositor_closing_state; + #endif /* gscompt_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscoord.c ghostscript-9.25~dfsg+1/base/gscoord.c --- ghostscript-9.10~dfsg/base/gscoord.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscoord.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -54,7 +54,7 @@ } static int -ctm_set_inverse(gs_state * pgs) +ctm_set_inverse(gs_gstate * pgs) { int code = gs_matrix_invert(&ctm_only(pgs), &pgs->ctm_inverse); @@ -96,7 +96,7 @@ /* ------ Coordinate system definition ------ */ int -gs_initmatrix(gs_state * pgs) +gs_initmatrix(gs_gstate * pgs) { gs_matrix imat; @@ -111,7 +111,7 @@ } int -gs_defaultmatrix(const gs_state * pgs, gs_matrix * pmat) +gs_defaultmatrix(const gs_gstate * pgs, gs_matrix * pmat) { gx_device *dev; @@ -122,15 +122,13 @@ dev = gs_currentdevice_inline(pgs); gs_deviceinitialmatrix(dev, pmat); /* Add in the translation for the Margins. */ - pmat->tx += dev->Margins[0] * - dev->HWResolution[0] / dev->MarginsHWResolution[0]; - pmat->ty += dev->Margins[1] * - dev->HWResolution[1] / dev->MarginsHWResolution[1]; + pmat->tx += dev->Margins[0]; + pmat->ty += dev->Margins[1]; return 0; } int -gs_setdefaultmatrix(gs_state * pgs, const gs_matrix * pmat) +gs_setdefaultmatrix(gs_gstate * pgs, const gs_matrix * pmat) { if (pmat == NULL) pgs->ctm_default_set = false; @@ -142,7 +140,7 @@ } int -gs_currentmatrix(const gs_state * pgs, gs_matrix * pmat) +gs_currentmatrix(const gs_gstate * pgs, gs_matrix * pmat) { *pmat = ctm_only(pgs); return 0; @@ -151,7 +149,7 @@ /* Set the current transformation matrix for rendering text. */ /* Note that this may be based on a font other than the current font. */ int -gs_setcharmatrix(gs_state * pgs, const gs_matrix * pmat) +gs_setcharmatrix(gs_gstate * pgs, const gs_matrix * pmat) { gs_matrix cmat; int code = gs_matrix_multiply(pmat, &ctm_only(pgs), &cmat); @@ -172,7 +170,7 @@ /* for rendering text. If force=true, update char_tm if it is invalid; */ /* if force=false, don't update char_tm, and return an error code. */ int -gs_currentcharmatrix(gs_state * pgs, gs_matrix * ptm, bool force) +gs_currentcharmatrix(gs_gstate * pgs, gs_matrix * ptm, bool force) { if (!pgs->char_tm_valid) { int code; @@ -189,7 +187,7 @@ } int -gs_setmatrix(gs_state * pgs, const gs_matrix * pmat) +gs_setmatrix(gs_gstate * pgs, const gs_matrix * pmat) { update_ctm(pgs, pmat->tx, pmat->ty); set_ctm_only(pgs, *pmat); @@ -201,19 +199,19 @@ } int -gs_imager_setmatrix(gs_imager_state * pis, const gs_matrix * pmat) +gs_gstate_setmatrix(gs_gstate * pgs, const gs_matrix * pmat) { - update_matrix_fixed(pis->ctm, pmat->tx, pmat->ty); - set_ctm_only(pis, *pmat); + update_matrix_fixed(pgs->ctm, pmat->tx, pmat->ty); + set_ctm_only(pgs, *pmat); #ifdef DEBUG if (gs_debug_c('x')) - dmlprintf(pis->memory, "[x]imager_setmatrix:\n"), trace_ctm(pis); + dmlprintf(pgs->memory, "[x]imager_setmatrix:\n"), trace_ctm(pgs); #endif return 0; } int -gs_settocharmatrix(gs_state * pgs) +gs_settocharmatrix(gs_gstate * pgs) { if (pgs->char_tm_valid) { pgs->ctm = pgs->char_tm; @@ -224,7 +222,7 @@ } int -gs_translate(gs_state * pgs, floatp dx, floatp dy) +gs_translate(gs_gstate * pgs, double dx, double dy) { gs_point pt; int code; @@ -244,10 +242,9 @@ } int -gs_translate_untransformed(gs_state * pgs, floatp dx, floatp dy) +gs_translate_untransformed(gs_gstate * pgs, double dx, double dy) { gs_point pt; - int code; pt.x = (float)dx + pgs->ctm.tx; pt.y = (float)dy + pgs->ctm.ty; @@ -262,7 +259,7 @@ } int -gs_scale(gs_state * pgs, floatp sx, floatp sy) +gs_scale(gs_gstate * pgs, double sx, double sy) { pgs->ctm.xx *= sx; pgs->ctm.xy *= sx; @@ -277,7 +274,7 @@ } int -gs_rotate(gs_state * pgs, floatp ang) +gs_rotate(gs_gstate * pgs, double ang) { int code = gs_matrix_rotate(&ctm_only(pgs), ang, &ctm_only_writable(pgs)); @@ -291,7 +288,7 @@ } int -gs_concat(gs_state * pgs, const gs_matrix * pmat) +gs_concat(gs_gstate * pgs, const gs_matrix * pmat) { gs_matrix cmat; int code = gs_matrix_multiply(pmat, &ctm_only(pgs), &cmat); @@ -312,19 +309,19 @@ #define is_skewed(pmat) (!(is_xxyy(pmat) || is_xyyx(pmat))) int -gs_transform(gs_state * pgs, floatp x, floatp y, gs_point * pt) +gs_transform(gs_gstate * pgs, double x, double y, gs_point * pt) { return gs_point_transform(x, y, &ctm_only(pgs), pt); } int -gs_dtransform(gs_state * pgs, floatp dx, floatp dy, gs_point * pt) +gs_dtransform(gs_gstate * pgs, double dx, double dy, gs_point * pt) { return gs_distance_transform(dx, dy, &ctm_only(pgs), pt); } int -gs_itransform(gs_state * pgs, floatp x, floatp y, gs_point * pt) +gs_itransform(gs_gstate * pgs, double x, double y, gs_point * pt) { /* If the matrix isn't skewed, we get more accurate results */ /* by using transform_inverse than by using the inverse matrix. */ if (!is_skewed(&pgs->ctm)) { @@ -336,7 +333,7 @@ } int -gs_idtransform(gs_state * pgs, floatp dx, floatp dy, gs_point * pt) +gs_idtransform(gs_gstate * pgs, double dx, double dy, gs_point * pt) { /* If the matrix isn't skewed, we get more accurate results */ /* by using transform_inverse than by using the inverse matrix. */ if (!is_skewed(&pgs->ctm)) { @@ -349,10 +346,10 @@ } int -gs_imager_idtransform(const gs_imager_state * pis, floatp dx, floatp dy, +gs_gstate_idtransform(const gs_gstate * pgs, double dx, double dy, gs_point * pt) { - return gs_distance_transform_inverse(dx, dy, &ctm_only(pis), pt); + return gs_distance_transform_inverse(dx, dy, &ctm_only(pgs), pt); } /* ------ For internal use only ------ */ @@ -360,7 +357,7 @@ /* Set the translation to a fixed value, and translate any existing path. */ /* Used by gschar.c to prepare for a BuildChar or BuildGlyph procedure. */ int -gx_translate_to_fixed(register gs_state * pgs, fixed px, fixed py) +gx_translate_to_fixed(register gs_gstate * pgs, fixed px, fixed py) { double fpx = fixed2float(px); double fdx = fpx - pgs->ctm.tx; @@ -408,7 +405,7 @@ /* Scale the CTM and character matrix for oversampling. */ int -gx_scale_char_matrix(register gs_state * pgs, int sx, int sy) +gx_scale_char_matrix(register gs_gstate * pgs, int sx, int sy) { #define scale_cxy(s, vx, vy)\ if ( s != 1 )\ diff -Nru ghostscript-9.10~dfsg/base/gscoord.h ghostscript-9.25~dfsg+1/base/gscoord.h --- ghostscript-9.10~dfsg/base/gscoord.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscoord.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,34 +21,34 @@ # define gscoord_INCLUDED /* Coordinate system modification */ -int gs_initmatrix(gs_state *), - gs_defaultmatrix(const gs_state *, gs_matrix *), - gs_currentmatrix(const gs_state *, gs_matrix *), - gs_setmatrix(gs_state *, const gs_matrix *), - gs_translate(gs_state *, floatp, floatp), - gs_translate_untransformed(gs_state *, floatp, floatp), - gs_scale(gs_state *, floatp, floatp), - gs_rotate(gs_state *, floatp), - gs_concat(gs_state *, const gs_matrix *); +int gs_initmatrix(gs_gstate *), + gs_defaultmatrix(const gs_gstate *, gs_matrix *), + gs_currentmatrix(const gs_gstate *, gs_matrix *), + gs_setmatrix(gs_gstate *, const gs_matrix *), + gs_translate(gs_gstate *, double, double), + gs_translate_untransformed(gs_gstate *, double, double), + gs_scale(gs_gstate *, double, double), + gs_rotate(gs_gstate *, double), + gs_concat(gs_gstate *, const gs_matrix *); /* Extensions */ -int gs_setdefaultmatrix(gs_state *, const gs_matrix *), - gs_currentcharmatrix(gs_state *, gs_matrix *, bool), - gs_setcharmatrix(gs_state *, const gs_matrix *), - gs_settocharmatrix(gs_state *); +int gs_setdefaultmatrix(gs_gstate *, const gs_matrix *), + gs_currentcharmatrix(gs_gstate *, gs_matrix *, bool), + gs_setcharmatrix(gs_gstate *, const gs_matrix *), + gs_settocharmatrix(gs_gstate *); /* Coordinate transformation */ -int gs_transform(gs_state *, floatp, floatp, gs_point *), - gs_dtransform(gs_state *, floatp, floatp, gs_point *), - gs_itransform(gs_state *, floatp, floatp, gs_point *), - gs_idtransform(gs_state *, floatp, floatp, gs_point *); - -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +int gs_transform(gs_gstate *, double, double, gs_point *), + gs_dtransform(gs_gstate *, double, double, gs_point *), + gs_itransform(gs_gstate *, double, double, gs_point *), + gs_idtransform(gs_gstate *, double, double, gs_point *); + +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif -int gs_imager_setmatrix(gs_imager_state *, const gs_matrix *); -int gs_imager_idtransform(const gs_imager_state *, floatp, floatp, gs_point *); +int gs_gstate_setmatrix(gs_gstate *, const gs_matrix *); +int gs_gstate_idtransform(const gs_gstate *, double, double, gs_point *); #endif /* gscoord_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gscparam.c ghostscript-9.25~dfsg+1/base/gscparam.c --- ghostscript-9.10~dfsg/base/gscparam.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscparam.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -235,10 +235,12 @@ gs_c_param *pparam = gs_alloc_struct(plist->memory, gs_c_param, &st_c_param, "c_param_add entry"); - uint len = strlen(pkey); + uint len; - if (pparam == 0) - return 0; + if ((pparam == NULL) || (pkey == NULL)) + return NULL; + + len = strlen(pkey); pparam->next = plist->head; if (!plist->persistent_keys) { /* We must copy the key. */ @@ -306,6 +308,10 @@ top_level_sizeof + second_level_sizeof, "c_param_write data"); if (top_level_memory == 0) { + if (pparam->key.persistent == false) { + gs_free_string(plist->memory, (byte *)(pparam->key.data), + strlen((const char *)(pparam->key.data)), "c_param_add key"); + } gs_free_object(plist->memory, pparam, "c_param_write entry"); return_error(gs_error_VMerror); } @@ -364,12 +370,17 @@ { gs_c_param_list *const cplist = (gs_c_param_list *)plist; gs_c_param_list *dlist = (gs_c_param_list *) pvalue->list; + int code; - return c_param_write(cplist, pkey, pvalue->list, + code = c_param_write(cplist, pkey, pvalue->list, (dlist->coll_type == gs_param_collection_dict_int_keys ? gs_param_type_dict_int_keys : dlist->coll_type == gs_param_collection_array ? gs_param_type_array : gs_param_type_dict)); + + gs_free_object(plist->memory, pvalue->list, "c_param_end_write_collection"); + pvalue->list = 0; + return code; } static int c_param_write_typed(gs_param_list * plist, gs_param_name pkey, diff -Nru ghostscript-9.10~dfsg/base/gscpixel.c ghostscript-9.25~dfsg+1/base/gscpixel.c --- ghostscript-9.10~dfsg/base/gscpixel.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscpixel.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,7 +21,7 @@ #include "gxcspace.h" #include "gscpixel.h" #include "gxdevice.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gsovrc.h" #include "gsstate.h" #include "gzstate.h" @@ -43,7 +43,7 @@ gx_set_overprint_DevicePixel, NULL, gx_no_adjust_color_count, gx_serialize_DevicePixel, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_unknown }; /* Create a DevicePixel color space. */ @@ -79,7 +79,7 @@ gx_restrict_DevicePixel(gs_client_color * pcc, const gs_color_space * pcs) { /****** NOT ENOUGH BITS IN float OR frac ******/ - floatp pixel = pcc->paint.values[0]; + double pixel = pcc->paint.values[0]; ulong max_value = (1L << pcs->params.pixel.depth) - 1; pcc->paint.values[0] = (pixel < 0 ? 0 : min(pixel, max_value)); @@ -89,7 +89,7 @@ static int gx_concretize_DevicePixel(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { /****** NOT ENOUGH BITS IN float OR frac ******/ pconc[0] = (frac) (ulong) pc->paint.values[0]; @@ -97,9 +97,10 @@ } static int -gx_remap_concrete_DevicePixel(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) +gx_remap_concrete_DevicePixel(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select, + const cmm_dev_profile_t *dev_profile) { color_set_pure(pdc, pconc[0] & ((1 << dev->color_info.depth) - 1)); return 0; @@ -107,13 +108,13 @@ /* DevicePixel disables overprint */ static int -gx_set_overprint_DevicePixel(const gs_color_space * pcs, gs_state * pgs) +gx_set_overprint_DevicePixel(const gs_color_space * pcs, gs_gstate * pgs) { gs_overprint_params_t params; params.retain_any_comps = false; pgs->effective_overprint_mode = 0; - return gs_state_update_overprint(pgs, ¶ms); + return gs_gstate_update_overprint(pgs, ¶ms); } /* ---------------- Serialization. -------------------------------- */ diff -Nru ghostscript-9.10~dfsg/base/gscpixel.h ghostscript-9.25~dfsg+1/base/gscpixel.h --- ghostscript-9.10~dfsg/base/gscpixel.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscpixel.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscpm.h ghostscript-9.25~dfsg+1/base/gscpm.h --- ghostscript-9.10~dfsg/base/gscpm.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscpm.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscrd.c ghostscript-9.25~dfsg+1/base/gscrd.c --- ghostscript-9.10~dfsg/base/gscrd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscrd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -55,7 +55,7 @@ /* Default CRD procedures. */ static int -tpqr_identity(int index, floatp in, const gs_cie_wbsd * pwbsd, +tpqr_identity(int index, double in, const gs_cie_wbsd * pwbsd, gs_cie_render * pcrd, float *out) { *out = in; @@ -63,7 +63,7 @@ } static int -tpqr_from_cache(int index, floatp in, const gs_cie_wbsd * pwbsd, +tpqr_from_cache(int index, double in, const gs_cie_wbsd * pwbsd, gs_cie_render * pcrd, float *out) { /* @@ -76,7 +76,7 @@ } static float -render_identity(floatp in, const gs_cie_render * pcrd) +render_identity(double in, const gs_cie_render * pcrd) { return in; } @@ -89,32 +89,32 @@ /* Transformation procedures that just consult the cache. */ static float -EncodeABC_cached_A(floatp in, const gs_cie_render * pcrd) +EncodeABC_cached_A(double in, const gs_cie_render * pcrd) { return gs_cie_cached_value(in, &pcrd->caches.EncodeABC[0].floats); } static float -EncodeABC_cached_B(floatp in, const gs_cie_render * pcrd) +EncodeABC_cached_B(double in, const gs_cie_render * pcrd) { return gs_cie_cached_value(in, &pcrd->caches.EncodeABC[1].floats); } static float -EncodeABC_cached_C(floatp in, const gs_cie_render * pcrd) +EncodeABC_cached_C(double in, const gs_cie_render * pcrd) { return gs_cie_cached_value(in, &pcrd->caches.EncodeABC[2].floats); } static float -EncodeLMN_cached_L(floatp in, const gs_cie_render * pcrd) +EncodeLMN_cached_L(double in, const gs_cie_render * pcrd) { return gs_cie_cached_value(in, &pcrd->caches.EncodeLMN.caches[0].floats); } static float -EncodeLMN_cached_M(floatp in, const gs_cie_render * pcrd) +EncodeLMN_cached_M(double in, const gs_cie_render * pcrd) { return gs_cie_cached_value(in, &pcrd->caches.EncodeLMN.caches[1].floats); } static float -EncodeLMN_cached_N(floatp in, const gs_cie_render * pcrd) +EncodeLMN_cached_N(double in, const gs_cie_render * pcrd) { return gs_cie_cached_value(in, &pcrd->caches.EncodeLMN.caches[2].floats); } @@ -184,7 +184,7 @@ return code; } static int -tpqr_lookup(int index, floatp in, const gs_cie_wbsd * pwbsd, +tpqr_lookup(int index, double in, const gs_cie_wbsd * pwbsd, gs_cie_render * pcrd, float *out) { const gx_device *const *dev_list; @@ -262,6 +262,29 @@ return 0; } +static bool render_proc3_equal(const gs_cie_render_proc3 *p1, const gs_cie_render_proc3 *p2) +{ + int k; + + for (k = 0; k < 3; k++) { + if (p1->procs[k] != p2->procs[k]) + return false; + } + return true; +} + +static bool render_table_procs_equal(const gs_cie_render_table_procs *p1, + const gs_cie_render_table_procs *p2) +{ + int k; + + for (k = 0; k < 4; k++) { + if (p1->procs[k] != p2->procs[k]) + return false; + } + return true; +} + /* * Initialize a CRD given all of the relevant parameters. * Any of the pointers except WhitePoint may be zero, meaning @@ -305,28 +328,20 @@ *(TransformPQR ? TransformPQR : &TransformPQR_default); pcrd->MatrixLMN = *(MatrixLMN ? MatrixLMN : &Matrix3_default); pcrd->EncodeLMN = *(EncodeLMN ? EncodeLMN : &Encode_default); - if (pfrom_crd && - !memcmp(&pcrd->EncodeLMN, &EncodeLMN_from_cache, - sizeof(EncodeLMN_from_cache)) - ) + if (pfrom_crd && render_proc3_equal(&pcrd->EncodeLMN, &EncodeLMN_from_cache)) memcpy(&pcrd->caches.EncodeLMN, &pfrom_crd->caches.EncodeLMN, sizeof(pcrd->caches.EncodeLMN)); pcrd->RangeLMN = *(RangeLMN ? RangeLMN : &Range3_default); pcrd->MatrixABC = *(MatrixABC ? MatrixABC : &Matrix3_default); pcrd->EncodeABC = *(EncodeABC ? EncodeABC : &Encode_default); - if (pfrom_crd && - !memcmp(&pcrd->EncodeABC, &EncodeABC_from_cache, - sizeof(EncodeABC_from_cache)) - ) + if (pfrom_crd && render_proc3_equal(&pcrd->EncodeABC, &EncodeABC_from_cache)) memcpy(pcrd->caches.EncodeABC, pfrom_crd->caches.EncodeABC, sizeof(pcrd->caches.EncodeABC)); pcrd->RangeABC = *(RangeABC ? RangeABC : &Range3_default); if (RenderTable) { pcrd->RenderTable = *RenderTable; - if (pfrom_crd && - !memcmp(&pcrd->RenderTable.T, &RenderTableT_from_cache, - sizeof(RenderTableT_from_cache)) - ) { + if (pfrom_crd && render_table_procs_equal(&pcrd->RenderTable.T, + &RenderTableT_from_cache)) { memcpy(pcrd->caches.RenderTableT, pfrom_crd->caches.RenderTableT, sizeof(pcrd->caches.RenderTableT)); pcrd->caches.RenderTableT_is_identity = diff -Nru ghostscript-9.10~dfsg/base/gscrd.h ghostscript-9.25~dfsg+1/base/gscrd.h --- ghostscript-9.10~dfsg/base/gscrd.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscrd.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscrdp.c ghostscript-9.25~dfsg+1/base/gscrdp.c --- ghostscript-9.10~dfsg/base/gscrdp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscrdp.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -67,8 +67,7 @@ const gs_matrix3 * pmat, gs_memory_t * mem) { float values[9]; - - if (!memcmp(pmat, &Matrix3_default, sizeof(*pmat))) + if(matrix_equal(pmat, &Matrix3_default)) return 0; store_vector3(values, &pmat->cu); store_vector3(values + 3, &pmat->cv); @@ -81,13 +80,26 @@ { float values[6]; - if (!memcmp(prange, &Range3_default, sizeof(*prange))) + if (range_equal(prange, &Range3_default)) return 0; values[0] = prange->ranges[0].rmin, values[1] = prange->ranges[0].rmax; values[2] = prange->ranges[1].rmin, values[3] = prange->ranges[1].rmax; values[4] = prange->ranges[2].rmin, values[5] = prange->ranges[2].rmax; return write_floats(plist, key, values, 6, mem); } + +static bool +render_proc3_equal(const gs_cie_render_proc3 *p1, const gs_cie_render_proc3 *p2) +{ + int k; + + for (k = 0; k < 3; k++) { + if (p1->procs[k] != p2->procs[k]) + return false; + } + return true; +} + static int write_proc3(gs_param_list * plist, gs_param_name key, const gs_cie_render * pcrd, const gs_cie_render_proc3 * procs, @@ -98,7 +110,7 @@ gs_param_float_array fa; int i; - if (!memcmp(procs, &Encode_default, sizeof(*procs))) + if (render_proc3_equal(procs, &Encode_default)) return 0; values = (float *)gs_alloc_byte_array(mem, size * 3, sizeof(float), "write_proc3"); @@ -167,8 +179,7 @@ (code = write_vector3(plist, "WhitePoint", &pcrd->points.WhitePoint, mem)) < 0 ) return code; - if (memcmp(&pcrd->points.BlackPoint, &BlackPoint_default, - sizeof(pcrd->points.BlackPoint))) { + if (!vector_equal(&pcrd->points.BlackPoint, &BlackPoint_default)) { if ((code = write_vector3(plist, "BlackPoint", &pcrd->points.BlackPoint, mem)) < 0) return code; } @@ -385,7 +396,7 @@ /* Define procedures that retrieve the Encode values read from the list. */ static float -encode_from_data(floatp v, const float values[gx_cie_cache_size], +encode_from_data(double v, const float values[gx_cie_cache_size], const gs_range * range) { return (v <= range->rmin ? values[0] : @@ -398,7 +409,7 @@ * my craw, but I've got a mandate not to use macros.... */ static float -encode_lmn_0_from_data(floatp v, const gs_cie_render * pcrd) +encode_lmn_0_from_data(double v, const gs_cie_render * pcrd) { const encode_data_t *data = pcrd->client_data; @@ -406,7 +417,7 @@ &pcrd->DomainLMN.ranges[0]); } static float -encode_lmn_1_from_data(floatp v, const gs_cie_render * pcrd) +encode_lmn_1_from_data(double v, const gs_cie_render * pcrd) { const encode_data_t *data = pcrd->client_data; @@ -414,7 +425,7 @@ &pcrd->DomainLMN.ranges[1]); } static float -encode_lmn_2_from_data(floatp v, const gs_cie_render * pcrd) +encode_lmn_2_from_data(double v, const gs_cie_render * pcrd) { const encode_data_t *data = pcrd->client_data; @@ -422,7 +433,7 @@ &pcrd->DomainLMN.ranges[2]); } static float -encode_abc_0_from_data(floatp v, const gs_cie_render * pcrd) +encode_abc_0_from_data(double v, const gs_cie_render * pcrd) { const encode_data_t *data = pcrd->client_data; @@ -430,7 +441,7 @@ &pcrd->DomainABC.ranges[0]); } static float -encode_abc_1_from_data(floatp v, const gs_cie_render * pcrd) +encode_abc_1_from_data(double v, const gs_cie_render * pcrd) { const encode_data_t *data = pcrd->client_data; @@ -438,7 +449,7 @@ &pcrd->DomainABC.ranges[1]); } static float -encode_abc_2_from_data(floatp v, const gs_cie_render * pcrd) +encode_abc_2_from_data(double v, const gs_cie_render * pcrd) { const encode_data_t *data = pcrd->client_data; @@ -562,8 +573,8 @@ pcrd->EncodeABC = Encode_default; else pcrd->EncodeABC = EncodeABC_from_data; - code_rt = code = param_read_int_array(plist, "RenderTableSize", &rt_size); - if (code == 1) { + code_rt = param_read_int_array(plist, "RenderTableSize", &rt_size); + if (code_rt == 1) { if (pcrd->RenderTable.lookup.table) { gs_free_object(pcrd->rc.memory, (void *)pcrd->RenderTable.lookup.table, /* break const */ @@ -572,8 +583,8 @@ } pcrd->RenderTable.T = RenderTableT_default; code_t = 1; - } else if (code < 0) - return code; + } else if (code_rt < 0) + return code_rt; else if (rt_size.size != 4) return_error(gs_error_rangecheck); else { diff -Nru ghostscript-9.10~dfsg/base/gscrdp.h ghostscript-9.25~dfsg+1/base/gscrdp.h --- ghostscript-9.10~dfsg/base/gscrdp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscrdp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscrypt1.c ghostscript-9.25~dfsg+1/base/gscrypt1.c --- ghostscript-9.10~dfsg/base/gscrypt1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscrypt1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscrypt1.h ghostscript-9.25~dfsg+1/base/gscrypt1.h --- ghostscript-9.10~dfsg/base/gscrypt1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscrypt1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscscie.c ghostscript-9.25~dfsg+1/base/gscscie.c --- ghostscript-9.10~dfsg/base/gscscie.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscscie.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,6 +22,7 @@ #include "gsmatrix.h" /* for gscolor2.h */ #include "gxcspace.h" #include "gscolor2.h" /* for gs_set/currentcolorrendering */ +#include "gsicc_manage.h" /* for gsicc_adjust_profile_rc */ #include "gxcie.h" #include "gxarith.h" #include "gxdevice.h" /* for gxcmap.h */ @@ -58,7 +59,7 @@ gx_spot_colors_set_overprint, gx_final_CIEDEFG, gx_no_adjust_color_count, gx_serialize_CIEDEFG, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_subtractive }; /* CIEBasedDEF */ @@ -78,7 +79,7 @@ gx_spot_colors_set_overprint, gx_final_CIEDEF, gx_no_adjust_color_count, gx_serialize_CIEDEF, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_subtractive }; /* CIEBasedABC */ @@ -97,7 +98,7 @@ gx_spot_colors_set_overprint, gx_final_CIEABC, gx_no_adjust_color_count, gx_serialize_CIEABC, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_additive }; /* CIEBasedA */ @@ -117,21 +118,21 @@ gx_spot_colors_set_overprint, gx_final_CIEA, gx_no_adjust_color_count, gx_serialize_CIEA, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_additive }; /* Determine the concrete space underlying a CIEBased space. */ const gs_color_space * -gx_concrete_space_CIE(const gs_color_space * pcs, const gs_imager_state * pis) +gx_concrete_space_CIE(const gs_color_space * pcs, const gs_gstate * pgs) { - const gs_cie_render *pcie = pis->cie_render; + const gs_cie_render *pcie = pgs->cie_render; if (pcie == 0 || pcie->RenderTable.lookup.table == 0 || pcie->RenderTable.lookup.m == 3 ) { - return pis->devicergb_cs; + return pgs->devicergb_cs; } else { /* pcie->RenderTable.lookup.m == 4 */ - return pis->devicecmyk_cs; + return pgs->devicecmyk_cs; } } @@ -140,7 +141,7 @@ /* interpreters can substitute their own installer. */ /* This procedure is exported for the benefit of gsicc.c */ int -gx_install_CIE(gs_color_space * pcs, gs_state * pgs) +gx_install_CIE(gs_color_space * pcs, gs_gstate * pgs) { return (*pcs->params.a->common.install_cspace) (pcs, pgs); } @@ -155,7 +156,7 @@ rc_decrement(pcs_noconst->icc_equivalent, "gx_final_CIEDEFG"); } if (pcs->cmm_icc_profile_data != NULL) { - rc_decrement(pcs_noconst->cmm_icc_profile_data, "gx_final_CIEDEFG"); + gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEDEFG"); } rc_decrement(pcs_noconst->params.defg, "gx_final_CIEDEFG"); } @@ -169,7 +170,7 @@ rc_decrement(pcs_noconst->icc_equivalent,"gx_final_CIEDEF"); } if (pcs->cmm_icc_profile_data != NULL) { - rc_decrement(pcs_noconst->cmm_icc_profile_data, "gx_final_CIEDEF"); + gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEDEF"); } rc_decrement(pcs_noconst->params.def, "gx_final_CIEDEF"); } @@ -183,7 +184,7 @@ rc_decrement(pcs_noconst->icc_equivalent,"gx_final_CIEABC"); } if (pcs->cmm_icc_profile_data != NULL) { - rc_decrement(pcs_noconst->cmm_icc_profile_data, "gx_final_CIEABC"); + gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEABC"); } rc_decrement(pcs_noconst->params.abc, "gx_final_CIEABC"); } @@ -197,7 +198,7 @@ rc_decrement(pcs_noconst->icc_equivalent,"gx_final_CIEA"); } if (pcs->cmm_icc_profile_data != NULL) { - rc_decrement(pcs_noconst->cmm_icc_profile_data, "gx_final_CIEA"); + gsicc_adjust_profile_rc(pcs_noconst->cmm_icc_profile_data, -1, "gx_final_CIEA"); } rc_decrement(pcs_noconst->params.a, "gx_adjust_cspace_CIEA"); } @@ -406,6 +407,8 @@ int code; code = sputs(s, (const byte *)&c->params.is_identity, sizeof(c->params.is_identity), &n); + if (code < 0) + return_error(gs_error_ioerror); if (c->params.is_identity) return 0; code = sputs(s, (const byte *)&cache_size, sizeof(cache_size), &n); diff -Nru ghostscript-9.10~dfsg/base/gscsel.h ghostscript-9.25~dfsg+1/base/gscsel.h --- ghostscript-9.10~dfsg/base/gscsel.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscsel.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gscsepr.c ghostscript-9.25~dfsg+1/base/gscsepr.c --- ghostscript-9.10~dfsg/base/gscsepr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscsepr.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -34,6 +34,8 @@ #include "stream.h" #include "gsicc_cache.h" #include "gxdevice.h" +#include "gxcie.h" +#include "gxdevsop.h" /* ---------------- Color space ---------------- */ @@ -61,7 +63,7 @@ gx_set_overprint_Separation, gx_final_Separation, gx_no_adjust_color_count, gx_serialize_Separation, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_subtractive }; /* GC procedures */ @@ -80,30 +82,30 @@ /* Get the concrete space for a Separation space. */ static const gs_color_space * gx_concrete_space_Separation(const gs_color_space * pcs, - const gs_imager_state * pis) + const gs_gstate * pgs) { bool is_lab = false; #ifdef DEBUG /* - * Verify that the color space and imager state info match. + * Verify that the color space and gs_gstate info match. */ - if (pcs->id != pis->color_component_map.cspace_id) - dmprintf(pis->memory, "gx_concretze_space_Separation: color space id mismatch"); + if (pcs->id != pgs->color_component_map.cspace_id) + dmprintf(pgs->memory, "gx_concretze_space_Separation: color space id mismatch"); #endif /* * Check if we are using the alternate color space. */ - if (pis->color_component_map.use_alt_cspace) { + if (pgs->color_component_map.use_alt_cspace) { /* Need to handle PS CIE space */ if (gs_color_space_is_PSCIE(pcs->base_space)) { if (pcs->base_space->icc_equivalent == NULL) { - gs_colorspace_set_icc_equivalent(pcs->base_space, - &is_lab, pis->memory); + (void)gs_colorspace_set_icc_equivalent(pcs->base_space, + &is_lab, pgs->memory); } return (pcs->base_space->icc_equivalent); } - return cs_concrete_space(pcs->base_space, pis); + return cs_concrete_space(pcs->base_space, pgs); } /* * Separation color spaces are concrete (when not using alt. color space). @@ -112,11 +114,11 @@ } static int -check_Separation_component_name(const gs_color_space * pcs, gs_state * pgs); +check_Separation_component_name(const gs_color_space * pcs, gs_gstate * pgs); /* Install a Separation color space. */ static int -gx_install_Separation(gs_color_space * pcs, gs_state * pgs) +gx_install_Separation(gs_color_space * pcs, gs_gstate * pgs) { int code; @@ -133,40 +135,32 @@ * Give the device an opportunity to capture equivalent colors for any * spot colors which might be present in the color space. */ - if (code >= 0) - code = dev_proc(pgs->device, update_spot_equivalent_colors) + if (code >= 0) { + if (dev_proc(pgs->device, update_spot_equivalent_colors)) + code = dev_proc(pgs->device, update_spot_equivalent_colors) (pgs->device, pgs); + } } return code; } /* Set the overprint information appropriate to a separation color space */ static int -gx_set_overprint_Separation(const gs_color_space * pcs, gs_state * pgs) +gx_set_overprint_Separation(const gs_color_space * pcs, gs_gstate * pgs) { gs_devicen_color_map * pcmap = &pgs->color_component_map; - gx_device *dev = pgs->device; - cmm_dev_profile_t *dev_profile; - - dev_proc(dev, get_profile)(dev, &(dev_profile)); + if (pcmap->use_alt_cspace) - if (dev_profile->sim_overprint && - dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && - !gx_device_must_halftone(dev)) - return gx_simulated_set_overprint(pcs->base_space, pgs); - else - return gx_spot_colors_set_overprint(pcs->base_space, pgs); + return gx_spot_colors_set_overprint(pcs->base_space, pgs); else { gs_overprint_params_t params; /* We should not have to blend if we don't need the alternate tint transform */ - params.blendspot = false; params.retain_any_comps = pgs->overprint && pcs->params.separation.sep_type != SEP_ALL; if (params.retain_any_comps) { params.retain_spot_comps = false; params.drawn_comps = 0; - params.k_value = 0; if (pcs->params.separation.sep_type != SEP_NONE) { int mcomp = pcmap->color_map[0]; @@ -174,9 +168,9 @@ gs_overprint_set_drawn_comp( params.drawn_comps, mcomp); } } - + /* Only DeviceCMYK can use overprint mode */ pgs->effective_overprint_mode = 0; - return gs_state_update_overprint(pgs, ¶ms); + return gs_gstate_update_overprint(pgs, ¶ms); } } @@ -231,7 +225,7 @@ gs_cspace_set_sepr_proc(gs_color_space * pcspace, int (*proc)(const float *, float *, - const gs_imager_state *, + const gs_gstate *, void * ), void *proc_data @@ -297,14 +291,25 @@ static int gx_remap_Separation(const gs_client_color * pcc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { int code = 0; + bool mapped = false; - if (pcs->params.separation.sep_type != SEP_NONE) - code = gx_default_remap_color(pcc, pcs, pdc, pis, dev, select); - else { + if (pcs->params.separation.sep_type != SEP_NONE) { + /* First see if we want to do a direct remap with a named color table. + Note that this call occurs regardless of the alt color space boolean + value. A decision can be made in gsicc_transform_named_color to + return false if you don't want those named colors to be mapped */ + if (pcs->params.separation.sep_type == SEP_OTHER && + pgs->icc_manager->device_named != NULL) { + /* Try to apply the direct replacement */ + mapped = gx_remap_named_color(pcc, pcs, pdc, pgs, dev, select); + } + if (!mapped) + code = gx_default_remap_color(pcc, pcs, pdc, pgs, dev, select); + } else { color_set_null(pdc); } /* Save original color space and color info into dev color */ @@ -315,52 +320,16 @@ static int gx_concretize_Separation(const gs_client_color *pc, const gs_color_space *pcs, - frac *pconc, const gs_imager_state *pis, gx_device *dev) + frac *pconc, const gs_gstate *pgs, gx_device *dev) { int code; gs_client_color cc; gs_color_space *pacs = pcs->base_space; bool is_lab; - int k; - int num_des_comps = dev->color_info.num_components; - gsicc_namedcolor_t named_color; if (pcs->params.separation.sep_type == SEP_OTHER && pcs->params.separation.use_alt_cspace) { gs_device_n_map *map = pcs->params.separation.map; - /* First see if we have a named color object that we can use to try - to map from the spot color into device values. */ - if (pis->icc_manager->device_named != NULL) { - /* There is a table present. If we have the colorant name - then get the device values */ - gx_color_value device_values[GX_DEVICE_COLOR_MAX_COMPONENTS]; - const gs_separation_name name = pcs->params.separation.sep_name; - byte *pname; - uint name_size; - gsicc_rendering_param_t rendering_params; - - /* Define the rendering intents. */ - rendering_params.black_point_comp = pis->blackptcomp; - rendering_params.graphics_type_tag = dev->graphics_type_tag; - rendering_params.override_icc = false; - rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; - rendering_params.cmm = gsCMM_DEFAULT; - pcs->params.separation.get_colorname_string(pis->memory, name, - &pname, &name_size); - /* Make the name structure and initialized it */ - named_color.colorant_name = (char*) pname; - named_color.name_size = name_size; - code = gsicc_transform_named_color(pc->paint.values, &named_color, - 1, device_values, pis, dev, NULL, - &rendering_params); - if (code == 0) { - for (k = 0; k < num_des_comps; k++){ - pconc[k] = float2frac(((float) device_values[k])/65535.0); - } - return(0); - } - } /* Check the 1-element cache first. */ if (map->cache_valid && map->tint[0] == pc->paint.values[0]) { int i, num_out = gs_color_space_num_components(pacs); @@ -371,55 +340,59 @@ } code = (*pcs->params.separation.map->tint_transform) (pc->paint.values, &cc.paint.values[0], - pis, pcs->params.separation.map->tint_transform_data); + pgs, pcs->params.separation.map->tint_transform_data); if (code < 0) return code; (*pacs->type->restrict_color)(&cc, pacs); /* First check if this was PS based. */ if (gs_color_space_is_PSCIE(pacs)) { - /* If we have not yet create the profile do that now */ + /* We may have to rescale data to 0 to 1 range */ + rescale_cie_colors(pacs, &cc); + /* If we have not yet created the profile do that now */ if (pacs->icc_equivalent == NULL) { - gs_colorspace_set_icc_equivalent(pacs, &(is_lab), pis->memory); + code = gs_colorspace_set_icc_equivalent(pacs, &(is_lab), pgs->memory); + if (code < 0) + return code; } /* Use the ICC equivalent color space */ pacs = pacs->icc_equivalent; } - if (pacs->cmm_icc_profile_data->data_cs == gsCIELAB || - pacs->cmm_icc_profile_data->islab) { + if (pacs->cmm_icc_profile_data && + (pacs->cmm_icc_profile_data->data_cs == gsCIELAB || + pacs->cmm_icc_profile_data->islab)) { /* Get the data in a form that is concrete for the CMM */ cc.paint.values[0] /= 100.0; cc.paint.values[1] = (cc.paint.values[1]+128)/255.0; cc.paint.values[2] = (cc.paint.values[2]+128)/255.0; } - return cs_concretize_color(&cc, pacs, pconc, pis, dev); - } - else { + return cs_concretize_color(&cc, pacs, pconc, pgs, dev); + } else { pconc[0] = gx_unit_frac(pc->paint.values[0]); } return 0; } static int -gx_remap_concrete_Separation(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) +gx_remap_concrete_Separation(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, + gs_color_select_t select, const cmm_dev_profile_t *dev_profile) { #ifdef DEBUG /* - * Verify that the color space and imager state info match. + * Verify that the color space and gs_gstate info match. */ - if (pcs->id != pis->color_component_map.cspace_id) - dmprintf(pis->memory, "gx_remap_concrete_Separation: color space id mismatch"); + if (pcs->id != pgs->color_component_map.cspace_id) + dmprintf(pgs->memory, "gx_remap_concrete_Separation: color space id mismatch"); #endif - if (pis->color_component_map.use_alt_cspace) { + if (pgs->color_component_map.use_alt_cspace) { const gs_color_space *pacs = pcs->base_space; return (*pacs->type->remap_concrete_color) - (pconc, pacs, pdc, pis, dev, select); - } - else { - gx_remap_concrete_separation(pconc[0], pdc, pis, dev, select); + (pacs, pconc, pdc, pgs, dev, select, dev_profile); + } else { + /* We need to determine if we did a direct color replacement */ + gx_remap_concrete_separation(pconc[0], pdc, pgs, dev, select); return 0; } } @@ -430,7 +403,7 @@ * structure. */ static int -check_Separation_component_name(const gs_color_space * pcs, gs_state * pgs) +check_Separation_component_name(const gs_color_space * pcs, gs_gstate * pgs) { const gs_separation_name name = pcs->params.separation.sep_name; int colorant_number; @@ -455,9 +428,17 @@ /* * Always use the alternate color space if the current device is * using an additive color model. Separations are only for use - * with a subtractive color model. + * with a subtractive color model. The exception is if we have a separation + * device and we are doing transparency blending in an additive color + * space. In that case, the spots are kept separated and blended + * individually per the PDF specification. Note however, if the spot is + * a CMYK process color and we are doing the blend in an additive color space + * the alternate color space is used. This matches AR. */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { + + if (!(dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) && + dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0)) && + dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { pcolor_component_map->use_alt_cspace = true; return 0; } diff -Nru ghostscript-9.10~dfsg/base/gscsepr.h ghostscript-9.25~dfsg+1/base/gscsepr.h --- ghostscript-9.10~dfsg/base/gscsepr.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscsepr.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -54,7 +54,7 @@ int gs_cspace_set_sepr_proc(gs_color_space * pcspace, int (*proc)(const float *, float *, - const gs_imager_state *, + const gs_gstate *, void * ), void *proc_data diff -Nru ghostscript-9.10~dfsg/base/gscspace.c ghostscript-9.25~dfsg+1/base/gscspace.c --- ghostscript-9.10~dfsg/base/gscspace.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscspace.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,7 +23,7 @@ #include "gsutil.h" /* for gs_next_ids */ #include "gxcmap.h" #include "gxcspace.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gsovrc.h" #include "gsstate.h" #include "gsdevice.h" @@ -53,7 +53,7 @@ gx_spot_colors_set_overprint, NULL, gx_no_adjust_color_count, gx_serialize_cspace_type, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_additive }; static const gs_color_space_type gs_color_space_type_DeviceRGB = { gs_color_space_index_DeviceRGB, true, true, @@ -65,7 +65,7 @@ gx_spot_colors_set_overprint, NULL, gx_no_adjust_color_count, gx_serialize_cspace_type, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_additive }; static cs_proc_set_overprint(gx_set_overprint_DeviceCMYK); @@ -80,7 +80,7 @@ gx_set_overprint_DeviceCMYK, NULL, gx_no_adjust_color_count, gx_serialize_cspace_type, - gx_cspace_is_linear_default + gx_cspace_is_linear_default, gx_polarity_subtractive }; /* Structure descriptors */ @@ -97,7 +97,7 @@ if (pcs->type->final) pcs->type->final(pcs); - if_debug2m('c', cmem, "[c]cspace final %08x %d\n", pcs, pcs->id); + if_debug2m('c', cmem, "[c]cspace final %p %d\n", pcs, (int)pcs->id); rc_decrement_only_cs(pcs->base_space, "gs_cspace_final"); /* No need to decrement the ICC profile data. It is handled @@ -114,7 +114,7 @@ rc_alloc_struct_1(pcs, gs_color_space, &st_color_space, mem, return NULL, "gs_cspace_alloc_with_id"); - if_debug3m('c', mem, "[c]cspace alloc %08x %s %d\n", + if_debug3m('c', mem, "[c]cspace alloc %p %s %d\n", pcs, pcstype->stype->sname, pcstype->index); pcs->type = pcstype; pcs->id = id; @@ -163,19 +163,22 @@ /* For use in initializing ICC color spaces for XPS */ gs_color_space * -gs_cspace_new_ICC(gs_memory_t *pmem, gs_state * pgs, int components) +gs_cspace_new_ICC(gs_memory_t *pmem, gs_gstate * pgs, int components) { gsicc_manager_t *icc_manage = pgs->icc_manager; - int code; + int code = 0; gs_color_space *pcspace = gs_cspace_alloc(pmem, &gs_color_space_type_ICC); + if (pcspace == NULL) + return pcspace; + switch (components) { case -1: /* alpha case */ if (icc_manage->smask_profiles == NULL) { code = gsicc_initialize_iccsmask(icc_manage); } if (code == 0) { - pcspace->cmm_icc_profile_data = + pcspace->cmm_icc_profile_data = icc_manage->smask_profiles->smask_gray; } else { pcspace->cmm_icc_profile_data = icc_manage->default_gray; @@ -186,18 +189,18 @@ code = gsicc_initialize_iccsmask(icc_manage); } if (code == 0) { - pcspace->cmm_icc_profile_data = + pcspace->cmm_icc_profile_data = icc_manage->smask_profiles->smask_rgb; } else { pcspace->cmm_icc_profile_data = icc_manage->default_rgb; } break; - case 1: pcspace->cmm_icc_profile_data = icc_manage->default_gray; break; - case 3: pcspace->cmm_icc_profile_data = icc_manage->default_rgb; break; - case 4: pcspace->cmm_icc_profile_data = icc_manage->default_cmyk; break; + case 1: pcspace->cmm_icc_profile_data = icc_manage->default_gray; break; + case 3: pcspace->cmm_icc_profile_data = icc_manage->default_rgb; break; + case 4: pcspace->cmm_icc_profile_data = icc_manage->default_cmyk; break; default: rc_decrement(pcspace,"gs_cspace_new_ICC"); return NULL; } - rc_increment(pcspace->cmm_icc_profile_data); + gsicc_adjust_profile_rc(pcspace->cmm_icc_profile_data, 1, "gs_cspace_new_ICC"); return pcspace; } @@ -263,7 +266,7 @@ /* Install a DeviceGray color space. */ static int -gx_install_DeviceGray(gs_color_space * pcs, gs_state * pgs) +gx_install_DeviceGray(gs_color_space * pcs, gs_gstate * pgs) { /* If we already have profile data installed, nothing to do here. */ if (pcs->cmm_icc_profile_data != NULL) @@ -275,7 +278,7 @@ /* pcs takes a reference to the default_gray profile data */ pcs->cmm_icc_profile_data = pgs->icc_manager->default_gray; - rc_increment(pgs->icc_manager->default_gray); + gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "gx_install_DeviceGray"); pcs->type = &gs_color_space_type_ICC; return 0; } @@ -296,6 +299,24 @@ return 4; } +gx_color_polarity_t +gx_polarity_subtractive(const gs_color_space * pcs) +{ + return GX_CINFO_POLARITY_SUBTRACTIVE; +} + +gx_color_polarity_t +gx_polarity_additive(const gs_color_space * pcs) +{ + return GX_CINFO_POLARITY_ADDITIVE; +} + +gx_color_polarity_t +gx_polarity_unknown(const gs_color_space * pcs) +{ + return GX_CINFO_POLARITY_UNKNOWN; +} + /* * For color spaces that have a base or alternative color space, return that * color space. Otherwise return null. @@ -329,7 +350,7 @@ } } -void cs_adjust_counts_icc(gs_state *pgs, int delta) +void cs_adjust_counts_icc(gs_gstate *pgs, int delta) { gs_color_space *pcs = gs_currentcolorspace_inline(pgs); @@ -342,14 +363,14 @@ /* Null color space installation procedure. */ int -gx_no_install_cspace(gs_color_space * pcs, gs_state * pgs) +gx_no_install_cspace(gs_color_space * pcs, gs_gstate * pgs) { return 0; } /* Install a DeviceRGB color space. */ static int -gx_install_DeviceRGB(gs_color_space * pcs, gs_state * pgs) +gx_install_DeviceRGB(gs_color_space * pcs, gs_gstate * pgs) { /* If we already have profile_data, nothing to do here. */ if (pcs->cmm_icc_profile_data != NULL) @@ -361,14 +382,14 @@ /* pcs takes a reference to default_rgb */ pcs->cmm_icc_profile_data = pgs->icc_manager->default_rgb; - rc_increment(pcs->cmm_icc_profile_data); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "gx_install_DeviceRGB"); pcs->type = &gs_color_space_type_ICC; return 0; } /* Install a DeviceCMYK color space. */ static int -gx_install_DeviceCMYK(gs_color_space * pcs, gs_state * pgs) +gx_install_DeviceCMYK(gs_color_space * pcs, gs_gstate * pgs) { /* If we already have profile data, nothing to do here. */ if (pcs->cmm_icc_profile_data != NULL) @@ -380,7 +401,7 @@ /* pcs takes a reference to default_cmyk */ pcs->cmm_icc_profile_data = pgs->icc_manager->default_cmyk; - rc_increment(pcs->cmm_icc_profile_data); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "gx_install_DeviceCMYK"); pcs->type = &gs_color_space_type_ICC; return 0; } @@ -396,37 +417,17 @@ * special verson that supports overprint mode. */ int -gx_spot_colors_set_overprint(const gs_color_space * pcs, gs_state * pgs) -{ - gs_imager_state * pis = (gs_imager_state *)pgs; - gs_overprint_params_t params; - - if ((params.retain_any_comps = pis->overprint)) - params.retain_spot_comps = true; - pgs->effective_overprint_mode = 0; - params.k_value = 0; - params.blendspot = false; - return gs_state_update_overprint(pgs, ¶ms); -} - -/* - * Push an overprint compositor onto the current device indicating that - * incoming CMYK values should be blended to simulate overprinting. This - * allows us to get simulated overprinting of spot colors on standard CMYK - * devices - */ -int -gx_simulated_set_overprint(const gs_color_space * pcs, gs_state * pgs) +gx_spot_colors_set_overprint(const gs_color_space * pcs, gs_gstate * pgs) { - gs_imager_state * pis = (gs_imager_state *)pgs; gs_overprint_params_t params; - if ((params.retain_any_comps = pis->overprint)) + if ((params.retain_any_comps = pgs->overprint)) { params.retain_spot_comps = true; + params.retain_any_comps = false; + } + /* Only DeviceCMYK case can have overprint mode set to true */ pgs->effective_overprint_mode = 0; - params.k_value = 0; - params.blendspot = true; - return gs_state_update_overprint(pgs, ¶ms); + return gs_gstate_update_overprint(pgs, ¶ms); } static bool @@ -463,10 +464,9 @@ check_cmyk_color_model_comps(gx_device * dev) { gx_device_color_info * pcinfo = &dev->color_info; - int ncomps = pcinfo->num_components; + uchar ncomps = pcinfo->num_components; int cyan_c, magenta_c, yellow_c, black_c; - const gx_cm_color_map_procs * pprocs; - cm_map_proc_cmyk((*map_cmyk)); + subclass_color_mappings scm; frac frac_14 = frac_1 / 4; frac out[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index process_comps; @@ -500,20 +500,18 @@ return 0; /* check the mapping */ - if ( (pprocs = dev_proc(dev, get_color_mapping_procs)(dev)) == 0 || - (map_cmyk = pprocs->map_cmyk) == 0 ) - return 0; + scm = get_color_mapping_procs_subclass(dev); - map_cmyk(dev, frac_14, frac_0, frac_0, frac_0, out); + map_cmyk_subclass(scm, frac_14, frac_0, frac_0, frac_0, out); if (!check_single_comp(cyan_c, frac_14, ncomps, out)) return 0; - map_cmyk(dev, frac_0, frac_14, frac_0, frac_0, out); + map_cmyk_subclass(scm, frac_0, frac_14, frac_0, frac_0, out); if (!check_single_comp(magenta_c, frac_14, ncomps, out)) return 0; - map_cmyk(dev, frac_0, frac_0, frac_14, frac_0, out); + map_cmyk_subclass(scm, frac_0, frac_0, frac_14, frac_0, out); if (!check_single_comp(yellow_c, frac_14, ncomps, out)) return false; - map_cmyk(dev, frac_0, frac_0, frac_0, frac_14, out); + map_cmyk_subclass(scm, frac_0, frac_0, frac_0, frac_14, out); if (!check_single_comp(black_c, frac_14, ncomps, out)) return 0; @@ -527,65 +525,6 @@ return process_comps; } -/* This is used in the RGB simulation overprint case */ - -gx_color_index -check_rgb_color_model_comps(gx_device * dev) -{ - gx_device_color_info * pcinfo = &dev->color_info; - int ncomps = pcinfo->num_components; - int red_c, green_c, blue_c; - const gx_cm_color_map_procs * pprocs; - cm_map_proc_rgb((*map_rgb)); - frac frac_14 = frac_1 / 4; - frac out[GX_DEVICE_COLOR_MAX_COMPONENTS]; - gx_color_index process_comps; - - /* check for the appropriate components */ - if ( ncomps < 3 || - (red_c = dev_proc(dev, get_color_comp_index)( - dev, - "Red", - sizeof("Red") - 1, - NO_COMP_NAME_TYPE )) < 0 || - red_c == GX_DEVICE_COLOR_MAX_COMPONENTS || - (green_c = dev_proc(dev, get_color_comp_index)( - dev, - "Green", - sizeof("Green") - 1, - NO_COMP_NAME_TYPE )) < 0 || - green_c == GX_DEVICE_COLOR_MAX_COMPONENTS || - (blue_c = dev_proc(dev, get_color_comp_index)( - dev, - "Blue", - sizeof("Blue") - 1, - NO_COMP_NAME_TYPE )) < 0 || - blue_c == GX_DEVICE_COLOR_MAX_COMPONENTS ) - return 0; - - /* check the mapping */ - if ( (pprocs = dev_proc(dev, get_color_mapping_procs)(dev)) == 0 || - (map_rgb = pprocs->map_rgb) == 0 ) - return 0; - - map_rgb(dev, NULL, frac_14, frac_0, frac_0, out); - if (!check_single_comp(red_c, frac_14, ncomps, out)) - return 0; - map_rgb(dev, NULL, frac_0, frac_14, frac_0, out); - if (!check_single_comp(green_c, frac_14, ncomps, out)) - return 0; - map_rgb(dev, NULL, frac_0, frac_0, frac_14, out); - if (!check_single_comp(blue_c, frac_14, ncomps, out)) - return 0; - - process_comps = ((gx_color_index)1 << red_c) - | ((gx_color_index)1 << green_c) - | ((gx_color_index)1 << blue_c); - pcinfo->opmode = GC_CINFO_OPMODE_RGB_SET; - pcinfo->process_comps = process_comps; - return process_comps; -} - /* * This set_overprint method is unique. If overprint is true, overprint * mode is set to 1, the process color model has DeviceCMYK behavior (see @@ -594,7 +533,7 @@ * the set of drawn components. */ static int -gx_set_overprint_DeviceCMYK(const gs_color_space * pcs, gs_state * pgs) +gx_set_overprint_DeviceCMYK(const gs_color_space * pcs, gs_gstate * pgs) { gx_device * dev = pgs->device; gx_device_color_info * pcinfo = (dev == 0 ? 0 : &dev->color_info); @@ -611,18 +550,18 @@ /* A few comments about ICC profiles and overprint simulation. In order to do proper overprint simulation, the source ICC profile and the - destination ICC profile must be the same. If they are not, then - we end up mapping the source CMYK data to a different CMYK value. In - this case, the non-zero components, which with overprint mode = 1 specify - which are to be overprinted will not be correct to produce the proper - overprint simulation. This is seen with AR when doing output preview, + destination ICC profile must be the same. If they are not, then + we end up mapping the source CMYK data to a different CMYK value. In + this case, the non-zero components, which with overprint mode = 1 specify + which are to be overprinted will not be correct to produce the proper + overprint simulation. This is seen with AR when doing output preview, overprint simulation enabled of the file overprint_icc.pdf (see our - test files) which has SWOP ICC based CMYK fills. In AR, if we use a - simluation ICC profile that is different than the source profile, - overprinting is no longer previewed. We follow the same logic here. - If the source and destination ICC profiles do not match, then there is + test files) which has SWOP ICC based CMYK fills. In AR, if we use a + simluation ICC profile that is different than the source profile, + overprinting is no longer previewed. We follow the same logic here. + If the source and destination ICC profiles do not match, then there is effectively no overprinting enabled. This is bug 692433 */ -int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_state * pgs) +int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_gstate * pgs) { gx_device * dev = pgs->device; gx_device_color_info * pcinfo = (dev == 0 ? 0 : &dev->color_info); @@ -630,35 +569,39 @@ gs_overprint_params_t params; gx_device_color *pdc; cmm_dev_profile_t *dev_profile; - cmm_profile_t *output_profile; + cmm_profile_t *output_profile = 0; int code; bool profile_ok = false; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; - code = dev_proc(dev, get_profile)(dev, &dev_profile); - gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &(output_profile), - &render_cond); - - /* check if color model behavior must be determined */ - if (pcinfo->opmode == GX_CINFO_OPMODE_UNKNOWN) - drawn_comps = check_cmyk_color_model_comps(dev); - else - drawn_comps = pcinfo->process_comps; + if (dev) { + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + + gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &(output_profile), + &render_cond); + + /* check if color model behavior must be determined */ + if (pcinfo->opmode == GX_CINFO_OPMODE_UNKNOWN) + drawn_comps = check_cmyk_color_model_comps(dev); + else + drawn_comps = pcinfo->process_comps; + } if (drawn_comps == 0) return gx_spot_colors_set_overprint(pcs, pgs); /* correct for any zero'ed color components. But only if profiles - match */ + match AND pgs->overprint_mode is true */ if (pcs->cmm_icc_profile_data != NULL && output_profile != NULL) { - if (output_profile->hashcode == + if (output_profile->hashcode == pcs->cmm_icc_profile_data->hashcode) { - profile_ok = true; + profile_ok = true; } } - pgs->effective_overprint_mode = 1; pdc = gs_currentdevicecolor_inline(pgs); - if (color_is_set(pdc) && profile_ok) { + if (color_is_set(pdc) && profile_ok && pgs->overprint_mode == 1) { gx_color_index nz_comps, one, temp; int code; int num_colorant[4], k; @@ -668,11 +611,11 @@ procp = pdc->type->get_nonzero_comps; if (pdc->ccolor_valid) { - /* If we have the source colors, then use those in making the - decision as to which ones are non-zero. Then we avoid - accidently looking at small values that get quantized to zero - Note that to get here in the code, the source color data color - space has to be CMYK. Trick is that we do need to worry about + /* If we have the source colors, then use those in making the + decision as to which ones are non-zero. Then we avoid + accidently looking at small values that get quantized to zero + Note that to get here in the code, the source color data color + space has to be CMYK. Trick is that we do need to worry about the colorant order on the target device */ num_colorant[0] = (dev_proc(dev, get_color_comp_index))\ (dev, "Cyan", strlen("Cyan"), NO_COMP_NAME_TYPE); @@ -709,102 +652,16 @@ params.retain_any_comps = true; params.retain_spot_comps = false; params.drawn_comps = drawn_comps; - params.k_value = 0; - params.blendspot = false; - return gs_state_update_overprint(pgs, ¶ms); -} - -/* This is used for the case where we have an RGB based device, but we want - to simulate CMY overprinting. Color management is pretty much thrown out - the window when doing this. */ + /* We are in CMYK, the profiles match and overprint is true. Set effective + overprint mode to overprint mode */ + pgs->effective_overprint_mode = pgs->overprint_mode; -int gx_set_overprint_rgb(const gs_color_space * pcs, gs_state * pgs) -{ - gx_device * dev = pgs->device; - gx_device_color_info * pcinfo = (dev == 0 ? 0 : &dev->color_info); - gx_color_index drawn_comps = 0; - gs_overprint_params_t params; - gx_device_color *pdc; - - /* check if color model behavior must be determined. This is why we - need the GX_CINFO_OPMODE_RGB and GX_CINFO_OPMODE_RGB_SET. - We only need to do this once */ - if (pcinfo->opmode == GX_CINFO_OPMODE_RGB) - drawn_comps = check_rgb_color_model_comps(dev); - else - drawn_comps = pcinfo->process_comps; - if (drawn_comps == 0) - return gx_spot_colors_set_overprint(pcs, pgs); - - /* correct for any zero'ed color components. Note that matching of - ICC profiles as a condition is not possible here, since the source - will be CMYK and the destination RGB */ - pgs->effective_overprint_mode = 1; - pdc = gs_currentdevicecolor_inline(pgs); - params.k_value = 0; - params.blendspot = false; - if (color_is_set(pdc)) { - gx_color_index nz_comps, one, temp; - int code; - int num_colorant[3], k; - bool colorant_ok; - - dev_color_proc_get_nonzero_comps((*procp)); - - procp = pdc->type->get_nonzero_comps; - if (pdc->ccolor_valid) { - /* If we have the source colors, then use those in making the - decision as to which ones are non-zero. Then we avoid - accidently looking at small values that get quantized to zero - Note that to get here in the code, the source color data color - space has to be CMYK. Trick is that we do need to worry about - the RGB colorant order on the target device */ - num_colorant[0] = (dev_proc(dev, get_color_comp_index))\ - (dev, "Red", strlen("Red"), NO_COMP_NAME_TYPE); - num_colorant[1] = (dev_proc(dev, get_color_comp_index))\ - (dev, "Green", strlen("Green"), NO_COMP_NAME_TYPE); - num_colorant[2] = (dev_proc(dev, get_color_comp_index))\ - (dev, "Blue", strlen("Blue"), NO_COMP_NAME_TYPE); - nz_comps = 0; - one = 1; - colorant_ok = true; - for (k = 0; k < 3; k++) { - if (pdc->ccolor.paint.values[k] != 0) { - if (num_colorant[k] == -1) { - colorant_ok = false; - } else { - temp = one << num_colorant[k]; - nz_comps = nz_comps | temp; - } - } - } - /* Check for the case where we have a K component. In this case - we need to fudge things a bit. And we will end up needing - to do some special stuff in the overprint compositor's rect - fill to reduce the destination RGB values of the ones - that we are not blowing away with the source values. Those - that have the source value will have already been reduced */ - params.k_value = (unsigned short) (pdc->ccolor.paint.values[3] * 256); - /* For some reason we don't have one of the standard colorants */ - if (!colorant_ok) { - if ((code = procp(pdc, dev, &nz_comps)) < 0) - return code; - } - } else { - if ((code = procp(pdc, dev, &nz_comps)) < 0) - return code; - } - drawn_comps &= nz_comps; - } - params.retain_any_comps = true; - params.retain_spot_comps = false; - params.drawn_comps = drawn_comps; - return gs_state_update_overprint(pgs, ¶ms); + return gs_gstate_update_overprint(pgs, ¶ms); } /* A stub for a color mapping linearity check, when it is inapplicable. */ int -gx_cspace_no_linear(const gs_color_space *cs, const gs_imager_state * pis, +gx_cspace_no_linear(const gs_color_space *cs, const gs_gstate * pgs, gx_device * dev, const gs_client_color *c0, const gs_client_color *c1, const gs_client_color *c2, const gs_client_color *c3, @@ -814,10 +671,10 @@ } static inline int -cc2dc(const gs_color_space *cs, const gs_imager_state * pis, gx_device *dev, +cc2dc(const gs_color_space *cs, const gs_gstate * pgs, gx_device *dev, gx_device_color *dc, const gs_client_color *cc) { - return cs->type->remap_color(cc, cs, dc, pis, dev, gs_color_select_texture); + return cs->type->remap_color(cc, cs, dc, pgs, dev, gs_color_select_texture); } static inline void @@ -833,11 +690,11 @@ static inline bool is_dc_nearly_linear(const gx_device *dev, const gx_device_color *c, const gx_device_color *c0, const gx_device_color *c1, - double t, int n, float smoothness) + double t, uchar n, float smoothness) { + uchar i; if (c0->type == &gx_dc_type_data_pure) { - int i; gx_color_index pure0 = c0->colors.pure; gx_color_index pure1 = c1->colors.pure; gx_color_index pure = c->colors.pure; @@ -856,6 +713,23 @@ return false; } return true; + } else if (c0->type == &gx_dc_type_data_devn) { + for (i = 0; i < n; i++) { + int max_color = (i == dev->color_info.gray_index ? dev->color_info.max_gray + : dev->color_info.max_color); + double max_diff = max(1, max_color * smoothness); + /* Color values are 16 bit. We are basing the smoothness on the + device bit depth. So make sure to adjust the above max diff + based upon our device bit depth */ + double ratio = (double)max_color / (double)gx_max_color_value; + double b0 = (c0->colors.devn.values[i]) * ratio; + double b1 = (c1->colors.devn.values[i]) * ratio; + double b = (c->colors.devn.values[i]) * ratio; + double bb = b0 * t + b1 * (1 - t); + if (any_abs(b - bb) > max_diff) + return false; + } + return true; } else { /* Halftones must not paint with fill_linear_color_*. */ return false; @@ -864,7 +738,7 @@ /* Default color mapping linearity check, a 2-points case. */ static int -gx_cspace_is_linear_in_line(const gs_color_space *cs, const gs_imager_state * pis, +gx_cspace_is_linear_in_line(const gs_color_space *cs, const gs_gstate * pgs, gx_device *dev, const gs_client_color *c0, const gs_client_color *c1, float smoothness) @@ -872,23 +746,23 @@ gs_client_color c01a, c01b; gx_device_color d[2], d01a, d01b; int n = cs->type->num_components(cs); - int ndev = dev->color_info.num_components; + uchar ndev = dev->color_info.num_components; int code; - code = cc2dc(cs, pis, dev, &d[0], c0); + code = cc2dc(cs, pgs, dev, &d[0], c0); if (code < 0) return code; - code = cc2dc(cs, pis, dev, &d[1], c1); + code = cc2dc(cs, pgs, dev, &d[1], c1); if (code < 0) return code; interpolate_cc(&c01a, c0, c1, 0.3, n); - code = cc2dc(cs, pis, dev, &d01a, &c01a); + code = cc2dc(cs, pgs, dev, &d01a, &c01a); if (code < 0) return code; if (!is_dc_nearly_linear(dev, &d01a, &d[0], &d[1], 0.3, ndev, smoothness)) return 0; interpolate_cc(&c01b, c0, c1, 0.7, n); - code = cc2dc(cs, pis, dev, &d01b, &c01b); + code = cc2dc(cs, pgs, dev, &d01b, &c01b); if (code < 0) return code; if (!is_dc_nearly_linear(dev, &d01b, &d[0], &d[1], 0.7, ndev, smoothness)) @@ -898,7 +772,7 @@ /* Default color mapping linearity check, a triangle case. */ static int -gx_cspace_is_linear_in_triangle(const gs_color_space *cs, const gs_imager_state * pis, +gx_cspace_is_linear_in_triangle(const gs_color_space *cs, const gs_gstate * pgs, gx_device *dev, const gs_client_color *c0, const gs_client_color *c1, const gs_client_color *c2, float smoothness) @@ -913,43 +787,43 @@ can have a different number of components */ int n = cs->type->num_components(cs); - int ndev = dev->color_info.num_components; + uchar ndev = dev->color_info.num_components; int code; - code = cc2dc(cs, pis, dev, &d[0], c0); + code = cc2dc(cs, pgs, dev, &d[0], c0); if (code < 0) return code; - code = cc2dc(cs, pis, dev, &d[1], c1); + code = cc2dc(cs, pgs, dev, &d[1], c1); if (code < 0) return code; - code = cc2dc(cs, pis, dev, &d[2], c2); + code = cc2dc(cs, pgs, dev, &d[2], c2); if (code < 0) return code; interpolate_cc(&c01, c0, c1, 0.5, n); - code = cc2dc(cs, pis, dev, &d01, &c01); + code = cc2dc(cs, pgs, dev, &d01, &c01); if (code < 0) return code; if (!is_dc_nearly_linear(dev, &d01, &d[0], &d[1], 0.5, ndev, smoothness)) return 0; interpolate_cc(&c012, c2, &c01, 2.0 / 3, n); - code = cc2dc(cs, pis, dev, &d012, &c012); + code = cc2dc(cs, pgs, dev, &d012, &c012); if (code < 0) return code; if (!is_dc_nearly_linear(dev, &d012, &d[2], &d01, 2.0 / 3, ndev, smoothness)) return 0; interpolate_cc(&c12, c1, c2, 0.5, n); - code = cc2dc(cs, pis, dev, &d12, &c12); + code = cc2dc(cs, pgs, dev, &d12, &c12); if (code < 0) return code; if (!is_dc_nearly_linear(dev, &d12, &d[1], &d[2], 0.5, ndev, smoothness)) return 0; interpolate_cc(&c20, c2, c0, 0.5, n); - code = cc2dc(cs, pis, dev, &d20, &c20); + code = cc2dc(cs, pgs, dev, &d20, &c20); if (code < 0) return code; if (!is_dc_nearly_linear(dev, &d20, &d[2], &d[0], 0.5, ndev, smoothness)) @@ -959,7 +833,7 @@ /* Default color mapping linearity check. */ int -gx_cspace_is_linear_default(const gs_color_space *cs, const gs_imager_state * pis, +gx_cspace_is_linear_default(const gs_color_space *cs, const gs_gstate * pgs, gx_device *dev, const gs_client_color *c0, const gs_client_color *c1, const gs_client_color *c2, const gs_client_color *c3, @@ -969,16 +843,16 @@ /* With nc == 4 assuming a convex plain quadrangle in the client color space. */ int code; - if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN) + if (!colors_are_separable_and_linear(&dev->color_info)) return_error(gs_error_rangecheck); if (c2 == NULL) - return gx_cspace_is_linear_in_line(cs, pis, dev, c0, c1, smoothness); - code = gx_cspace_is_linear_in_triangle(cs, pis, dev, c0, c1, c2, smoothness); + return gx_cspace_is_linear_in_line(cs, pgs, dev, c0, c1, smoothness); + code = gx_cspace_is_linear_in_triangle(cs, pgs, dev, c0, c1, c2, smoothness); if (code <= 0) return code; if (c3 == NULL) return 1; - return gx_cspace_is_linear_in_triangle(cs, pis, dev, c1, c2, c3, smoothness); + return gx_cspace_is_linear_in_triangle(cs, pgs, dev, c1, c2, c3, smoothness); } /* Serialization. */ diff -Nru ghostscript-9.10~dfsg/base/gscspace.h ghostscript-9.25~dfsg+1/base/gscspace.h --- ghostscript-9.10~dfsg/base/gscspace.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscspace.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -133,9 +133,9 @@ */ /* Opaque types for a graphics state stuff */ -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gsicc_link_DEFINED @@ -158,6 +158,8 @@ typedef struct gs_color_space_s gs_color_space; #endif +typedef struct cmm_dev_profile_s cmm_dev_profile_t; + /* * Define color space type indices. NOTE: PostScript code (gs_res.ps, * gs_ll3.ps) and the color space substitution code (gscssub.[hc] and its @@ -346,7 +348,7 @@ gs_color_space *gs_cspace_new_DeviceGray(gs_memory_t *mem); gs_color_space *gs_cspace_new_DeviceRGB(gs_memory_t *mem); gs_color_space *gs_cspace_new_DeviceCMYK(gs_memory_t *mem); -gs_color_space *gs_cspace_new_ICC(gs_memory_t *pmem, gs_state * pgs, +gs_color_space *gs_cspace_new_ICC(gs_memory_t *pmem, gs_gstate * pgs, int components); /* ------ Accessors ------ */ @@ -395,7 +397,7 @@ void rc_decrement_only_cs(gs_color_space *pcs, const char *cname); -void cs_adjust_counts_icc(gs_state *pgs, int delta); +void cs_adjust_counts_icc(gs_gstate *pgs, int delta); /* backwards compatibility */ #define gs_color_space_indexed_base_space(pcspace)\ diff -Nru ghostscript-9.10~dfsg/base/gscssub.c ghostscript-9.25~dfsg+1/base/gscssub.c --- ghostscript-9.10~dfsg/base/gscssub.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscssub.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,7 +27,7 @@ * for the Device* color spaces (previously, only CIEBased color spaces could * be used for this purpose). */ int -gs_setsubstitutecolorspace(gs_state *pgs, gs_color_space_index csi, +gs_setsubstitutecolorspace(gs_gstate *pgs, gs_color_space_index csi, const gs_color_space *pcs) { int index = (int)csi; @@ -65,7 +65,7 @@ /* Possibly-substituted color space accessors. */ const gs_color_space * -gs_current_DeviceGray_space(const gs_state *pgs) +gs_current_DeviceGray_space(const gs_gstate *pgs) { const gs_color_space *pcs; @@ -74,7 +74,7 @@ pgs->shared->device_color_spaces.named.Gray : pcs); } const gs_color_space * -gs_current_DeviceRGB_space(const gs_state *pgs) +gs_current_DeviceRGB_space(const gs_gstate *pgs) { const gs_color_space *pcs; @@ -83,7 +83,7 @@ pgs->shared->device_color_spaces.named.RGB : pcs); } const gs_color_space * -gs_current_DeviceCMYK_space(const gs_state *pgs) +gs_current_DeviceCMYK_space(const gs_gstate *pgs) { const gs_color_space *pcs; @@ -94,7 +94,7 @@ /* .currentsubstitutecolorspace */ const gs_color_space * -gs_currentsubstitutecolorspace(const gs_state *pgs, gs_color_space_index csi) +gs_currentsubstitutecolorspace(const gs_gstate *pgs, gs_color_space_index csi) { switch (csi) { case gs_color_space_index_DeviceGray: diff -Nru ghostscript-9.10~dfsg/base/gscssub.h ghostscript-9.25~dfsg+1/base/gscssub.h --- ghostscript-9.10~dfsg/base/gscssub.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gscssub.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -53,18 +53,18 @@ */ /* If pcs is NULL, it means undo any substitution. */ -int gs_setsubstitutecolorspace(gs_state *pgs, gs_color_space_index csi, +int gs_setsubstitutecolorspace(gs_gstate *pgs, gs_color_space_index csi, const gs_color_space *pcs); const gs_color_space * - gs_currentsubstitutecolorspace(const gs_state *pgs, + gs_currentsubstitutecolorspace(const gs_gstate *pgs, gs_color_space_index csi); /* * The following procedures are primarily for internal use, to provide * fast access to specific color spaces. */ -const gs_color_space *gs_current_DeviceGray_space(const gs_state *pgs); -const gs_color_space *gs_current_DeviceRGB_space(const gs_state *pgs); -const gs_color_space *gs_current_DeviceCMYK_space(const gs_state *pgs); +const gs_color_space *gs_current_DeviceGray_space(const gs_gstate *pgs); +const gs_color_space *gs_current_DeviceRGB_space(const gs_gstate *pgs); +const gs_color_space *gs_current_DeviceCMYK_space(const gs_gstate *pgs); #endif /* gscssub_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsdcolor.h ghostscript-9.25~dfsg+1/base/gsdcolor.h --- ghostscript-9.10~dfsg/base/gsdcolor.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdcolor.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,6 +20,7 @@ # define gsdcolor_INCLUDED #include "gsccolor.h" +#include "gscms.h" /* for gs_graphics_type_tag_t */ #include "gxarith.h" /* for imod */ #include "gxbitmap.h" #include "gxhttile.h" @@ -101,7 +102,7 @@ #define color_is_set(pdc)\ ((pdc)->type != gx_dc_type_none) #define color_unset(pdc)\ - ((pdc)->type = gx_dc_type_none) + (((pdc)->type = gx_dc_type_none), ((pdc)->tag = 0)) #define gx_dc_is_null(pdc)\ ((pdc)->type == gx_dc_type_null) @@ -266,6 +267,7 @@ * union, we put the type first. */ gx_device_color_type type; + gs_graphics_type_tag_t tag; /* value used to set dev_color */ /* * See the comment above for descriptions of the members. We use * b_, c_, and p_ member names because some old compilers don't @@ -375,6 +377,7 @@ struct gx_device_color_saved_s { gx_device_color_type type; + gs_graphics_type_tag_t tag; /* value used to set dev_color */ union _svc { gx_color_index pure; struct _svbin { diff -Nru ghostscript-9.10~dfsg/base/gsdevice.c ghostscript-9.25~dfsg+1/base/gsdevice.c --- ghostscript-9.10~dfsg/base/gsdevice.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdevice.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -56,10 +56,47 @@ } if (dev->finalize) dev->finalize(dev); + + /* Deal with subclassed devices. Ordinarily these should not be a problem, we + * will never see them, but if ths is a end of job restore we can end up + * with the 'child' device(s) being freed before their parents. We need to make + * sure we don't leave any dangling pointers in that case. + */ + if (dev->child) + dev->child->parent = dev->parent; + if (dev->parent) + dev->parent->child = dev->child; + if (dev->PageList) { + rc_decrement(dev->PageList, "gx_device_finalize(PageList)"); + dev->PageList = 0; + } + discard(gs_closedevice(dev)); if (dev->stype_is_dynamic) gs_free_const_object(dev->memory->non_gc_memory, dev->stype, "gx_device_finalize"); + +#ifdef DEBUG + /* Slightly ugly hack: because the garbage collector makes no promises + * about the order objects can be garbage collected, it is possible for + * a forwarding device to remain in existence (awaiting garbage collection + * itself) after it's target marked as free memory by the garbage collector. + * In such a case, the normal reference counting is fine (since the garbage + * collector leaves the object contents alone until is has completed its + * sweep), but the reference counting debugging attempts to access the + * memory header to output type information - and the header has been + * overwritten by the garbage collector, causing a crash. + * Setting the rc memory to NULL here should be safe, since the memory + * is now in the hands of the garbage collector, and means we can check in + * debugging code to ensure we don't try to use values that not longer exist + * in the memmory header. + * In the non-gc case, finalize is the very last thing to happen before the + * memory is actually freed, so the rc.memory pointer is moot. + * See rc_object_type_name() + */ + if (gs_debug_c('^')) + dev->rc.memory = NULL; +#endif } /* "Free" a device locally allocated on the stack, by finalizing it. */ @@ -71,6 +108,17 @@ /* GC procedures */ static +ENUM_PTRS_WITH(device_enum_ptrs, gx_device *dev) return 0; +case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); +case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); +ENUM_PTRS_END +static RELOC_PTRS_WITH(device_reloc_ptrs, gx_device *dev) +{ + dev->parent = gx_device_reloc_ptr(dev->parent, gcst); + dev->child = gx_device_reloc_ptr(dev->child, gcst); +} +RELOC_PTRS_END +static ENUM_PTRS_WITH(device_forward_enum_ptrs, gx_device_forward *fdev) return 0; case 0: ENUM_RETURN(gx_device_enum_ptr(fdev->target)); ENUM_PTRS_END @@ -119,7 +167,7 @@ /* Flush buffered output to the device */ int -gs_flushpage(gs_state * pgs) +gs_flushpage(gs_gstate * pgs) { gx_device *dev = gs_currentdevice(pgs); @@ -128,27 +176,27 @@ /* Make the device output the accumulated page description */ int -gs_copypage(gs_state * pgs) +gs_copypage(gs_gstate * pgs) { return gs_output_page(pgs, 1, 0); } int -gs_output_page(gs_state * pgs, int num_copies, int flush) +gs_output_page(gs_gstate * pgs, int num_copies, int flush) { gx_device *dev = gs_currentdevice(pgs); cmm_dev_profile_t *dev_profile; int code; - /* for devices that hook 'fill_path' in order to pick up imager state */ + /* for devices that hook 'fill_path' in order to pick up gs_gstate */ /* values such as dev_ht (such as tiffsep1), make a dummy call here */ /* to make sure that it has been called at least once */ code = gs_gsave(pgs); if (code < 0) return code; - if (((code = gs_newpath(pgs)) < 0) || + if (((code = gs_newpath(pgs)) < 0) || ((code = gs_moveto(pgs, 0.0, 0.0)) < 0) || - ((code = gs_setgray(pgs, 0.0) < 0)) || - ((code = gs_fill(pgs)) < 0)) + ((code = gs_setgray(pgs, 0.0)) < 0) || + ((code = gs_fill(pgs)) < 0)) { gs_grestore(pgs); return code; @@ -163,9 +211,11 @@ return code; code = dev_proc(dev, get_profile)(dev, &(dev_profile)); + if (code < 0) + return code; if (dev_profile->graydetection && !dev_profile->pageneutralcolor) { dev_profile->pageneutralcolor = true; /* start detecting again */ - gsicc_mcm_begin_monitor(pgs->icc_link_cache, dev); + code = gsicc_mcm_begin_monitor(pgs->icc_link_cache, dev); } return code; } @@ -210,7 +260,7 @@ /* Get the current device from the graphics state. */ gx_device * -gs_currentdevice(const gs_state * pgs) +gs_currentdevice(const gs_gstate * pgs) { return pgs->device; } @@ -244,7 +294,7 @@ /* Get the default device from the known device list */ const gx_device * -gs_getdefaultdevice(void) +gs_getdefaultlibdevice(gs_memory_t *mem) { const gx_device *const *list; int count = gs_lib_device_list(&list, NULL); @@ -252,8 +302,15 @@ int i; /* Search the compiled in device list for a known device name */ - name = gs_dev_defaults; - fin = name + strlen(name); + /* In the case the lib ctx hasn't been initialised */ + if (mem && mem->gs_lib_ctx && mem->gs_lib_ctx->default_device_list) { + name = mem->gs_lib_ctx->default_device_list; + fin = name + strlen(name); + } + else { + name = gs_dev_defaults; + fin = name + strlen(name); + } /* iterate through each name in the string */ while (name < fin) { @@ -279,25 +336,20 @@ return gs_getdevice(0); } +const gx_device * +gs_getdefaultdevice(void) +{ + return gs_getdefaultlibdevice(NULL); +} + /* Fill in the GC structure descriptor for a device. */ static void gx_device_make_struct_type(gs_memory_struct_type_t *st, const gx_device *dev) { - const gx_device_procs *procs = dev->static_procs; - - /* - * Try to figure out whether this is a forwarding device. For printer - * devices, we rely on the prototype referencing the correct structure - * descriptor; for other devices, we look for a likely forwarding - * procedure in the vector. The algorithm isn't foolproof, but it's the - * best we can come up with. - */ - if (procs == 0) - procs = &dev->procs; if (dev->stype) *st = *dev->stype; - else if (procs->get_xfont_procs == gx_forward_get_xfont_procs) + else if (dev_proc(dev, get_xfont_procs) == gx_forward_get_xfont_procs) *st = st_device_forward; else *st = st_device; @@ -346,8 +398,10 @@ */ new_dev = gs_alloc_struct_immovable(mem, gx_device, new_std, "gs_copydevice(device)"); - if (new_dev == 0) + if (new_dev == 0) { + gs_free_object(mem->non_gc_memory, a_std, "gs_copydevice(stype)"); return_error(gs_error_VMerror); + } gx_device_init(new_dev, dev, mem, false); gx_device_set_procs(new_dev); new_dev->stype = new_std; @@ -399,36 +453,33 @@ } } -/* Set device parameters, updating a graphics state or imager state. */ -int -gs_imager_putdeviceparams(gs_imager_state *pis, gx_device *dev, - gs_param_list *plist) -{ - int code = gs_putdeviceparams(dev, plist); - - if (code >= 0) - gx_set_cmap_procs(pis, dev); - return code; -} static void -gs_state_update_device(gs_state *pgs) +gs_gstate_update_device(gs_gstate *pgs, gx_device *dev) { - gx_set_cmap_procs((gs_imager_state *)pgs, pgs->device); - gx_unset_dev_color(pgs); + gx_set_cmap_procs(pgs, dev); + gx_unset_both_dev_colors(pgs); } + int -gs_state_putdeviceparams(gs_state *pgs, gs_param_list *plist) +gs_gstate_putdeviceparams(gs_gstate *pgs, gx_device *dev, gs_param_list *plist) { - int code = gs_putdeviceparams(pgs->device, plist); + int code; + gx_device *dev2; + if (dev) + dev2 = dev; + else + dev2 = pgs->device; + + code = gs_putdeviceparams(dev2, plist); if (code >= 0) - gs_state_update_device(pgs); + gs_gstate_update_device(pgs, dev2); return code; } /* Set the device in the graphics state */ int -gs_setdevice(gs_state * pgs, gx_device * dev) +gs_setdevice(gs_gstate * pgs, gx_device * dev) { int code = gs_setdevice_no_erase(pgs, dev); @@ -437,7 +488,7 @@ return code; } int -gs_setdevice_no_erase(gs_state * pgs, gx_device * dev) +gs_setdevice_no_erase(gs_gstate * pgs, gx_device * dev) { int open_code = 0, code; gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(pgs->memory); @@ -451,6 +502,10 @@ } /* Also, if the device profile is not yet set then take care of that before we start filling pages, if we can */ + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ if (dev->procs.get_profile != NULL) { code = dev_proc(dev, get_profile)(dev, &dev_profile); if (code < 0) { @@ -462,7 +517,7 @@ gsDEFAULTPROFILE)) < 0) return(code); /* set the intent too */ - if ((code = gsicc_set_device_profile_intent(dev, gsPERCEPTUAL, + if ((code = gsicc_set_device_profile_intent(dev, gsRINOTSPECIFIED, gsDEFAULTPROFILE)) < 0) return(code); } @@ -480,6 +535,10 @@ */ if (libctx->io_device_table != NULL) { cmm_dev_profile_t *dev_profile; + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ if (dev->procs.get_profile != NULL) { code = dev_proc(dev, get_profile)(dev, &dev_profile); if (code < 0) { @@ -519,7 +578,7 @@ return open_code; } int -gs_setdevice_no_init(gs_state * pgs, gx_device * dev) +gs_setdevice_no_init(gs_gstate * pgs, gx_device * dev) { /* * Just set the device, possibly changing color space but no other @@ -541,7 +600,7 @@ return code; } rc_assign(pgs->device, dev, "gs_setdevice_no_init"); - gs_state_update_device(pgs); + gs_gstate_update_device(pgs, dev); return pgs->overprint ? gs_do_set_overprint(pgs) : 0; } @@ -554,6 +613,7 @@ dev->memory = mem; dev->retained = !internal; rc_init(dev, mem, (internal ? 0 : 1)); + rc_increment(dev->icc_struct); } void @@ -563,6 +623,9 @@ memcpy(dev, proto, proto->params_size); dev->memory = mem; dev->retained = 0; + dev->pad = proto->pad; + dev->log2_align_mod = proto->log2_align_mod; + dev->is_planar = proto->is_planar; rc_init(dev, NULL, 0); } @@ -588,6 +651,17 @@ set_dev_proc(dn, decode_color, gx_forward_decode_color); set_dev_proc(dn, get_profile, gx_forward_get_profile); set_dev_proc(dn, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + set_dev_proc(dn, begin_transparency_group, gx_default_begin_transparency_group); + set_dev_proc(dn, end_transparency_group, gx_default_end_transparency_group); + set_dev_proc(dn, begin_transparency_mask, gx_default_begin_transparency_mask); + set_dev_proc(dn, end_transparency_mask, gx_default_end_transparency_mask); + set_dev_proc(dn, discard_transparency_layer, gx_default_discard_transparency_layer); + set_dev_proc(dn, pattern_manage, gx_default_pattern_manage); + set_dev_proc(dn, push_transparency_state, gx_default_push_transparency_state); + set_dev_proc(dn, pop_transparency_state, gx_default_pop_transparency_state); + set_dev_proc(dn, put_image, gx_default_put_image); + set_dev_proc(dn, copy_planes, gx_default_copy_planes); + set_dev_proc(dn, copy_alpha_hl_color, gx_default_no_copy_alpha_hl_color); dn->graphics_type_tag = dev->graphics_type_tag; /* initialize to same as target */ gx_device_copy_color_params(dn, dev); } @@ -614,15 +688,19 @@ /* Select a null device. */ int -gs_nulldevice(gs_state * pgs) +gs_nulldevice(gs_gstate * pgs) { + int code = 0; + bool saveLockSafety = false; if (pgs->device == 0 || !gx_device_is_null(pgs->device)) { gx_device *ndev; - int code = gs_copydevice(&ndev, (const gx_device *)&gs_null_device, + code = gs_copydevice(&ndev, (const gx_device *)&gs_null_device, pgs->memory); if (code < 0) return code; + if (gs_currentdevice_inline(pgs) != NULL) + saveLockSafety = gs_currentdevice_inline(pgs)->LockSafetyParams; /* * Internal devices have a reference count of 0, not 1, * aside from references from graphics states. @@ -633,16 +711,18 @@ is one */ rc_init(ndev, pgs->memory, 0); if (pgs->device != NULL) { - if ((code = dev_proc(pgs->device, get_profile)(pgs->device, + if ((code = dev_proc(pgs->device, get_profile)(pgs->device, &(ndev->icc_struct))) < 0) return code; rc_increment(ndev->icc_struct); set_dev_proc(ndev, get_profile, gx_default_get_profile); - } + } - return gs_setdevice_no_erase(pgs, ndev); + if ((code = gs_setdevice_no_erase(pgs, ndev)) < 0) + gs_free_object(pgs->memory, ndev, "gs_copydevice(device)"); + gs_currentdevice_inline(pgs)->LockSafetyParams = saveLockSafety; } - return 0; + return code; } /* Close a device. The client is responsible for ensuring that */ @@ -666,19 +746,61 @@ * (For internal use only.) */ void -gx_set_device_only(gs_state * pgs, gx_device * dev) +gx_set_device_only(gs_gstate * pgs, gx_device * dev) { rc_assign(pgs->device, dev, "gx_set_device_only"); } -/* Compute the size of one scan line for a device, */ -/* with or without padding to a word boundary. */ +/* Compute the size of one scan line for a device. */ +/* If pad = 0 return the line width in bytes. If pad = 1, + * return the actual raster value (the number of bytes to offset from + * a byte on one scanline to the same byte on the scanline below.) */ uint gx_device_raster(const gx_device * dev, bool pad) { ulong bits = (ulong) dev->width * dev->color_info.depth; + ulong raster; + int l2align; - return (pad ? bitmap_raster(bits) : (uint) ((bits + 7) >> 3)); + if (dev->is_planar) + bits /= dev->color_info.num_components; + + raster = (uint)((bits + 7) >> 3); + if (!pad) + return raster; + l2align = dev->log2_align_mod; + if (l2align < log2_align_bitmap_mod) + l2align = log2_align_bitmap_mod; + return (uint)(((bits + (8 << l2align) - 1) >> (l2align + 3)) << l2align); +} + +uint +gx_device_raster_chunky(const gx_device * dev, bool pad) +{ + ulong bits = (ulong) dev->width * dev->color_info.depth; + ulong raster; + int l2align; + + raster = (uint)((bits + 7) >> 3); + if (!pad) + return raster; + l2align = dev->log2_align_mod; + if (l2align < log2_align_bitmap_mod) + l2align = log2_align_bitmap_mod; + return (uint)(((bits + (8 << l2align) - 1) >> (l2align + 3)) << l2align); +} +uint +gx_device_raster_plane(const gx_device * dev, const gx_render_plane_t *render_plane) +{ + ulong bpc = (render_plane && render_plane->index >= 0 ? + render_plane->depth : dev->color_info.depth/(dev->is_planar ? dev->color_info.num_components : 1)); + ulong bits = (ulong) dev->width * bpc; + int l2align; + + l2align = dev->log2_align_mod; + if (l2align < log2_align_bitmap_mod) + l2align = log2_align_bitmap_mod; + return (uint)(((bits + (8 << l2align) - 1) >> (l2align + 3)) << l2align); } /* Adjust the resolution for devices that only have a fixed set of */ @@ -713,8 +835,8 @@ for (i = 0; i < 4; ++i) dev->HWMargins[i] = margins[i] * 72.0; if (move_origin) { - dev->Margins[0] = -margins[0] * dev->MarginsHWResolution[0]; - dev->Margins[1] = -margins[3] * dev->MarginsHWResolution[1]; + dev->Margins[0] = -margins[0] * dev->HWResolution[0]; + dev->Margins[1] = -margins[3] * dev->HWResolution[1]; } } @@ -722,8 +844,8 @@ gx_device_set_hwsize_from_media(gx_device *dev) { int rot = (dev->LeadingEdge & 1); - floatp rot_media_x = rot ? dev->MediaSize[1] : dev->MediaSize[0]; - floatp rot_media_y = rot ? dev->MediaSize[0] : dev->MediaSize[1]; + double rot_media_x = rot ? dev->MediaSize[1] : dev->MediaSize[0]; + double rot_media_y = rot ? dev->MediaSize[0] : dev->MediaSize[1]; dev->width = (int)(rot_media_x * dev->HWResolution[0] / 72.0 + 0.5); dev->height = (int)(rot_media_y * dev->HWResolution[1] / 72.0 + 0.5); @@ -733,8 +855,8 @@ gx_device_set_media_from_hwsize(gx_device *dev) { int rot = (dev->LeadingEdge & 1); - floatp x = dev->width * 72.0 / dev->HWResolution[0]; - floatp y = dev->height * 72.0 / dev->HWResolution[1]; + double x = dev->width * 72.0 / dev->HWResolution[0]; + double y = dev->height * 72.0 / dev->HWResolution[1]; if (rot) { dev->MediaSize[1] = x; @@ -756,7 +878,7 @@ /* Set the resolution, updating width and height to remain consistent. */ void -gx_device_set_resolution(gx_device * dev, floatp x_dpi, floatp y_dpi) +gx_device_set_resolution(gx_device * dev, double x_dpi, double y_dpi) { dev->HWResolution[0] = x_dpi; dev->HWResolution[1] = y_dpi; @@ -765,7 +887,7 @@ /* Set the MediaSize, updating width and height to remain consistent. */ void -gx_device_set_media_size(gx_device * dev, floatp media_width, floatp media_height) +gx_device_set_media_size(gx_device * dev, double media_width, double media_height) { dev->MediaSize[0] = media_width; dev->MediaSize[1] = media_height; @@ -847,7 +969,6 @@ COPY_ARRAY_PARAM(ImagingBBox); COPY_PARAM(ImagingBBox_set); COPY_ARRAY_PARAM(HWResolution); - COPY_ARRAY_PARAM(MarginsHWResolution); COPY_ARRAY_PARAM(Margins); COPY_ARRAY_PARAM(HWMargins); COPY_PARAM(PageCount); @@ -1001,6 +1122,57 @@ return (code >= 0 && fmt != 0); } +/* Delete the current output file for a device (file must be closed first) */ +int gx_device_delete_output_file(const gx_device * dev, const char *fname) +{ + gs_parsed_file_name_t parsed; + const char *fmt; + char *pfname = (char *)gs_alloc_bytes(dev->memory, gp_file_name_sizeof, "gx_device_delete_output_file(pfname)"); + int code; + + if (pfname == NULL) { + code = gs_note_error(gs_error_VMerror); + goto done; + } + + code = gx_parse_output_file_name(&parsed, &fmt, fname, strlen(fname), + dev->memory); + if (code < 0) { + goto done; + } + + if (parsed.iodev && !strcmp(parsed.iodev->dname, "%stdout%")) + goto done; + + if (fmt) { /* filename includes "%nnd" */ + long count1 = dev->PageCount + 1; + + while (*fmt != 'l' && *fmt != '%') + --fmt; + if (*fmt == 'l') + gs_sprintf(pfname, parsed.fname, count1); + else + gs_sprintf(pfname, parsed.fname, (int)count1); + } else if (parsed.len && strchr(parsed.fname, '%')) /* filename with "%%" but no "%nnd" */ + gs_sprintf(pfname, parsed.fname); + else + pfname[0] = 0; /* 0 to use "fname", not "pfname" */ + if (pfname[0]) { + parsed.fname = pfname; + parsed.len = strlen(parsed.fname); + } + if (parsed.iodev) + code = parsed.iodev->procs.delete_file((gx_io_device *)(&parsed.iodev), (const char *)parsed.fname); + else + code = gs_note_error(gs_error_invalidfileaccess); + +done: + if (pfname != NULL) + gs_free_object(dev->memory, pfname, "gx_device_delete_output_file(pfname)"); + + return(code); +} + /* Open the output file for a device. */ int gx_device_open_output_file(const gx_device * dev, char *fname, @@ -1008,18 +1180,33 @@ { gs_parsed_file_name_t parsed; const char *fmt; - char pfname[gp_file_name_sizeof]; - int code = gx_parse_output_file_name(&parsed, &fmt, fname, strlen(fname), - dev->memory); + char *pfname = (char *)gs_alloc_bytes(dev->memory, gp_file_name_sizeof, "gx_device_open_output_file(pfname)"); + int code; + + if (pfname == NULL) { + code = gs_note_error(gs_error_VMerror); + goto done; + } + + if (strlen(fname) == 0) { + code = gs_note_error(gs_error_undefinedfilename); + emprintf1(dev->memory, "Device '%s' requires an output file but no file was specified.\n", dev->dname); + goto done; + } + code = gx_parse_output_file_name(&parsed, &fmt, fname, strlen(fname), dev->memory); + if (code < 0) { + goto done; + } - if (code < 0) - return code; if (parsed.iodev && !strcmp(parsed.iodev->dname, "%stdout%")) { - if (parsed.fname) - return_error(gs_error_undefinedfilename); + if (parsed.fname) { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } *pfile = dev->memory->gs_lib_ctx->fstdout; /* Force stdout to binary. */ - return gp_setmode_binary(*pfile, true); + code = gp_setmode_binary(*pfile, true); + goto done; } else if (parsed.iodev && !strcmp(parsed.iodev->dname, "%pipe%")) { positionable = false; } @@ -1043,8 +1230,10 @@ if (positionable || (parsed.iodev && parsed.iodev != iodev_default(dev->memory))) { char fmode[4]; - if (!parsed.fname) - return_error(gs_error_undefinedfilename); + if (!parsed.fname) { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } strcpy(fmode, gp_fmode_wb); if (positionable) strcat(fmode, "+"); @@ -1054,15 +1243,21 @@ emprintf1(dev->memory, "**** Could not open the file %s .\n", parsed.fname); - return code; } - *pfile = gp_open_printer(dev->memory, (pfname[0] ? pfname : fname), binary); - if (*pfile) - return 0; - emprintf1(dev->memory, - "**** Could not open the file %s .\n", - (pfname[0] ? pfname : fname)); - return_error(gs_error_invalidfileaccess); + else { + *pfile = gp_open_printer(dev->memory, (pfname[0] ? pfname : fname), binary); + if (!(*pfile)) { + emprintf1(dev->memory, "**** Could not open the file '%s'.\n", (pfname[0] ? pfname : fname)); + + code = gs_note_error(gs_error_invalidfileaccess); + } + } + +done: + if (pfname != NULL) + gs_free_object(dev->memory, pfname, "gx_device_open_output_file(pfname)"); + + return(code); } /* Close the output file for a device. */ @@ -1087,3 +1282,38 @@ gp_close_printer(dev->memory, file, (parsed.fname ? parsed.fname : fname)); return 0; } + +bool gx_color_info_equal(const gx_device_color_info * p1, const gx_device_color_info * p2) +{ + if (p1->anti_alias.graphics_bits != p2->anti_alias.graphics_bits) + return false; + if (p1->anti_alias.text_bits != p2->anti_alias.text_bits) + return false; + if (p1->black_component != p2->black_component) + return false; + if (strcmp(p1->cm_name, p2->cm_name) != 0) + return false; + if (p1->depth != p2->depth) + return false; + if (p1->dither_colors != p2->dither_colors) + return false; + if (p1->dither_grays != p2->dither_grays) + return false; + if (p1->gray_index != p2->gray_index) + return false; + if (p1->max_color != p2->max_color) + return false; + if (p1->max_components != p2->max_components) + return false; + if (p1->opmode != p2->opmode) + return false; + if (p1->polarity != p2->polarity) + return false; + if (p1->process_comps != p2->process_comps) + return false; + if (p1->separable_and_linear != p2->separable_and_linear) + return false; + if (p1->use_antidropout_downscaler != p2->use_antidropout_downscaler) + return false; + return true; +} diff -Nru ghostscript-9.10~dfsg/base/gsdevice.h ghostscript-9.25~dfsg+1/base/gsdevice.h --- ghostscript-9.10~dfsg/base/gsdevice.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdevice.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -42,8 +42,13 @@ /* Device procedures not involving a graphics state. */ const gx_device *gs_getdevice(int); + +/****** DEPRECATED: use gs_getdefaultlibdevice() *********/ const gx_device *gs_getdefaultdevice(void); +const gx_device * +gs_getdefaultlibdevice(gs_memory_t *mem); + int gs_opendevice(gx_device *); int gs_copyscanlines(gx_device *, int, byte *, uint, int *, uint *); int gs_copydevice(gx_device **, const gx_device *, gs_memory_t *); @@ -86,38 +91,36 @@ int gs_putdeviceparams(gx_device *, gs_param_list *); int gs_closedevice(gx_device *); -/* Device procedures involving an imager state. */ +/* Device procedures involving an gs_gstate. */ -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif -int gs_imager_putdeviceparams(gs_imager_state *pis, gx_device *dev, - gs_param_list *plist); +int gs_gstate_putdeviceparams(gs_gstate *pgs, gx_device *dev, +gs_param_list *plist); /* Device procedures involving a graphics state. */ -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif -int gs_flushpage(gs_state *); -int gs_copypage(gs_state *); -int gs_output_page(gs_state *, int, int); -int gs_nulldevice(gs_state *); -int gs_setdevice(gs_state *, gx_device *); -int gs_setdevice_no_erase(gs_state *, gx_device *); /* returns 1 */ +int gs_flushpage(gs_gstate *); +int gs_copypage(gs_gstate *); +int gs_output_page(gs_gstate *, int, int); +int gs_nulldevice(gs_gstate *); +int gs_setdevice(gs_gstate *, gx_device *); +int gs_setdevice_no_erase(gs_gstate *, gx_device *); /* returns 1 */ /* if erasepage required */ -int gs_setdevice_no_init(gs_state *, gx_device *); -gx_device *gs_currentdevice(const gs_state *); +int gs_setdevice_no_init(gs_gstate *, gx_device *); +gx_device *gs_currentdevice(const gs_gstate *); /* gzstate.h redefines the following: */ #ifndef gs_currentdevice_inline # define gs_currentdevice_inline(pgs) gs_currentdevice(pgs) #endif -int gs_state_putdeviceparams(gs_state *pgs, gs_param_list *plist); - #endif /* gsdevice_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsdevmem.c ghostscript-9.25~dfsg+1/base/gsdevmem.c --- ghostscript-9.10~dfsg/base/gsdevmem.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdevmem.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,24 +47,28 @@ case 3 * 2: palette_count = 2; num_components = 3; + /* fall through */ case 2: bits_per_pixel = 1; break; case 3 * 4: palette_count = 4; num_components = 3; + /* fall through */ case 4: bits_per_pixel = 2; break; case 3 * 16: palette_count = 16; num_components = 3; + /* fall through */ case 16: bits_per_pixel = 4; break; case 3 * 256: palette_count = 256; num_components = 3; + /* fall through */ case 256: bits_per_pixel = 8; break; @@ -185,10 +189,8 @@ rc_init(new_dev, new_dev->memory, 1); new_dev->initial_matrix = *pmat; - new_dev->MarginsHWResolution[0] = new_dev->HWResolution[0] = - fabs(x_pixels_per_unit) * 72; - new_dev->MarginsHWResolution[1] = new_dev->HWResolution[1] = - fabs(y_pixels_per_unit) * 72; + new_dev->HWResolution[0] = fabs(x_pixels_per_unit) * 72; + new_dev->HWResolution[1] = fabs(y_pixels_per_unit) * 72; gx_device_set_width_height((gx_device *) new_dev, width, height); /* Set the ImagingBBox so we get a correct clipping region. */ { @@ -223,6 +225,18 @@ if (pnew == 0) return_error(gs_error_VMerror); + + /* Bug #697450 "Null pointer dereference in gx_device_finalize()" + * If we have incorrect data passed to gs_initialise_wordimagedevice() then the + * initialisation will fail, crucially it will fail *before* it calls + * gs_make_mem_device() which initialises the device. This means that the + * icc_struct member will be uninitialsed, but the device finalise method + * will unconditionally free that memory. Since its a garbage pointer, bad things happen. + * Apparently we do still need makeimagedevice to be available from + * PostScript, so in here just zero the device memory, which means that + * the finalise routine won't have a problem. + */ + memset(pnew, 0x00, st_device_memory.ssize); code = gs_initialize_wordimagedevice(pnew, pmat, width, height, colors, num_colors, word_oriented, page_device, mem); diff -Nru ghostscript-9.10~dfsg/base/gsdfilt.c ghostscript-9.25~dfsg+1/base/gsdfilt.c --- ghostscript-9.10~dfsg/base/gsdfilt.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdfilt.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Functions for managing the device filter stack */ @@ -46,7 +46,7 @@ "gs_device_filter"); int -gs_push_device_filter(gs_memory_t *mem, gs_state *pgs, gs_device_filter_t *df) +gs_push_device_filter(gs_memory_t *mem, gs_gstate *pgs, gs_device_filter_t *df) { gs_device_filter_stack_t *dfs; gx_device *new_dev = NULL; @@ -73,7 +73,7 @@ } int -gs_pop_device_filter(gs_memory_t *mem, gs_state *pgs) +gs_pop_device_filter(gs_memory_t *mem, gs_gstate *pgs) { gs_device_filter_stack_t *dfs_tos = pgs->dfilter_stack; gx_device *tos_device = pgs->device; @@ -96,7 +96,7 @@ } int -gs_clear_device_filters(gs_memory_t *mem, gs_state *pgs) +gs_clear_device_filters(gs_memory_t *mem, gs_gstate *pgs) { int code; diff -Nru ghostscript-9.10~dfsg/base/gsdfilt.h ghostscript-9.25~dfsg+1/base/gsdfilt.h --- ghostscript-9.10~dfsg/base/gsdfilt.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdfilt.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,15 +9,15 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ #ifndef gsdfilt_INCLUDED # define gsdfilt_INCLUDED -/* The device filter stack lives in the gs_state structure. It represents +/* The device filter stack lives in the gs_gstate structure. It represents a chained sequence of devices that filter device requests, each forwarding to its target. The last such target is the physical device as set by setpagedevice. @@ -38,11 +38,11 @@ #endif struct gs_device_filter_s { - int (*push)(gs_device_filter_t *self, gs_memory_t *mem, gs_state *pgs, + int (*push)(gs_device_filter_t *self, gs_memory_t *mem, gs_gstate *pgs, gx_device **pdev, gx_device *target); - int (*prepop)(gs_device_filter_t *self, gs_memory_t *mem, gs_state *pgs, + int (*prepop)(gs_device_filter_t *self, gs_memory_t *mem, gs_gstate *pgs, gx_device *dev); - int (*postpop)(gs_device_filter_t *self, gs_memory_t *mem, gs_state *pgs, + int (*postpop)(gs_device_filter_t *self, gs_memory_t *mem, gs_gstate *pgs, gx_device *dev); }; @@ -58,7 +58,7 @@ * * Return value: 0 on success, or error code. **/ -int gs_push_device_filter(gs_memory_t *mem, gs_state *pgs, gs_device_filter_t *df); +int gs_push_device_filter(gs_memory_t *mem, gs_gstate *pgs, gs_device_filter_t *df); /** * gs_pop_device_filter: Pop a device filter. @@ -70,7 +70,7 @@ * * Return value: 0 on success, or error code. **/ -int gs_pop_device_filter(gs_memory_t *mem, gs_state *pgs); +int gs_pop_device_filter(gs_memory_t *mem, gs_gstate *pgs); /** * gs_clear_device_filters: Clear device filters from a graphics state. @@ -81,6 +81,6 @@ * * Return value: 0 on success, or error code. **/ -int gs_clear_device_filters(gs_memory_t *mem, gs_state *pgs); +int gs_clear_device_filters(gs_memory_t *mem, gs_gstate *pgs); #endif /* gsdfilt_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gs_dll_call.h ghostscript-9.25~dfsg+1/base/gs_dll_call.h --- ghostscript-9.10~dfsg/base/gs_dll_call.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gs_dll_call.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,7 +27,15 @@ #ifdef _Windows # ifndef GSDLLEXPORT -# define GSDLLEXPORT __declspec(dllexport) +/* We don't need both the "__declspec(dllexport)" declaration + * and the listing in the .def file - having both results in + * a linker warning on x64 builds (but is incorrect on x86, too) + */ +# if 0 +# define GSDLLEXPORT __declspec(dllexport) +# else +# define GSDLLEXPORT +# endif # endif # ifndef GSDLLAPI # define GSDLLAPI __stdcall diff -Nru ghostscript-9.10~dfsg/base/gsdll.h ghostscript-9.25~dfsg+1/base/gsdll.h --- ghostscript-9.10~dfsg/base/gsdll.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdll.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsdllwin.h ghostscript-9.25~dfsg+1/base/gsdllwin.h --- ghostscript-9.10~dfsg/base/gsdllwin.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdllwin.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsdparam.c ghostscript-9.25~dfsg+1/base/gsdparam.c --- ghostscript-9.10~dfsg/base/gsdparam.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdparam.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Default device parameters for Ghostscript library */ @@ -43,7 +43,7 @@ * prototype. */ gx_device *dev; - int code; + int code = 0; if (orig_dev->memory) dev = orig_dev; @@ -56,14 +56,438 @@ fill_dev_proc(dev, get_params, gx_default_get_params); fill_dev_proc(dev, get_page_device, gx_default_get_page_device); fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); - code = (is_hardware ? - (*dev_proc(dev, get_hardware_params)) (dev, plist) : - (*dev_proc(dev, get_params)) (dev, plist)); + if (is_hardware) { + if (dev_proc(dev, get_hardware_params) != NULL) + code = (*dev_proc(dev, get_hardware_params)) (dev, plist); + } else { + if (dev_proc(dev, get_params) != NULL) + code = (*dev_proc(dev, get_params)) (dev, plist); + } if (dev != orig_dev) gx_device_retain(dev, false); /* frees the copy */ return code; } +int gx_default_get_param(gx_device *dev, char *Param, void *list) +{ + gs_param_list * plist = (gs_param_list *)list; + int k, colors = dev->color_info.num_components; + gs_param_string profile_array[NUM_DEVICE_PROFILES]; + gs_param_string postren_profile, blend_profile; + gs_param_string proof_profile, link_profile, icc_colorants; + gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES]; + gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES]; + gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES]; + int color_accuracy = MAX_COLOR_ACCURACY; + int depth = dev->color_info.depth; + cmm_dev_profile_t *dev_profile; + char null_str[1]={'\0'}; +#define set_param_array(a, d, s)\ + (a.data = d, a.size = s, a.persistent = false); + bool devicegraytok = true; /* Default if device profile stuct not set */ + bool graydetection = false; + bool usefastcolor = false; /* set for unmanaged color */ + bool sim_overprint = false; /* By default do not simulate overprinting */ + bool prebandthreshold = true, temp_bool = false; + + if(strcmp(Param, "OutputDevice") == 0){ + gs_param_string dns; + param_string_from_string(dns, dev->dname); + return param_write_name(plist, "OutputDevice", &dns); + } +#ifdef PAGESIZE_IS_MEDIASIZE + if (strcmp(Param, "PageSize") == 0) { + gs_param_float_array msa; + set_param_array(msa, dev->MediaSize, 2); + return param_write_float_array(plist, "PageSize", &msa); + } +#endif + if (strcmp(Param, "ProcessColorModel") == 0) { + const char *cms = get_process_color_model_name(dev); + + /* We might have an uninitialized device with */ + /* color_info.num_components = 0.... */ + if ((cms != NULL) && (*cms != '\0')) { + gs_param_string pcms; + param_string_from_string(pcms, cms); + return param_write_name(plist, "ProcessColorModel", &pcms); + } + } + if (strcmp(Param, "HWResolution") == 0) { + gs_param_float_array hwra; + set_param_array(hwra, dev->HWResolution, 2); + return param_write_float_array(plist, "HWResolution", &hwra); + } + if (strcmp(Param, "ImagingBBox") == 0) { + gs_param_float_array ibba; + set_param_array(ibba, dev->ImagingBBox, 4); + if (dev->ImagingBBox_set) + return param_write_float_array(plist, "ImagingBBox", &ibba); + else + return param_write_null(plist, "ImagingBBox"); + } + if (strcmp(Param, "Margins") == 0) { + gs_param_float_array ma; + set_param_array(ma, dev->Margins, 2); + return param_write_float_array(plist, "Margins", &ma); + } + if (strcmp(Param, "MaxSeparations") == 0) { + int max_sep = dev->color_info.max_components; + return param_write_int(plist, "MaxSeparations", &max_sep); + } + if (strcmp(Param, "NumCopies") == 0) { + if (dev->NumCopies_set < 0 || (*dev_proc(dev, get_page_device))(dev) == 0) { + return_error(gs_error_undefined); + } else { + if (dev->NumCopies_set) + return param_write_int(plist, "NumCopies", &dev->NumCopies); + else + return param_write_null(plist, "NumCopies"); + } + } + if (strcmp(Param, "SeparationColorNames") == 0) { + gs_param_string_array scna; + set_param_array(scna, NULL, 0); + return param_write_name_array(plist, "SeparationColorNames", &scna); + } + if (strcmp(Param, "Separations") == 0) { + bool seprs = false; + return param_write_bool(plist, "Separations", &seprs); + } + if (strcmp(Param, "UseCIEColor") == 0) { + return param_write_bool(plist, "UseCIEColor", &dev->UseCIEColor); + } + + /* Non-standard parameters */ + if (strcmp(Param, "HWSize") == 0) { + int HWSize[2]; + gs_param_int_array hwsa; + + HWSize[0] = dev->width; + HWSize[1] = dev->height; + set_param_array(hwsa, HWSize, 2); + return param_write_int_array(plist, "HWSize", &hwsa); + } + if (strcmp(Param, ".HWMargins") == 0) { + gs_param_float_array hwma; + set_param_array(hwma, dev->HWMargins, 4); + return param_write_float_array(plist, ".HWMargins", &hwma); + } + if (strcmp(Param, ".MediaSize") == 0) { + gs_param_float_array msa; + set_param_array(msa, dev->MediaSize, 2); + return param_write_float_array(plist, ".MediaSize", &msa); + } + if (strcmp(Param, "Name") == 0) { + gs_param_string dns; + param_string_from_string(dns, dev->dname); + return param_write_string(plist, "Name", &dns); + } + if (strcmp(Param, "Colors") == 0) { + int colors = dev->color_info.num_components; + return param_write_int(plist, "Colors", &colors); + } + if (strcmp(Param, "BitsPerPixel") == 0) { + return param_write_int(plist, "BitsPerPixel", &depth); + } + if (strcmp(Param, "GrayValues") == 0) { + int GrayValues = dev->color_info.max_gray + 1; + return param_write_int(plist, "GrayValues", &GrayValues); + } + if (strcmp(Param, "PageCount") == 0) { + return param_write_long(plist, "PageCount", &dev->PageCount); + } + if (strcmp(Param, ".IgnoreNumCopies") == 0) { + return param_write_bool(plist, ".IgnoreNumCopies", &dev->IgnoreNumCopies); + } + if (strcmp(Param, "TextAlphaBits") == 0) { + return param_write_int(plist, "TextAlphaBits", + &dev->color_info.anti_alias.text_bits); + } + if (strcmp(Param, "GraphicsAlphaBits") == 0) { + return param_write_int(plist, "GraphicsAlphaBits", + &dev->color_info.anti_alias.graphics_bits); + } + if (strcmp(Param, "AntidropoutDownscaler") == 0) { + return param_write_bool(plist, "AntidropoutDownscaler", + &dev->color_info.use_antidropout_downscaler); + } + if (strcmp(Param, ".LockSafetyParams") == 0) { + return param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams); + } + if (strcmp(Param, "MaxPatternBitmap") == 0) { + return param_write_int(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap); + } + if (strcmp(Param, "PageUsesTransparency") == 0) { + return param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency); + } + if (strcmp(Param, "MaxBitmap") == 0) { + return param_write_long(plist, "MaxBitmap", &(dev->space_params.MaxBitmap)); + } + if (strcmp(Param, "BandBufferSpace") == 0) { + return param_write_long(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace); + } + if (strcmp(Param, "BandHeight") == 0) { + return param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight); + } + if (strcmp(Param, "BandWidth") == 0) { + return param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth); + } + if (strcmp(Param, "BufferSpace") == 0) { + return param_write_long(plist, "BufferSpace", &dev->space_params.BufferSpace); + } + if (strcmp(Param, "InterpolateControl") == 0) { + int interpolate_control = dev->interpolate_control; + return param_write_int(plist, "InterpolateControl", &interpolate_control); + } + if (strcmp(Param, "LeadingEdge") == 0) { + if (dev->LeadingEdge & LEADINGEDGE_SET_MASK) { + int leadingedge = dev->LeadingEdge & LEADINGEDGE_MASK; + return param_write_int(plist, "LeadingEdge", &leadingedge); + } else + return param_write_null(plist, "LeadingEdge"); + } + + if (dev->color_info.num_components > 1) { + int RGBValues = dev->color_info.max_color + 1; + long ColorValues = (depth >= 32 ? -1 : 1L << depth); /* value can only be 32 bits */ + + if (strcmp(Param, "RedValues") == 0) { + return param_write_int(plist, "RedValues", &RGBValues); + } + if (strcmp(Param, "GreenValues") == 0) { + return param_write_int(plist, "GreenValues", &RGBValues); + } + if (strcmp(Param, "BlueValues") == 0) { + return param_write_int(plist, "BlueValues", &RGBValues); + } + if (strcmp(Param, "ColorValues") == 0) { + return param_write_long(plist, "ColorValues", &ColorValues); + } + } + if (strcmp(Param, "HWColorMap") == 0) { + byte palette[3 << 8]; + + if (param_HWColorMap(dev, palette)) { + gs_param_string hwcms; + + hwcms.data = palette, hwcms.size = colors << depth, + hwcms.persistent = false; + return param_write_string(plist, "HWColorMap", &hwcms); + } + } + + /* ICC profiles */ + /* Check if the device profile is null. If it is, then we need to + go ahead and get it set up at this time. If the proc is not + set up yet then we are not going to do anything yet */ + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) != NULL) { + int code; + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + if (dev_profile == NULL) { + code = gsicc_init_device_profile_struct(dev, NULL, 0); + if (code < 0) + return code; + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + } + for (k = 0; k < NUM_DEVICE_PROFILES; k++) { + if (dev_profile->device_profile[k] == NULL + || dev_profile->device_profile[k]->name == NULL) { + param_string_from_string(profile_array[k], null_str); + profile_intents[k] = gsRINOTSPECIFIED; + blackptcomps[k] = gsBPNOTSPECIFIED; + blackpreserve[k] = gsBKPRESNOTSPECIFIED; + } else { + param_string_from_transient_string(profile_array[k], + dev_profile->device_profile[k]->name); + profile_intents[k] = dev_profile->rendercond[k].rendering_intent; + blackptcomps[k] = dev_profile->rendercond[k].black_point_comp; + blackpreserve[k] = dev_profile->rendercond[k].preserve_black; + } + } + if (dev_profile->blend_profile == NULL) { + param_string_from_string(blend_profile, null_str); + } else { + param_string_from_transient_string(blend_profile, + dev_profile->blend_profile->name); + } + if (dev_profile->postren_profile == NULL) { + param_string_from_string(postren_profile, null_str); + } else { + param_string_from_transient_string(postren_profile, + dev_profile->postren_profile->name); + } + if (dev_profile->proof_profile == NULL) { + param_string_from_string(proof_profile, null_str); + } else { + param_string_from_transient_string(proof_profile, + dev_profile->proof_profile->name); + } + if (dev_profile->link_profile == NULL) { + param_string_from_string(link_profile, null_str); + } else { + param_string_from_transient_string(link_profile, + dev_profile->link_profile->name); + } + devicegraytok = dev_profile->devicegraytok; + graydetection = dev_profile->graydetection; + usefastcolor = dev_profile->usefastcolor; + sim_overprint = dev_profile->sim_overprint; + prebandthreshold = dev_profile->prebandthreshold; + /* With respect to Output profiles that have non-standard colorants, + we rely upon the default profile to give us the colorants if they do + exist. */ + if (dev_profile->spotnames == NULL) { + param_string_from_string(icc_colorants, null_str); + } else { + char *colorant_names; + + colorant_names = + gsicc_get_dev_icccolorants(dev_profile); + if (colorant_names != NULL) { + param_string_from_transient_string(icc_colorants, colorant_names); + } else { + param_string_from_string(icc_colorants, null_str); + } + } + } else { + for (k = 0; k < NUM_DEVICE_PROFILES; k++) { + param_string_from_string(profile_array[k], null_str); + profile_intents[k] = gsRINOTSPECIFIED; + blackptcomps[k] = gsBPNOTSPECIFIED; + blackpreserve[k] = gsBKPRESNOTSPECIFIED; + } + param_string_from_string(blend_profile, null_str); + param_string_from_string(postren_profile, null_str); + param_string_from_string(proof_profile, null_str); + param_string_from_string(link_profile, null_str); + param_string_from_string(icc_colorants, null_str); + } + if (strcmp(Param, "DeviceGrayToK") == 0) { + return param_write_bool(plist, "DeviceGrayToK", &devicegraytok); + } + if (strcmp(Param, "GrayDetection") == 0) { + return param_write_bool(plist, "GrayDetection", &graydetection); + } + if (strcmp(Param, "UseFastColor") == 0) { + return param_write_bool(plist, "UseFastColor", &usefastcolor); + } + if (strcmp(Param, "SimulateOverprint") == 0) { + return param_write_bool(plist, "SimulateOverprint", &sim_overprint); + } + if (strcmp(Param, "PreBandThreshold") == 0) { + return param_write_bool(plist, "PreBandThreshold", &prebandthreshold); + } + if (strcmp(Param, "PostRenderProfile") == 0) { + return param_write_string(plist, "PostRenderProfile", &(postren_profile)); + } + if (strcmp(Param, "BlendColorProfile") == 0) { + return param_write_string(plist, "BlendColorProfile", &(blend_profile)); + } + if (strcmp(Param, "ProofProfile") == 0) { + return param_write_string(plist,"ProofProfile", &(proof_profile)); + } + if (strcmp(Param, "DeviceLinkProfile") == 0) { + return param_write_string(plist,"DeviceLinkProfile", &(link_profile)); + } + if (strcmp(Param, "ICCOutputColors") == 0) { + return param_write_string(plist,"ICCOutputColors", &(icc_colorants)); + } + if (strcmp(Param, "OutputICCProfile") == 0) { + return param_write_string(plist,"OutputICCProfile", &(profile_array[0])); + } + if (strcmp(Param, "GraphicICCProfile") == 0) { + return param_write_string(plist,"GraphicICCProfile", &(profile_array[1])); + } + if (strcmp(Param, "ImageICCProfile") == 0) { + return param_write_string(plist,"ImageICCProfile", &(profile_array[2])); + } + if (strcmp(Param, "TextICCProfile") == 0) { + return param_write_string(plist,"TextICCProfile", &(profile_array[3])); + } + if (strcmp(Param, "ColorAccuracy") == 0) { + return param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy))); + } + if (strcmp(Param, "RenderIntent") == 0) { + return param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0]))); + } + if (strcmp(Param, "GraphicIntent") == 0) { + return param_write_int(plist,"GraphicIntent", (const int *) &(profile_intents[1])); + } + if (strcmp(Param, "ImageIntent") == 0) { + return param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2])); + } + if (strcmp(Param, "TextIntent") == 0) { + return param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3])); + } + if (strcmp(Param, "BlackPtComp") == 0) { + return param_write_int(plist,"BlackPtComp", (const int *) (&(blackptcomps[0]))); + } + if (strcmp(Param, "GraphicBlackPt") == 0) { + return param_write_int(plist,"GraphicBlackPt", (const int *) &(blackptcomps[1])); + } + if (strcmp(Param, "ImageBlackPt") == 0) { + return param_write_int(plist,"ImageBlackPt", (const int *) &(blackptcomps[2])); + } + if (strcmp(Param, "TextBlackPt") == 0) { + return param_write_int(plist,"TextBlackPt", (const int *) &(blackptcomps[3])); + } + if (strcmp(Param, "KPreserve") == 0) { + return param_write_int(plist,"KPreserve", (const int *) (&(blackpreserve[0]))); + } + if (strcmp(Param, "GraphicKPreserve") == 0) { + return param_write_int(plist,"GraphicKPreserve", (const int *) &(blackpreserve[1])); + } + if (strcmp(Param, "ImageKPreserve") == 0) { + return param_write_int(plist,"ImageKPreserve", (const int *) &(blackpreserve[2])); + } + if (strcmp(Param, "TextKPreserve") == 0) { + return param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3])); + } + if (strcmp(Param, "FirstPage") == 0) { + return param_write_int(plist, "FirstPage", &dev->FirstPage); + } + if (strcmp(Param, "LastPage") == 0) { + return param_write_int(plist, "LastPage", &dev->LastPage); + } + if (strcmp(Param, "DisablePageHandler") == 0) { + temp_bool = dev->DisablePageHandler; + return param_write_bool(plist, "DisablePageHandler", &temp_bool); + } + if (strcmp(Param, "PageList") == 0){ + gs_param_string pagelist; + if (dev->PageList) { + gdev_pagelist *p = (gdev_pagelist *)dev->PageList; + param_string_from_string(pagelist, p->Pages); + } + else + param_string_from_string(pagelist, null_str); + return param_write_string(plist, "PageList", &pagelist); + } + if (strcmp(Param, "FILTERIMAGE") == 0) { + temp_bool = dev->ObjectFilter & FILTERIMAGE; + return param_write_bool(plist, "FILTERIMAGE", &temp_bool); + } + if (strcmp(Param, "FILTERTEXT") == 0) { + temp_bool = dev->ObjectFilter & FILTERTEXT; + return param_write_bool(plist, "FILTERTEXT", &temp_bool); + } + if (strcmp(Param, "FILTERVECTOR") == 0) { + temp_bool = dev->ObjectFilter & FILTERVECTOR; + return param_write_bool(plist, "FILTERVECTOR", &temp_bool); + } + + return_error(gs_error_undefined); +} + /* Get standard parameters. */ int gx_default_get_params(gx_device * dev, gs_param_list * plist) @@ -74,6 +498,7 @@ bool seprs = false; gs_param_string dns, pcms, profile_array[NUM_DEVICE_PROFILES]; + gs_param_string blend_profile, postren_profile, pagelist; gs_param_string proof_profile, link_profile, icc_colorants; gsicc_rendering_intents_t profile_intents[NUM_DEVICE_PROFILES]; gsicc_blackptcomp_t blackptcomps[NUM_DEVICE_PROFILES]; @@ -81,9 +506,10 @@ bool devicegraytok = true; /* Default if device profile stuct not set */ bool graydetection = false; bool usefastcolor = false; /* set for unmanaged color */ - bool sim_overprint = true; /* By default simulate overprinting */ - bool prebandthreshold = true; + bool sim_overprint = false; /* By default do not simulate overprinting */ + bool prebandthreshold = true, temp_bool; int k; + int color_accuracy = MAX_COLOR_ACCURACY; gs_param_float_array msa, ibba, hwra, ma; gs_param_string_array scna; char null_str[1]={'\0'}; @@ -98,7 +524,7 @@ int GrayValues = dev->color_info.max_gray + 1; int HWSize[2]; gs_param_int_array hwsa; - gs_param_float_array hwma, mhwra; + gs_param_float_array hwma; cmm_dev_profile_t *dev_profile; /* Fill in page device parameters. */ @@ -126,48 +552,70 @@ HWSize[1] = dev->height; set_param_array(hwsa, HWSize, 2); set_param_array(hwma, dev->HWMargins, 4); - set_param_array(mhwra, dev->MarginsHWResolution, 2); /* Check if the device profile is null. If it is, then we need to go ahead and get it set up at this time. If the proc is not set up yet then we are not going to do anything yet */ - if (dev->procs.get_profile != NULL) { + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) != NULL) { code = dev_proc(dev, get_profile)(dev, &dev_profile); - if (dev_profile == NULL) { + if (code < 0) + return code; + + if (dev_profile == NULL) { code = gsicc_init_device_profile_struct(dev, NULL, 0); + if (code < 0) + return code; code = dev_proc(dev, get_profile)(dev, &dev_profile); - } - /* It is possible that the current device profile name is NULL if we - have a pdf14 device in line with a transparency group that is in a - color space specified from a source defined ICC profile. Check for + if (code < 0) + return code; + } + /* It is possible that the current device profile name is NULL if we + have a pdf14 device in line with a transparency group that is in a + color space specified from a source defined ICC profile. Check for that here to avoid any access violations. Bug 692558 */ for (k = 0; k < NUM_DEVICE_PROFILES; k++) { - if (dev_profile->device_profile[k] == NULL + if (dev_profile->device_profile[k] == NULL || dev_profile->device_profile[k]->name == NULL) { param_string_from_string(profile_array[k], null_str); profile_intents[k] = gsRINOTSPECIFIED; blackptcomps[k] = gsBPNOTSPECIFIED; blackpreserve[k] = gsBKPRESNOTSPECIFIED; } else { - param_string_from_string(profile_array[k], + param_string_from_transient_string(profile_array[k], dev_profile->device_profile[k]->name); profile_intents[k] = dev_profile->rendercond[k].rendering_intent; blackptcomps[k] = dev_profile->rendercond[k].black_point_comp; blackpreserve[k] = dev_profile->rendercond[k].preserve_black; } } - /* The proof and link profile */ + /* The proof, link and post render profile */ if (dev_profile->proof_profile == NULL) { param_string_from_string(proof_profile, null_str); } else { - param_string_from_string(proof_profile, + param_string_from_transient_string(proof_profile, dev_profile->proof_profile->name); } if (dev_profile->link_profile == NULL) { param_string_from_string(link_profile, null_str); } else { - param_string_from_string(link_profile, + param_string_from_transient_string(link_profile, dev_profile->link_profile->name); } + if (dev_profile->postren_profile == NULL) { + param_string_from_string(postren_profile, null_str); + } else { + param_string_from_transient_string(postren_profile, + dev_profile->postren_profile->name); + } + if (dev_profile->blend_profile == NULL) { + param_string_from_string(blend_profile, null_str); + } else { + param_string_from_transient_string(blend_profile, + dev_profile->blend_profile->name); + } devicegraytok = dev_profile->devicegraytok; graydetection = dev_profile->graydetection; usefastcolor = dev_profile->usefastcolor; @@ -184,7 +632,7 @@ colorant_names = gsicc_get_dev_icccolorants(dev_profile); if (colorant_names != NULL) { - param_string_from_string(icc_colorants, colorant_names); + param_string_from_transient_string(icc_colorants, colorant_names); } else { param_string_from_string(icc_colorants, null_str); } @@ -199,6 +647,8 @@ param_string_from_string(proof_profile, null_str); param_string_from_string(link_profile, null_str); param_string_from_string(icc_colorants, null_str); + param_string_from_string(postren_profile, null_str); + param_string_from_string(blend_profile, null_str); } /* Transmit the values. */ /* Standard parameters */ @@ -236,9 +686,12 @@ (code = param_write_string(plist,"ImageICCProfile", &(profile_array[2]))) < 0 || (code = param_write_string(plist,"TextICCProfile", &(profile_array[3]))) < 0 || (code = param_write_string(plist,"ProofProfile", &(proof_profile))) < 0 || + (code = param_write_string(plist, "PostRenderProfile", &(postren_profile))) < 0 || + (code = param_write_string(plist, "BlendColorProfile", &(blend_profile))) < 0 || (code = param_write_string(plist,"DeviceLinkProfile", &(link_profile))) < 0 || - (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 || - (code = param_write_int(plist,"RenderIntent", (const int *) (&(profile_intents[0])))) < 0 || + (code = param_write_string(plist,"ICCOutputColors", &(icc_colorants))) < 0 || + (code = param_write_int(plist, "RenderIntent", (const int *)(&(profile_intents[0])))) < 0 || + (code = param_write_int(plist, "ColorAccuracy", (const int *)(&(color_accuracy)))) < 0 || (code = param_write_int(plist,"GraphicIntent", (const int *) &(profile_intents[1]))) < 0 || (code = param_write_int(plist,"ImageIntent", (const int *) &(profile_intents[2]))) < 0 || (code = param_write_int(plist,"TextIntent", (const int *) &(profile_intents[3]))) < 0 || @@ -252,7 +705,6 @@ (code = param_write_int(plist,"TextKPreserve", (const int *) &(blackpreserve[3]))) < 0 || (code = param_write_int_array(plist, "HWSize", &hwsa)) < 0 || (code = param_write_float_array(plist, ".HWMargins", &hwma)) < 0 || - (code = param_write_float_array(plist, ".MarginsHWResolution", &mhwra)) < 0 || (code = param_write_float_array(plist, ".MediaSize", &msa)) < 0 || (code = param_write_string(plist, "Name", &dns)) < 0 || (code = param_write_int(plist, "Colors", &colors)) < 0 || @@ -264,8 +716,17 @@ &dev->color_info.anti_alias.text_bits)) < 0 || (code = param_write_int(plist, "GraphicsAlphaBits", &dev->color_info.anti_alias.graphics_bits)) < 0 || + (code = param_write_bool(plist, "AntidropoutDownscaler", + &dev->color_info.use_antidropout_downscaler)) < 0 || (code = param_write_bool(plist, ".LockSafetyParams", &dev->LockSafetyParams)) < 0 || - (code = param_write_int(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 + (code = param_write_int(plist, "MaxPatternBitmap", &dev->MaxPatternBitmap)) < 0 || + (code = param_write_bool(plist, "PageUsesTransparency", &dev->page_uses_transparency)) < 0 || + (code = param_write_long(plist, "MaxBitmap", &(dev->space_params.MaxBitmap))) < 0 || + (code = param_write_long(plist, "BandBufferSpace", &dev->space_params.band.BandBufferSpace)) < 0 || + (code = param_write_int(plist, "BandHeight", &dev->space_params.band.BandHeight)) < 0 || + (code = param_write_int(plist, "BandWidth", &dev->space_params.band.BandWidth)) < 0 || + (code = param_write_long(plist, "BufferSpace", &dev->space_params.BufferSpace)) < 0 || + (code = param_write_int(plist, "InterpolateControl", &dev->interpolate_control)) < 0 ) return code; @@ -273,10 +734,39 @@ if (dev->LeadingEdge & LEADINGEDGE_SET_MASK) { int leadingedge = dev->LeadingEdge & LEADINGEDGE_MASK; code = param_write_int(plist, "LeadingEdge", &leadingedge); - } + } else + code = param_write_null(plist, "LeadingEdge"); if (code < 0) return code; + if ((code = param_write_int(plist, "FirstPage", &dev->FirstPage)) < 0) + return code; + if ((code = param_write_int(plist, "LastPage", &dev->LastPage)) < 0) + return code; + + temp_bool = dev->DisablePageHandler; + if ((code = param_write_bool(plist, "DisablePageHandler", &temp_bool)) < 0) + return code; + + if (dev->PageList) { + gdev_pagelist *p = (gdev_pagelist *)dev->PageList; + param_string_from_string(pagelist, p->Pages); + } + else + param_string_from_string(pagelist, null_str); + if ((code = param_write_name(plist, "PageList", &pagelist)) < 0) + return code; + + temp_bool = dev->ObjectFilter & FILTERIMAGE; + if ((code = param_write_bool(plist, "FILTERIMAGE", &temp_bool)) < 0) + return code; + temp_bool = dev->ObjectFilter & FILTERTEXT; + if ((code = param_write_bool(plist, "FILTERTEXT", &temp_bool)) < 0) + return code; + temp_bool = dev->ObjectFilter & FILTERVECTOR; + if ((code = param_write_bool(plist, "FILTERVECTOR", &temp_bool)) < 0) + return code; + /* Fill in color information. */ if (colors > 1) { @@ -427,7 +917,7 @@ int gdev_write_input_page_size(int index, gs_param_dict * pdict, - floatp width_points, floatp height_points) + double width_points, double height_points) { gdev_input_media_t media; @@ -520,17 +1010,21 @@ } static int -gx_default_put_graydetection(bool graydetection, gx_device * dev) +gx_default_put_graydetection(bool graydetection, gx_device * dev) { int code = 0; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device. For now allocate the profile structure - but do not intialize the profile yet as the color info + but do not intialize the profile yet as the color info may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ @@ -550,19 +1044,23 @@ } return code; } - + static int -gx_default_put_graytok(bool graytok, gx_device * dev) +gx_default_put_graytok(bool graytok, gx_device * dev) { int code = 0; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device. For now allocate the profile structure - but do not intialize the profile yet as the color info + but do not intialize the profile yet as the color info may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ @@ -586,17 +1084,21 @@ } static int -gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev) +gx_default_put_prebandthreshold(bool prebandthreshold, gx_device * dev) { int code = 0; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device. For now allocate the profile structure - but do not intialize the profile yet as the color info + but do not intialize the profile yet as the color info may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ @@ -620,17 +1122,21 @@ } static int -gx_default_put_usefastcolor(bool fastcolor, gx_device * dev) +gx_default_put_usefastcolor(bool fastcolor, gx_device * dev) { int code = 0; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device. For now allocate the profile structure - but do not intialize the profile yet as the color info + but do not intialize the profile yet as the color info may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ @@ -654,17 +1160,21 @@ } static int -gx_default_put_simulateoverprint(bool sim_overprint, gx_device * dev) +gx_default_put_simulateoverprint(bool sim_overprint, gx_device * dev) { int code = 0; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device. For now allocate the profile structure - but do not intialize the profile yet as the color info + but do not intialize the profile yet as the color info may not be fully set up at this time. */ if (dev->icc_struct == NULL) { /* Allocate at this time the structure */ @@ -688,16 +1198,20 @@ } static int -gx_default_put_intent(gsicc_rendering_intents_t icc_intent, gx_device * dev, - gsicc_profile_types_t index) +gx_default_put_intent(gsicc_rendering_intents_t icc_intent, gx_device * dev, + gsicc_profile_types_t index) { int code; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device */ if (dev->icc_struct == NULL) { /* Intializes the device structure. Not the profile though for index */ @@ -708,6 +1222,8 @@ code = gsicc_set_device_profile_intent(dev, icc_intent, index); } else { code = dev_proc(dev, get_profile)(dev, &profile_struct); + if (code < 0) + return code; if (profile_struct == NULL) { /* Create now */ dev->icc_struct = gsicc_new_device_profile_array(dev->memory); @@ -720,16 +1236,20 @@ } static int -gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * dev, - gsicc_profile_types_t index) +gx_default_put_blackpreserve(gsicc_blackpreserve_t blackpreserve, gx_device * dev, + gsicc_profile_types_t index) { int code; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device */ if (dev->icc_struct == NULL) { /* Intializes the device structure. Not the profile though for index */ @@ -757,16 +1277,20 @@ static int -gx_default_put_blackptcomp(gsicc_blackptcomp_t blackptcomp, gx_device * dev, - gsicc_profile_types_t index) +gx_default_put_blackptcomp(gsicc_blackptcomp_t blackptcomp, gx_device * dev, + gsicc_profile_types_t index) { int code; cmm_dev_profile_t *profile_struct; - if (dev->procs.get_profile == NULL) { - /* This is an odd case where the device has not yet fully been + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { + /* This is an odd case where the device has not yet fully been set up with its procedures yet. We want to make sure that - we catch this so we assume here that we are dealing with + we catch this so we assume here that we are dealing with the target device */ if (dev->icc_struct == NULL) { /* Intializes the device structure. Not the profile though for index */ @@ -800,7 +1324,7 @@ /* See below about this device fill proc */ fill_dev_proc(dev, get_profile, gx_default_get_profile); - tempstr = (char *) gs_alloc_bytes(dev->memory, colorants->size+1, + tempstr = (char *) gs_alloc_bytes(dev->memory, colorants->size+1, "gx_default_put_icc_colorants"); memcpy(tempstr, colorants->data, colorants->size); /* Set last position to NULL. */ @@ -811,8 +1335,8 @@ } static int -gx_default_put_icc(gs_param_string *icc_pro, gx_device * dev, - gsicc_profile_types_t index) +gx_default_put_icc(gs_param_string *icc_pro, gx_device * dev, + gsicc_profile_types_t index) { char *tempstr; int code = 0; @@ -826,7 +1350,7 @@ exercise to the device start-up experts */ fill_dev_proc(dev, get_profile, gx_default_get_profile); if (icc_pro->size < gp_file_name_sizeof) { - tempstr = (char *) gs_alloc_bytes(dev->memory, icc_pro->size+1, + tempstr = (char *) gs_alloc_bytes(dev->memory, icc_pro->size+1, "gx_default_put_icc"); if (tempstr == NULL) return_error(gs_error_VMerror); @@ -839,6 +1363,17 @@ return code; } +static void +rc_free_pages_list(gs_memory_t * mem, void *ptr_in, client_name_t cname) +{ + gdev_pagelist *PageList = (gdev_pagelist *)ptr_in; + + if (PageList->rc.ref_count <= 1) { + gs_free(mem->non_gc_memory, PageList->Pages, 1, PagesSize, "free page list"); + gs_free(mem->non_gc_memory, PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list"); + } +} + /* Set standard parameters. */ /* Note that setting the size or resolution closes the device. */ /* Window devices that don't want this to happen must temporarily */ @@ -855,7 +1390,6 @@ gs_param_float_array msa; gs_param_float_array ma; gs_param_float_array hwma; - gs_param_float_array mhwra; gs_param_string_array scna; int nci = dev->NumCopies; int ncset = dev->NumCopies_set; @@ -873,22 +1407,30 @@ int tab = dev->color_info.anti_alias.text_bits; int gab = dev->color_info.anti_alias.graphics_bits; int mpbm = dev->MaxPatternBitmap; + int ic = dev->interpolate_control; + bool page_uses_transparency = dev->page_uses_transparency; + gdev_space_params sp = dev->space_params; + gdev_space_params save_sp = dev->space_params; int rend_intent[NUM_DEVICE_PROFILES]; int blackptcomp[NUM_DEVICE_PROFILES]; int blackpreserve[NUM_DEVICE_PROFILES]; - gs_param_string cms; + gs_param_string cms, pagelist; int leadingedge = dev->LeadingEdge; int k; + int color_accuracy; bool devicegraytok = true; bool graydetection = false; bool usefastcolor = false; - bool sim_overprint = true; + bool sim_overprint = false; bool prebandthreshold = false; + bool use_antidropout = dev->color_info.use_antidropout_downscaler; + bool temp_bool; int profile_types[NUM_DEVICE_PROFILES] = {gsDEFAULTPROFILE, gsGRAPHICPROFILE, gsIMAGEPROFILE, - gsTEXTPROFILE}; + gsTEXTPROFILE}; + color_accuracy = gsicc_currentcoloraccuracy(dev->memory); if (dev->icc_struct != NULL) { for (k = 0; k < NUM_DEVICE_PROFILES; k++) { rend_intent[k] = dev->icc_struct->rendercond[k].rendering_intent; @@ -996,7 +1538,6 @@ if (param_read_null(plist, "LeadingEdge") == 0) { /* if param is null, clear explicitly-set flag */ leadingedge &= ~LEADINGEDGE_SET_MASK; - code = 0; } else { ecode = code; } @@ -1040,15 +1581,6 @@ BEGIN_ARRAY_PARAM(param_read_float_array, ".HWMargins", hwma, 4, hwme) { break; } END_ARRAY_PARAM(hwma, hwme); - /* MarginsHWResolution cannot be changed, only checked. */ - BEGIN_ARRAY_PARAM(param_read_float_array, ".MarginsHWResolution", mhwra, 2, mhwre) { - if (mhwra.data[0] != dev->MarginsHWResolution[0] || - mhwra.data[1] != dev->MarginsHWResolution[1] - ) - ecode = gs_note_error(gs_error_rangecheck); - else - break; - } END_ARRAY_PARAM(mhwra, mhwre); switch (code = param_read_bool(plist, (param_name = ".IgnoreNumCopies"), &ignc)) { default: ecode = code; @@ -1061,131 +1593,169 @@ (*dev_proc(dev, get_page_device))(dev) != 0 ) { switch (code = param_read_int(plist, (param_name = "NumCopies"), &nci)) { - case 0: - if (nci < 0) - ecode = gs_error_rangecheck; - else { - ncset = 1; - break; - } - goto nce; - default: - if ((code = param_read_null(plist, param_name)) == 0) { - ncset = 0; - break; - } - ecode = code; /* can't be 1 */ + case 0: + if (nci < 0) + ecode = gs_error_rangecheck; + else { + ncset = 1; + break; + } + goto nce; + default: + if ((code = param_read_null(plist, param_name)) == 0) { + ncset = 0; + break; + } + ecode = code; /* can't be 1 */ nce: - param_signal_error(plist, param_name, ecode); - case 1: - break; + param_signal_error(plist, param_name, ecode); + case 1: + break; + } } + /* Set the ICC output colors first */ + if ((code = param_read_string(plist, "ICCOutputColors", &icc_pro)) != 1) { + if ((code = gx_default_put_icc_colorants(&icc_pro, dev)) < 0) { + ecode = code; + param_signal_error(plist, "ICCOutputColors", ecode); + } + } + if ((code = param_read_string(plist, "DeviceLinkProfile", &icc_pro)) != 1) { + if ((code = gx_default_put_icc(&icc_pro, dev, gsLINKPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "DeviceLinkProfile", ecode); + } + } + if ((code = param_read_string(plist, "PostRenderProfile", &icc_pro)) != 1) { + if ((code = gx_default_put_icc(&icc_pro, dev, gsPRPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "PostRenderProfile", ecode); + } } - /* Set the directory first */ if ((code = param_read_string(plist, "OutputICCProfile", &icc_pro)) != 1) { - gx_default_put_icc(&icc_pro, dev, gsDEFAULTPROFILE); + if ((code = gx_default_put_icc(&icc_pro, dev, gsDEFAULTPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "OutputICCProfile", ecode); + } } /* Note, if a change is made to NUM_DEVICE_PROFILES we need to update this with the name of the profile */ if ((code = param_read_string(plist, "GraphicICCProfile", &icc_pro)) != 1) { - gx_default_put_icc(&icc_pro, dev, gsGRAPHICPROFILE); + if ((code = gx_default_put_icc(&icc_pro, dev, gsGRAPHICPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "GraphicICCProfile", ecode); + } } if ((code = param_read_string(plist, "ImageICCProfile", &icc_pro)) != 1) { - gx_default_put_icc(&icc_pro, dev, gsIMAGEPROFILE); + if ((code = gx_default_put_icc(&icc_pro, dev, gsIMAGEPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "ImageICCProfile", ecode); + } } if ((code = param_read_string(plist, "TextICCProfile", &icc_pro)) != 1) { - gx_default_put_icc(&icc_pro, dev, gsTEXTPROFILE); + if ((code = gx_default_put_icc(&icc_pro, dev, gsTEXTPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "TextICCProfile", ecode); + } } if ((code = param_read_string(plist, "ProofProfile", &icc_pro)) != 1) { - gx_default_put_icc(&icc_pro, dev, gsPROOFPROFILE); - } - if ((code = param_read_string(plist, "DeviceLinkProfile", &icc_pro)) != 1) { - gx_default_put_icc(&icc_pro, dev, gsLINKPROFILE); + if ((code = gx_default_put_icc(&icc_pro, dev, gsPROOFPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "ProofProfile", ecode); + } } - if ((code = param_read_string(plist, "ICCOutputColors", &icc_pro)) != 1) { - gx_default_put_icc_colorants(&icc_pro, dev); + if ((code = param_read_string(plist, "BlendColorProfile", &icc_pro)) != 1) { + if ((code = gx_default_put_icc(&icc_pro, dev, gsBLENDPROFILE)) < 0) { + ecode = code; + param_signal_error(plist, "BlendColorProfile", ecode); + } } - if ((code = param_read_int(plist, (param_name = "RenderIntent"), + if ((code = param_read_int(plist, (param_name = "RenderIntent"), &(rend_intent[0]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "GraphicIntent"), + } + if ((code = param_read_int(plist, (param_name = "GraphicIntent"), &(rend_intent[1]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "ImageIntent"), + } + if ((code = param_read_int(plist, (param_name = "ImageIntent"), &(rend_intent[2]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "TextIntent"), + } + if ((code = param_read_int(plist, (param_name = "TextIntent"), &(rend_intent[3]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "BlackPtComp"), + } + if ((code = param_read_int(plist, (param_name = "BlackPtComp"), &(blackptcomp[0]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "GraphicBlackPt"), + } + if ((code = param_read_int(plist, (param_name = "GraphicBlackPt"), &(blackptcomp[1]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "ImageBlackPt"), + } + if ((code = param_read_int(plist, (param_name = "ImageBlackPt"), &(blackptcomp[2]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "TextBlackPt"), + } + if ((code = param_read_int(plist, (param_name = "TextBlackPt"), &(blackptcomp[3]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "KPreserve"), + } + if ((code = param_read_int(plist, (param_name = "KPreserve"), &(blackpreserve[0]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "GraphicKPreserve"), + } + if ((code = param_read_int(plist, (param_name = "GraphicKPreserve"), &(blackpreserve[1]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "ImageKPreserve"), + } + if ((code = param_read_int(plist, (param_name = "ImageKPreserve"), &(blackpreserve[2]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); - } - if ((code = param_read_int(plist, (param_name = "TextKPreserve"), + } + if ((code = param_read_int(plist, (param_name = "TextKPreserve"), &(blackpreserve[3]))) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_bool(plist, (param_name = "DeviceGrayToK"), + if ((code = param_read_int(plist, (param_name = "ColorAccuracy"), + &color_accuracy)) < 0) { + ecode = code; + param_signal_error(plist, param_name, ecode); + } + if ((code = param_read_bool(plist, (param_name = "DeviceGrayToK"), &devicegraytok)) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_bool(plist, (param_name = "GrayDetection"), + if ((code = param_read_bool(plist, (param_name = "GrayDetection"), &graydetection)) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_bool(plist, (param_name = "UseFastColor"), + if ((code = param_read_bool(plist, (param_name = "UseFastColor"), &usefastcolor)) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_bool(plist, (param_name = "SimulateOverprint"), + if ((code = param_read_bool(plist, (param_name = "SimulateOverprint"), &sim_overprint)) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); } - if ((code = param_read_bool(plist, (param_name = "PreBandThreshold"), + if ((code = param_read_bool(plist, (param_name = "PreBandThreshold"), &prebandthreshold)) < 0) { ecode = code; param_signal_error(plist, param_name, ecode); @@ -1198,8 +1768,50 @@ ecode = code; if ((code = param_anti_alias_bits(plist, "GraphicsAlphaBits", &gab)) < 0) ecode = code; + if ((code = param_read_bool(plist, "AntidropoutDownscaler", &use_antidropout)) < 0) + ecode = code; if ((code = param_read_int(plist, "MaxPatternBitmap", &mpbm)) < 0) ecode = code; + if ((code = param_read_int(plist, "InterpolateControl", &ic)) < 0) + ecode = code; + if ((code = param_read_bool(plist, (param_name = "PageUsesTransparency"), + &page_uses_transparency)) < 0) { + ecode = code; + param_signal_error(plist, param_name, ecode); + } + if ((code = param_read_long(plist, "MaxBitmap", &sp.MaxBitmap)) < 0) + ecode = code; + +#define CHECK_PARAM_CASES(member, bad, label)\ + case 0:\ + if ((sp.params_are_read_only ? sp.member != save_sp.member : bad))\ + ecode = gs_error_rangecheck;\ + else\ + break;\ + goto label;\ + default:\ + ecode = code;\ +label:\ + param_signal_error(plist, param_name, ecode);\ + case 1:\ + break + + switch (code = param_read_long(plist, (param_name = "BufferSpace"), &sp.BufferSpace)) { + CHECK_PARAM_CASES(BufferSpace, sp.BufferSpace < 10000, bse); + } + + switch (code = param_read_int(plist, (param_name = "BandWidth"), &sp.band.BandWidth)) { + CHECK_PARAM_CASES(band.BandWidth, sp.band.BandWidth < 0, bwe); + } + + switch (code = param_read_int(plist, (param_name = "BandHeight"), &sp.band.BandHeight)) { + CHECK_PARAM_CASES(band.BandHeight, sp.band.BandHeight < 0, bhe); + } + + switch (code = param_read_long(plist, (param_name = "BandBufferSpace"), &sp.band.BandBufferSpace)) { + CHECK_PARAM_CASES(band.BandBufferSpace, sp.band.BandBufferSpace < 0, bbse); + } + switch (code = param_read_bool(plist, (param_name = ".LockSafetyParams"), &locksafe)) { case 0: @@ -1275,8 +1887,10 @@ ecode = code; if ((code = param_check_int(plist, "GrayValues", GrayValues, true)) < 0) ecode = code; - if ((code = param_check_long(plist, "PageCount", dev->PageCount, true)) < 0) - ecode = code; + + /* with saved-pages, PageCount can't be checked. No harm in letting it change */ + IGNORE_INT_PARAM("PageCount") + if ((code = param_check_int(plist, "RedValues", RGBValues, true)) < 0) ecode = code; if ((code = param_check_int(plist, "GreenValues", RGBValues, true)) < 0) @@ -1297,13 +1911,85 @@ ecode = code; } + code = param_read_int(plist, "FirstPage", &dev->FirstPage); + if (code < 0) + ecode = code; + + code = param_read_int(plist, "LastPage", &dev->LastPage); + if (code < 0) + ecode = code; + + code = param_read_bool(plist, "DisablePageHandler", &temp_bool); + if (code < 0) + ecode = code; + if (code == 0) + dev->DisablePageHandler = temp_bool; + + if ((code = param_read_string(plist, "PageList", &pagelist)) != 1 && pagelist.size > 0) { + if (dev->PageList) + rc_decrement(dev->PageList, "default put_params PageList"); + dev->PageList = (gdev_pagelist *)gs_alloc_bytes(dev->memory->non_gc_memory, sizeof(gdev_pagelist), "structure to hold page list"); + if (!dev->PageList) + return gs_note_error(gs_error_VMerror); + dev->PageList->Pages = (void *)gs_alloc_bytes(dev->memory->non_gc_memory, pagelist.size + 1, "String to hold page list"); + if (!dev->PageList->Pages){ + gs_free(dev->memory->non_gc_memory, dev->PageList, 1, sizeof(gdev_pagelist), "free structure to hold page list"); + dev->PageList = 0; + return gs_note_error(gs_error_VMerror); + } + memset(dev->PageList->Pages, 0x00, pagelist.size + 1); + memcpy(dev->PageList->Pages, pagelist.data, pagelist.size); + dev->PageList->PagesSize = pagelist.size + 1; + rc_init_free(dev->PageList, dev->memory->non_gc_memory, 1, rc_free_pages_list); + } + + code = param_read_bool(plist, "FILTERIMAGE", &temp_bool); + if (code < 0) + ecode = code; + if (code == 0) { + if (temp_bool) + dev->ObjectFilter |= FILTERIMAGE; + else + dev->ObjectFilter &= ~FILTERIMAGE; + } + + code = param_read_bool(plist, "FILTERTEXT", &temp_bool); + if (code < 0) + ecode = code; + if (code == 0) { + if (temp_bool) + dev->ObjectFilter |= FILTERTEXT; + else + dev->ObjectFilter &= ~FILTERTEXT; + } + + code = param_read_bool(plist, "FILTERVECTOR", &temp_bool); + if (code < 0) + ecode = code; + if (code == 0) { + if (temp_bool) + dev->ObjectFilter |= FILTERVECTOR; + else + dev->ObjectFilter &= ~FILTERVECTOR; + } + /* We must 'commit', in order to detect unknown parameters, */ /* even if there were errors. */ code = param_commit(plist); - if (ecode < 0) + if (ecode < 0) { + /* restore_page_device (zdevice2.c) will turn off LockSafetyParams, and relies on putparams + * to put it back if we are restoring a device. The locksafe value is picked up above from the + * device we are restoring to, and we *must* make sure it is preserved, even if setting the + * params failed. Otherwise an attacker can use a failed grestore to reset LockSafetyParams. + * See bug #699687. + */ + dev->LockSafetyParams = locksafe; return ecode; - if (code < 0) + } + if (code < 0) { + dev->LockSafetyParams = locksafe; return code; + } /* * Now actually make the changes. Changing resolution, rotation @@ -1313,6 +1999,8 @@ * replacing the values with the same ones. */ + dev->color_info.use_antidropout_downscaler = use_antidropout; + if (hwra.data != 0 && (dev->HWResolution[0] != hwra.data[0] || dev->HWResolution[1] != hwra.data[1]) @@ -1381,13 +2069,16 @@ dev->color_info.max_color), gab); dev->LockSafetyParams = locksafe; dev->MaxPatternBitmap = mpbm; + dev->interpolate_control = ic; + dev->space_params = sp; + dev->page_uses_transparency = page_uses_transparency; gx_device_decache_colors(dev); /* Take care of the rendering intents and blackpts. For those that are not set special, the default provides an override */ if (dev->icc_struct != NULL) { /* Set the default object */ - code = gx_default_put_intent(rend_intent[0], dev, gsDEFAULTPROFILE); + code = gx_default_put_intent(rend_intent[0], dev, gsDEFAULTPROFILE); if (code < 0) return code; code = gx_default_put_blackptcomp(blackptcomp[0], dev, gsDEFAULTPROFILE); @@ -1425,6 +2116,7 @@ return code; } } + gsicc_setcoloraccuracy(dev->memory, color_accuracy); code = gx_default_put_graytok(devicegraytok, dev); if (code < 0) return code; @@ -1437,7 +2129,8 @@ code = gx_default_put_graydetection(graydetection, dev); if (code < 0) return code; - return gx_default_put_prebandthreshold(prebandthreshold, dev);} + return gx_default_put_prebandthreshold(prebandthreshold, dev); +} void gx_device_request_leadingedge(gx_device *dev, int le_req) @@ -1472,6 +2165,7 @@ default: code = gs_error_rangecheck; } + /* fall through */ default: param_signal_error(plist, param_name, code); case 1: @@ -1497,7 +2191,7 @@ ecode = gs_note_error(gs_error_rangecheck); #define max_coord (max_fixed / fixed_1) #if max_coord < max_int - else if (width_new > max_coord || height_new > max_coord) + else if (width_new > (long)max_coord || height_new > (long)max_coord) ecode = gs_note_error(gs_error_limitcheck); #endif #undef max_coord diff -Nru ghostscript-9.10~dfsg/base/gsdpnext.h ghostscript-9.25~dfsg+1/base/gsdpnext.h --- ghostscript-9.10~dfsg/base/gsdpnext.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdpnext.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsdps1.c ghostscript-9.25~dfsg+1/base/gsdps1.c --- ghostscript-9.10~dfsg/base/gsdps1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdps1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -49,7 +49,7 @@ /* Set the bounding box for the current path. */ int -gs_setbbox(gs_state * pgs, floatp llx, floatp lly, floatp urx, floatp ury) +gs_setbbox(gs_gstate * pgs, double llx, double lly, double urx, double ury) { gs_rect ubox, dbox; gs_fixed_rect obox, bbox; @@ -98,12 +98,12 @@ /* Append a list of rectangles to a path. */ static int -gs_rectappend_compat(gs_state * pgs, const gs_rect * pr, uint count, bool clip) +gs_rectappend_compat(gs_gstate * pgs, const gs_rect * pr, uint count, bool clip) { bool CPSI_mode = gs_currentcpsimode(pgs->memory); for (; count != 0; count--, pr++) { - floatp px = pr->p.x, py = pr->p.y, qx = pr->q.x, qy = pr->q.y; + double px = pr->p.x, py = pr->p.y, qx = pr->q.x, qy = pr->q.y; int code; if (CPSI_mode) { @@ -156,14 +156,14 @@ return 0; } int -gs_rectappend(gs_state * pgs, const gs_rect * pr, uint count) +gs_rectappend(gs_gstate * pgs, const gs_rect * pr, uint count) { return gs_rectappend_compat(pgs, pr, count, false); } /* Clip to a list of rectangles. */ int -gs_rectclip(gs_state * pgs, const gs_rect * pr, uint count) +gs_rectclip(gs_gstate * pgs, const gs_rect * pr, uint count) { int code; gx_path save; @@ -185,7 +185,7 @@ /* Fill a list of rectangles. */ /* We take the trouble to do this efficiently in the simple cases. */ int -gs_rectfill(gs_state * pgs, const gs_rect * pr, uint count) +gs_rectfill(gs_gstate * pgs, const gs_rect * pr, uint count) { const gs_rect *rlist = pr; gx_clip_path *pcpath; @@ -193,15 +193,15 @@ int code; gx_device * pdev = pgs->device; gx_device_color *pdc = gs_currentdevicecolor_inline(pgs); - const gs_imager_state *pis = (const gs_imager_state *)pgs; - bool hl_color_available = gx_hld_is_hl_color_available(pis, pdc); + const gs_gstate *pgs2 = (const gs_gstate *)pgs; + bool hl_color_available = gx_hld_is_hl_color_available(pgs2, pdc); bool hl_color = (hl_color_available && dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_hlcolor, NULL, 0)); bool center_of_pixel = (pgs->fill_adjust.x == 0 && pgs->fill_adjust.y == 0); /* Processing a fill object operation */ - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_PATH_TAG); + ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ code = gx_set_dev_color(pgs); if (code != 0) @@ -214,7 +214,7 @@ pdc->type == gx_dc_type_pure || pdc->type == gx_dc_type_ht_binary || pdc->type == gx_dc_type_ht_colored) && - gs_state_color_load(pgs) >= 0 && + gs_gstate_color_load(pgs) >= 0 && (*dev_proc(pdev, get_alpha_bits)) (pdev, go_graphics) <= 1 && (!pgs->overprint || !pgs->effective_overprint_mode) @@ -251,7 +251,7 @@ if (draw_rect.p.x <= draw_rect.q.x && draw_rect.p.y <= draw_rect.q.y) { code = dev_proc(pdev, fill_rectangle_hl_color)(pdev, - &draw_rect, pis, pdc, pcpath); + &draw_rect, pgs2, pdc, pcpath); if (code < 0) return code; } @@ -300,10 +300,11 @@ if (do_save) { if ((code = gs_gsave(pgs)) < 0) return code; - gs_newpath(pgs); + code = gs_newpath(pgs); } - if ((code = gs_rectappend(pgs, rlist, rcount)) < 0 || - (code = gs_fill(pgs)) < 0 + if ((code >= 0) && + (((code = gs_rectappend(pgs, rlist, rcount)) < 0) || + ((code = gs_fill(pgs)) < 0)) ) DO_NOTHING; if (do_save) @@ -317,7 +318,7 @@ /* Stroke a list of rectangles. */ /* (We could do this a lot more efficiently.) */ int -gs_rectstroke(gs_state * pgs, const gs_rect * pr, uint count, +gs_rectstroke(gs_gstate * pgs, const gs_rect * pr, uint count, const gs_matrix * pmat) { bool do_save = pmat != NULL || !gx_path_is_null(pgs->path); diff -Nru ghostscript-9.10~dfsg/base/gsdps.c ghostscript-9.25~dfsg+1/base/gsdps.c --- ghostscript-9.10~dfsg/base/gsdps.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdps.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,10 +27,10 @@ /* ---------------- View clipping ---------------- */ /* Forward references */ -static int common_viewclip(gs_state *, int); +static int common_viewclip(gs_gstate *, int); int -gs_initviewclip(gs_state * pgs) +gs_initviewclip(gs_gstate * pgs) { gx_clip_path *pcpath = pgs->view_clip; @@ -42,13 +42,13 @@ } int -gs_viewclip(gs_state * pgs) +gs_viewclip(gs_gstate * pgs) { return common_viewclip(pgs, gx_rule_winding_number); } int -gs_eoviewclip(gs_state * pgs) +gs_eoviewclip(gs_gstate * pgs) { return common_viewclip(pgs, gx_rule_even_odd); } @@ -56,7 +56,7 @@ /* This code is (almost) copied from common_clip in gspath.c. */ /* Someday we'll find a way to merge them. */ static int -common_viewclip(gs_state * pgs, int rule) +common_viewclip(gs_gstate * pgs, int rule) { gs_fixed_rect bbox; gx_clip_path rpath; @@ -86,7 +86,7 @@ } int -gs_viewclippath(gs_state * pgs) +gs_viewclippath(gs_gstate * pgs) { gx_path cpath; gx_clip_path *pcpath = pgs->view_clip; diff -Nru ghostscript-9.10~dfsg/base/gsdps.h ghostscript-9.25~dfsg+1/base/gsdps.h --- ghostscript-9.10~dfsg/base/gsdps.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdps.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,9 +23,9 @@ #include "gsiparm2.h" /* View clipping */ -int gs_initviewclip(gs_state *); -int gs_eoviewclip(gs_state *); -int gs_viewclip(gs_state *); -int gs_viewclippath(gs_state *); +int gs_initviewclip(gs_gstate *); +int gs_eoviewclip(gs_gstate *); +int gs_viewclip(gs_gstate *); +int gs_viewclippath(gs_gstate *); #endif /* gsdps_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsdsrc.c ghostscript-9.25~dfsg+1/base/gsdsrc.c --- ghostscript-9.10~dfsg/base/gsdsrc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdsrc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsdsrc.h ghostscript-9.25~dfsg+1/base/gsdsrc.h --- ghostscript-9.10~dfsg/base/gsdsrc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsdsrc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsequivc.c ghostscript-9.25~dfsg+1/base/gsequivc.c --- ghostscript-9.10~dfsg/base/gsequivc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsequivc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -60,7 +60,7 @@ * do the following: * a. Create a copy of the color space and change the copy so that it * uses its alternate colorspace. - * b. Create a copy of the current imager state and modify its color + * b. Create a copy of the current gs_gstate and modify its color * mapping (cmap) procs to use a special set of 'capture' procs. * c. Based upon the type of color space (Separation or DeviceN) create * a 'color' which consists of the desired spot color set to 100% and @@ -111,7 +111,7 @@ static void update_Separation_spot_equivalent_cmyk_colors(gx_device * pdev, - const gs_state * pgs, const gs_color_space * pcs, + const gs_gstate * pgs, const gs_color_space * pcs, gs_devn_params * pdevn_params, equivalent_cmyk_color_params * pparams) { @@ -152,9 +152,9 @@ /* This is used for getting the equivalent CMYK values for the spots that may exist in a DeviceN output ICC profile */ -static void +static int update_ICC_spot_equivalent_cmyk_colors(gx_device * pdev, - const gs_state * pgs, const gs_color_space * pcs, + const gs_gstate * pgs, const gs_color_space * pcs, gs_devn_params * pdevn_params, equivalent_cmyk_color_params * pparams) { @@ -165,6 +165,8 @@ code = dev_proc(pdev, get_profile)(pdev, &dev_profile); + if (code < 0) + return code; /* * Check if the ICC spot names matche any of the * separations for which we need an equivalent CMYK color. @@ -197,12 +199,12 @@ } } } + return 0; } - static void update_DeviceN_spot_equivalent_cmyk_colors(gx_device * pdev, - const gs_state * pgs, const gs_color_space * pcs, + const gs_gstate * pgs, const gs_color_space * pcs, gs_devn_params * pdevn_params, equivalent_cmyk_color_params * pparams) { @@ -282,8 +284,8 @@ } /* If possible, update the equivalent CMYK color for a spot color */ -void -update_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs, +int +update_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_gstate * pgs, gs_devn_params * pdevn_params, equivalent_cmyk_color_params * pparams) { const gs_color_space * pcs; @@ -291,14 +293,17 @@ int code; code = dev_proc(pdev, get_profile)(pdev, &dev_profile); + if (code < 0) + return code; + /* If all of the color_info is valid then there is nothing to do. */ if (pparams->all_color_info_valid) - return; + return 0; /* Verify that we really have some separations. */ if (pdevn_params->separations.num_separations == 0) { pparams->all_color_info_valid = true; - return; + return 0; } /* * Verify that the given color space is a Separation or a DeviceN color @@ -322,17 +327,21 @@ dev_profile->spotnames != NULL) { /* In this case, we are trying to set up the equivalent colors for the spots in the output ICC profile */ - update_ICC_spot_equivalent_cmyk_colors(pdev, pgs, pcs, pdevn_params, - pparams); + code = update_ICC_spot_equivalent_cmyk_colors(pdev, pgs, pcs, + pdevn_params, + pparams); + if (code < 0) + return code; pparams->all_color_info_valid = check_all_colors_known (pdevn_params->separations.num_separations, pparams); } } + return 0; } static void save_spot_equivalent_cmyk_color(int sep_num, - equivalent_cmyk_color_params * pparams, frac cmyk[4]) + equivalent_cmyk_color_params * pparams, const frac cmyk[4]) { pparams->color[sep_num].c = cmyk[0]; pparams->color[sep_num].m = cmyk[1]; @@ -376,7 +385,7 @@ static void cmap_gray_capture_cmyk_color(frac gray, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { equivalent_cmyk_color_params * pparams = ((color_capture_device *)dev)->pequiv_cmyk_colors; @@ -390,20 +399,20 @@ static void cmap_rgb_capture_cmyk_color(frac r, frac g, frac b, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { equivalent_cmyk_color_params * pparams = ((color_capture_device *)dev)->pequiv_cmyk_colors; int sep_num = ((color_capture_device *)dev)->sep_num; frac cmyk[4]; - color_rgb_to_cmyk(r, g, b, pis, cmyk, dev->memory); + color_rgb_to_cmyk(r, g, b, pgs, cmyk, dev->memory); save_spot_equivalent_cmyk_color(sep_num, pparams, cmyk); } static void cmap_cmyk_capture_cmyk_color(frac c, frac m, frac y, frac k, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select, + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select, const gs_color_space *pcs) { equivalent_cmyk_color_params * pparams = @@ -420,24 +429,32 @@ static void cmap_rgb_alpha_capture_cmyk_color(frac r, frac g, frac b, frac alpha, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - cmap_rgb_capture_cmyk_color(r, g, b, pdc, pis, dev, select); + cmap_rgb_capture_cmyk_color(r, g, b, pdc, pgs, dev, select); } static void cmap_separation_capture_cmyk_color(frac all, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - dmprintf(pis->memory, "cmap_separation_capture_cmyk_color - this routine should not be executed\n"); + dmprintf(pgs->memory, "cmap_separation_capture_cmyk_color - this routine should not be executed\n"); } +/* The call to this is actually going to occur if we happen to be using a + named color profile and doing a replacement. Since the destination profile + will have been CMYK based during the swap out to find the equivalent color, we can + go ahead and just grab the cmyk portion */ static void cmap_devicen_capture_cmyk_color(const frac * pcc, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - dmprintf(pis->memory, "cmap_devicen_capture_cmyk_color - this routine should not be executed\n"); + equivalent_cmyk_color_params * pparams = + ((color_capture_device *)dev)->pequiv_cmyk_colors; + int sep_num = ((color_capture_device *)dev)->sep_num; + + save_spot_equivalent_cmyk_color(sep_num, pparams, pcc); } /* @@ -445,29 +462,29 @@ * alternate color space. */ void -capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_state * pgs, +capture_spot_equivalent_cmyk_colors(gx_device * pdev, const gs_gstate * pgs, const gs_client_color * pcc, const gs_color_space * pcs, int sep_num, equivalent_cmyk_color_params * pparams) { - gs_imager_state temp_state = *((const gs_imager_state *)pgs); + gs_gstate temp_state = *((const gs_gstate *)pgs); color_capture_device temp_device = { 0 }; gx_device_color dev_color; gsicc_rendering_param_t render_cond; - int code; cmm_dev_profile_t *dev_profile; cmm_profile_t *curr_output_profile; cmm_dev_profile_t temp_profile = { /* Initialize to 0's/NULL's */ { 0 } /* device_profile[] */, 0 /* proof_profile */, - 0 /* link_profile */, 0 /* oi_profile */, - { {0} } /* rendercond[] */, 0 /* devicegraytok */, - 0 /* graydection */, 0 /* pageneutralcolor */, + 0 /* link_profile */, 0 /* oi_profile */, + 0 /* blend_profile */, 0 /* postren_profile */, + { {0} } /* rendercond[] */, 0 /* devicegraytok */, + 0 /* graydection */, 0 /* pageneutralcolor */, 0 /* usefastcolor */, 0 /* supports_devn */, - 0 /* sim_overprint */, 0 /* spotnames */, - 0 /* prebandthreshold */, 0 /* memory */, + 0 /* sim_overprint */, 0 /* spotnames */, + 0 /* prebandthreshold */, 0 /* memory */, { 0 } /* rc_header */ }; - code = dev_proc(pdev, get_profile)(pdev, &dev_profile); + dev_proc(pdev, get_profile)(pdev, &dev_profile); gsicc_extract_profile(pdev->graphics_type_tag, dev_profile, &(curr_output_profile), &render_cond); /* @@ -508,7 +525,7 @@ set_dev_proc(&temp_device, get_profile, gx_default_get_profile); /* - * Create a temp copy of the imager state. We do this so that we + * Create a temp copy of the gs_gstate. We do this so that we * can modify the color space mapping (cmap) procs. We use our * replacment procs to capture the color. The installation of a * Separation or DeviceN color space also sets a use_alt_cspace flag @@ -521,3 +538,11 @@ pcs->type->remap_color (pcc, pcs, &dev_color, &temp_state, (gx_device *)&temp_device, gs_color_select_texture); } + +/* Used for detecting if we are trying to find the equivalant color during + named color replacement */ +bool +named_color_equivalent_cmyk_colors(const gs_gstate * pgs) +{ + return pgs->cmap_procs == &cmap_capture_cmyk_color; +} diff -Nru ghostscript-9.10~dfsg/base/gsequivc.h ghostscript-9.25~dfsg+1/base/gsequivc.h --- ghostscript-9.10~dfsg/base/gsequivc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsequivc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -48,8 +48,8 @@ /* * If possible, update the equivalent CMYK color for spot colors. */ -void update_spot_equivalent_cmyk_colors(gx_device * pdev, - const gs_state * pgs, gs_devn_params * pdevn_params, +int update_spot_equivalent_cmyk_colors(gx_device * pdev, + const gs_gstate * pgs, gs_devn_params * pdevn_params, equivalent_cmyk_color_params * pparams); /* @@ -57,8 +57,12 @@ * color space. */ void capture_spot_equivalent_cmyk_colors(gx_device * pdev, - const gs_state * pgs, const gs_client_color * pcc, + const gs_gstate * pgs, const gs_client_color * pcc, const gs_color_space * pcs, int sep_num, equivalent_cmyk_color_params * pparams); +/* Used in named color replacement to detect that we are doing the equivalent + computation */ +bool named_color_equivalent_cmyk_colors(const gs_gstate * pgs); + #endif /* define gsequivc_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gserrors.h ghostscript-9.25~dfsg+1/base/gserrors.h --- ghostscript-9.10~dfsg/base/gserrors.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gserrors.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,30 +22,102 @@ /* A procedure that may return an error always returns */ /* a non-negative value (zero, unless otherwise noted) for success, */ /* or negative for failure. */ -/* We use ints rather than an enum to avoid a lot of casting. */ +/* We don't use a typedef internally to avoid a lot of casting. */ -#define gs_error_unknownerror (-1) /* unknown error */ -#define gs_error_interrupt (-6) -#define gs_error_invalidaccess (-7) -#define gs_error_invalidfileaccess (-9) -#define gs_error_invalidfont (-10) -#define gs_error_ioerror (-12) -#define gs_error_limitcheck (-13) -#define gs_error_nocurrentpoint (-14) -#define gs_error_rangecheck (-15) -#define gs_error_typecheck (-20) -#define gs_error_undefined (-21) -#define gs_error_undefinedfilename (-22) -#define gs_error_undefinedresult (-23) -#define gs_error_VMerror (-25) -#define gs_error_unregistered (-28) +enum gs_error_type { + gs_error_ok = 0, + gs_error_unknownerror = -1, /* unknown error */ + gs_error_dictfull = -2, + gs_error_dictstackoverflow = -3, + gs_error_dictstackunderflow = -4, + gs_error_execstackoverflow = -5, + gs_error_interrupt = -6, + gs_error_invalidaccess = -7, + gs_error_invalidexit = -8, + gs_error_invalidfileaccess = -9, + gs_error_invalidfont = -10, + gs_error_invalidrestore = -11, + gs_error_ioerror = -12, + gs_error_limitcheck = -13, + gs_error_nocurrentpoint = -14, + gs_error_rangecheck = -15, + gs_error_stackoverflow = -16, + gs_error_stackunderflow = -17, + gs_error_syntaxerror = -18, + gs_error_timeout = -19, + gs_error_typecheck = -20, + gs_error_undefined = -21, + gs_error_undefinedfilename = -22, + gs_error_undefinedresult = -23, + gs_error_unmatchedmark = -24, + gs_error_VMerror = -25, /* must be the last Level 1 error */ + + /* ------ Additional Level 2 errors (also in DPS, ------ */ + + gs_error_configurationerror = -26, + gs_error_undefinedresource = -27, + + gs_error_unregistered = -28, + gs_error_invalidcontext = -29, +/* invalidid is for the NeXT DPS extension. */ + gs_error_invalidid = -30, + + /* ------ Pseudo-errors used internally ------ */ + + gs_error_hit_detected = -99, + + gs_error_Fatal = -100, +/* + * Internal code for the .quit operator. + * The real quit code is an integer on the operand stack. + * gs_interpret returns this only for a .quit with a zero exit code. + */ + gs_error_Quit = -101, + +/* + * Internal code for a normal exit from the interpreter. + * Do not use outside of interp.c. + */ + gs_error_InterpreterExit = -102, -#define gs_error_hit_detected (-99) +/* Need the remap color error for high level pattern support */ + gs_error_Remap_Color = -103, -#define gs_error_Fatal (-100) +/* + * Internal code to indicate we have underflowed the top block + * of the e-stack. + */ + gs_error_ExecStackUnderflow = -104, + +/* + * Internal code for the vmreclaim operator with a positive operand. + * We need to handle this as an error because otherwise the interpreter + * won't reload enough of its state when the operator returns. + */ + gs_error_VMreclaim = -105, + +/* + * Internal code for requesting more input from run_string. + */ + gs_error_NeedInput = -106, + +/* + * Internal code for a normal exit when usage info is displayed. + * This allows Window versions of Ghostscript to pause until + * the message can be read. + */ + gs_error_Info = -110, + +/* A special 'error', like reamp color above. This is used by a subclassing + * device to indicate that it has fully processed a device method, and parent + * subclasses should not perform any further action. Currently this is limited + * to compositor creation. + */ + gs_error_handled = -111 +}; -/* Need the remap color error for high level pattern support */ -#define gs_error_Remap_Color (-103) +/* We do provide a typedef type for external API use */ +typedef enum gs_error_type gs_error_t; int gs_log_error(int, const char *, int); #if !defined(DEBUG) || defined(GS_THREADSAFE) diff -Nru ghostscript-9.10~dfsg/base/gsexit.h ghostscript-9.25~dfsg+1/base/gsexit.h --- ghostscript-9.10~dfsg/base/gsexit.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsexit.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfcid2.c ghostscript-9.25~dfsg+1/base/gsfcid2.c --- ghostscript-9.10~dfsg/base/gsfcid2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfcid2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,7 +31,7 @@ static int identity_CIDMap_proc(gs_font_cid2 *pfont, gs_glyph glyph) { - ulong cid = glyph - gs_min_cid_glyph; + ulong cid = glyph - GS_MIN_CID_GLYPH; if (cid >= pfont->cidata.common.CIDCount) return_error(gs_error_rangecheck); @@ -104,7 +104,7 @@ uint segment2; if (pstr->size < *pindex + 2) { - *pglyph = gs_no_glyph; + *pglyph = GS_NO_GLYPH; return (*pindex == pstr->size ? 2 : -1); } chr = U16(pstr->data + *pindex); @@ -135,7 +135,7 @@ value = chr + delta; break; } - *pglyph = gs_min_cid_glyph + (value & 0xffff); + *pglyph = GS_MIN_CID_GLYPH + (value & 0xffff); *pchr = chr; *pindex += 2; *pfidx = 0; @@ -164,8 +164,9 @@ gs_cmap_ranges_enum_setup(pre, pcmap, &tt_16bit_format4_range_procs); } static int -tt_16bit_format4_next_lookup(gs_cmap_lookups_enum_t *penum) +tt_16bit_format4_next_lookup(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum) { + penum->entry.value.data = 0L; if (penum->index[0] == 0) { penum->entry.key_size = 2; penum->entry.key_is_range = true; diff -Nru ghostscript-9.10~dfsg/base/gsfcid.c ghostscript-9.25~dfsg+1/base/gsfcid.c --- ghostscript-9.10~dfsg/base/gsfcid.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfcid.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -192,7 +192,7 @@ while (*pindex < pfont->cidata.common.CIDCount) { gs_glyph_data_t gdata; int fidx; - gs_glyph glyph = (gs_glyph)(gs_min_cid_glyph + (*pindex)++); + gs_glyph glyph = (gs_glyph)(GS_MIN_CID_GLYPH + (*pindex)++); int code; gdata.memory = pfont->memory; diff -Nru ghostscript-9.10~dfsg/base/gsfcmap1.c ghostscript-9.25~dfsg+1/base/gsfcmap1.c --- ghostscript-9.10~dfsg/base/gsfcmap1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfcmap1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -77,6 +77,7 @@ */ #ifndef GS_THREADSAFE +#ifdef DEBUG static void print_msg_str_in_range(const byte *str, const byte *key_lo, const byte *key_hi, @@ -90,6 +91,7 @@ dlprintf("\n"); } #endif +#endif static int gs_cmap_get_shortest_chr(const gx_code_map_t * pcmap, uint *pfidx) @@ -149,7 +151,7 @@ * Decode a character from a string using a code map, updating the index. * Return 0 for a CID or name, N > 0 for a character code where N is the * number of bytes in the code, or an error. Store the decoded bytes in - * *pchr. For undefined characters, set *pglyph = gs_no_glyph and return 0. + * *pchr. For undefined characters, set *pglyph = GS_NO_GLYPH and return 0. */ static int code_map_decode_next_multidim_regime(const gx_code_map_t * pcmap, @@ -311,13 +313,13 @@ switch (pclr->value_type) { case CODE_VALUE_CID: - *pglyph = gs_min_cid_glyph + + *pglyph = GS_MIN_CID_GLYPH + bytes2int(pvalue, pclr->value_size) + gs_multidim_CID_offset(str + pre_size, key, key + step - key_size, key_size); return 0; case CODE_VALUE_NOTDEF: - *pglyph = gs_min_cid_glyph + + *pglyph = GS_MIN_CID_GLYPH + bytes2int(pvalue, pclr->value_size); return 0; case CODE_VALUE_GLYPH: @@ -338,7 +340,7 @@ *pchr = pm_chr; *pindex = pm_index; *pfidx = pm_fidx; - *pglyph = gs_no_glyph; + *pglyph = GS_NO_GLYPH; #ifndef GS_THREADSAFE #ifdef DEBUG @@ -373,7 +375,6 @@ uint pm_index; uint pm_fidx; - gs_char pm_chr; /* For first, check defined map */ if_debug0('J', "[J]GCDN() check def CMap\n"); @@ -381,14 +382,13 @@ code_map_decode_next_multidim_regime(&pcmap->def, pstr, pindex, pfidx, pchr, pglyph); /* This is defined character */ - if (code != 0 || *pglyph != gs_no_glyph) + if (code != 0 || *pglyph != GS_NO_GLYPH) return code; /* In here, this is NOT defined character */ /* save partially matched results */ pm_index = *pindex; pm_fidx = *pfidx; - pm_chr = *pchr; /* check notdef map. */ if_debug0('J', "[J]GCDN() check notdef CMap\n"); @@ -397,7 +397,7 @@ code_map_decode_next_multidim_regime(&pcmap->notdef, pstr, pindex, pfidx, pchr, pglyph); /* This is defined "notdef" character. */ - if (code != 0 || *pglyph != gs_no_glyph) + if (code != 0 || *pglyph != GS_NO_GLYPH) return code; /* @@ -408,7 +408,7 @@ /* there was some partially matched */ - *pglyph = gs_min_cid_glyph; /* CID = 0 */ + *pglyph = GS_MIN_CID_GLYPH; /* CID = 0 */ *pindex = pm_index; *pfidx = pm_fidx; *pchr = '\0'; @@ -425,18 +425,18 @@ * at the end of Fonts chapter. */ - const byte *str = pstr->data + save_index; uint ssize = pstr->size - save_index; int chr_size_shortest = gs_cmap_get_shortest_chr(&pcmap->def, pfidx); if (chr_size_shortest <= ssize) { - *pglyph = gs_min_cid_glyph; /* CID = 0, this is CMap fallback */ + *pglyph = GS_MIN_CID_GLYPH; /* CID = 0, this is CMap fallback */ *pindex = save_index + chr_size_shortest; *pchr = '\0'; #ifndef GS_THREADSAFE #ifdef DEBUG if (gs_debug_c('J')) { + const byte *str = pstr->data + save_index; dlprintf1("[J]GCDN() no partial match, skip %d byte (", chr_size_shortest); debug_print_string_hex_nomem(str, chr_size_shortest); @@ -448,7 +448,7 @@ } else { /* Undecodable string is shorter than the shortest character, - * return 'gs_no_glyph' and update index to end-of-string + * return 'GS_NO_GLYPH' and update index to end-of-string */ #ifndef GS_THREADSAFE #ifdef DEBUG @@ -458,7 +458,7 @@ } #endif #endif - *pglyph = gs_no_glyph; + *pglyph = GS_NO_GLYPH; *pindex += ssize; return 0; /* fixme: should return a code != 0 if caller needs to know */ } @@ -496,6 +496,7 @@ { const gx_cmap_lookup_range_t *lookup = &pcm->lookup[penum->index[0]]; + penum->entry.value.data = 0L; if (penum->index[0] >= pcm->num_lookup) return 1; penum->entry.key_size = lookup->key_prefix_size + lookup->key_size; @@ -508,13 +509,13 @@ return 0; } static int -adobe1_next_lookup_def(gs_cmap_lookups_enum_t *penum) +adobe1_next_lookup_def(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum) { return adobe1_next_lookup(penum, &((const gs_cmap_adobe1_t *)penum->cmap)->def); } static int -adobe1_next_lookup_notdef(gs_cmap_lookups_enum_t *penum) +adobe1_next_lookup_notdef(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum) { return adobe1_next_lookup(penum, &((const gs_cmap_adobe1_t *)penum->cmap)->notdef); diff -Nru ghostscript-9.10~dfsg/base/gsfcmap.c ghostscript-9.25~dfsg+1/base/gsfcmap.c --- ghostscript-9.10~dfsg/base/gsfcmap.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfcmap.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -64,11 +64,11 @@ uint value; if (str->size < *pindex + num_bytes) { - *pglyph = gs_no_glyph; + *pglyph = GS_NO_GLYPH; return (*pindex == str->size ? 2 : -1); } value = get_integer_bytes(str->data + *pindex, num_bytes); - *pglyph = gs_min_cid_glyph + value; + *pglyph = GS_MIN_CID_GLYPH + value; *pchr = value; *pindex += num_bytes; *pfidx = 0; @@ -98,8 +98,9 @@ gs_cmap_ranges_enum_setup(pre, pcmap, &identity_range_procs); } static int -identity_next_lookup(gs_cmap_lookups_enum_t *penum) +identity_next_lookup(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum) { + penum->entry.value.data = 0L; if (penum->index[0] == 0) { const gs_cmap_identity_t *const pcimap = (const gs_cmap_identity_t *)penum->cmap; @@ -120,8 +121,9 @@ return 1; } static int -no_next_lookup(gs_cmap_lookups_enum_t *penum) +no_next_lookup(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum) { + penum->entry.value.data = 0L; return 1; } static int @@ -267,9 +269,9 @@ pcmap->procs->enum_lookups(pcmap, which, penum); } int -gs_cmap_enum_next_lookup(gs_cmap_lookups_enum_t *penum) +gs_cmap_enum_next_lookup(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum) { - return penum->procs->next_lookup(penum); + return penum->procs->next_lookup(mem, penum); } int gs_cmap_enum_next_entry(gs_cmap_lookups_enum_t *penum) @@ -385,7 +387,7 @@ (const byte *)"Artifex", 7)) return false; for (gs_cmap_lookups_enum_init(pcmap, which, &lenum); - (code = gs_cmap_enum_next_lookup(&lenum)) == 0; ) { + (code = gs_cmap_enum_next_lookup(NULL, &lenum)) == 0; ) { if (font_index_only >= 0 && lenum.entry.font_index != font_index_only) continue; if (font_index_only < 0 && lenum.entry.font_index > 0) @@ -423,13 +425,6 @@ static const int gs_cmap_ToUnicode_code_bytes = 2; -typedef struct gs_cmap_ToUnicode_s { - GS_CMAP_COMMON; - int num_codes; - int key_size; - bool is_identity; -} gs_cmap_ToUnicode_t; - gs_private_st_suffix_add0(st_cmap_ToUnicode, gs_cmap_ToUnicode_t, "gs_cmap_ToUnicode_t", cmap_ToUnicode_enum_ptrs, cmap_ToUnicode_reloc_ptrs, st_cmap); @@ -466,19 +461,19 @@ } static int -gs_cmap_ToUnicode_next_lookup(gs_cmap_lookups_enum_t *penum) +gs_cmap_ToUnicode_next_lookup(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum) { const gs_cmap_ToUnicode_t *cmap = (gs_cmap_ToUnicode_t *)penum->cmap; if (penum->index[0]++ > 0) return 1; - penum->entry.value.data = penum->temp_value; - penum->entry.value.size = gs_cmap_ToUnicode_code_bytes; penum->index[1] = 0; penum->entry.key_is_range = true; penum->entry.value_type = CODE_VALUE_CHARS; penum->entry.key_size = cmap->key_size; penum->entry.value.size = gs_cmap_ToUnicode_code_bytes; penum->entry.font_index = 0; + penum->entry.value.data = gs_alloc_bytes(mem, cmap->value_size, "working ToUnicode buffer"); + penum->entry.value.size = cmap->value_size; return 0; } @@ -491,12 +486,15 @@ uchar c0, c1, c2; for (i = index; i < num_codes; i++) - if (map[i + i + 0] != 0 || map[i + i + 1] != 0) + if (map[i * (cmap->value_size + 2)] != 0 || map[i * (cmap->value_size + 2) + 1] != 0) break; if (i >= num_codes) return 1; - c0 = map[i + i + 0]; - c1 = map[i + i + 1]; + c0 = map[i * (cmap->value_size + 2) + 2]; + if (cmap->value_size > 1) + c1 = map[i * (cmap->value_size + 2) + 3]; + else + c1 = 0; for (j = i + 1, c2 = c1 + 1; j < num_codes; j++, c2++) { /* Due to PDF spec, *bfrange boundaries may differ in the last byte only. */ @@ -504,7 +502,7 @@ break; if ((uchar)c2 == 0) break; - if (map[j + j + 0] != c0 || map[j + j + 1] != c2) + if (map[j * (cmap->value_size + 2) + 2] != c0 || map[i * (cmap->value_size + 2) + 3] != c2) break; } penum->index[1] = j; @@ -517,8 +515,11 @@ penum->entry.key[0][0] = (uchar)(i); penum->entry.key[1][0] = (uchar)(j - 1); } - memcpy(penum->temp_value, map + i * gs_cmap_ToUnicode_code_bytes, - gs_cmap_ToUnicode_code_bytes); + c0 = map[i * (cmap->value_size + 2)]; + c1 = map[i * (cmap->value_size + 2) + 1]; + penum->entry.value.size = (c0 << 8) + c1; + memcpy((void *)penum->entry.value.data, map + (i * (cmap->value_size + 2)) + 2, + penum->entry.value.size); return 0; } @@ -552,7 +553,7 @@ * Allocate and initialize a ToUnicode CMap. */ int -gs_cmap_ToUnicode_alloc(gs_memory_t *mem, int id, int num_codes, int key_size, gs_cmap_t **ppcmap) +gs_cmap_ToUnicode_alloc(gs_memory_t *mem, int id, int num_codes, int key_size, int value_size, gs_cmap_t **ppcmap) { int code; uchar *map, *cmap_name = NULL; gs_cmap_ToUnicode_t *cmap; @@ -580,18 +581,19 @@ 0, cmap_name, name_len, NULL, 0, &gs_cmap_ToUnicode_procs, mem); if (code < 0) return code; - map = (uchar *)gs_alloc_bytes(mem, num_codes * gs_cmap_ToUnicode_code_bytes, + map = (uchar *)gs_alloc_bytes(mem, num_codes * (value_size + 2), "gs_cmap_ToUnicode_alloc"); if (map == NULL) { gs_cmap_free(*ppcmap, mem); return_error(gs_error_VMerror); } - memset(map, 0, num_codes * gs_cmap_ToUnicode_code_bytes); + memset(map, 0, num_codes * (value_size + 2)); cmap = (gs_cmap_ToUnicode_t *)*ppcmap; cmap->glyph_name_data = map; cmap->CMapType = 2; cmap->num_fonts = 1; cmap->key_size = key_size; + cmap->value_size = value_size; cmap->num_codes = num_codes; cmap->ToUnicode = true; cmap->is_identity = true; @@ -605,18 +607,60 @@ return 0; } +/* Ths function is called when we discover that the value length we are using to + * store Unicode code points is too small for a new value. It increases + * the size of the map, and of each entry in the map, which is why we have to + * use a for loop rather than a memcpy. Note that when we increase the number + * of bytes used for a map entry, unused bytes are stored at the end, the initial + * 2 bytes are the length (in bytes) actually used by ths entry. + */ +int +gs_cmap_ToUnicode_realloc(gs_memory_t *mem, int new_value_size, gs_cmap_t **ppcmap) +{ + gs_cmap_ToUnicode_t *cmap = (gs_cmap_ToUnicode_t *)*ppcmap; + uchar *new_ptr, *new_map, *old_map = cmap->glyph_name_data; + int i; + + new_map = (uchar *)gs_alloc_bytes(mem, cmap->num_codes * (new_value_size + 2), + "gs_cmap_ToUnicode_alloc"); + if (new_map == NULL) { + return_error(gs_error_VMerror); + } + new_ptr = new_map; + memset(new_map, 0, cmap->num_codes * (new_value_size + 2)); + + for (i=0;inum_codes;i++) { + memcpy(new_ptr, old_map, cmap->value_size + 2); + old_map += cmap->value_size + 2; + new_ptr += new_value_size + 2; + } + gs_free_object(mem, cmap->glyph_name_data, "Free (realloc) ToUnicode glyph data"); + cmap->glyph_name_data = new_map; + cmap->value_size = new_value_size; + return 0; +} + /* * Write a code pair to ToUnicode CMap. */ void -gs_cmap_ToUnicode_add_pair(gs_cmap_t *pcmap, int code0, int code1) -{ gs_cmap_ToUnicode_t *cmap = (gs_cmap_ToUnicode_t *)pcmap; - uchar *map = pcmap->glyph_name_data; +gs_cmap_ToUnicode_add_pair(gs_cmap_t *pcmap, int code0, ushort *u, unsigned int length) +{ + gs_cmap_ToUnicode_t *cmap = (gs_cmap_ToUnicode_t *)pcmap; + uchar *map = pcmap->glyph_name_data, *unicode = (uchar *)u; const int num_codes = ((gs_cmap_ToUnicode_t *)pcmap)->num_codes; + int i, code1 = 0; if (code0 >= num_codes) return; /* must not happen. */ - map[code0 * gs_cmap_ToUnicode_code_bytes + 0] = (uchar)(code1 >> 8); - map[code0 * gs_cmap_ToUnicode_code_bytes + 1] = (uchar)(code1 & 0xFF); - cmap->is_identity &= (code0 == code1); + map[code0 * (cmap->value_size + 2)] = (uchar)(length >> 8); + map[code0 * (cmap->value_size + 2) + 1] = (uchar)(length & 0xFF); + + memcpy(&map[(code0 * (cmap->value_size + 2)) + 2], unicode, length); + if (length <= 4) { + for (i=0;iis_identity &= (code0 == code1); + } } diff -Nru ghostscript-9.10~dfsg/base/gsfcmap.h ghostscript-9.25~dfsg+1/base/gsfcmap.h --- ghostscript-9.10~dfsg/base/gsfcmap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfcmap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,7 +47,7 @@ * Decode a character from a string using a CMap, updating the index. * Return 0 for a CID or name, N > 0 for a character code where N is the * number of bytes in the code, or an error. Store the decoded bytes in - * *pchr. For undefined characters, set *pglyph = gs_no_glyph and return 0. + * *pchr. For undefined characters, set *pglyph = GS_NO_GLYPH and return 0. */ int gs_cmap_decode_next(const gs_cmap_t *pcmap, const gs_const_string *str, uint *pindex, uint *pfidx, @@ -57,13 +57,16 @@ * Allocate and initialize a ToUnicode CMap. */ int gs_cmap_ToUnicode_alloc(gs_memory_t *mem, int id, int num_codes, int key_size, - gs_cmap_t **ppcmap); + int value_size, gs_cmap_t **ppcmap); int gs_cmap_ToUnicode_free(gs_memory_t *mem, gs_cmap_t *pcmap); +int gs_cmap_ToUnicode_realloc(gs_memory_t *mem, int new_value_size, gs_cmap_t **ppcmap); + + /* * Write a code pair to ToUnicode CMap. */ -void gs_cmap_ToUnicode_add_pair(gs_cmap_t *pcmap, int code0, int code2); +void gs_cmap_ToUnicode_add_pair(gs_cmap_t *pcmap, int code0, ushort *unicode, unsigned int length); #endif /* gsfcmap_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsflip.c ghostscript-9.25~dfsg+1/base/gsflip.c --- ghostscript-9.10~dfsg/base/gsflip.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsflip.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -308,17 +308,20 @@ /* This is only needed for DeviceN colors, so it can be slow. */ uint mask = (1 << bits_per_sample) - 1; int bi, pi; - sample_store_declare_setup(dptr, dbit, dbbyte, buffer, 0, bits_per_sample); + byte *dptr = buffer; + int dbit = 0; + byte dbbyte = 0; for (bi = 0; bi < nbytes * 8; bi += bits_per_sample) { for (pi = 0; pi < num_planes; ++pi) { const byte *sptr = planes[pi] + offset + (bi >> 3); uint value = (*sptr >> (8 - (bi & 7) - bits_per_sample)) & mask; - sample_store_next8(value, dptr, dbit, bits_per_sample, dbbyte); + if (sample_store_next8(value, &dptr, &dbit, bits_per_sample, &dbbyte) < 0) + return_error(gs_error_rangecheck); } } - sample_store_flush(dptr, dbit, bits_per_sample, dbbyte); + sample_store_flush(dptr, dbit, dbbyte); return 0; } @@ -329,7 +332,9 @@ { /* This is only needed for DeviceN colors, so it can be slow. */ int bi, pi; - sample_store_declare_setup(dptr, dbit, dbbyte, buffer, 0, 12); + byte *dptr = buffer; + int dbit = 0; + byte dbbyte = 0; for (bi = 0; bi < nbytes * 8; bi += 12) { for (pi = 0; pi < num_planes; ++pi) { @@ -338,10 +343,10 @@ (bi & 4 ? ((*sptr & 0xf) << 8) | sptr[1] : (*sptr << 4) | (sptr[1] >> 4)); - sample_store_next_12(value, dptr, dbit, dbbyte); + sample_store_next_12(value, &dptr, &dbit, &dbbyte); } } - sample_store_flush(dptr, dbit, 12, dbbyte); + sample_store_flush(dptr, dbit, dbbyte); return 0; } diff -Nru ghostscript-9.10~dfsg/base/gsflip.h ghostscript-9.25~dfsg+1/base/gsflip.h --- ghostscript-9.10~dfsg/base/gsflip.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsflip.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfname.c ghostscript-9.25~dfsg+1/base/gsfname.c --- ghostscript-9.10~dfsg/base/gsfname.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfname.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfname.h ghostscript-9.25~dfsg+1/base/gsfname.h --- ghostscript-9.10~dfsg/base/gsfname.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfname.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfont0.c ghostscript-9.25~dfsg+1/base/gsfont0.c --- ghostscript-9.10~dfsg/base/gsfont0.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfont0.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfont0c.c ghostscript-9.25~dfsg+1/base/gsfont0c.c --- ghostscript-9.10~dfsg/base/gsfont0c.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfont0c.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfont.c ghostscript-9.25~dfsg+1/base/gsfont.c --- ghostscript-9.10~dfsg/base/gsfont.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfont.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -219,7 +219,7 @@ { gs_font_dir *pdir = 0; -#if !arch_small_memory +#if !ARCH_SMALL_MEMORY # ifdef DEBUG if (!gs_debug_c('.')) # endif @@ -255,6 +255,8 @@ code = gx_char_cache_alloc(struct_mem, bits_mem, pdir, bmax, mmax, cmax, upper); if (code < 0) { + gs_free_object(struct_mem, pdir->ccache.table, "font_dir_alloc(chars)"); + gs_free_object(struct_mem, pdir->fmcache.mdata, "font_dir_alloc(mdata)"); gs_free_object(struct_mem, pdir, "font_dir_alloc(dir)"); return 0; } @@ -264,7 +266,7 @@ pdir->smax = smax; pdir->align_to_pixels = false; pdir->glyph_to_unicode_table = NULL; - pdir->grid_fit_tt = 2; + pdir->grid_fit_tt = 1; pdir->memory = struct_mem; pdir->tti = 0; pdir->ttm = 0; @@ -278,9 +280,28 @@ gs_font_dir_finalize(const gs_memory_t *cmem, void *vptr) { gs_font_dir *pdir = vptr; + gx_bits_cache_chunk *chunk = pdir->ccache.chunks; + gx_bits_cache_chunk *start_chunk = chunk; + gx_bits_cache_chunk *prev_chunk; + if (pdir == cmem->gs_lib_ctx->font_dir) { cmem->gs_lib_ctx->font_dir = NULL; } + + /* free the circular list of memory chunks */ + while (chunk) { + if (start_chunk == chunk->next) { + gs_free_object(pdir->ccache.bits_memory, chunk->data, "gs_font_dir_finalize"); + gs_free_object(pdir->ccache.bits_memory, chunk, "gs_font_dir_finalize"); + break; + } + + prev_chunk = chunk; + chunk = chunk->next; + gs_free_object(pdir->ccache.bits_memory, prev_chunk->data, "gs_font_dir_finalize"); + gs_free_object(pdir->ccache.bits_memory, prev_chunk, "gs_font_dir_finalize"); + } + pdir->ccache.chunks = NULL; } @@ -442,7 +463,7 @@ /* scalefont */ int -gs_scalefont(gs_font_dir * pdir, const gs_font * pfont, floatp scale, +gs_scalefont(gs_font_dir * pdir, const gs_font * pfont, double scale, gs_font ** ppfont) { gs_matrix mat; @@ -599,7 +620,7 @@ /* Set the current font. This is provided only for the benefit of cshow, */ /* which must reset the current font without disturbing the root font. */ void -gs_set_currentfont(gs_state * pgs, gs_font * pfont) +gs_set_currentfont(gs_gstate * pgs, gs_font * pfont) { pgs->font = pfont; pgs->char_tm_valid = false; @@ -607,7 +628,7 @@ /* setfont */ int -gs_setfont(gs_state * pgs, gs_font * pfont) +gs_setfont(gs_gstate * pgs, gs_font * pfont) { pgs->font = pgs->root_font = pfont; pgs->char_tm_valid = false; @@ -616,14 +637,14 @@ /* currentfont */ gs_font * -gs_currentfont(const gs_state * pgs) +gs_currentfont(const gs_gstate * pgs) { return pgs->font; } /* rootfont */ gs_font * -gs_rootfont(const gs_state * pgs) +gs_rootfont(const gs_gstate * pgs) { return pgs->root_font; } @@ -643,7 +664,7 @@ /* setcacheparams */ int -gs_setcachesize(gs_state * pgs, gs_font_dir * pdir, uint size) +gs_setcachesize(gs_gstate * pgs, gs_font_dir * pdir, uint size) { gs_memory_t *stable_mem = pdir->memory->stable_memory; if (size < 100000) /* limits derived from CPSI emulation (CET 27-07) */ @@ -844,7 +865,7 @@ /* * Scan the glyph space to compute the fixed width if any. */ - gs_glyph notdef = gs_no_glyph; + gs_glyph notdef = GS_NO_GLYPH; gs_glyph glyph; int fixed_width = 0; int index; @@ -859,6 +880,7 @@ ) { gs_glyph_info_t glyph_info; + memset(&glyph_info, 0x00, sizeof(gs_glyph_info_t)); code = font->procs.glyph_info(font, glyph, pmat, (GLYPH_INFO_WIDTH0 << wmode), &glyph_info); @@ -866,7 +888,7 @@ ecode = code; continue; } - if (notdef == gs_no_glyph && gs_font_glyph_is_notdef(bfont, glyph)) { + if (notdef == GS_NO_GLYPH && gs_font_glyph_is_notdef(bfont, glyph)) { notdef = glyph; info->MissingWidth = (int)glyph_info.width[wmode].x; info->members |= FONT_INFO_MISSING_WIDTH; @@ -964,10 +986,10 @@ { gs_const_string gnstr; - if (glyph == gs_no_glyph) + if (glyph == GS_NO_GLYPH) return false; - if (glyph >= gs_min_cid_glyph) - return (glyph == gs_min_cid_glyph); + if (glyph >= GS_MIN_CID_GLYPH) + return (glyph == GS_MIN_CID_GLYPH); return (bfont->procs.glyph_name((gs_font *)bfont, glyph, &gnstr) >= 0 && gnstr.size == 7 && !memcmp(gnstr.data, ".notdef", 7)); } @@ -976,14 +998,14 @@ gs_glyph gs_no_encode_char(gs_font *pfont, gs_char chr, gs_glyph_space_t glyph_space) { - return gs_no_glyph; + return GS_NO_GLYPH; } /* Dummy glyph decoding procedure */ -gs_char -gs_no_decode_glyph(gs_font *pfont, gs_glyph glyph, int ch) +int +gs_no_decode_glyph(gs_font *pfont, gs_glyph glyph, int ch, ushort *unicode_return, unsigned int length) { - return GS_NO_CHAR; + return (int)GS_NO_CHAR; } /* Dummy glyph enumeration procedure */ diff -Nru ghostscript-9.10~dfsg/base/gsfont.h ghostscript-9.25~dfsg+1/base/gsfont.h --- ghostscript-9.10~dfsg/base/gsfont.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfont.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -63,12 +63,12 @@ /* gs_scalefont and gs_makefont return 0 if the scaled font */ /* was already in the cache, 1 if a new font was created. */ -int gs_scalefont(gs_font_dir *, const gs_font *, floatp, gs_font **); +int gs_scalefont(gs_font_dir *, const gs_font *, double, gs_font **); int gs_makefont(gs_font_dir *, const gs_font *, const gs_matrix *, gs_font **); -int gs_setfont(gs_state *, gs_font *); -gs_font *gs_currentfont(const gs_state *); -gs_font *gs_rootfont(const gs_state *); -void gs_set_currentfont(gs_state *, gs_font *); +int gs_setfont(gs_gstate *, gs_font *); +gs_font *gs_currentfont(const gs_gstate *); +gs_font *gs_rootfont(const gs_gstate *); +void gs_set_currentfont(gs_gstate *, gs_font *); int gs_purge_font(gs_font *); /* Locate a gs_font by gs_id. */ gs_font *gs_find_font_by_id(gs_font_dir *pdir, gs_id id, gs_matrix *FontMatrix); @@ -78,7 +78,7 @@ #define gs_setcachelimit(pdir,limit) gs_setcacheupper(pdir,limit) uint gs_currentcachesize(const gs_font_dir *); -int gs_setcachesize(gs_state * pgs, gs_font_dir *, uint); +int gs_setcachesize(gs_gstate * pgs, gs_font_dir *, uint); uint gs_currentcachelower(const gs_font_dir *); int gs_setcachelower(gs_font_dir *, uint); uint gs_currentcacheupper(const gs_font_dir *); diff -Nru ghostscript-9.10~dfsg/base/gsform1.h ghostscript-9.25~dfsg+1/base/gsform1.h --- ghostscript-9.10~dfsg/base/gsform1.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsform1.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,27 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Client interface to FormType 1 Forms */ + +typedef struct gs_form_template_s { + gs_rect BBox; + gs_matrix form_matrix; + gs_matrix CTM; + gx_clip_path * pcpath; + int FormID; + gs_gstate *pgs; +} gs_form_template_t; + diff -Nru ghostscript-9.10~dfsg/base/gsfunc0.c ghostscript-9.25~dfsg+1/base/gsfunc0.c --- ghostscript-9.10~dfsg/base/gsfunc0.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc0.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -186,7 +186,7 @@ * (thanks to Raph Levien for the reference). */ static double -interpolate_cubic(floatp x, floatp f0, floatp f1, floatp f2, floatp f3) +interpolate_cubic(double x, double f0, double f1, double f2, double f3) { /* * The parameter 'a' affects the contribution of the high-frequency @@ -219,7 +219,7 @@ * match what we believe is Acrobat Reader's behavior. */ static inline double -interpolate_quadratic(floatp x, floatp f0, floatp f1, floatp f2) +interpolate_quadratic(double x, double f0, double f1, double f2) { return interpolate_cubic(x + 1, f0, f0, f1, f2); } @@ -339,7 +339,7 @@ if (pfn->params.Range) r0 = pfn->params.Range[2 * i], r1 = pfn->params.Range[2 * i + 1]; else - r0 = 0, r1 = (float)((1 << bps) - 1); + r0 = 0, r1 = (float)max_samp; if (pfn->params.Decode) d0 = pfn->params.Decode[2 * i], d1 = pfn->params.Decode[2 * i + 1]; else @@ -477,17 +477,12 @@ { float d0 = pfn->params.Domain[2 * 0]; float d1 = pfn->params.Domain[2 * 0 + 1]; - float x0 = in[0]; const int pole_step_minor = pfn->params.n; const int pole_step = 3 * pole_step_minor; int i0; /* A cell index. */ int ib, ie, i, k; double *p, t0, t1, tt; - if (x0 < d0) - x0 = d0; - if (x0 > d1) - x0 = d1; tt = (in[0] - d0) * (pfn->params.Size[0] - 1) / (d1 - d0); i0 = (int)floor(tt); ib = max(i0 - 1, 0); @@ -740,6 +735,8 @@ } if (pfn->params.Order == 3) { code = make_interpolation_tensor(pfn, I, T, 0, 0, pfn->params.m - 1); + if (code < 0) + return code; } } else { int i; @@ -860,7 +857,7 @@ const float small_noise = (float)1e-6; if (v0 < d0 || v0 > d1) - return gs_error_rangecheck; + return_error(gs_error_rangecheck); if (pfn->params.Encode) e0 = pfn->params.Encode[i * 2 + 0], e1 = pfn->params.Encode[i * 2 + 1]; else @@ -1070,7 +1067,7 @@ TT1[i] = 0; } *mask = tensor_dimension_monotonity(TT0, TT1, ii, i0, pole, 0, - count_of(pole) / 4, -1, pfn->params.Order); + count_of(pole) / 4, 1, pfn->params.Order); return 0; } diff -Nru ghostscript-9.10~dfsg/base/gsfunc0.h ghostscript-9.25~dfsg+1/base/gsfunc0.h --- ghostscript-9.10~dfsg/base/gsfunc0.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc0.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfunc3.c ghostscript-9.25~dfsg+1/base/gsfunc3.c --- ghostscript-9.10~dfsg/base/gsfunc3.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc3.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -217,13 +217,22 @@ uint n; const gs_function_ElIn_params_t * p = (const gs_function_ElIn_params_t *)&pfn->params; int code = fn_common_serialize(pfn, s); + float C0_default[2] = {0, 0}; + float C1_default[2] = {1, 0}; if (code < 0) return code; - code = sputs(s, (const byte *)&p->C0[0], sizeof(p->C0[0]) * p->n, &n); + if (p->C0) + code = sputs(s, (const byte *)&p->C0[0], sizeof(p->C0[0]) * p->n, &n); + else + code = sputs(s, (const byte *)&C0_default, sizeof(float) * 2, &n); if (code < 0) return code; - code = sputs(s, (const byte *)&p->C1[0], sizeof(p->C1[0]) * p->n, &n); + + if (p->C1) + code = sputs(s, (const byte *)&p->C1[0], sizeof(p->C1[0]) * p->n, &n); + else + code = sputs(s, (const byte *)&C1_default, sizeof(float) * 2, &n); if (code < 0) return code; return sputs(s, (const byte *)&p->N, sizeof(p->N), &n); @@ -335,6 +344,13 @@ int i; *mask = 0; + + /* If the upper and lower parametric values are the same then this is a point + * and so is monotonic. + */ + if (v0 == v1) + return 1; + if (v0 > v1) { v0 = v1; v1 = lower[0]; } @@ -352,12 +368,15 @@ float e0, e1; float w0, w1; float vv0, vv1; - double vb0, vb1; + float vb0, vb1; if (v0 >= b1 - bsmall) continue; /* Ignore a small noise */ vv0 = max(b0, v0); - vv1 = v1; + /* make sure we promote *both* values, in case v0 was within the + * noise threshold above. + */ + vv1 = max(b0, v1); if (vv1 > b1 && v1 < b1 + bsmall) vv1 = b1; /* Ignore a small noise */ if (vv0 == vv1) @@ -369,8 +388,8 @@ e0 = pfn->params.Encode[2 * i]; e1 = pfn->params.Encode[2 * i + 1]; esmall = (float)1e-6 * any_abs(e1 - e0); - vb0 = max(vv0, b0); - vb1 = min(vv1, b1); + vb0 = (float)max(vv0, b0); + vb1 = (float)min(vv1, b1); if (b1 == b0) return 1; /* function is monotonous in a point */ w0 = (float)(vb0 - b0) * (e1 - e0) / (b1 - b0) + e0; @@ -521,7 +540,7 @@ }; int n = (params->Range == 0 ? 0 : params->n); float prev = params->Domain[0]; - int i; + int code, i; *ppfn = 0; /* in case of error */ for (i = 0; i < params->k; ++i) { @@ -542,7 +561,11 @@ } if (params->Domain[1] < prev) return_error(gs_error_rangecheck); - fn_check_mnDR((const gs_function_params_t *)params, 1, n); + + code = fn_check_mnDR((const gs_function_params_t *)params, 1, n); + if(code < 0) + return code; + else { gs_function_1ItSg_t *pfn = gs_alloc_struct(mem, gs_function_1ItSg_t, &st_function_1ItSg, diff -Nru ghostscript-9.10~dfsg/base/gsfunc3.h ghostscript-9.25~dfsg+1/base/gsfunc3.h --- ghostscript-9.10~dfsg/base/gsfunc3.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc3.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfunc4.c ghostscript-9.25~dfsg+1/base/gsfunc4.c --- ghostscript-9.10~dfsg/base/gsfunc4.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc4.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -62,7 +62,7 @@ /* Store a float. */ static inline void -store_float(calc_value_t *vsp, floatp f) +store_float(calc_value_t *vsp, double f) { vsp->value.f = f; vsp->type = CVT_FLOAT; @@ -221,6 +221,9 @@ OP_NONE(PtCr_repeat_end) /* repeat_end */ }; + memset(repeat_count, 0x00, MAX_PSC_FUNCTION_NESTING * sizeof(int)); + memset(repeat_proc_size, 0x00, MAX_PSC_FUNCTION_NESTING * sizeof(int)); + vstack[-1].type = CVT_NONE; /* for type dispatch in empty stack case */ vstack[0].type = CVT_NONE; /* catch underflow */ for (i = 0; i < pfn->params.m; ++i) @@ -242,12 +245,13 @@ /* Coerce and re-dispatch */ case PtCr_int_to_float: - store_float(vsp, (floatp)vsp->value.i); + store_float(vsp, (double)vsp->value.i); --p; goto sw; case PtCr_int2_to_float: - store_float(vsp, (floatp)vsp->value.i); + store_float(vsp, (double)vsp->value.i); + /* fall through */ case PtCr_2nd_int_to_float: - store_float(vsp - 1, (floatp)vsp[-1].value.i); + store_float(vsp - 1, (double)vsp[-1].value.i); --p; goto sw; /* Arithmetic operators */ @@ -351,7 +355,7 @@ case PtCr_neg_int: neg_int: if (vsp->value.i == min_int) - store_float(vsp, (floatp)vsp->value.i); /* =self negated */ + store_float(vsp, (double)vsp->value.i); /* =self negated */ else vsp->value.i = -vsp->value.i; continue; @@ -535,6 +539,9 @@ p += 3 + (p[0] <<8) + p[1]; /* advance just past the repeat_end */ /* falls through */ case PtCr_repeat_end: + if (repeat_nesting_level < 0) + return_error(gs_error_rangecheck); + if ((repeat_count[repeat_nesting_level])-- <= 0) repeat_nesting_level--; else diff -Nru ghostscript-9.10~dfsg/base/gsfunc4.h ghostscript-9.25~dfsg+1/base/gsfunc4.h --- ghostscript-9.10~dfsg/base/gsfunc4.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc4.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfunc.c ghostscript-9.25~dfsg+1/base/gsfunc.c --- ghostscript-9.10~dfsg/base/gsfunc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsfunc.h ghostscript-9.25~dfsg+1/base/gsfunc.h --- ghostscript-9.10~dfsg/base/gsfunc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsfunc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,6 +19,7 @@ #ifndef gsfunc_INCLUDED # define gsfunc_INCLUDED +#include "memento.h" /* Because we use 'free' below */ #include "gstypes.h" /* for gs_range_t */ #ifndef stream_DEFINED diff -Nru ghostscript-9.10~dfsg/base/gsgcache.c ghostscript-9.25~dfsg+1/base/gsgcache.c --- ghostscript-9.10~dfsg/base/gsgcache.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsgcache.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,7 +47,7 @@ uint lock_count; gs_glyph_cache_elem *next; }; -gs_public_st_composite(st_glyph_cache_elem, gs_glyph_cache_elem, "gs_glyph_cache_elem", +gs_private_st_composite(st_glyph_cache_elem, gs_glyph_cache_elem, "gs_glyph_cache_elem", gs_glyph_cache_elem_enum_ptrs, gs_glyph_cache_elem_reloc_ptrs); static diff -Nru ghostscript-9.10~dfsg/base/gsgcache.h ghostscript-9.25~dfsg+1/base/gsgcache.h --- ghostscript-9.10~dfsg/base/gsgcache.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsgcache.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsgc.h ghostscript-9.25~dfsg+1/base/gsgc.h --- ghostscript-9.10~dfsg/base/gsgc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsgc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsgdata.c ghostscript-9.25~dfsg+1/base/gsgdata.c --- ghostscript-9.10~dfsg/base/gsgdata.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsgdata.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsgdata.h ghostscript-9.25~dfsg+1/base/gsgdata.h --- ghostscript-9.10~dfsg/base/gsgdata.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsgdata.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsgstate.c ghostscript-9.25~dfsg+1/base/gsgstate.c --- ghostscript-9.10~dfsg/base/gsgstate.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsgstate.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,253 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* gs_gstate housekeeping */ +#include "gx.h" +#include "gserrors.h" +#include "gscspace.h" +#include "gscie.h" +#include "gsstruct.h" +#include "gsutil.h" /* for gs_next_ids */ +#include "gxbitmap.h" +#include "gxcmap.h" +#include "gxdht.h" +#include "gxgstate.h" +#include "gzht.h" +#include "gzline.h" +#include "gxfmap.h" +#include "gsicc_cache.h" +#include "gsicc_manage.h" +#include "gsicc_profilecache.h" + +/****************************************************************************** + * See gsstate.c for a discussion of graphics state memory management. * + ******************************************************************************/ + +/* Imported values */ +/* The following should include a 'const', but for some reason */ +/* the Watcom compiler won't accept it, even though it happily accepts */ +/* the same construct everywhere else. */ +extern /*const*/ gx_color_map_procs *const cmap_procs_default; + +/* GC procedures for gx_line_params */ +static +ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0; + case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ? + NULL : plp->dash.pattern)); +ENUM_PTRS_END +static RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp) +{ + if (plp->dash.pattern_size) + RELOC_VAR(plp->dash.pattern); +} RELOC_PTRS_END +private_st_line_params(); + +/* + * GC procedures for gs_gstate + * + * See comments in gixstate.h before the definition of gs_cr_state_do_rc and + * st_cr_state_num_ptrs for an explanation about why the effective_transfer + * pointers are handled in this manner. + */ +public_st_gs_gstate(); +static +ENUM_PTRS_WITH(gs_gstate_enum_ptrs, gs_gstate *gisvptr) + ENUM_SUPER(gs_gstate, st_line_params, line_params, st_gs_gstate_num_ptrs - st_line_params_num_ptrs); +#define e1(i,elt) ENUM_PTR(i,gs_gstate,elt); + gs_gstate_do_ptrs(e1) +#undef e1 +#define E1(i,elt) ENUM_PTR(i + gs_gstate_num_ptrs,gs_gstate,elt); + gs_cr_state_do_ptrs(E1) +#undef E1 + case (gs_gstate_num_ptrs + st_cr_state_num_ptrs): /* handle device specially */ + ENUM_RETURN(gx_device_enum_ptr(gisvptr->device)); +ENUM_PTRS_END + +static RELOC_PTRS_WITH(gs_gstate_reloc_ptrs, gs_gstate *gisvptr) +{ + RELOC_SUPER(gs_gstate, st_line_params, line_params); +#define r1(i,elt) RELOC_PTR(gs_gstate,elt); + gs_gstate_do_ptrs(r1) +#undef r1 +#define R1(i,elt) RELOC_PTR(gs_gstate,elt); + gs_cr_state_do_ptrs(R1) +#undef R1 + + gisvptr->device = gx_device_reloc_ptr(gisvptr->device, gcst); + { + int i = GX_DEVICE_COLOR_MAX_COMPONENTS - 1; + + for (; i >= 0; i--) + RELOC_PTR(gs_gstate, effective_transfer[i]); + } +} RELOC_PTRS_END + +/* Initialize an gs_gstate, other than the parts covered by */ +/* GS_STATE_INIT_VALUES(). */ +int +gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem) +{ + int i; + pgs->memory = mem; + pgs->client_data = 0; + pgs->trans_device = 0; + /* Color rendering state */ + pgs->halftone = 0; + { + int i; + + for (i = 0; i < gs_color_select_count; ++i) + pgs->screen_phase[i].x = pgs->screen_phase[i].y = 0; + } + pgs->dev_ht = 0; + pgs->cie_render = 0; + pgs->cie_to_xyz = false; + pgs->black_generation = 0; + pgs->undercolor_removal = 0; + /* Allocate an initial transfer map. */ + rc_alloc_struct_n(pgs->set_transfer.gray, + gx_transfer_map, &st_transfer_map, + mem, return_error(gs_error_VMerror), + "gs_gstate_init(transfer)", 1); + pgs->set_transfer.gray->proc = gs_identity_transfer; + pgs->set_transfer.gray->id = gs_next_ids(pgs->memory, 1); + pgs->set_transfer.gray->values[0] = frac_0; + pgs->set_transfer.red = + pgs->set_transfer.green = + pgs->set_transfer.blue = NULL; + for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) + pgs->effective_transfer[i] = pgs->set_transfer.gray; + pgs->cie_joint_caches = NULL; + pgs->cie_joint_caches_alt = NULL; + pgs->cmap_procs = cmap_procs_default; + pgs->pattern_cache = NULL; + pgs->have_pattern_streams = false; + pgs->devicergb_cs = gs_cspace_new_DeviceRGB(mem); + pgs->devicecmyk_cs = gs_cspace_new_DeviceCMYK(mem); + if (pgs->devicergb_cs == NULL || pgs->devicecmyk_cs == NULL) + return_error(gs_error_VMerror); + pgs->icc_link_cache = gsicc_cache_new(pgs->memory); + pgs->icc_manager = gsicc_manager_new(pgs->memory); + pgs->icc_profile_cache = gsicc_profilecache_new(pgs->memory); +#if ENABLE_CUSTOM_COLOR_CALLBACK + pgs->custom_color_callback = INIT_CUSTOM_COLOR_PTR; +#endif + return 0; +} + +/* + * Make a temporary copy of a gs_gstate. Note that this does not + * do all the necessary reference counting, etc. However, it does + * clear out the transparency stack in the destination. + */ +gs_gstate * +gs_gstate_copy_temp(const gs_gstate * pgs, gs_memory_t * mem) +{ + gs_gstate *pgs_copy = + gs_alloc_struct(mem, gs_gstate, &st_gs_gstate, + "gs_gstate_copy"); + + if (pgs_copy) { + *pgs_copy = *pgs; + } + return pgs_copy; +} + +/* Increment reference counts to note that an gs_gstate has been copied. */ +void +gs_gstate_copied(gs_gstate * pgs) +{ + rc_increment(pgs->halftone); + rc_increment(pgs->dev_ht); + rc_increment(pgs->cie_render); + rc_increment(pgs->black_generation); + rc_increment(pgs->undercolor_removal); + rc_increment(pgs->set_transfer.gray); + rc_increment(pgs->set_transfer.red); + rc_increment(pgs->set_transfer.green); + rc_increment(pgs->set_transfer.blue); + rc_increment(pgs->cie_joint_caches); + rc_increment(pgs->cie_joint_caches_alt); + rc_increment(pgs->devicergb_cs); + rc_increment(pgs->devicecmyk_cs); + rc_increment(pgs->icc_link_cache); + rc_increment(pgs->icc_profile_cache); + rc_increment(pgs->icc_manager); +} + +/* Adjust reference counts before assigning one gs_gstate to another. */ +void +gs_gstate_pre_assign(gs_gstate *pto, const gs_gstate *pfrom) +{ + const char *const cname = "gs_gstate_pre_assign"; + +#define RCCOPY(element)\ + rc_pre_assign(pto->element, pfrom->element, cname) + + RCCOPY(cie_joint_caches); + RCCOPY(cie_joint_caches_alt); + RCCOPY(set_transfer.blue); + RCCOPY(set_transfer.green); + RCCOPY(set_transfer.red); + RCCOPY(set_transfer.gray); + RCCOPY(undercolor_removal); + RCCOPY(black_generation); + RCCOPY(cie_render); + RCCOPY(dev_ht); + RCCOPY(halftone); + RCCOPY(devicergb_cs); + RCCOPY(devicecmyk_cs); + RCCOPY(icc_link_cache); + RCCOPY(icc_profile_cache); + RCCOPY(icc_manager); +#undef RCCOPY +} + +/* Release a gs_gstate. */ +void +gs_gstate_release(gs_gstate * pgs) +{ + const char *const cname = "gs_gstate_release"; + gx_device_halftone *pdht = pgs->dev_ht; + +#define RCDECR(element)\ + rc_decrement(pgs->element, cname);\ + pgs->element = NULL /* prevent subsequent decrements from this gs_gstate */ + + RCDECR(cie_joint_caches); + RCDECR(set_transfer.gray); + RCDECR(set_transfer.blue); + RCDECR(set_transfer.green); + RCDECR(set_transfer.red); + RCDECR(undercolor_removal); + RCDECR(black_generation); + RCDECR(cie_render); + /* + * If we're going to free the device halftone, make sure we free the + * dependent structures as well. + */ + if (pdht != 0 && pdht->rc.ref_count == 1) { + gx_device_halftone_release(pdht, pdht->rc.memory); + } + RCDECR(dev_ht); + RCDECR(halftone); + RCDECR(devicergb_cs); + RCDECR(devicecmyk_cs); + RCDECR(icc_link_cache); + RCDECR(icc_profile_cache); + RCDECR(icc_manager); +#undef RCDECR +} diff -Nru ghostscript-9.10~dfsg/base/gshsb.c ghostscript-9.25~dfsg+1/base/gshsb.c --- ghostscript-9.10~dfsg/base/gshsb.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gshsb.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,15 +21,15 @@ #include "gxfrac.h" /* Forward references */ -static void color_hsb_to_rgb(floatp h, floatp s, floatp b, float rgb[3]); -static void color_rgb_to_hsb(floatp r, floatp g, floatp b, float hsb[3]); +static void color_hsb_to_rgb(double h, double s, double b, float rgb[3]); +static void color_rgb_to_hsb(double r, double g, double b, float hsb[3]); /* Force a parameter into the range [0.0..1.0]. */ #define force_unit(p) (p < 0.0 ? 0.0 : p > 1.0 ? 1.0 : p) /* sethsbcolor */ int -gs_sethsbcolor(gs_state * pgs, floatp h, floatp s, floatp b) +gs_sethsbcolor(gs_gstate * pgs, double h, double s, double b) { float rgb[3]; @@ -39,7 +39,7 @@ /* currenthsbcolor */ int -gs_currenthsbcolor(const gs_state * pgs, float pr3[3]) +gs_currenthsbcolor(const gs_gstate * pgs, float pr3[3]) { float rgb[3]; @@ -55,7 +55,7 @@ /* Convert RGB to HSB. */ static void -color_rgb_to_hsb(floatp r, floatp g, floatp b, float hsb[3]) +color_rgb_to_hsb(double r, double g, double b, float hsb[3]) { frac red = float2frac(r), green = float2frac(g), blue = float2frac(b); @@ -96,14 +96,14 @@ /* Convert HSB to RGB. */ static void -color_hsb_to_rgb(floatp hue, floatp saturation, floatp brightness, float rgb[3]) +color_hsb_to_rgb(double hue, double saturation, double brightness, float rgb[3]) { if (saturation == 0) { rgb[0] = rgb[1] = rgb[2] = brightness; } else { /* Convert hsb to rgb. */ /* We rely on the fact that the product of two */ /* fracs fits into an unsigned long. */ - floatp h6 = hue * 6; + double h6 = hue * 6; ulong V = float2frac(brightness); /* force arithmetic to long */ frac S = float2frac(saturation); int I = (int)h6; diff -Nru ghostscript-9.10~dfsg/base/gshsb.h ghostscript-9.25~dfsg+1/base/gshsb.h --- ghostscript-9.10~dfsg/base/gshsb.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gshsb.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,7 +19,7 @@ #ifndef gshsb_INCLUDED # define gshsb_INCLUDED -int gs_sethsbcolor(gs_state *, floatp, floatp, floatp), - gs_currenthsbcolor(const gs_state *, float[3]); +int gs_sethsbcolor(gs_gstate *, double, double, double), + gs_currenthsbcolor(const gs_gstate *, float[3]); #endif /* gshsb_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsht1.c ghostscript-9.25~dfsg+1/base/gsht1.c --- ghostscript-9.10~dfsg/base/gsht1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsht1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,16 +27,16 @@ /* Imports from gscolor.c */ -void load_transfer_map(gs_state *, gx_transfer_map *, floatp); +void load_transfer_map(gs_gstate *, gx_transfer_map *, double); /* Forward declarations */ -static int process_spot(gx_ht_order *, gs_state *, +static int process_spot(gx_ht_order *, gs_gstate *, gs_spot_halftone *, gs_memory_t *); -static int process_threshold(gx_ht_order *, gs_state *, +static int process_threshold(gx_ht_order *, gs_gstate *, gs_threshold_halftone *, gs_memory_t *); -static int process_threshold2(gx_ht_order *, gs_state *, +static int process_threshold2(gx_ht_order *, gs_gstate *, gs_threshold2_halftone *, gs_memory_t *); -static int process_client_order(gx_ht_order *, gs_state *, +static int process_client_order(gx_ht_order *, gs_gstate *, gs_client_order_halftone *, gs_memory_t *); /* Structure types */ @@ -106,7 +106,7 @@ /* setcolorscreen */ int -gs_setcolorscreen(gs_state * pgs, gs_colorscreen_halftone * pht) +gs_setcolorscreen(gs_gstate * pgs, gs_colorscreen_halftone * pht) { gs_halftone ht; @@ -117,7 +117,7 @@ /* currentcolorscreen */ int -gs_currentcolorscreen(gs_state * pgs, gs_colorscreen_halftone * pht) +gs_currentcolorscreen(gs_gstate * pgs, gs_colorscreen_halftone * pht) { int code; @@ -138,7 +138,7 @@ /* Set the halftone in the graphics state. */ int -gs_sethalftone(gs_state * pgs, gs_halftone * pht) +gs_sethalftone(gs_gstate * pgs, gs_halftone * pht) { gs_halftone ht; @@ -147,7 +147,7 @@ return gs_sethalftone_allocated(pgs, &ht); } int -gs_sethalftone_allocated(gs_state * pgs, gs_halftone * pht) +gs_sethalftone_allocated(gs_gstate * pgs, gs_halftone * pht) { gx_device_halftone dev_ht; int code = gs_sethalftone_prepare(pgs, pht, &dev_ht); @@ -162,7 +162,7 @@ /* Prepare the halftone, but don't install it. */ int -gs_sethalftone_prepare(gs_state * pgs, gs_halftone * pht, +gs_sethalftone_prepare(gs_gstate * pgs, gs_halftone * pht, gx_device_halftone * pdht) { gs_memory_t *mem = pht->rc.memory; @@ -250,7 +250,7 @@ return_error(gs_error_VMerror); poc_next = pocs + 1; for (i = 0; i < count; i++, phc++) { - gx_ht_order_component *poc = poc_next; + gx_ht_order_component *poc; if (phc->comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) { if (have_Default) { @@ -320,7 +320,7 @@ /* Process a transfer function override, if any. */ static int -process_transfer(gx_ht_order * porder, gs_state * pgs, +process_transfer(gx_ht_order * porder, gs_gstate * pgs, gs_mapping_proc proc, gs_mapping_closure_t * pmc, gs_memory_t * mem) { @@ -347,7 +347,7 @@ /* Process a spot plane. */ static int -process_spot(gx_ht_order * porder, gs_state * pgs, +process_spot(gx_ht_order * porder, gs_gstate * pgs, gs_spot_halftone * phsp, gs_memory_t * mem) { gs_screen_enum senum; @@ -396,7 +396,7 @@ /* Process a threshold plane. */ static int -process_threshold(gx_ht_order * porder, gs_state * pgs, +process_threshold(gx_ht_order * porder, gs_gstate * pgs, gs_threshold_halftone * phtp, gs_memory_t * mem) { int code; @@ -416,7 +416,7 @@ /* Process an extended threshold plane. */ static int -process_threshold2(gx_ht_order * porder, gs_state * pgs, +process_threshold2(gx_ht_order * porder, gs_gstate * pgs, gs_threshold2_halftone * phtp, gs_memory_t * mem) { int code; @@ -525,14 +525,14 @@ } } gx_ht_complete_threshold_order(porder); - return process_transfer(porder, pgs, NULL, &phtp->transfer_closure, mem); + return process_transfer(porder, pgs, phtp->transfer, &phtp->transfer_closure, mem); #undef LOG2_MAX_HT_LEVELS #undef MAX_HT_LEVELS } /* Process a client-order plane. */ static int -process_client_order(gx_ht_order * porder, gs_state * pgs, +process_client_order(gx_ht_order * porder, gs_gstate * pgs, gs_client_order_halftone * phcop, gs_memory_t * mem) { int code = (*phcop->procs->create_order) (porder, pgs, phcop, mem); diff -Nru ghostscript-9.10~dfsg/base/gsht1.h ghostscript-9.25~dfsg+1/base/gsht1.h --- ghostscript-9.10~dfsg/base/gsht1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsht1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,8 +22,8 @@ #include "gsht.h" /* Procedural interface */ -int gs_setcolorscreen(gs_state *, gs_colorscreen_halftone *); -int gs_currentcolorscreen(gs_state *, gs_colorscreen_halftone *); +int gs_setcolorscreen(gs_gstate *, gs_colorscreen_halftone *); +int gs_currentcolorscreen(gs_gstate *, gs_colorscreen_halftone *); /* * We include sethalftone here, even though it is a Level 2 feature, @@ -39,13 +39,13 @@ * gs_halftone structures may have complex substructures. We provide two * procedures for setting them. gs_halftone assumes that the gs_halftone * structure and all its substructures was allocated with the same allocator - * as the gs_state; gs_halftone_allocated looks in the structure itself (the + * as the gs_gstate; gs_halftone_allocated looks in the structure itself (the * rc.memory member) to find the allocator that was used. Both procedures * copy the top-level structure (using the appropriate allocator), but take * ownership of the substructures. */ -int gs_sethalftone(gs_state *, gs_halftone *); -int gs_sethalftone_allocated(gs_state *, gs_halftone *); -int gs_currenthalftone(gs_state *, gs_halftone *); +int gs_sethalftone(gs_gstate *, gs_halftone *); +int gs_sethalftone_allocated(gs_gstate *, gs_halftone *); +int gs_currenthalftone(gs_gstate *, gs_halftone *); #endif /* gsht1_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsht.c ghostscript-9.25~dfsg+1/base/gsht.c --- ghostscript-9.10~dfsg/base/gsht.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsht.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,26 +28,8 @@ #include "gzht.h" #include "gxfmap.h" /* For effective transfer usage in threshold */ -#define TRANSFER_INVERSE_SIZE 1024 -#define TRANSFER_IN_THRESHOLDS 0 - -/* Used in threshold from tiles construction */ -static const uint32_t bit_order[32]={ -#if arch_is_big_endian - 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000, - 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, - 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, - 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001 -#else - 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008, 0x00000004, 0x00000002, 0x00000001, - 0x00008000, 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200, 0x00000100, - 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000, 0x00040000, 0x00020000, 0x00010000, - 0x80000000, 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000, 0x01000000 -#endif - }; - /* Forward declarations */ -void gx_set_effective_transfer(gs_state *); +void gx_set_effective_transfer(gs_gstate *); /* Structure types */ public_st_ht_order(); @@ -100,6 +82,7 @@ case ht_type_colorscreen: return 0; } +/* fall through */ case 1: switch (hptr->type) { case ht_type_threshold: @@ -149,7 +132,7 @@ /* setscreen */ int -gs_setscreen(gs_state * pgs, gs_screen_halftone * phsp) +gs_setscreen(gs_gstate * pgs, gs_screen_halftone * phsp) { gs_screen_enum senum; int code = gx_ht_process_screen(&senum, pgs, phsp, @@ -162,7 +145,7 @@ /* currentscreen */ int -gs_currentscreen(const gs_state * pgs, gs_screen_halftone * phsp) +gs_currentscreen(const gs_gstate * pgs, gs_screen_halftone * phsp) { switch (pgs->halftone->type) { case ht_type_screen: @@ -178,7 +161,7 @@ /* .currentscreenlevels */ int -gs_currentscreenlevels(const gs_state * pgs) +gs_currentscreenlevels(const gs_gstate * pgs) { int gi = 0; @@ -192,25 +175,25 @@ /* .setscreenphase */ int -gx_imager_setscreenphase(gs_imager_state * pis, int x, int y, +gx_gstate_setscreenphase(gs_gstate * pgs, int x, int y, gs_color_select_t select) { if (select == gs_color_select_all) { int i; for (i = 0; i < gs_color_select_count; ++i) - gx_imager_setscreenphase(pis, x, y, (gs_color_select_t) i); + gx_gstate_setscreenphase(pgs, x, y, (gs_color_select_t) i); return 0; - } else if (select < 0 || select >= gs_color_select_count) + } else if ((int)select < 0 || (int)select >= gs_color_select_count) return_error(gs_error_rangecheck); - pis->screen_phase[select].x = x; - pis->screen_phase[select].y = y; + pgs->screen_phase[select].x = x; + pgs->screen_phase[select].y = y; return 0; } int -gs_setscreenphase(gs_state * pgs, int x, int y, gs_color_select_t select) +gs_setscreenphase(gs_gstate * pgs, int x, int y, gs_color_select_t select) { - int code = gx_imager_setscreenphase((gs_imager_state *) pgs, x, y, + int code = gx_gstate_setscreenphase(pgs, x, y, select); /* @@ -226,26 +209,26 @@ } int -gs_currentscreenphase_pis(const gs_imager_state * pis, gs_int_point * pphase, +gs_currentscreenphase_pgs(const gs_gstate * pgs, gs_int_point * pphase, gs_color_select_t select) { - if (select < 0 || select >= gs_color_select_count) + if ((int)select < 0 || (int)select >= gs_color_select_count) return_error(gs_error_rangecheck); - *pphase = pis->screen_phase[select]; + *pphase = pgs->screen_phase[select]; return 0; } /* .currentscreenphase */ int -gs_currentscreenphase(const gs_state * pgs, gs_int_point * pphase, +gs_currentscreenphase(const gs_gstate * pgs, gs_int_point * pphase, gs_color_select_t select) { - return gs_currentscreenphase_pis((const gs_imager_state *)pgs, pphase, select); + return gs_currentscreenphase_pgs((const gs_gstate *)pgs, pphase, select); } /* currenthalftone */ int -gs_currenthalftone(gs_state * pgs, gs_halftone * pht) +gs_currenthalftone(gs_gstate * pgs, gs_halftone * pht) { *pht = *pgs->halftone; return 0; @@ -255,7 +238,7 @@ /* Process one screen plane. */ int -gx_ht_process_screen_memory(gs_screen_enum * penum, gs_state * pgs, +gx_ht_process_screen_memory(gs_screen_enum * penum, gs_gstate * pgs, gs_screen_halftone * phsp, bool accurate, gs_memory_t * mem) { gs_point pt; @@ -298,6 +281,7 @@ "alloc_ht_order_data(levels)"); if (porder->levels == 0) return_error(gs_error_VMerror); + memset(porder->levels, 0, sizeof(uint) * porder->num_levels); } else porder->levels = 0; @@ -592,11 +576,12 @@ "gx_ht_order_release(bit_data)"); gs_free_object(porder->data_memory, porder->levels, "gx_ht_order_release(levels)"); - } - if (porder->threshold != NULL) { - gs_free_object(porder->data_memory->non_gc_memory, porder->threshold, + if (porder->threshold != NULL) { + gs_free_object(porder->data_memory->non_gc_memory, porder->threshold, "gx_ht_order_release(threshold)"); + } } + porder->threshold = 0; porder->levels = 0; porder->bit_data = 0; } @@ -720,7 +705,7 @@ * then call gs_color_name_component_number. */ int -gs_cname_to_colorant_number(gs_state * pgs, byte * pname, uint name_size, +gs_cname_to_colorant_number(gs_gstate * pgs, byte * pname, uint name_size, int halftonetype) { gx_device * dev = pgs->device; @@ -730,15 +715,15 @@ } /* - * Install a device halftone into the imager state. + * Install a device halftone into the gs_gstate. * - * To allow halftones to be shared between graphic states, the imager - * state contains a pointer to a device halftone structure. Thus, when - * we say a halftone is "in" the imager state, we are only claiming - * that the halftone pointer in the imager state points to that halftone. + * To allow halftones to be shared between graphic states, the + * gs_gstate contains a pointer to a device halftone structure. Thus, when + * we say a halftone is "in" the gs_gstate, we are only claiming + * that the halftone pointer in the gs_gstate points to that halftone. * * Though the operand halftone uses the same structure as the halftone - * "in" the imager state, not all of its fields are filled in, and the + * "in" the gs_gstate, not all of its fields are filled in, and the * organization of components differs. Specifically, the following fields * are not filled in: * @@ -748,7 +733,7 @@ * on the stack by clients. * * id A halftone is not considered to have an identity until it - * is installed in the imager state. This is a design error + * is installed in the gs_gstate. This is a design error * which reflects the PostScript origins of this code. In * PostScript, it is impossible to check if two halftone * specifications (sets of operands to setscreen/setcolorscreen @@ -776,7 +761,7 @@ * * num_comp For the operand halftone, this is the number of halftone * components included in the specification. For the device - * halftone in the imager state, this is always the same as + * halftone in the gs_gstate, this is always the same as * the number of color model components (see num_dev_comp). * * num_dev_comp The number of components in the device process color model @@ -791,7 +776,7 @@ * components provided. One of these components will usually * be the same as that identified by the "order" field. * - * For the device halftone in the imager state, this field is + * For the device halftone in the gs_gstate, this field is * always non-null, and the size of the array pointed to will * be the same as the number of components in the process * color model. @@ -809,11 +794,11 @@ * halftone. There it represents the default halftone component, which will * be used for all device color components for which a named halftone is * not available. It is ignored (filled with 0's) in the device halftone - * in the imager state. + * in the gs_gstate. * * The ordering of entries and the set of fields initialized in the * components array also vary between the operand device halftone and - * the device halftone in the imager state. + * the device halftone in the gs_gstate. * * If the components array is present in the operand device halftone, the * cname field in each entry of the array will contain a name index @@ -825,7 +810,7 @@ * is provided (i.e.: via a HalftoneType 5 dictionary), the first * entry of the array will be the same as the "order" (default) field. * - * For the device halftone in the imager state, the components array is + * For the device halftone in the gs_gstate, the components array is * always present, but the cname and comp_number fields of individual * entries are ignored. The order of the entries in the array always * matches the order of components in the device color model. @@ -835,19 +820,19 @@ * gx_ht_order structure incorporated in the order field of the halftone * and the corder field of the elements of the components array. The * fields of this structure that are handled differently in the operand - * and imager state device halftones are: + * and gs_gstate device halftones are: * * params Provides a set of parameters that are required for * converting a halftone specification to a single * component order. This field is used only in the * operand device halftone; it is not set in the device - * halftone in the imager state. + * halftone in the gs_gstate. * * orig_height, The height and shift values of the halftone cell, * orig_shift prior to any replication. These fields are currently * unused, and will always be the same as the height * and width fields in the device halftone in the - * imager state. + * gs_gstate. * * full_height The height of the smallest replicated tile whose shift * value is 0. This is calculated as part of the @@ -860,10 +845,10 @@ * is a bit complicated. For orders that are "taken over" * by the installation process, this field will have the * same value in the operand device halftone and the - * device halftone in the imager state. For halftones + * device halftone in the gs_gstate. For halftones * that are copied by the installation process, this * field will have the same value as the memory field in - * the imager state (the two are usually the same). + * the gs_gstate (the two are usually the same). * * cache Pointer to a cache of tiles representing various * levels of the halftone. This may or may not be @@ -910,7 +895,7 @@ * halftone structure (i.e.: an ostensibly shareable structure is not * shareable). Hence, this procedure will always create a new copy of the * gx_device_halftone structure, either by allocating a new structure or - * re-using the structure already referenced by the imager state. This + * re-using the structure already referenced by the gs_gstate. This * feature must be retained, as in several cases the calling code will * allocate the operand device halftone structure on the stack. * @@ -918,17 +903,17 @@ * referenced by the operand device halftone structure. This implied * that all structures referenced by the gx_device_halftone structure * needed to be allocated on the heap, and should not be released once - * the call to gx_imager_dev_ht_install completes. + * the call to gx_gstate_dev_ht_install completes. * * There were two problems with this approach: * * 1. In the event of an error, the calling code most likely would have - * to release referenced components, as the imager state had not yet + * to release referenced components, as the gs_gstate had not yet * take ownership of them. In many cases, the code did not do this. * * 2. When the structures referenced by a single order needed to be * shared amongst more than one component, there was no easy way to - * discover this sharing when the imager state's device halftone + * discover this sharing when the gs_gstate's device halftone * subsequently needed to be released. Hence, objects would be * released multiple times. * @@ -939,7 +924,7 @@ * * The approach now taken uses a mixture of the two approaches. * Ownership to structures referenced by the operand device halftone is - * assumed by the device halftone in the imager state where this is + * assumed by the device halftone in the gs_gstate where this is * possible. In these cases, the corresponding references are removed in * the operand device halftone (hence, this operand is no longer * qualified as const). When a structure is required but ownership cannot @@ -949,8 +934,8 @@ * returns, whether or not an error is indicated. */ int -gx_imager_dev_ht_install( - gs_imager_state * pis, +gx_gstate_dev_ht_install( + gs_gstate * pgs, gx_device_halftone * pdht, gs_halftone_type type, const gx_device * dev ) @@ -960,21 +945,21 @@ int i, code = 0; bool used_default = false; int lcm_width = 1, lcm_height = 1; - bool mem_diff = pdht->rc.memory != pis->memory; + bool mem_diff = pdht->rc.memory != pgs->memory; uint w, h; int dw, dh; /* construct the new device halftone structure */ memset(&dht.order, 0, sizeof(dht.order)); /* the rc field is filled in later */ - dht.id = gs_next_ids(pis->memory, 1); + dht.id = gs_next_ids(pgs->memory, 1); dht.type = type; dht.components = gs_alloc_struct_array( - pis->memory, + pgs->memory, num_comps, gx_ht_order_component, &st_ht_order_component_element, - "gx_imager_dev_ht_install(components)" ); + "gx_gstate_dev_ht_install(components)" ); if (dht.components == NULL) return_error(gs_error_VMerror); dht.num_comp = dht.num_dev_comp = num_comps; @@ -988,7 +973,7 @@ /* * Duplicate any of the non-default components, but do not create copies * of the levels or bit_data arrays. If all goes according to plan, the - * imager state's device halftone will assume ownership of these arrays + * gs_gstate's device halftone will assume ownership of these arrays * by clearing the corresponding pointers in the operand halftone's * orders. */ @@ -1013,7 +998,7 @@ if (mem_diff) code = gx_ht_copy_ht_order( p_d_order, p_s_order, - pis->memory ); + pgs->memory ); else { /* check if this is also the default component */ used_default = used_default || @@ -1034,7 +1019,7 @@ if (dht.components[i].comp_number != i) { if (used_default || mem_diff) - code = gx_ht_copy_ht_order(porder, &pdht->order, pis->memory); + code = gx_ht_copy_ht_order(porder, &pdht->order, pgs->memory); else { gx_ht_move_ht_order(porder, &pdht->order); used_default = true; @@ -1072,13 +1057,13 @@ if (rep_count > sizeof(ulong) * 8 && (num_tiles > 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count) )) num_tiles = 1 + ((num_tiles * 8 * sizeof(ulong)) / rep_count); - pcache = gx_ht_alloc_cache( pis->memory, num_tiles, + pcache = gx_ht_alloc_cache( pgs->memory, num_tiles, tile_bytes * num_tiles ); if (pcache == NULL) code = gs_error_VMerror; else { porder->cache = pcache; - gx_ht_init_cache(pis->memory, pcache, porder); + gx_ht_init_cache(pgs->memory, pcache, porder); } } } @@ -1087,10 +1072,10 @@ /* * If everything is OK so far, allocate a unique copy of the device - * halftone reference by the imager state. + * halftone reference by the gs_gstate. * * This code requires a special check for the case in which the - * deivce halftone referenced by the imager state is already unique. + * deivce halftone referenced by the gs_gstate is already unique. * In this case, we must explicitly release just the components array * (and any structures it refers to) of the existing halftone. This * cannot be done automatically, as the rc_unshare_struct macro only @@ -1099,32 +1084,32 @@ * * Though this is scheduled to be changed, for the time being the * command list renderer may invoke this code with pdht == psi->dev_ht - * (in which case we know pis->dev_ht.rc.ref_count == 1). Special + * (in which case we know pgs->dev_ht.rc.ref_count == 1). Special * handling is required in that case, to avoid releasing structures * we still need. */ if (code >= 0) { - gx_device_halftone * pisdht = pis->dev_ht; + gx_device_halftone * pgsdht = pgs->dev_ht; rc_header tmp_rc; - if (pisdht != 0 && pisdht->rc.ref_count == 1) { - if (pdht != pisdht) - gx_device_halftone_release(pisdht, pisdht->rc.memory); + if (pgsdht != 0 && pgsdht->rc.ref_count == 1) { + if (pdht != pgsdht) + gx_device_halftone_release(pgsdht, pgsdht->rc.memory); } else { - rc_unshare_struct( pis->dev_ht, + rc_unshare_struct( pgs->dev_ht, gx_device_halftone, &st_device_halftone, - pis->memory, + pgs->memory, BEGIN code = gs_error_VMerror; goto err; END, - "gx_imager_dev_ht_install" ); - pisdht = pis->dev_ht; + "gx_gstate_dev_ht_install" ); + pgsdht = pgs->dev_ht; } /* * Everything worked. "Assume ownership" of the appropriate * portions of the source device halftone by clearing the * associated references. Since we might have - * pdht == pis->dev_ht, this must done before updating pis->dev_ht. + * pdht == pgs->dev_ht, this must done before updating pgs->dev_ht. * * If the default order has been used for a device component, and * any of the source component orders share their levels or bit_data @@ -1153,12 +1138,12 @@ memset(&pdht->order, 0, sizeof(pdht->order)); } - tmp_rc = pisdht->rc; - *pisdht = dht; - pisdht->rc = tmp_rc; + tmp_rc = pgsdht->rc; + *pgsdht = dht; + pgsdht->rc = tmp_rc; /* update the effective transfer function array */ - gx_imager_set_effective_xfer(pis); + gx_gstate_set_effective_xfer(pgs); return 0; } @@ -1169,10 +1154,15 @@ gx_ht_order_component * pcomp = &dht.components[i]; gx_ht_order * porder = &pcomp->corder; - if (pcomp->comp_number == -1) - gx_ht_order_release(porder, pis->memory, true); + if (pcomp->comp_number == -1) { + gx_ht_order_release(porder, pgs->memory, true); + } + else if (porder->cache != NULL) { + gx_ht_free_cache(pgs->memory, porder->cache); + porder->cache = NULL; + } } - gs_free_object(pis->memory, dht.components, "gx_imager_dev_ht_install"); + gs_free_object(pgs->memory, dht.components, "gx_gstate_dev_ht_install"); return code; } @@ -1183,7 +1173,7 @@ * of any substructures. */ int -gx_ht_install(gs_state * pgs, const gs_halftone * pht, +gx_ht_install(gs_gstate * pgs, const gs_halftone * pht, gx_device_halftone * pdht) { gs_memory_t *mem = pht->rc.memory; @@ -1200,7 +1190,7 @@ rc_alloc_struct_1(new_ht, gs_halftone, &st_halftone, mem, return_error(gs_error_VMerror), "gx_ht_install(new halftone)"); - code = gx_imager_dev_ht_install((gs_imager_state *) pgs, + code = gx_gstate_dev_ht_install(pgs, pdht, pht->type, gs_currentdevice_inline(pgs)); if (code < 0) { if (new_ht != old_ht) @@ -1224,8 +1214,7 @@ new_ht->rc = rc; } pgs->halftone = new_ht; - gx_unset_dev_color(pgs); - gx_unset_alt_dev_color(pgs); + gx_unset_both_dev_colors(pgs); return 0; } @@ -1239,260 +1228,152 @@ /* Reestablish the effective transfer functions, taking into account */ /* any overrides from halftone dictionaries. */ void -gx_imager_set_effective_xfer(gs_imager_state * pis) +gx_gstate_set_effective_xfer(gs_gstate * pgs) { - const gx_device_halftone *pdht = pis->dev_ht; + gx_device_halftone *pdht = pgs->dev_ht; gx_transfer_map *pmap; - int i, component_num; + gx_ht_order *porder; + int i, component_num, non_id_count; + non_id_count = (pgs->set_transfer.gray->proc == &gs_identity_transfer) ? 0 : GX_DEVICE_COLOR_MAX_COMPONENTS; for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) - pis->effective_transfer[i] = pis->set_transfer.gray; /* default */ + pgs->effective_transfer[i] = pgs->set_transfer.gray; /* default */ /* Check if we have a transfer functions from setcolortransfer */ - if (pis->set_transfer.red) { - component_num = pis->set_transfer.red_component_num; - if (component_num >= 0) - pis->effective_transfer[component_num] = pis->set_transfer.red;; - } - if (pis->set_transfer.green) { - component_num = pis->set_transfer.green_component_num; - if (component_num >= 0) - pis->effective_transfer[component_num] = pis->set_transfer.green; - } - if (pis->set_transfer.blue) { - component_num = pis->set_transfer.blue_component_num; - if (component_num >= 0) - pis->effective_transfer[component_num] = pis->set_transfer.blue; - } - - if (pdht == NULL) - return; /* not initialized yet */ - - for (i = 0; i < pdht->num_comp; i++) { - pmap = pdht->components[i].corder.transfer; - if (pmap != NULL) - pis->effective_transfer[i] = pmap; - } -} - -void -gx_set_effective_transfer(gs_state * pgs) -{ - gx_imager_set_effective_xfer((gs_imager_state *) pgs); -} -#if TRANSFER_IN_THRESHOLDS -#define round(x) (((x) < 0.0) ? (ceil ((x) - 0.5)) : (floor ((x) + 0.5))) -/* This creates a 256 entry LUT to invert the effective transfer function so - that it is built into the threshold values. This only works correctly - for monotonic curves. */ -static int -gx_ht_construct_transfer_inverse(gs_memory_t *memory, byte *transfer_inverse, - gs_imager_state * pis, int plane_index, - bool *is_inverting) -{ - frac frac_val; - float float_val; - frac *transfer_sampled; - int k, min_pos, max_pos, mid_pos, max_pos_start, min_pos_start; - bool done, hit; - frac min_val, max_val; - frac zero_val, one_val; - int offset; - frac prev_value; - bool is_monotonic = true; - - is_monotonic = true; - /* First construct a representation of the forward curve */ - transfer_sampled = (frac *)gs_malloc(memory, TRANSFER_INVERSE_SIZE, - sizeof(frac), - "gx_ht_construct_transfer_inverse"); - if (transfer_sampled == NULL) { - return -1 ; /* error if allocation failed */ + if (pgs->set_transfer.red) { + component_num = pgs->set_transfer.red_component_num; + if (component_num >= 0) { + if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) + non_id_count--; + pgs->effective_transfer[component_num] = pgs->set_transfer.red; + if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) + non_id_count++; + } } - zero_val = gx_map_color_frac(pis, 0, effective_transfer[plane_index]); - one_val = gx_map_color_frac(pis, frac_1, effective_transfer[plane_index]); - if (zero_val > one_val) { - *is_inverting = true; - } else { - *is_inverting = false; - } - if (*is_inverting) { - min_pos_start = 0; - max_pos_start = TRANSFER_INVERSE_SIZE - 1; - offset = TRANSFER_INVERSE_SIZE - 1; - prev_value = gx_map_color_frac(pis, frac_1, effective_transfer[plane_index]); - for (k = 0; k < TRANSFER_INVERSE_SIZE; k++) { - float_val = (float) (offset - k)/(float) (TRANSFER_INVERSE_SIZE - 1); - frac_val = float2frac(float_val); - transfer_sampled[k] = gx_map_color_frac(pis, frac_val, - effective_transfer[plane_index]); - if (prev_value > transfer_sampled[k]) { - is_monotonic = false; - } - prev_value = transfer_sampled[k]; - /* Take note of any leading zeros and ending ones for the inversion */ - if (transfer_sampled[k] == 0) min_pos_start = k; - if (transfer_sampled[k] == frac_1 && k < max_pos_start) max_pos_start = k; + if (pgs->set_transfer.green) { + component_num = pgs->set_transfer.green_component_num; + if (component_num >= 0) { + if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) + non_id_count--; + pgs->effective_transfer[component_num] = pgs->set_transfer.green; + if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) + non_id_count++; } - } else { - min_pos_start = 0; - max_pos_start = TRANSFER_INVERSE_SIZE - 1; - prev_value = gx_map_color_frac(pis, 0, effective_transfer[plane_index]); - for (k = 0; k < TRANSFER_INVERSE_SIZE; k++) { - float_val = (float) k / (float) (TRANSFER_INVERSE_SIZE - 1); - frac_val = float2frac(float_val); - transfer_sampled[k] = gx_map_color_frac(pis, frac_val, - effective_transfer[plane_index]); - if (prev_value > transfer_sampled[k]) { - is_monotonic = false; - } - prev_value = transfer_sampled[k]; - /* Take note of any leading zeros and ending ones for the inversion */ - if (transfer_sampled[k] == 0) min_pos_start = k; - if (transfer_sampled[k] == frac_1 && k < max_pos_start) max_pos_start = k; + } + if (pgs->set_transfer.blue) { + component_num = pgs->set_transfer.blue_component_num; + if (component_num >= 0) { + if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) + non_id_count--; + pgs->effective_transfer[component_num] = pgs->set_transfer.blue; + if (pgs->effective_transfer[component_num]->proc != &gs_identity_transfer) + non_id_count++; } } - if (!is_monotonic) { - gs_free_object(memory, transfer_sampled, "gx_ht_construct_transfer_inverse"); - return -1; - } - /* Now run over our invertible range from min_pos to max_pos doing - a binary search with interpolation for the inversion */ - for (k = 0; k < 256; k++) { - float_val = (float) k / 256.0; - frac_val = float2frac(float_val); - /* Find where this value occurs */ - done = false; - hit = false; - max_pos = max_pos_start; - min_pos = min_pos_start; - while (!done) { - mid_pos = min_pos + (max_pos - min_pos) / 2; - if (frac_val > transfer_sampled[mid_pos]) { - min_pos = mid_pos; - } else if (frac_val < transfer_sampled[mid_pos]) { - max_pos = mid_pos; - } else { - done = true; - hit = true; - } - if (max_pos - min_pos == 1) { - done = true; - } + + if (pdht) { /* might not be initialized yet */ + + /* Since the transfer function is pickled into the threshold array (if any)*/ + /* we need to free it so it can be reconstructed with the current transfer */ + porder = &(pdht->order); + if (porder->threshold != NULL) { + gs_free_object(porder->data_memory->non_gc_memory, porder->threshold, + "set_effective_transfer(threshold)"); + porder->threshold = 0; } - /* OK found the point go ahead and interpolate if needed */ - if (*is_inverting) { - if (hit) { - transfer_inverse[255 - k] = - round((float) mid_pos * 255.0 / (float) (TRANSFER_INVERSE_SIZE - 1)); - } else { - /* Interpolate */ - min_val = transfer_sampled[min_pos]; - max_val = transfer_sampled[max_pos]; - float_val = (float) min_pos + - (float) (max_pos - min_pos) * (float) (frac_val - min_val) / - (float) (max_val - min_val); - transfer_inverse[255 - k] = - round(float_val * 255.0 / (float) (TRANSFER_INVERSE_SIZE - 1)); + for (i = 0; i < pdht->num_comp; i++) { + pmap = pdht->components[i].corder.transfer; + if (pmap != NULL) { + if (pgs->effective_transfer[i]->proc != &gs_identity_transfer) + non_id_count--; + pgs->effective_transfer[i] = pmap; + if (pgs->effective_transfer[i]->proc != &gs_identity_transfer) + non_id_count++; } - } else { - if (hit) { - transfer_inverse[k] = - round((float) mid_pos * 255.0 / (float) (TRANSFER_INVERSE_SIZE - 1)); - } else { - /* Interpolate */ - min_val = transfer_sampled[min_pos]; - max_val = transfer_sampled[max_pos]; - float_val = (float) min_pos + - (float) (max_pos - min_pos) * (float) (frac_val - min_val) / - (float) (max_val - min_val); - transfer_inverse[k] = - round(float_val * 255.0 / (float) (TRANSFER_INVERSE_SIZE - 1)); + porder = &(pdht->components[i].corder); + if (porder->threshold != NULL) { + gs_free_object(porder->data_memory->non_gc_memory, porder->threshold, + "set_effective_transfer(threshold)"); + porder->threshold = 0; } } } - /* Make sure the end points are set */ - if (*is_inverting) { - transfer_inverse[255] = 0; - transfer_inverse[0] = 255; - } else { - transfer_inverse[255] = 255; - transfer_inverse[0] = 0; + + pgs->effective_transfer_non_identity_count = non_id_count; +} + +void +gx_set_effective_transfer(gs_gstate * pgs) +{ + gx_gstate_set_effective_xfer(pgs); +} + +/* Check if the transfer function for a component is monotonic. */ +/* Used to determine if we can do fast halftoning */ +bool +gx_transfer_is_monotonic(const gs_gstate *pgs, int plane_index) +{ + if (pgs->effective_transfer[plane_index]->proc != gs_identity_transfer) { + bool threshold_inverted; + int t_level; + frac mapped, prev; + + prev = gx_map_color_frac(pgs, frac_0, effective_transfer[plane_index]); + threshold_inverted = prev > + gx_map_color_frac(pgs, frac_1, effective_transfer[plane_index]); + for (t_level = 1; t_level < 255; t_level++) { + mapped = gx_map_color_frac(pgs, byte2frac(t_level), effective_transfer[plane_index]); + if ((threshold_inverted && mapped > prev) || + (!threshold_inverted && mapped < prev)) + return false; + prev = mapped; + } } - gs_free_object(memory, transfer_sampled, "gx_ht_construct_transfer_inverse"); - return 0; + return true; } -#undef round -#endif -/* Lifted from threshold_from_order in gdevtsep.c. This creates a threshold - array from the tiles. Threshold is allocated in non-gc memory and is - not known to the gc */ +/* This creates a threshold array from the tiles. Threshold is allocated in + non-gc memory and is not known to the GC. The algorithm cycles through the + threshold values, computing the shade the same way as gx_render_device_DeviceN + so that the threshold matches the non-threshold halftoning. +*/ int gx_ht_construct_threshold( gx_ht_order *d_order, gx_device *dev, - const gs_imager_state * pis, int plane_index) + const gs_gstate * pgs, int plane_index) { - int i, j, l, prev_l; + int i, j; unsigned char *thresh; - gs_memory_t *memory = d_order->data_memory->non_gc_memory; + gs_memory_t *memory = d_order ? d_order->data_memory->non_gc_memory : NULL; uint max_value; unsigned long hsize, nshades; - int t_level, t_level_adjust; + int t_level; int row, col; - int delta, delta_sum = 0; - bool have_transfer = false; - byte *transfer_inverse = NULL; int code; - byte init_value = 255; - bool is_inverting = false; - int num_repeat, shift; + int num_repeat, shift, num_levels = d_order ? d_order->num_levels : 0; int row_kk, col_kk, kk; + frac t_level_frac_color; + int shade, base_shade = 0; + bool have_transfer = false, threshold_inverted = false; + if (d_order == NULL) return -1; /* We can have simple or complete orders. Simple ones tile the threshold - with shifts. To handle those we simply loop over the number of + with shifts. To handle those we simply loop over the number of repeats making sure to shift columns when we set our threshold values */ num_repeat = d_order->full_height / d_order->height; shift = d_order->shift; - if (d_order == NULL) return -1; if (d_order->threshold != NULL) return 0; - d_order->threshold_inverts = is_inverting; thresh = (byte *)gs_malloc(memory, d_order->width * d_order->full_height, 1, "gx_ht_construct_threshold"); if (thresh == NULL) { return -1 ; /* error if allocation failed */ } - d_order->threshold_inverts = false; -#if TRANSFER_IN_THRESHOLDS /* Check if we need to apply a transfer function to the values */ - if (pis->effective_transfer[plane_index]->proc != gs_identity_transfer) { - transfer_inverse = (byte *)gs_malloc(memory, 256, 1, - "gx_ht_construct_threshold"); - if (transfer_inverse == NULL) { - return -1 ; /* error if allocation failed */ - } - /* Create an inverse of the transfer. Hopefully it is invertible. If - not, we will get some strange results... */ - code = gx_ht_construct_transfer_inverse(memory, transfer_inverse, pis, - plane_index, &is_inverting); - d_order->threshold_inverts = is_inverting; - if (code < 0) { - /* If this failed then we will go and use the non-threshold code */ -#ifdef DEBUG - gs_warn("Transfer function inversion for threshold matrix failed!"); -#endif - if (transfer_inverse != NULL) { - gs_free_object(memory, transfer_inverse, "gx_ht_construct_threshold"); - } - return -1; - } else { - have_transfer = true; - init_value = transfer_inverse[255]; - } - } else { - d_order->threshold_inverts = false; + if (pgs->effective_transfer[plane_index]->proc != gs_identity_transfer) { + have_transfer = true; + threshold_inverted = gx_map_color_frac(pgs, frac_0, effective_transfer[plane_index]) > + gx_map_color_frac(pgs, frac_1, effective_transfer[plane_index]); } -#endif /* Adjustments to ensure that we properly map our 256 levels into the number of shades that we have in our halftone screen. For example if we have a 16x16 screen, we have 257 shadings that we can represent @@ -1502,74 +1383,69 @@ max_value = (dev->color_info.gray_index == plane_index) ? dev->color_info.dither_grays - 1 : dev->color_info.dither_colors - 1; - hsize = d_order->num_levels; + hsize = num_levels; nshades = hsize * max_value + 1; - for( i = 0; i < d_order->num_bits; i++ ) { - thresh[i] = init_value; - } - prev_l = 0; - l = 1; - while (l < d_order->num_levels) { - /* If we have some dots to turn on then proceed */ - if (d_order->levels[l] > d_order->levels[prev_l]) { - t_level = (256 * l) / d_order->num_levels; - t_level_adjust = byte2frac(t_level) * nshades / (frac_1_long + 1); - delta = t_level_adjust - t_level; - if (delta > delta_sum) { - /* We had a change in our value. We need to do some adjustments. - This particular level stays were it is and subsequent ones - will be offset by delta_sum. */ - t_level -= delta_sum; - delta_sum += delta; - } else { - t_level -= delta_sum; - } - /* If needed, map through the inverse of the transfer function */ - if (have_transfer) { - t_level = transfer_inverse[t_level]; - } - /* Loop over the number of dots that we have to set in going - to this new level from the old level */ - for (j = d_order->levels[prev_l]; j < d_order->levels[l]; j++) { - gs_int_point ppt; - code = d_order->procs->bit_index(d_order, j, &ppt); - if (code < 0) - return code; - row = ppt.y; - col = ppt.x; - if( col < (int)d_order->width ) { - for (kk = 0; kk < num_repeat; kk++) { - row_kk = row + kk * d_order->height; - col_kk = col + kk * shift; - col_kk = col_kk % d_order->width; - *(thresh + col_kk + (row_kk * d_order->width)) = t_level; + /* search upwards to find the correct value for the last threshold value */ + /* Use this to initialize the threshold array (transition to all white) */ + t_level = 0; + do { + t_level++; + t_level_frac_color = byte2frac(threshold_inverted ? 255 - t_level : t_level); + if (have_transfer) + t_level_frac_color = gx_map_color_frac(pgs, t_level_frac_color, effective_transfer[plane_index]); + shade = t_level_frac_color * nshades / (frac_1_long + 1); + } while (shade < num_levels && t_level < 255); + /* Initialize the thresholds to the lowest level that will be all white */ + for( i = 0; i < d_order->width * d_order->full_height; i++ ) { + thresh[i] = t_level; + } + for (t_level = 1; t_level < 256; t_level++) { + t_level_frac_color = byte2frac(threshold_inverted ? 255 - t_level : t_level); + if (have_transfer) + t_level_frac_color = gx_map_color_frac(pgs, t_level_frac_color, effective_transfer[plane_index]); + shade = t_level_frac_color * nshades / (frac_1_long + 1); + if (shade < num_levels && shade > base_shade) { + if (d_order->levels[shade] > d_order->levels[base_shade]) { + /* Loop over the number of dots that we have to set in going + to this new shade from the old shade */ + for (j = d_order->levels[base_shade]; j < d_order->levels[shade]; j++) { + gs_int_point ppt; + code = d_order->procs->bit_index(d_order, j, &ppt); + if (code < 0) + return code; + row = ppt.y; + col = ppt.x; + if( col < (int)d_order->width ) { + for (kk = 0; kk < num_repeat; kk++) { + row_kk = row + kk * d_order->height; + col_kk = col + kk * shift; + col_kk = col_kk % d_order->width; + *(thresh + col_kk + (row_kk * d_order->width)) = t_level; + } } } } - prev_l = l; + base_shade = shade; } - l++; } d_order->threshold = thresh; + d_order->threshold_inverted = threshold_inverted; if (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) { - for(i = 0; i < (int)d_order->height; i++ ) { - for( j=(int)d_order->width-1; j>=0; j-- ) - *(thresh+j+(i*d_order->width)) = 255 - *(thresh+j+(i*d_order->width)); - } - } + for(i = 0; i < (int)d_order->height; i++ ) { + for( j=(int)d_order->width-1; j>=0; j-- ) + *(thresh+j+(i*d_order->width)) = 255 - *(thresh+j+(i*d_order->width)); + } + } #ifdef DEBUG - if ( gs_debug_c('h') ) { - for( i=0; i<(int)d_order->height; i++ ) { - dmprintf1(memory, "threshold array row %3d= ", i); - for( j=(int)d_order->width-1; j>=0; j-- ) - dmprintf1(memory, "%3d ", *(thresh+j+(i*d_order->width)) ); - dmprintf(memory, "\n"); - } + if ( gs_debug_c('h') ) { + for( i=0; i<(int)d_order->height; i++ ) { + dmprintf1(memory, "threshold array row %3d= ", i); + for( j=0; j<(int)(d_order->width); j++ ) + dmprintf1(memory, "%3d ", *(thresh+j+(i*d_order->width)) ); + dmprintf(memory, "\n"); + } } #endif - if (transfer_inverse != NULL) { - gs_free_object(memory, transfer_inverse, "gx_ht_construct_threshold"); - } return 0; } diff -Nru ghostscript-9.10~dfsg/base/gsht.h ghostscript-9.25~dfsg+1/base/gsht.h --- ghostscript-9.10~dfsg/base/gsht.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsht.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,7 +23,7 @@ typedef struct gs_screen_halftone_s { float frequency; float angle; - float (*spot_function) (floatp, floatp); + float (*spot_function) (double, double); /* setscreen or sethalftone sets these: */ /* (a Level 2 feature, but we include them in Level 1) */ float actual_frequency; @@ -45,9 +45,9 @@ #define st_colorscreen_halftone_max_ptrs 0 /* Procedural interface */ -int gs_setscreen(gs_state *, gs_screen_halftone *); -int gs_currentscreen(const gs_state *, gs_screen_halftone *); -int gs_currentscreenlevels(const gs_state *); +int gs_setscreen(gs_gstate *, gs_screen_halftone *); +int gs_currentscreen(const gs_gstate *, gs_screen_halftone *); +int gs_currentscreenlevels(const gs_gstate *); /* * Enumeration-style definition of a single screen. The client must: @@ -60,9 +60,9 @@ */ typedef struct gs_screen_enum_s gs_screen_enum; gs_screen_enum *gs_screen_enum_alloc(gs_memory_t *, client_name_t); -int gs_screen_init(gs_screen_enum *, gs_state *, gs_screen_halftone *); +int gs_screen_init(gs_screen_enum *, gs_gstate *, gs_screen_halftone *); int gs_screen_currentpoint(gs_screen_enum *, gs_point *); -int gs_screen_next(gs_screen_enum *, floatp); +int gs_screen_next(gs_screen_enum *, double); int gs_screen_install(gs_screen_enum *); #endif /* gsht_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gshtscr.c ghostscript-9.25~dfsg+1/base/gshtscr.c --- ghostscript-9.10~dfsg/base/gshtscr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gshtscr.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -178,7 +178,7 @@ /* Set up for halftone sampling. */ int -gs_screen_init(gs_screen_enum * penum, gs_state * pgs, +gs_screen_init(gs_screen_enum * penum, gs_gstate * pgs, gs_screen_halftone * phsp) { gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(pgs->memory); @@ -187,7 +187,7 @@ ctx->screen_accurate_screens); } int -gs_screen_init_memory(gs_screen_enum * penum, gs_state * pgs, +gs_screen_init_memory(gs_screen_enum * penum, gs_gstate * pgs, gs_screen_halftone * phsp, bool accurate, gs_memory_t * mem) { int code = @@ -232,7 +232,7 @@ return code; } int -gs_screen_order_init_memory(gx_ht_order * porder, const gs_state * pgs, +gs_screen_order_init_memory(gx_ht_order * porder, const gs_gstate * pgs, gs_screen_halftone * phsp, bool accurate, gs_memory_t * mem) { @@ -358,11 +358,18 @@ p.R = p.R1 = rt; for (p.M = m0 + 1; p.M >= m0; p.M--) for (p.N = n0 + 1; p.N >= n0; p.N--) { - long raster, wt, wt_size; + long raster, wt; +#ifdef DEBUG + long wt_size; +#endif double fr, ar, ft, at, f_diff, a_diff, f_err, a_err; p.M1 = (int)floor(p.M / T + 0.5); p.N1 = (int)floor(p.N * T + 0.5); + + if (p.M1 == 0 && p.N1 == 0) + return_error(gs_error_rangecheck); + gx_compute_cell_values(&p); if_debug3('h', "[h]trying m=%d, n=%d, r=%d\n", p.M, p.N, rt); wt = p.W; @@ -373,7 +380,9 @@ raster = bitmap_raster(wt); if (raster > max_size / p.D || raster > max_long / wt) continue; +#ifdef DEBUG wt_size = raster * wt; +#endif /* Compute the corresponding values of F and A. */ @@ -466,7 +475,7 @@ /* This is the second half of gs_screen_init_accurate. */ int gs_screen_enum_init_memory(gs_screen_enum * penum, const gx_ht_order * porder, - gs_state * pgs, const gs_screen_halftone * phsp, + gs_gstate * pgs, const gs_screen_halftone * phsp, gs_memory_t * mem) { penum->pgs = pgs; /* ensure clean for GC */ @@ -569,7 +578,7 @@ /* Record next halftone sample */ int -gs_screen_next(gs_screen_enum * penum, floatp value) +gs_screen_next(gs_screen_enum * penum, double value) { ht_sample_t sample; int width = penum->order.width; diff -Nru ghostscript-9.10~dfsg/base/gshtx.c ghostscript-9.25~dfsg+1/base/gshtx.c --- ghostscript-9.10~dfsg/base/gshtx.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gshtx.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,7 +47,7 @@ */ static float null_closure_transfer( - floatp val, + double val, const gx_transfer_map * pmap_dummy, /* NOTUSED */ const void *dummy /* NOTUSED */ ) @@ -116,9 +116,9 @@ gs_ht_set_spot_comp( gs_ht * pht, int comp, - floatp freq, - floatp angle, - float (*spot_func) (floatp, floatp), + double freq, + double angle, + float (*spot_func) (double, double), bool accurate, gs_ht_transfer_proc transfer, const void *client_data @@ -320,7 +320,7 @@ build_component( gs_ht_component * phtc, gx_ht_order * porder, - gs_state * pgs, + gs_gstate * pgs, gs_memory_t * pmem ) { @@ -396,7 +396,7 @@ */ int gs_ht_install( - gs_state * pgs, + gs_gstate * pgs, gs_ht * pht ) { @@ -501,7 +501,7 @@ return count; } static int -create_mask_order(gx_ht_order * porder, gs_state * pgs, +create_mask_order(gx_ht_order * porder, gs_gstate * pgs, const gs_client_order_halftone * phcop, gs_memory_t * mem) { diff -Nru ghostscript-9.10~dfsg/base/gshtx.h ghostscript-9.25~dfsg+1/base/gshtx.h --- ghostscript-9.10~dfsg/base/gshtx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gshtx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -43,9 +43,9 @@ #define ht_threshold threshold #define ht_multiple multiple -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif @@ -89,9 +89,9 @@ extern int gs_ht_set_spot_comp( gs_ht * pht, int component_index, - floatp freq, - floatp angle, - float (*spot_func) (floatp, floatp), + double freq, + double angle, + float (*spot_func) (double, double), bool accurate, gs_ht_transfer_proc transfer, const void *client_data @@ -141,6 +141,6 @@ #define gs_ht_init_ptr(pto, pfrom) \ BEGIN gs_ht_reference(pfrom); pto = pfrom; END -extern int gs_ht_install(gs_state * pgs, gs_ht * pht); +extern int gs_ht_install(gs_gstate * pgs, gs_ht * pht); #endif /* gshtx_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsicc.c ghostscript-9.25~dfsg+1/base/gsicc.c --- ghostscript-9.10~dfsg/base/gsicc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,6 +31,7 @@ #include "gsicc_cms.h" #include "gsicc_manage.h" #include "gxdevice.h" +#include "gsccolor.h" #define SAVEICCPROFILE 0 @@ -54,6 +55,7 @@ static cs_proc_serialize(gx_serialize_ICC); static cs_proc_is_linear(gx_cspace_is_linear_ICC); static cs_proc_set_overprint(gx_set_overprint_ICC); +static cs_proc_polarity(gx_polarity_ICC); cs_proc_remap_color(gx_remap_ICC_imagelab); const gs_color_space_type gs_color_space_type_ICC = { @@ -73,7 +75,8 @@ gx_final_ICC, /* final */ gx_no_adjust_color_count, /* adjust_color_count */ gx_serialize_ICC, /* serialize */ - gx_cspace_is_linear_ICC + gx_cspace_is_linear_ICC, + gx_polarity_ICC }; static inline void @@ -85,7 +88,7 @@ /* ICC color mapping linearity check, a 2-points case. Check only the 1/2 point */ static int -gx_icc_is_linear_in_line(const gs_color_space *cs, const gs_imager_state * pis, +gx_icc_is_linear_in_line(const gs_color_space *cs, const gs_gstate * pgs, gx_device *dev, const gs_client_color *c0, const gs_client_color *c1, float smoothness, gsicc_link_t *icclink) @@ -105,6 +108,8 @@ int k; code = dev_proc(dev, get_profile)(dev, &(dev_profile)); + if (code < 0) + return code; ndes = gsicc_get_device_profile_comps(dev_profile); /* Get us to ushort and get mid point */ @@ -128,7 +133,7 @@ /* Default icc color mapping linearity check, a triangle case. */ static int -gx_icc_is_linear_in_triangle(const gs_color_space *cs, const gs_imager_state * pis, +gx_icc_is_linear_in_triangle(const gs_color_space *cs, const gs_gstate * pgs, gx_device *dev, const gs_client_color *c0, const gs_client_color *c1, const gs_client_color *c2, float smoothness, gsicc_link_t *icclink) @@ -157,6 +162,8 @@ cmm_dev_profile_t *dev_profile; code = dev_proc(dev, get_profile)(dev, &(dev_profile)); + if (code < 0) + return code; ndes = gsicc_get_device_profile_comps(dev_profile); /* This needs to be optimized. And range corrected */ @@ -198,7 +205,7 @@ /* ICC color mapping linearity check. */ int -gx_cspace_is_linear_ICC(const gs_color_space *cs, const gs_imager_state * pis, +gx_cspace_is_linear_ICC(const gs_color_space *cs, const gs_gstate * pgs, gx_device *dev, const gs_client_color *c0, const gs_client_color *c1, const gs_client_color *c2, const gs_client_color *c3, @@ -213,17 +220,17 @@ if (gx_device_must_halftone(dev)) return 0; if (icclink->is_identity) return 1; /* Transform is identity, linear! */ - if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN) + if (!colors_are_separable_and_linear(&dev->color_info)) return_error(gs_error_rangecheck); if (c2 == NULL) - return gx_icc_is_linear_in_line(cs, pis, dev, c0, c1, smoothness, icclink); - code = gx_icc_is_linear_in_triangle(cs, pis, dev, c0, c1, c2, + return gx_icc_is_linear_in_line(cs, pgs, dev, c0, c1, smoothness, icclink); + code = gx_icc_is_linear_in_triangle(cs, pgs, dev, c0, c1, c2, smoothness, icclink); if (code <= 0) return code; if (c3 == NULL) return 1; - return gx_icc_is_linear_in_triangle(cs, pis, dev, c1, c2, c3, + return gx_icc_is_linear_in_triangle(cs, pgs, dev, c1, c2, c3, smoothness, icclink); } /* @@ -235,6 +242,27 @@ return pcs->cmm_icc_profile_data->num_comps; } +/* Get the polarity of the ICC Based space */ +static gx_color_polarity_t +gx_polarity_ICC(const gs_color_space * pcs) +{ + switch (pcs->cmm_icc_profile_data->data_cs) { + case gsUNDEFINED: + case gsNAMED: + return GX_CINFO_POLARITY_UNKNOWN; + case gsGRAY: + case gsRGB: + case gsCIELAB: + case gsCIEXYZ: + return GX_CINFO_POLARITY_ADDITIVE; + case gsCMYK: + case gsNCHANNEL: + return GX_CINFO_POLARITY_SUBTRACTIVE; + default: + return GX_CINFO_POLARITY_UNKNOWN; + } +} + /* * Set the initial client color for an ICCBased color space. The convention * suggested by the ICC specification is to set all components to 0. @@ -261,8 +289,8 @@ const gs_range * ranges = pcs->cmm_icc_profile_data->Range.ranges; for (i = 0; i < ncomps; ++i) { - floatp v = pcc->paint.values[i]; - floatp rmin = ranges[i].rmin, rmax = ranges[i].rmax; + double v = pcc->paint.values[i]; + double rmin = ranges[i].rmin, rmax = ranges[i].rmax; if (v < rmin) pcc->paint.values[i] = rmin; @@ -272,28 +300,27 @@ } static int -gx_remap_concrete_icc_devicen(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) +gx_remap_concrete_icc_devicen(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select, + const cmm_dev_profile_t *dev_profile) { /* Check if this is a device with a DeviceN ICC profile. In this case, we need to do some special stuff */ - cmm_dev_profile_t *dev_profile; - int code; + int code = 0; - code = dev_proc(dev, get_profile)(dev, &dev_profile); - if (dev_profile->spotnames != NULL && + if (dev_profile->spotnames != NULL && !dev_profile->spotnames->equiv_cmyk_set) { - /* This means that someone has specified a DeviceN (Ncolor) + /* This means that someone has specified a DeviceN (Ncolor) ICC destination profile for this device and we still need to set up the equivalent CMYK colors for the spot colors that are present. This allows us to have some sort of composite viewing of the spot colors as they would colorimetrically appear. */ - gsicc_set_devicen_equiv_colors(dev, pis, dev_profile->device_profile[0]); + code = gsicc_set_devicen_equiv_colors(dev, pgs, dev_profile->device_profile[0]); dev_profile->spotnames->equiv_cmyk_set = true; } - gx_remap_concrete_devicen(pconc, pdc, pis, dev, select); - return 0; + gx_remap_concrete_devicen(pconc, pdc, pgs, dev, select); + return code; } /* If the color is already concretized, then we are in the color space @@ -302,42 +329,32 @@ do any halftoning. The remap is based upon the ICC profile defined in the device profile entry of the profile manager. */ int -gx_remap_concrete_ICC(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) +gx_remap_concrete_ICC(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select, + const cmm_dev_profile_t *dev_profile) { - int num_colorants; - int code; - cmm_dev_profile_t *dev_profile; - - code = dev_proc(dev, get_profile)(dev, &dev_profile); - num_colorants = gsicc_get_device_profile_comps(dev_profile); - switch( num_colorants ) { + switch (gsicc_get_device_profile_comps(dev_profile)) { case 1: - code = gx_remap_concrete_DGray(pconc, pcs, pdc, pis, dev, select); - break; + return gx_remap_concrete_DGray(pcs, pconc, pdc, pgs, dev, select, dev_profile); case 3: - code = gx_remap_concrete_DRGB(pconc, pcs, pdc, pis, dev, select); - break; + return gx_remap_concrete_DRGB(pcs, pconc, pdc, pgs, dev, select, dev_profile); case 4: - code = gx_remap_concrete_DCMYK(pconc, pcs, pdc, pis, dev, select); - break; + return gx_remap_concrete_DCMYK(pcs, pconc, pdc, pgs, dev, select, dev_profile); default: - /* This is a special case where we have a source color and our - output profile must be DeviceN. We will need to map our + /* This is a special case where we have a source color and our + output profile must be DeviceN. We will need to map our colorants to the proper planes */ - code = gx_remap_concrete_icc_devicen(pconc, pcs, pdc, pis, dev, select); - break; - } - return code; + return gx_remap_concrete_icc_devicen(pcs, pconc, pdc, pgs, dev, select, dev_profile); } +} /* * To device space */ int gx_remap_ICC(const gs_client_color * pcc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { gsicc_link_t *icc_link; @@ -354,12 +371,16 @@ cmm_dev_profile_t *dev_profile; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + if (dev_profile == NULL) + return gs_throw(gs_error_Fatal, "Attempting to do ICC remap with no profile"); num_des_comps = gsicc_get_device_profile_comps(dev_profile); - rendering_params.black_point_comp = pis->blackptcomp; + rendering_params.black_point_comp = pgs->blackptcomp; rendering_params.graphics_type_tag = dev->graphics_type_tag; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; + rendering_params.rendering_intent = pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; /* Need to clear out psrc_cm in case we have separation bands that are not color managed */ @@ -377,9 +398,12 @@ } } /* Get a link from the cache, or create if it is not there. Need to get 16 bit profile */ - icc_link = gsicc_get_link(pis, dev, pcs, NULL, &rendering_params, pis->memory); + icc_link = gsicc_get_link(pgs, dev, pcs, NULL, &rendering_params, pgs->memory); if (icc_link == NULL) { - return gs_rethrow(-1, "Could not create ICC link: Check profiles"); + #ifdef DEBUG + gs_warn("Could not create ICC link: Check profiles"); + #endif + return -1; } if (icc_link->is_identity) { psrc_temp = &(psrc[0]); @@ -400,6 +424,14 @@ if_debug1m(gs_debug_flag_icc, dev->memory, "%d ", psrc_temp[k]); } if_debug0m(gs_debug_flag_icc, dev->memory, "]\n"); + } else { + num_src_comps = pcs->cmm_icc_profile_data->num_comps; + if_debug0m(gs_debug_flag_icc, dev->memory, "[icc] Identity mapping\n"); + if_debug0m(gs_debug_flag_icc, dev->memory, "[icc] [ "); + for (k = 0; k < num_src_comps; k++) { + if_debug1m(gs_debug_flag_icc, dev->memory, "%d ", psrc[k]); + } + if_debug0m(gs_debug_flag_icc, dev->memory, "]\n"); } #endif /* Release the link */ @@ -411,7 +443,7 @@ for ( k = 0; k < num_des_comps; k++){ conc[k] = ushort2frac(psrc_temp[k]); } - gx_remap_concrete_ICC(conc, pcs, pdc, pis, dev, select); + gx_remap_concrete_ICC(pcs, conc, pdc, pgs, dev, select, dev_profile); /* Save original color space and color info into dev color */ i = pcs->cmm_icc_profile_data->num_comps; @@ -423,13 +455,13 @@ /* * Same as above, but there is no rescale of CIELAB colors. This is needed - since the rescale is not needed when the source data is image based. + since the rescale is not needed when the source data is image based. The DeviceN image rendering case uses the remap proc vs. the ICC based method which handles the remapping itself. */ int gx_remap_ICC_imagelab(const gs_client_color * pcc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { gsicc_link_t *icc_link; @@ -443,24 +475,29 @@ cmm_dev_profile_t *dev_profile; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; num_des_comps = gsicc_get_device_profile_comps(dev_profile); - rendering_params.black_point_comp = pis->blackptcomp; + rendering_params.black_point_comp = pgs->blackptcomp; rendering_params.graphics_type_tag = dev->graphics_type_tag; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; + rendering_params.rendering_intent = pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; /* Need to clear out psrc_cm in case we have separation bands that are not color managed */ - memset(psrc_cm,0,sizeof(unsigned short)*GS_CLIENT_COLOR_MAX_COMPONENTS); + memset(psrc_cm, 0, sizeof(unsigned short)*GS_CLIENT_COLOR_MAX_COMPONENTS); for (k = 0; k < pcs->cmm_icc_profile_data->num_comps; k++) psrc[k] = (unsigned short) (pcc->paint.values[k]*65535.0); /* Get a link from the cache, or create if it is not there. Need to get 16 bit profile */ - icc_link = gsicc_get_link(pis, dev, pcs, NULL, &rendering_params, pis->memory); + icc_link = gsicc_get_link(pgs, dev, pcs, NULL, &rendering_params, pgs->memory); if (icc_link == NULL) { - return gs_rethrow(-1, "Could not create ICC link: Check profiles"); + #ifdef DEBUG + gs_warn("Could not create ICC link: Check profiles"); + #endif + return -1; } if (icc_link->is_identity) { psrc_temp = &(psrc[0]); @@ -478,7 +515,7 @@ for ( k = 0; k < num_des_comps; k++){ conc[k] = ushort2frac(psrc_temp[k]); } - gx_remap_concrete_ICC(conc, pcs, pdc, pis, dev, select); + gx_remap_concrete_ICC(pcs, conc, pdc, pgs, dev, select, dev_profile); /* Save original color space and color info into dev color */ i = pcs->cmm_icc_profile_data->num_comps; @@ -495,7 +532,7 @@ const gs_client_color * pcc, const gs_color_space * pcs, frac * pconc, - const gs_imager_state * pis, + const gs_gstate * pgs, gx_device *dev) { @@ -509,21 +546,26 @@ cmm_dev_profile_t *dev_profile; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; num_des_comps = gsicc_get_device_profile_comps(dev_profile); /* Define the rendering intents. */ - rendering_params.black_point_comp = pis->blackptcomp; + rendering_params.black_point_comp = pgs->blackptcomp; rendering_params.graphics_type_tag = dev->graphics_type_tag; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; + rendering_params.rendering_intent = pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; for (k = 0; k < pcs->cmm_icc_profile_data->num_comps; k++) { psrc[k] = (unsigned short) (pcc->paint.values[k]*65535.0); } /* Get a link from the cache, or create if it is not there. Get 16 bit profile */ - icc_link = gsicc_get_link(pis, dev, pcs, NULL, &rendering_params, pis->memory); + icc_link = gsicc_get_link(pgs, dev, pcs, NULL, &rendering_params, pgs->memory); if (icc_link == NULL) { - return gs_rethrow(-1, "Could not create ICC link: Check profiles"); + #ifdef DEBUG + gs_warn("Could not create ICC link: Check profiles"); + #endif + return -1; } /* Transform the color */ if (icc_link->is_identity) { @@ -553,7 +595,7 @@ gx_final_ICC(const gs_color_space * pcs) { if (pcs->cmm_icc_profile_data != NULL) { - rc_decrement_only(pcs->cmm_icc_profile_data, "gx_final_ICC"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gx_final_ICC"); } } @@ -564,7 +606,7 @@ * the ICC profile or the alternate color space is to be used. */ static int -gx_install_ICC(gs_color_space * pcs, gs_state * pgs) +gx_install_ICC(gs_color_space * pcs, gs_gstate * pgs) { /* update the stub information used by the joint caches */ return 0; @@ -604,33 +646,66 @@ /* Overprint. Here we may have either spot colors or CMYK colors. */ static int -gx_set_overprint_ICC(const gs_color_space * pcs, gs_state * pgs) +gx_set_overprint_ICC(const gs_color_space * pcs, gs_gstate * pgs) { - gx_device * dev = pgs->device; - gx_device_color_info * pcinfo = (dev == 0 ? 0 : &dev->color_info); + gx_device *dev = pgs->device; + gx_device_color_info *pcinfo = (dev == 0 ? 0 : &dev->color_info); + bool cs_ok; cmm_dev_profile_t *dev_profile; - int code = dev_proc(dev, get_profile)(dev, &dev_profile); + bool gray_to_k; - /* check if we require special handling */ - if ( !pgs->overprint || - pgs->overprint_mode != 1 || - pcinfo == 0 || - pcs->cmm_icc_profile_data->data_cs != gsCMYK || - pcinfo->opmode == GX_CINFO_OPMODE_NOT ) { - return gx_spot_colors_set_overprint(pcs, pgs); - } + if (dev == 0 || pcinfo == NULL) + return gx_spot_colors_set_overprint(pcs, pgs); - if (pcinfo->opmode == GX_CINFO_OPMODE_RGB || - pcinfo->opmode == GC_CINFO_OPMODE_RGB_SET) { - return gx_set_overprint_rgb(pcs, pgs); - } else { + dev_proc(dev, get_profile)(dev, &dev_profile); + gray_to_k = dev_profile->devicegraytok; + + /* Possibly do CMYK based overprinting if profile is CMYK based or if we + are gray source based and doing gray to k mapping + (Ghent GWG 3.0 Gray Overprint Patch (030_Gray_K_black_OP_x1a.pdf) */ + cs_ok = ((pcs->cmm_icc_profile_data->data_cs == gsCMYK) || + (pcs->cmm_icc_profile_data->data_cs == gsGRAY && gray_to_k)); + + if (!pgs->overprint || pcinfo->opmode == GX_CINFO_OPMODE_NOT || !cs_ok) + return gx_spot_colors_set_overprint(pcs, pgs); + else return gx_set_overprint_cmyk(pcs, pgs); - } } int -gx_default_get_profile(gx_device *dev, cmm_dev_profile_t **profile) +gx_default_get_profile(gx_device *dev, cmm_dev_profile_t **profile) { *profile = dev->icc_struct; return 0; } + +/* Adjust the color model of the device to match that of the profile. Used by + vector based devices and the tiff scaled devices. Only valid for bit depths + of 8n/component. Note the caller likely will need to update its procs */ +int +gx_change_color_model(gx_device *dev, int num_comps, int bit_depth) +{ + int k; + + if (!((num_comps == 1) || (num_comps == 3) || (num_comps == 4))) + return -1; + + dev->color_info.max_components = num_comps; + dev->color_info.num_components = num_comps; + dev->color_info.depth = num_comps * bit_depth; + + if (num_comps == 4) { + dev->color_info.polarity = GX_CINFO_POLARITY_SUBTRACTIVE; + } else { + dev->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE; + } + + for (k = 0; k < num_comps; k++) { + dev->color_info.comp_shift[k] = bit_depth * (3 - k); + dev->color_info.comp_bits[k] = bit_depth; + dev->color_info.comp_mask[k] = + ((gx_color_index)255) << dev->color_info.comp_shift[k]; + } + + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/gsicc_cache.c ghostscript-9.25~dfsg+1/base/gsicc_cache.c --- ghostscript-9.10~dfsg/base/gsicc_cache.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_cache.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* GS ICC link cache. Initial stubbing of functions. */ @@ -22,7 +22,7 @@ #include "gsstruct.h" #include "scommon.h" #include "gx.h" -#include "gxistate.h" +#include "gxgstate.h" #include "smd5.h" #include "gscms.h" #include "gsicc_cms.h" @@ -50,18 +50,18 @@ static gsicc_link_t * gsicc_alloc_link(gs_memory_t *memory, gsicc_hashlink_t hashcode); -static void gsicc_get_cspace_hash(gsicc_manager_t *icc_manager, gx_device *dev, - cmm_profile_t *profile, int64_t *hash); +static int gsicc_get_cspace_hash(gsicc_manager_t *icc_manager, gx_device *dev, + cmm_profile_t *profile, int64_t *hash); -static void gsicc_compute_linkhash(gsicc_manager_t *icc_manager, gx_device *dev, - cmm_profile_t *input_profile, - cmm_profile_t *output_profile, - gsicc_rendering_param_t *rendering_params, - gsicc_hashlink_t *hash); +static int gsicc_compute_linkhash(gsicc_manager_t *icc_manager, gx_device *dev, + cmm_profile_t *input_profile, + cmm_profile_t *output_profile, + gsicc_rendering_param_t *rendering_params, + gsicc_hashlink_t *hash); static gsicc_link_t* gsicc_find_zeroref_cache(gsicc_link_cache_t *icc_link_cache); -static void gsicc_remove_link(gsicc_link_t *link, gs_memory_t *memory); +static void gsicc_remove_link(gsicc_link_t *link, const gs_memory_t *memory); static void gsicc_get_buff_hash(unsigned char *data, int64_t *hash, unsigned int num_bytes); @@ -73,13 +73,13 @@ gs_private_st_ptrs3_final(st_icc_link, gsicc_link_t, "gsiccmanage_link", icc_link_enum_ptrs, icc_link_reloc_ptrs, icc_link_finalize, - icc_link_cache, next, wait); + icc_link_cache, next, lock); struct_proc_finalize(icc_linkcache_finalize); -gs_private_st_ptrs3_final(st_icc_linkcache, gsicc_link_cache_t, "gsiccmanage_linkcache", +gs_private_st_ptrs2_final(st_icc_linkcache, gsicc_link_cache_t, "gsiccmanage_linkcache", icc_linkcache_enum_ptrs, icc_linkcache_reloc_ptrs, icc_linkcache_finalize, - head, lock, wait); + head, lock); /* These are used to construct a hash for the ICC link based upon the render parameters */ @@ -104,19 +104,22 @@ "gsicc_cache_new"); if ( result == NULL ) return(NULL); - result->lock = gx_monitor_alloc(memory->stable_memory); - result->wait = gx_semaphore_alloc(memory->stable_memory); - if (result->lock == NULL || result->wait == NULL) { +#ifdef MEMENTO_SQUEEZE_BUILD + result->lock = NULL; +#else + result->lock = gx_monitor_label(gx_monitor_alloc(memory->stable_memory), + "gsicc_cache_new"); + if (result->lock == NULL) { gs_free_object(memory->stable_memory, result, "gsicc_cache_new"); return(NULL); } - result->num_waiting = 0; +#endif rc_init_free(result, memory->stable_memory, 1, rc_gsicc_link_cache_free); result->head = NULL; result->num_links = 0; result->memory = memory->stable_memory; if_debug2m(gs_debug_flag_icc, memory, - "[icc] Allocating link cache = 0x%x memory = 0x%x\n", result, + "[icc] Allocating link cache = 0x%p memory = 0x%p\n", result, result->memory); return(result); } @@ -127,35 +130,136 @@ /* Ending the entire cache. The ref counts on all the links should be 0 */ gsicc_link_cache_t *link_cache = (gsicc_link_cache_t * ) ptr_in; + if_debug2m(gs_debug_flag_icc, mem, + "[icc] Removing link cache = 0x%p memory = 0x%p\n", + link_cache, link_cache->memory); + /* NB: freeing the link_cache will call icc_linkcache_finalize */ + gs_free_object(mem->stable_memory, link_cache, "rc_gsicc_link_cache_free"); +} + +/* release the monitor of the link_cache when it is freed */ +void +icc_linkcache_finalize(const gs_memory_t *mem, void *ptr) +{ + gsicc_link_cache_t *link_cache = (gsicc_link_cache_t * ) ptr; + while (link_cache->head != NULL) { + if (link_cache->head->ref_count != 0) { + emprintf2(mem, "link at 0x%p being removed, but has ref_count = %d\n", + link_cache->head, link_cache->head->ref_count); + link_cache->head->ref_count = 0; /* force removal */ + } gsicc_remove_link(link_cache->head, mem); - link_cache->num_links--; } #ifdef DEBUG if (link_cache->num_links != 0) { emprintf1(mem, "num_links is %d, should be 0.\n", link_cache->num_links); } #endif - gx_semaphore_free(link_cache->wait); - link_cache->wait = NULL; - gx_monitor_free(link_cache->lock); - link_cache->lock = NULL; - if_debug2m(gs_debug_flag_icc, mem, - "[icc] Removing link cache = 0x%x memory = 0x%x\n", - link_cache, link_cache->memory); - gs_free_object(mem->stable_memory, link_cache, "rc_gsicc_link_cache_free"); + if (link_cache->rc.ref_count == 0) { +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_free(link_cache->lock); + link_cache->lock = NULL; +#endif + } } -/* release the semaphore and monitor of the link_cache when it is freed */ -void -icc_linkcache_finalize(const gs_memory_t *mem, void *ptr) +/* This is a special allocation for a link that is used by devices for + doing color management on post rendered data. It is not tied into the + profile cache like gsicc_alloc_link. Also it goes ahead and creates + the link, i.e. link creation is not delayed. */ +gsicc_link_t * +gsicc_alloc_link_dev(gs_memory_t *memory, cmm_profile_t *src_profile, + cmm_profile_t *des_profile, gsicc_rendering_param_t *rendering_params) { - gsicc_link_cache_t *link_cache = (gsicc_link_cache_t * ) ptr; + gsicc_link_t *result; + int cms_flags = 0; + + result = (gsicc_link_t*) gs_malloc(memory->stable_memory, 1, + sizeof(gsicc_link_t), "gsicc_alloc_link_dev"); + + if (result == NULL) + return NULL; +#ifndef MEMENTO_SQUEEZE_BUILD + result->lock = gx_monitor_label(gx_monitor_alloc(memory->stable_memory), + "gsicc_link_new"); + if (result->lock == NULL) { + gs_free_object(memory->stable_memory, result, "gsicc_alloc_link(lock)"); + return NULL; + } + gx_monitor_enter(result->lock); +#endif + + /* set up placeholder values */ + result->is_monitored = false; + result->orig_procs.map_buffer = NULL; + result->orig_procs.map_color = NULL; + result->orig_procs.free_link = NULL; + result->next = NULL; + result->link_handle = NULL; + result->icc_link_cache = NULL; + result->procs.map_buffer = gscms_transform_color_buffer; + result->procs.map_color = gscms_transform_color; + result->procs.free_link = gscms_release_link; + result->hashcode.link_hashcode = 0; + result->hashcode.des_hash = 0; + result->hashcode.src_hash = 0; + result->hashcode.rend_hash = 0; + result->ref_count = 1; + result->includes_softproof = 0; + result->includes_devlink = 0; + result->is_identity = false; + result->valid = true; + result->memory = memory->stable_memory; - gx_semaphore_free(link_cache->wait); - link_cache->wait = NULL; - gx_monitor_free(link_cache->lock); - link_cache->lock = NULL; + if_debug2m('^', result->memory, "[^]%s 0x%lx init = 1\n", + "icclink", result); + + if (src_profile->profile_handle == NULL) { + src_profile->profile_handle = gsicc_get_profile_handle_buffer( + src_profile->buffer, src_profile->buffer_size, memory->stable_memory); + } + + if (des_profile->profile_handle == NULL) { + des_profile->profile_handle = gsicc_get_profile_handle_buffer( + des_profile->buffer, des_profile->buffer_size, memory->stable_memory); + } + + /* Check for problems.. */ + if (src_profile->profile_handle == 0 || des_profile->profile_handle == 0) { + gs_free_object(memory->stable_memory, result, "gsicc_alloc_link_dev"); + return NULL; + } + + /* [0] is chunky, littleendian, noalpha, 16-in, 16-out */ + result->link_handle = gscms_get_link(src_profile->profile_handle, + des_profile->profile_handle, rendering_params, cms_flags, + memory->stable_memory); + + /* Check for problems.. */ + if (result->link_handle == NULL) { + gs_free_object(memory->stable_memory, result, "gsicc_alloc_link_dev"); + return NULL; + } + + /* Check for identity transform */ + if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile)) + result->is_identity = true; + + /* Set the rest */ + result->data_cs = src_profile->data_cs; + result->num_input = src_profile->num_comps; + result->num_output = des_profile->num_comps; + + return result; +} + +/* And the related release of the link */ +void +gsicc_free_link_dev(gs_memory_t *memory, gsicc_link_t *link) +{ + gs_memory_t *nongc_mem = memory->non_gc_memory; + gs_free_object(nongc_mem, link, "gsicc_free_link_dev"); } static gsicc_link_t * @@ -169,11 +273,15 @@ "gsicc_alloc_link"); if (result == NULL) return NULL; - result->wait = gx_semaphore_alloc(memory->stable_memory); - if (result->wait == NULL) { - gs_free_object(memory->stable_memory, result, "gsicc_alloc_link(wait)"); +#ifndef MEMENTO_SQUEEZE_BUILD + result->lock = gx_monitor_label(gx_monitor_alloc(memory->stable_memory), + "gsicc_link_new"); + if (result->lock == NULL) { + gs_free_object(memory->stable_memory, result, "gsicc_alloc_link(lock)"); return NULL; } + gx_monitor_enter(result->lock); /* this link is owned by this thread until built and made "valid" */ +#endif /* set up placeholder values */ result->is_monitored = false; result->orig_procs.map_buffer = NULL; @@ -193,8 +301,11 @@ result->includes_devlink = 0; result->is_identity = false; result->valid = false; /* not yet complete */ - result->num_waiting = 0; - return(result); + result->memory = memory->stable_memory; + + if_debug2m('^', result->memory, "[^]%s 0x%lx init = 1\n", + "icclink", result); + return result; } static void @@ -203,9 +314,12 @@ bool includes_softproof, bool includes_devlink, bool pageneutralcolor, gsicc_colorbuffer_t data_cs) { +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_enter(lock); /* lock the cache while changing data */ +#endif icc_link->link_handle = link_handle; - gscms_get_link_dim(link_handle, &(icc_link->num_input), &(icc_link->num_output)); + gscms_get_link_dim(link_handle, &(icc_link->num_input), &(icc_link->num_output), + icc_link->memory); icc_link->hashcode.link_hashcode = hashcode.link_hashcode; icc_link->hashcode.des_hash = hashcode.des_hash; icc_link->hashcode.src_hash = hashcode.src_hash; @@ -218,38 +332,43 @@ } else { icc_link->is_identity = false; } - icc_link->valid = true; - /* Set up for monitoring */ icc_link->data_cs = data_cs; - if (pageneutralcolor) + if (pageneutralcolor) gsicc_mcm_set_link(icc_link); - /* Now release any tasks/threads waiting for these contents */ - while (icc_link->num_waiting > 0) { - gx_semaphore_signal(icc_link->wait); - icc_link->num_waiting--; - } + /* release the lock of the link so it can now be used */ + icc_link->valid = true; +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_leave(icc_link->lock); gx_monitor_leave(lock); /* done with updating, let everyone run */ +#endif } -void -gsicc_link_free(gsicc_link_t *icc_link, gs_memory_t *memory) +static void +gsicc_link_free_contents(gsicc_link_t *icc_link) { icc_link->procs.free_link(icc_link); - gx_semaphore_free(icc_link->wait); - icc_link->wait = NULL; +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_free(icc_link->lock); + icc_link->lock = NULL; +#endif +} + +void +gsicc_link_free(gsicc_link_t *icc_link, const gs_memory_t *memory) +{ + gsicc_link_free_contents(icc_link); + gs_free_object(memory->stable_memory, icc_link, "gsicc_link_free"); } -/* release the semaphore of the link when it is freed */ void icc_link_finalize(const gs_memory_t *mem, void *ptr) { gsicc_link_t *icc_link = (gsicc_link_t * ) ptr; - gx_semaphore_free(icc_link->wait); - icc_link->wait = NULL; + gsicc_link_free_contents(icc_link); } static void @@ -259,6 +378,19 @@ (hash->des_hash >> 1) ^ (hash->rend_hash) ^ (hash->src_hash); } +int64_t +gsicc_get_hash(cmm_profile_t *profile) +{ + if (!profile->hash_is_valid) { + int64_t hash; + + gsicc_get_icc_buff_hash(profile->buffer, &hash, profile->buffer_size); + profile->hashcode = hash; + profile->hash_is_valid = true; + } + return profile->hashcode; +} + void gsicc_get_icc_buff_hash(unsigned char *buffer, int64_t *hash, unsigned int buff_size) { @@ -297,16 +429,24 @@ This just computes a 64bit xor of upper and lower portions of md5 for the input, output and rendering params structure. We may change this later */ -static void +static int gsicc_compute_linkhash(gsicc_manager_t *icc_manager, gx_device *dev, cmm_profile_t *input_profile, cmm_profile_t *output_profile, gsicc_rendering_param_t *rendering_params, gsicc_hashlink_t *hash) { - /* first get the hash codes for the color spaces */ - gsicc_get_cspace_hash(icc_manager, dev, input_profile, &(hash->src_hash)); - gsicc_get_cspace_hash(icc_manager, dev, output_profile, &(hash->des_hash)); + int code; + + /* first get the hash codes for the color spaces */ + code = gsicc_get_cspace_hash(icc_manager, dev, input_profile, + &(hash->src_hash)); + if (code < 0) + return code; + code = gsicc_get_cspace_hash(icc_manager, dev, output_profile, + &(hash->des_hash)); + if (code < 0) + return code; /* now for the rendering paramaters, just use the word itself. At this point in time, we only include the black point setting, the intent @@ -318,48 +458,55 @@ hash->rend_hash = ((rendering_params->black_point_comp) << BP_SHIFT) + ((rendering_params->rendering_intent) << REND_SHIFT) + ((rendering_params->preserve_black) << PRESERVE_SHIFT); - /* for now, mash all of these into a link hash */ - gsicc_mash_hash(hash); + /* for now, mash all of these into a link hash */ + gsicc_mash_hash(hash); + return 0; } -static void +static int gsicc_get_cspace_hash(gsicc_manager_t *icc_manager, gx_device *dev, cmm_profile_t *cmm_icc_profile_data, int64_t *hash) { cmm_dev_profile_t *dev_profile; cmm_profile_t *icc_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; int code; - if (cmm_icc_profile_data == NULL ) { - code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (cmm_icc_profile_data == NULL) + { + if (dev == NULL) + return -1; + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; gsicc_extract_profile(dev->graphics_type_tag, dev_profile, - &(icc_profile), &render_cond); + &(icc_profile), &render_cond); *hash = icc_profile->hashcode; - return; + return 0; } if (cmm_icc_profile_data->hash_is_valid ) { *hash = cmm_icc_profile_data->hashcode; - return; } else { /* We need to compute for this color space */ gsicc_get_icc_buff_hash(cmm_icc_profile_data->buffer, hash, cmm_icc_profile_data->buffer_size); cmm_icc_profile_data->hashcode = *hash; cmm_icc_profile_data->hash_is_valid = true; - return; } + return 0; } gsicc_link_t* -gsicc_findcachelink(gsicc_hashlink_t hash, gsicc_link_cache_t *icc_link_cache, +gsicc_findcachelink(gsicc_hashlink_t hash, gsicc_link_cache_t *icc_link_cache, bool includes_proof, bool includes_devlink) { gsicc_link_t *curr, *prev; int64_t hashcode = hash.link_hashcode; /* Look through the cache for the hashcode */ +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_enter(icc_link_cache->lock); +#endif /* List scanning is fast, so we scan the entire list, this includes */ /* links that are currently unused, but still in the cache (zero_ref) */ @@ -367,32 +514,46 @@ prev = NULL; while (curr != NULL ) { - if (curr->hashcode.link_hashcode == hashcode && + if (curr->hashcode.link_hashcode == hashcode && includes_proof == curr->includes_softproof && includes_devlink == curr->includes_devlink) { - /* move this one to the front of the list hoping we will use it + /* move this one to the front of the list hoping we will use it again soon */ - if (prev != NULL) { + if (prev != NULL) { /* if prev == NULL, curr is already the head */ prev->next = curr->next; curr->next = icc_link_cache->head; icc_link_cache->head = curr; } - curr->ref_count++; /* bump the ref_count since we will be using this one */ + curr->ref_count++; + if_debug3m('^', curr->memory, "[^]%s 0x%lx ++ => %ld\n", + "icclink", curr, curr->ref_count); while (curr->valid == false) { - curr->num_waiting++; - gx_monitor_leave(icc_link_cache->lock); - gx_semaphore_wait(curr->wait); - gx_monitor_enter(icc_link_cache->lock); /* re-enter breifly */ +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_leave(icc_link_cache->lock); /* exit to let other threads run briefly */ + gx_monitor_enter(curr->lock); /* wait until we can acquire the lock */ + gx_monitor_leave(curr->lock); /* it _should be valid now */ + /* If it is still not valid, but we were able to lock, it means that the thread */ + /* that was building it failed to be able to complete building it */ + /* this is probably a fatal error. MV ??? */ + if (curr->valid == false) { + emprintf1(curr->memory, "link 0x%p lock released, but still not valid.\n", curr); /* Breakpoint here */ + } + gx_monitor_enter(icc_link_cache->lock); /* re-enter to loop and check */ +#endif } +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_leave(icc_link_cache->lock); +#endif return(curr); /* success */ } prev = curr; curr = curr->next; } +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_leave(icc_link_cache->lock); +#endif return NULL; } @@ -417,6 +578,8 @@ while (curr != NULL ) { if (curr->ref_count == 0) { curr->ref_count++; /* we will use this one */ + if_debug3m('^', curr->memory, "[^]%s 0x%lx ++ => %ld\n", + "icclink", curr, curr->ref_count); break; } curr = curr->next; @@ -426,21 +589,27 @@ /* Remove link from cache. Notify CMS and free */ static void -gsicc_remove_link(gsicc_link_t *link, gs_memory_t *memory) +gsicc_remove_link(gsicc_link_t *link, const gs_memory_t *memory) { gsicc_link_t *curr, *prev; gsicc_link_cache_t *icc_link_cache = link->icc_link_cache; if_debug2m(gs_debug_flag_icc, memory, - "[icc] Removing link = 0x%x memory = 0x%x\n", link, + "[icc] Removing link = 0x%p memory = 0x%p\n", link, memory->stable_memory); /* NOTE: link->ref_count must be 0: assert ? */ +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_enter(icc_link_cache->lock); +#endif + if (link->ref_count != 0) { + emprintf2(memory, "link at 0x%p being removed, but has ref_count = %d\n", link, link->ref_count); + } curr = icc_link_cache->head; prev = NULL; while (curr != NULL ) { - if (curr == link) { + /* don't get rid of it if another thread has decided to use it */ + if (curr == link && link->ref_count == 0) { /* remove this one from the list */ if (prev == NULL) icc_link_cache->head = curr->next; @@ -451,13 +620,82 @@ prev = curr; curr = curr->next; } - /* if curr != link we didn't find it: assert ? */ - gx_monitor_leave(icc_link_cache->lock); - gsicc_link_free(link, memory); /* outside link */ + /* if curr != link we didn't find it or another thread may have decided to */ + /* use it (ref_count > 0). Skip freeing it if so. */ + if (curr == link && link->ref_count == 0) { + icc_link_cache->num_links--; /* no longer in the cache */ +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_leave(icc_link_cache->lock); +#endif + gsicc_link_free(link, memory); /* outside link cache now. */ + } else { + /* even if we didn't find the link to remove, unlock the cache */ +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_leave(icc_link_cache->lock); +#endif + } +} + +static void +gsicc_get_srcprofile(gsicc_colorbuffer_t data_cs, + gs_graphics_type_tag_t graphics_type_tag, + cmm_srcgtag_profile_t *srcgtag_profile, cmm_profile_t **profile, + gsicc_rendering_param_t *render_cond) +{ + (*profile) = NULL; + (*render_cond).rendering_intent = gsPERCEPTUAL; + switch (graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS) { + case GS_UNKNOWN_TAG: + case GS_UNTOUCHED_TAG: + default: + break; + case GS_PATH_TAG: + if (data_cs == gsRGB) { + (*profile) = srcgtag_profile->rgb_profiles[gsSRC_GRAPPRO]; + *render_cond = srcgtag_profile->rgb_rend_cond[gsSRC_GRAPPRO]; + } + else if (data_cs == gsCMYK) { + (*profile) = srcgtag_profile->cmyk_profiles[gsSRC_GRAPPRO]; + *render_cond = srcgtag_profile->cmyk_rend_cond[gsSRC_GRAPPRO]; + } + else if (data_cs == gsGRAY) { + (*profile) = srcgtag_profile->gray_profiles[gsSRC_GRAPPRO]; + *render_cond = srcgtag_profile->gray_rend_cond[gsSRC_GRAPPRO]; + } + break; + case GS_IMAGE_TAG: + if (data_cs == gsRGB) { + (*profile) = srcgtag_profile->rgb_profiles[gsSRC_IMAGPRO]; + *render_cond = srcgtag_profile->rgb_rend_cond[gsSRC_IMAGPRO]; + } + else if (data_cs == gsCMYK) { + (*profile) = srcgtag_profile->cmyk_profiles[gsSRC_IMAGPRO]; + *render_cond = srcgtag_profile->cmyk_rend_cond[gsSRC_IMAGPRO]; + } + else if (data_cs == gsGRAY) { + (*profile) = srcgtag_profile->gray_profiles[gsSRC_IMAGPRO]; + *render_cond = srcgtag_profile->gray_rend_cond[gsSRC_IMAGPRO]; + } + break; + case GS_TEXT_TAG: + if (data_cs == gsRGB) { + (*profile) = srcgtag_profile->rgb_profiles[gsSRC_TEXTPRO]; + *render_cond = srcgtag_profile->rgb_rend_cond[gsSRC_TEXTPRO]; + } + else if (data_cs == gsCMYK) { + (*profile) = srcgtag_profile->cmyk_profiles[gsSRC_TEXTPRO]; + *render_cond = srcgtag_profile->cmyk_rend_cond[gsSRC_TEXTPRO]; + } + else if (data_cs == gsGRAY) { + (*profile) = srcgtag_profile->gray_profiles[gsSRC_TEXTPRO]; + *render_cond = srcgtag_profile->gray_rend_cond[gsSRC_TEXTPRO]; + } + break; + } } gsicc_link_t* -gsicc_get_link(const gs_imager_state *pis, gx_device *dev_in, +gsicc_get_link(const gs_gstate *pgs1, gx_device *dev_in, const gs_color_space *pcs_in, gs_color_space *output_colorspace, gsicc_rendering_param_t *rendering_params, gs_memory_t *memory) @@ -465,79 +703,88 @@ cmm_profile_t *gs_input_profile; cmm_profile_t *gs_srcgtag_profile = NULL; cmm_profile_t *gs_output_profile; - gs_state *pgs; + gs_gstate *pgs = (gs_gstate *)pgs1; gx_device *dev; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; int code; bool devicegraytok; gs_color_space *input_colorspace = (gs_color_space*) pcs_in; if (dev_in == NULL) { - /* Get from the imager state which is going to be a graphic state. + /* Get from the gs_gstate which is going to be a graphic state. This only occurs for the other (non-ps/pdf) interpreters */ - pgs = (gs_state*) pis; + pgs = (gs_gstate*) pgs; dev = pgs->device; } else { dev = dev_in; } - if ( input_colorspace->cmm_icc_profile_data == NULL ) { - /* Use default type */ - gs_input_profile = gsicc_get_gscs_profile(input_colorspace, pis->icc_manager); + if (input_colorspace->cmm_icc_profile_data == NULL) { + if (input_colorspace->icc_equivalent != NULL) { + gs_input_profile = input_colorspace->icc_equivalent->cmm_icc_profile_data; + } else { + /* Use default type */ + gs_input_profile = gsicc_get_gscs_profile(input_colorspace, + pgs->icc_manager); + } } else { gs_input_profile = input_colorspace->cmm_icc_profile_data; } code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return NULL; /* If present, use an graphic object defined source profile */ - if (pis->icc_manager != NULL && - pis->icc_manager->srcgtag_profile != NULL) { + if (pgs->icc_manager != NULL && + pgs->icc_manager->srcgtag_profile != NULL) { if (gs_input_profile->data_cs == gsRGB - || gs_input_profile->data_cs == gsCMYK) { + || gs_input_profile->data_cs == gsCMYK + || gs_input_profile->data_cs == gsGRAY) { gsicc_get_srcprofile(gs_input_profile->data_cs, dev->graphics_type_tag, - pis->icc_manager->srcgtag_profile, + pgs->icc_manager->srcgtag_profile, &(gs_srcgtag_profile), &render_cond); if (gs_srcgtag_profile != NULL) { /* In this case, the user is letting the source profiles - drive the color management. Let that set the - rendering intent and blackpoint compensation also as they + drive the color management. Let that set the + rendering intent and blackpoint compensation also as they must know what they are doing. However, before we do - this we need to check if they want to overide - embedded source profiles. See if our profile is a + this we need to check if they want to overide + embedded source profiles. See if our profile is a default one that came from DefaultRGB or DefaultCMYK for example */ int csi; - + csi = gsicc_get_default_type(gs_input_profile); - if (render_cond.override_icc || + if (render_cond.override_icc || csi == gs_color_space_index_DeviceRGB || - csi == gs_color_space_index_DeviceCMYK) { + csi == gs_color_space_index_DeviceCMYK || + csi == gs_color_space_index_DeviceGray) { gs_input_profile = gs_srcgtag_profile; (*rendering_params) = render_cond; } /* We also need to worry about the case when the source profile is actually a device link profile. In this case we can go ahead now and the our link transform as we - don't need to worry about a destination profile. + don't need to worry about a destination profile. However, it is possible that someone could do another device link profile associated with the device. */ if (gs_input_profile->isdevlink) { /* OK. Go ahead and use this one. Note output profile is not NULL so that we can compute a hash with out special conditional logic */ - rendering_params->rendering_intent = + rendering_params->rendering_intent = render_cond.rendering_intent & gsRI_MASK; - rendering_params->black_point_comp = + rendering_params->black_point_comp = render_cond.black_point_comp & gsBP_MASK; - return gsicc_get_link_profile(pis, dev, gs_input_profile, - dev_profile->device_profile[0], - rendering_params, memory, + return gsicc_get_link_profile(pgs, dev, gs_input_profile, + dev_profile->device_profile[0], + rendering_params, memory, false); } } else { /* In this case we may be wanting for a "unmanaged color" - result. This is done by specifying "None" on the + result. This is done by specifying "None" on the particular line for that source object. Check if this is what is desired. If it is, then return the link now. Also need to worry about the replace case */ @@ -545,20 +792,20 @@ gsicc_link_t *link; if (gs_input_profile->data_cs == gsRGB) { - link = gsicc_nocm_get_link(pis, dev, 3); + link = gsicc_nocm_get_link(pgs, dev, 3); } else { - link = gsicc_nocm_get_link(pis, dev, 4); + link = gsicc_nocm_get_link(pgs, dev, 4); } /* Set the identity case if we are in that situation */ if (link != NULL) { - if (gs_input_profile->num_comps == + if (gs_input_profile->num_comps == dev_profile->device_profile[0]->num_comps) { link->is_identity = true; } return link; } } else if (render_cond.cmm == gsCMM_REPLACE) { - return gsicc_rcm_get_link(pis, dev, + return gsicc_rcm_get_link(pgs, dev, gs_input_profile->data_cs); /* Note that there is never an identity case */ } @@ -569,21 +816,21 @@ gs_output_profile = output_colorspace->cmm_icc_profile_data; devicegraytok = false; } else { - /* Use the device profile. Only use the rendering intent if it has - an override setting. Also, only use the blackpoint if overide_bp + /* Use the device profile. Only use the rendering intent if it has + an override setting. Also, only use the blackpoint if overide_bp is set. Note that this can conflict with intents set from the source objects so the user needs to understand what options to set. */ - gs_color_space_index index = + gs_color_space_index index = gsicc_get_default_type(gs_input_profile); code = dev_proc(dev, get_profile)(dev, &dev_profile); /* Check for unmanaged color case */ - if (index < gs_color_space_index_DevicePixel && + if (index < gs_color_space_index_DevicePixel && dev_profile->usefastcolor) { /* Return a "link" from the source space to the device color space */ - gsicc_link_t *link = gsicc_nocm_get_link(pis, dev, + gsicc_link_t *link = gsicc_nocm_get_link(pgs, dev, gs_input_profile->num_comps); if (link != NULL) { - if (gs_input_profile->num_comps == + if (gs_input_profile->num_comps == dev_profile->device_profile[0]->num_comps) { link->is_identity = true; } @@ -598,19 +845,19 @@ if (!(rendering_params->rendering_intent & gsRI_OVERRIDE)) { /* No it was not. Check if our device profile RI was specified */ if (render_cond.rendering_intent != gsRINOTSPECIFIED) { - rendering_params->rendering_intent = render_cond.rendering_intent; + rendering_params->rendering_intent = render_cond.rendering_intent; } } /* Similar for the black point compensation */ if (!(rendering_params->black_point_comp & gsBP_OVERRIDE)) { if (render_cond.black_point_comp != gsBPNOTSPECIFIED) { - rendering_params->black_point_comp = render_cond.black_point_comp; + rendering_params->black_point_comp = render_cond.black_point_comp; } } /* And the Black preservation */ if (!(rendering_params->preserve_black & gsKP_OVERRIDE)) { - if (render_cond.preserve_black != gsBPNOTSPECIFIED) { - rendering_params->preserve_black = render_cond.preserve_black; + if (render_cond.preserve_black != gsBKPRESNOTSPECIFIED) { + rendering_params->preserve_black = render_cond.preserve_black; } } devicegraytok = dev_profile->devicegraytok; @@ -621,41 +868,47 @@ rendering_params->rendering_intent = rendering_params->rendering_intent & gsRI_MASK; rendering_params->black_point_comp = rendering_params->black_point_comp & gsBP_MASK; rendering_params->preserve_black = rendering_params->preserve_black & gsKP_MASK; - return gsicc_get_link_profile(pis, dev, gs_input_profile, gs_output_profile, + return gsicc_get_link_profile(pgs, dev, gs_input_profile, gs_output_profile, rendering_params, memory, devicegraytok); } /* This operation of adding in a new link entry is actually shared amongst different functions that can each add an entry. For example, entrys may - come from the CMM or they may come from the non color managed approach - (i.e. gsicc_nocm_get_link) */ + come from the CMM or they may come from the non color managed approach + (i.e. gsicc_nocm_get_link) + Returns true if link was found with that has, false if alloc fails. +*/ bool -gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, +gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, gsicc_link_t **ret_link, gsicc_hashlink_t hash, bool include_softproof, bool include_devlink) { gs_memory_t *cache_mem = icc_link_cache->memory; gsicc_link_t *link; + *ret_link = NULL; /* First see if we can add a link */ /* TODO: this should be based on memory usage, not just num_links */ +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_enter(icc_link_cache->lock); +#endif while (icc_link_cache->num_links >= ICC_CACHE_MAXLINKS) { /* If not, see if there is anything we can remove from cache. */ while ((link = gsicc_find_zeroref_cache(icc_link_cache)) == NULL) { - icc_link_cache->num_waiting++; - /* safe to unlock since above will make sure semaphore is signalled */ +#ifndef MEMENTO_SQUEEZE_BUILD + /* unlock while waiting for a link to come available */ gx_monitor_leave(icc_link_cache->lock); - /* we get signalled (released from wait) when a link goes to zero ref */ - gx_semaphore_wait(icc_link_cache->wait); +#endif /* repeat the findcachelink to see if some other thread has */ /*already started building the link we need */ - *ret_link = gsicc_findcachelink(hash, icc_link_cache, + *ret_link = gsicc_findcachelink(hash, icc_link_cache, include_softproof, include_devlink); - /* Got a hit, return link (ref_count for the link was already bumped */ + /* Got a hit, return link. ref_count for the link was already bumped */ if (*ret_link != NULL) - return true; + return true; +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_enter(icc_link_cache->lock); /* restore the lock */ +#endif /* we will re-test the num_links above while locked to insure */ /* that some other thread didn't grab the slot and max us out */ } @@ -664,32 +917,35 @@ /* the outermost 'while' will check to make sure some other */ /* thread did not grab the one we remove. */ gsicc_remove_link(link, cache_mem); - icc_link_cache->num_links--; } - /* insert an empty link that we will reserve so we */ - /* can unlock while building the link contents */ + /* insert an empty link that we will reserve so we can unlock while */ + /* building the link contents. If successful, the entry will set */ + /* the hash for the link, set valid=false, and lock the profile */ (*ret_link) = gsicc_alloc_link(cache_mem->stable_memory, hash); + /* NB: the link returned will be have the lock owned by this thread */ + /* the lock will be released when the link becomes valid. */ if (*ret_link) { (*ret_link)->icc_link_cache = icc_link_cache; (*ret_link)->next = icc_link_cache->head; icc_link_cache->head = *ret_link; icc_link_cache->num_links++; - /* now that we own this link we can release - the lock since it is not valid */ } +#ifndef MEMENTO_SQUEEZE_BUILD + /* unlock before returning */ gx_monitor_leave(icc_link_cache->lock); +#endif return false; } -/* This is the main function called to obtain a linked transform from the ICC - cache If the cache has the link ready, it will return it. If not, it will - request one from the CMS and then return it. We may need to do some cache - locking during this process to avoid multi-threaded issues (e.g. someone +/* This is the main function called to obtain a linked transform from the ICC + cache If the cache has the link ready, it will return it. If not, it will + request one from the CMS and then return it. We may need to do some cache + locking during this process to avoid multi-threaded issues (e.g. someone deleting while someone is updating a reference count). Note that if the source profile is a device link profile we have no output profile but may still have a proofing or another device link profile to use */ gsicc_link_t* -gsicc_get_link_profile(const gs_imager_state *pis, gx_device *dev, +gsicc_get_link_profile(const gs_gstate *pgs, gx_device *dev, cmm_profile_t *gs_input_profile, cmm_profile_t *gs_output_profile, gsicc_rendering_param_t *rendering_params, @@ -698,9 +954,9 @@ gsicc_hashlink_t hash; gsicc_link_t *link, *found_link; gcmmhlink_t link_handle = NULL; - gsicc_manager_t *icc_manager = pis->icc_manager; - gsicc_link_cache_t *icc_link_cache = pis->icc_link_cache; - gs_memory_t *cache_mem = pis->icc_link_cache->memory; + gsicc_manager_t *icc_manager = pgs->icc_manager; + gsicc_link_cache_t *icc_link_cache = pgs->icc_link_cache; + gs_memory_t *cache_mem = pgs->icc_link_cache->memory; gcmmhprofile_t *cms_input_profile; gcmmhprofile_t *cms_output_profile = NULL; gcmmhprofile_t *cms_proof_profile = NULL; @@ -713,16 +969,19 @@ cmm_profile_t *devlink_profile = NULL; bool src_dev_link = gs_input_profile->isdevlink; bool pageneutralcolor = false; + int cms_flags = 0; /* Determine if we are using a soft proof or device link profile */ if (dev != NULL ) { code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return NULL; if (dev_profile != NULL) { proof_profile = dev_profile->proof_profile; devlink_profile = dev_profile->link_profile; pageneutralcolor = dev_profile->pageneutralcolor; } - /* If the source color is the same as the proofing color then we do not + /* If the source color is the same as the proofing color then we do not need to apply the proofing color in this case. This occurs in cases where we have a CMYK output intent profile, a Device CMYK color, and are going out to an RGB device */ @@ -735,44 +994,48 @@ } if (devlink_profile != NULL) include_devicelink = true; } - /* First compute the hash code for the incoming case. If the output color + /* First compute the hash code for the incoming case. If the output color space is NULL we will use the device profile for the output color space */ - gsicc_compute_linkhash(icc_manager, dev, gs_input_profile, gs_output_profile, - rendering_params, &hash); + code = gsicc_compute_linkhash(icc_manager, dev, gs_input_profile, + gs_output_profile, + rendering_params, &hash); + if (code < 0) + return NULL; /* Check the cache for a hit. Need to check if softproofing was used */ found_link = gsicc_findcachelink(hash, icc_link_cache, include_softproof, include_devicelink); /* Got a hit, return link (ref_count for the link was already bumped */ if (found_link != NULL) { if_debug2m(gs_debug_flag_icc, memory, - "[icc] Found Link = 0x%x, hash = %I64d \n", - found_link, hash.link_hashcode); + "[icc] Found Link = 0x%p, hash = %lld \n", + found_link, (long long)hash.link_hashcode); if_debug2m(gs_debug_flag_icc, memory, - "[icc] input_numcomps = %d, input_hash = %I64d \n", - gs_input_profile->num_comps, gs_input_profile->hashcode); + "[icc] input_numcomps = %d, input_hash = %lld \n", + gs_input_profile->num_comps, + (long long)gs_input_profile->hashcode); if_debug2m(gs_debug_flag_icc, memory, - "[icc] output_numcomps = %d, output_hash = %I64d \n", - gs_output_profile->num_comps, gs_output_profile->hashcode); + "[icc] output_numcomps = %d, output_hash = %lld \n", + gs_output_profile->num_comps, + (long long)gs_output_profile->hashcode); return found_link; } /* Before we do anything, check if we have a case where the source profile is coming from the clist and we don't even want to be doing any color managment */ - if (gs_input_profile->profile_handle == NULL && + if (gs_input_profile->profile_handle == NULL && gs_input_profile->buffer == NULL && gs_input_profile->dev != NULL) { - /* ICC profile should be in clist. This is - the first call to it. Note that the profiles are not - really shared amongst threads like the links are. Hence - the memory is for the local thread's chunk */ + /* ICC profile should be in clist. This is the first call to it. Note that + the profiles are not really shared amongst threads like the links are. + Hence the memory is for the local thread's chunk */ cms_input_profile = gsicc_get_profile_handle_clist(gs_input_profile, gs_input_profile->memory); gs_input_profile->profile_handle = cms_input_profile; /* It is possible that we are not using color management due to a setting forced from srcgtag object (the None option) - which has made its way though the clist in the clist imaging + which has made its way though the clist in the clist imaging code. In this case, the srcgtag_profile structure which was part of the ICC manager is no longer available. We also have the Replace option. */ @@ -780,13 +1043,13 @@ gs_input_profile->rend_cond.cmm == gsCMM_NONE) { if (gs_input_profile->data_cs == gsRGB) { - link = gsicc_nocm_get_link(pis, dev, 3); + link = gsicc_nocm_get_link(pgs, dev, 3); } else { - link = gsicc_nocm_get_link(pis, dev, 4); + link = gsicc_nocm_get_link(pgs, dev, 4); } /* Set the identity case if we are in that situation */ if (link != NULL) { - if (gs_input_profile->num_comps == + if (gs_input_profile->num_comps == dev_profile->device_profile[0]->num_comps) { link->is_identity = true; } @@ -794,25 +1057,34 @@ } } else if (gs_input_profile->rend_is_valid && gs_input_profile->rend_cond.cmm == gsCMM_REPLACE) { - return gsicc_rcm_get_link(pis, dev, gs_input_profile->data_cs); + return gsicc_rcm_get_link(pgs, dev, gs_input_profile->data_cs); /* Note that there is never an identity case for this type. */ - } + } /* We may have a source profile that is a device link profile and - made its way through the clist. If so get things set up to + made its way through the clist. If so get things set up to handle that properly. */ src_dev_link = gs_input_profile->isdevlink; } - /* No link was found so lets create a new one if there is room. This may + /* No link was found so lets create a new one if there is room. This may actually return a link if another thread has already created it */ if (gsicc_alloc_link_entry(icc_link_cache, &link, hash, include_softproof, - include_devicelink)) + include_devicelink)) return link; if (link == NULL) - return NULL; + return NULL; /* error, couldn't allocate a link */ + /* Here the link was new and the contents have valid=false and we */ + /* own the lock for the link_profile. Build the profile, set valid */ + /* to true and release the lock. */ /* Now compute the link contents */ cms_input_profile = gs_input_profile->profile_handle; + /* Check if the source was generated from a PS CIE color space. If yes, + then we need to make sure that the CMM does not do something like + force a white point mapping like lcms does */ + if (gsicc_profile_from_ps(gs_input_profile)) { + cms_flags = cms_flags | gscms_avoid_white_fix_flag(memory); + } if (cms_input_profile == NULL) { if (gs_input_profile->buffer != NULL) { cms_input_profile = @@ -822,19 +1094,16 @@ if (cms_input_profile == NULL) return NULL; gs_input_profile->profile_handle = cms_input_profile; - if (cms_input_profile == NULL) - return NULL; /* This *must* be a default profile that was not set up at start-up/ However it could be one from the icc creator code which does not do an initialization at the time of creation from CalRGB etc. */ - code = gsicc_initialize_default_profile(gs_input_profile); + code = gsicc_initialize_default_profile(gs_input_profile); if (code < 0) return NULL; } else { /* Cant create the link. No profile present, nor any defaults to use for this. Really need to throw an error for this case. */ gsicc_remove_link(link, cache_mem); - icc_link_cache->num_links--; return NULL; } } @@ -851,7 +1120,7 @@ memory); gs_output_profile->profile_handle = cms_output_profile; /* This *must* be a default profile that was not set up at start-up */ - code = gsicc_initialize_default_profile(gs_output_profile); + code = gsicc_initialize_default_profile(gs_output_profile); if (code < 0) return NULL; } else { /* See if we have a clist device pointer. */ @@ -867,7 +1136,6 @@ nor any defaults to use for this. Really need to throw an error for this case. */ gsicc_remove_link(link, cache_mem); - icc_link_cache->num_links--; return NULL; } } @@ -881,11 +1149,13 @@ proof_profile->buffer_size, memory); proof_profile->profile_handle = cms_proof_profile; - gx_monitor_enter(proof_profile->lock); +#if !defined(MEMENTO_SQUEEZE_BUILD) + if (!gscms_is_threadsafe()) + gx_monitor_enter(proof_profile->lock); +#endif } else { /* Cant create the link */ gsicc_remove_link(link, cache_mem); - icc_link_cache->num_links--; return NULL; } } @@ -899,42 +1169,57 @@ devlink_profile->buffer_size, memory); devlink_profile->profile_handle = cms_devlink_profile; - gx_monitor_enter(devlink_profile->lock); +#if !defined(MEMENTO_SQUEEZE_BUILD) + if (!gscms_is_threadsafe()) + gx_monitor_enter(devlink_profile->lock); +#endif } else { /* Cant create the link */ gsicc_remove_link(link, cache_mem); - icc_link_cache->num_links--; return NULL; } } } - /* Profile reading of same structure not thread safe in lcms */ - gx_monitor_enter(gs_input_profile->lock); - if (!src_dev_link) { - gx_monitor_enter(gs_output_profile->lock); +#if !defined(MEMENTO_SQUEEZE_BUILD) + /* Profile reading of same structure not thread safe in CMM */ + if (!gscms_is_threadsafe()) { + gx_monitor_enter(gs_input_profile->lock); + if (!src_dev_link) { + gx_monitor_enter(gs_output_profile->lock); + } } +#endif /* We may have to worry about special handling for DeviceGray to DeviceCMYK to ensure that Gray is mapped to K only. This is only - done once and then it is cached and the link used */ - if (!src_dev_link && gs_output_profile->data_cs == gsCMYK && - gs_input_profile->data_cs == gsGRAY && pis->icc_manager != NULL && - devicegraytok) { + done once and then it is cached and the link used. Note that Adobe + appears to do this only when the source color space was DeviceGray. + For us, this requirement is meant by the test of + gs_input_profile->default_match == DEFAULT_GRAY */ + if (!src_dev_link && gs_output_profile->data_cs == gsCMYK && + gs_input_profile->data_cs == gsGRAY && + gs_input_profile->default_match == DEFAULT_GRAY && + pgs->icc_manager != NULL && devicegraytok) { if (icc_manager->graytok_profile == NULL) { icc_manager->graytok_profile = - gsicc_set_iccsmaskprofile(GRAY_TO_K, strlen(GRAY_TO_K), - pis->icc_manager, - pis->icc_manager->memory->stable_memory); + gsicc_set_iccsmaskprofile(GRAY_TO_K, strlen(GRAY_TO_K), + pgs->icc_manager, + pgs->icc_manager->memory->stable_memory); if (icc_manager->graytok_profile == NULL) { + /* Cant create the link */ /* FIXME: clean up allocations and locksso far ??? */ + gsicc_remove_link(link, cache_mem); return NULL; } } if (icc_manager->smask_profiles == NULL) { code = gsicc_initialize_iccsmask(icc_manager); } - cms_input_profile = + cms_input_profile = icc_manager->smask_profiles->smask_gray->profile_handle; - cms_output_profile = + cms_output_profile = icc_manager->graytok_profile->profile_handle; + /* Turn off bp compensation in this case as there is a bug in lcms */ + rendering_params->black_point_comp = false; + cms_flags = 0; /* Turn off any flag setting */ } /* Get the link with the proof and or device link profile */ if (include_softproof || include_devicelink || src_dev_link) { @@ -943,40 +1228,61 @@ cms_output_profile, cms_devlink_profile, rendering_params, - src_dev_link, + src_dev_link, cms_flags, cache_mem->non_gc_memory); +#if !defined(MEMENTO_SQUEEZE_BUILD) + if (!gscms_is_threadsafe()) { if (include_softproof) { gx_monitor_leave(proof_profile->lock); } if (include_devicelink) { gx_monitor_leave(devlink_profile->lock); } + } +#endif } else { link_handle = gscms_get_link(cms_input_profile, cms_output_profile, - rendering_params, cache_mem->non_gc_memory); + rendering_params, cms_flags, + cache_mem->non_gc_memory); } - if (!src_dev_link) { - gx_monitor_leave(gs_output_profile->lock); +#if !defined(MEMENTO_SQUEEZE_BUILD) + if (!gscms_is_threadsafe()) { + if (!src_dev_link) { + gx_monitor_leave(gs_output_profile->lock); + } + gx_monitor_leave(gs_input_profile->lock); } - gx_monitor_leave(gs_input_profile->lock); +#endif if (link_handle != NULL) { - if (gs_input_profile->data_cs == gsGRAY) + if (gs_input_profile->data_cs == gsGRAY) pageneutralcolor = false; + gsicc_set_link_data(link, link_handle, hash, icc_link_cache->lock, - include_softproof, include_devicelink, pageneutralcolor, + include_softproof, include_devicelink, pageneutralcolor, gs_input_profile->data_cs); if_debug2m(gs_debug_flag_icc, cache_mem, - "[icc] New Link = 0x%x, hash = %I64d \n", - link, hash.link_hashcode); + "[icc] New Link = 0x%p, hash = %lld \n", + link, (long long)hash.link_hashcode); if_debug2m(gs_debug_flag_icc, cache_mem, - "[icc] input_numcomps = %d, input_hash = %I64d \n", - gs_input_profile->num_comps, gs_input_profile->hashcode); + "[icc] input_numcomps = %d, input_hash = %lld \n", + gs_input_profile->num_comps, + (long long)gs_input_profile->hashcode); if_debug2m(gs_debug_flag_icc, cache_mem, - "[icc] output_numcomps = %d, output_hash = %I64d \n", - gs_output_profile->num_comps, gs_output_profile->hashcode); + "[icc] output_numcomps = %d, output_hash = %lld \n", + gs_output_profile->num_comps, + (long long)gs_output_profile->hashcode); } else { + /* If other threads are waiting, we won't have set link->valid true. */ + /* This could result in an infinite loop if other threads are waiting */ + /* for it to be made valid. (see gsicc_findcachelink). */ + link->ref_count--; /* this thread no longer using this link entry */ + if_debug3m('^', link->memory, "[^]%s 0x%lx -- => %ld\n", + "icclink", link, link->ref_count); + +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_leave(link->lock); +#endif gsicc_remove_link(link, cache_mem); - icc_link_cache->num_links--; return NULL; } return link; @@ -1012,7 +1318,9 @@ buffer are parsed and placed into a custom stucture that is pointed to by the profile pointer. Note that this pointer is not visible to the garbage collector and should be allocated in non-gc memory as is demonstrated in - this sample. + this sample. The structure elements are released when the profile is + destroyed through the call to gsicc_named_profile_release, which is set + as the value of the profile member variable release. Note that there are calls defined in gsicc_littlecms.c that will create link transforms between Named Color ICC profiles and the output device. Such @@ -1029,8 +1337,8 @@ !!!!IT WILL BE NECESSARY TO PERFORM THE PROPER DEALLOCATION CLEAN-UP OF THE STRUCTURES WHEN rc_free_icc_profile OCCURS FOR THE NAMED - COLOR PROFILE!!!!!! - + COLOR PROFILE!!!!!! See gsicc_named_profile_release below for an example. + This is set in the profile release member variable. */ /* Define the demo structure and function for named color look-up */ @@ -1038,6 +1346,7 @@ typedef struct gsicc_namedcolortable_s { gsicc_namedcolor_t *named_color; /* The named color */ unsigned int number_entries; /* The number of entries */ + gs_memory_t *memory; } gsicc_namedcolortable_t; /* Support functions for parsing buffer */ @@ -1060,28 +1369,59 @@ } } -/* Function returns -1 if name not found. Otherwise transform the color. */ +/* Release the structures we allocated in gsicc_transform_named_color */ +static void +gsicc_named_profile_release(void *ptr, gs_memory_t *memory) +{ + gsicc_namedcolortable_t *namedcolor_table = (gsicc_namedcolortable_t*) ptr; + unsigned int num_entries; + gs_memory_t *mem; + int k; + gsicc_namedcolor_t *namedcolor_data; + + if (namedcolor_table != NULL) { + mem = namedcolor_table->memory; + num_entries = namedcolor_table->number_entries; + namedcolor_data = namedcolor_table->named_color; + + for (k = 0; k < num_entries; k++) { + gs_free(mem, namedcolor_data[k].colorant_name, 1, + namedcolor_data[k].name_size + 1, + "gsicc_named_profile_release (colorant_name)"); + } + + gs_free(mem, namedcolor_data, num_entries, sizeof(gsicc_namedcolor_t), + "gsicc_named_profile_release (namedcolor_data)"); + + gs_free(namedcolor_table->memory, namedcolor_table, 1, + sizeof(gsicc_namedcolortable_t), + "gsicc_named_profile_release (namedcolor_table)"); + } +} + +/* Function returns -1 if a name is not found. Otherwise it will transform + the named colors and return 0 */ int gsicc_transform_named_color(const float tint_values[], - gsicc_namedcolor_t color_names[], + gsicc_namedcolor_t color_names[], uint num_names, gx_color_value device_values[], - const gs_imager_state *pis, gx_device *dev, + const gs_gstate *pgs, gx_device *dev, cmm_profile_t *gs_output_profile, gsicc_rendering_param_t *rendering_params) { - gsicc_namedcolor_t *namedcolor_data; unsigned int num_entries; cmm_profile_t *named_profile; gsicc_namedcolortable_t *namedcolor_table; - int k,j,n; + int num_nonnone_names; + uint k,j,n; float lab[3]; char *buffptr; int buffer_count; int count; int code; - char *pch, *temp_ptr; + char *pch, *temp_ptr, *last = NULL; bool done; int curr_name_size; bool found_match; @@ -1093,59 +1433,66 @@ unsigned short white_lab[3] = {65535, 32767, 32767}; gsicc_link_t *icc_link; cmm_profile_t *curr_output_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile; - int indices[GS_CLIENT_COLOR_MAX_COMPONENTS]; + int indices[GS_CLIENT_COLOR_MAX_COMPONENTS]; + gs_memory_t *nongc_mem = pgs->memory->non_gc_memory; + + /* Set indices to avoid use of uninitialized index. It is actually not + possible to access them using real data but someone could perhaps + be malicious and cause a problem */ + memset(&(indices[0]), 0, sizeof(indices)); /* Check if the data that we have has already been generated. */ - if (pis->icc_manager != NULL) { - if (pis->icc_manager->device_named != NULL) { - named_profile = pis->icc_manager->device_named; + if (pgs->icc_manager != NULL) { + if (pgs->icc_manager->device_named != NULL) { + named_profile = pgs->icc_manager->device_named; if (named_profile->buffer != NULL && named_profile->profile_handle == NULL) { /* Create the structure that we will use in searching */ /* Note that we do this in non-GC memory since the profile pointer is not GC'd */ namedcolor_table = - (gsicc_namedcolortable_t*) gs_malloc(pis->memory->stable_memory, 1, + (gsicc_namedcolortable_t*) gs_malloc(nongc_mem, 1, sizeof(gsicc_namedcolortable_t), "gsicc_transform_named_color"); - if (namedcolor_table == NULL) return(-1); + if (namedcolor_table == NULL) + return(gs_error_VMerror); + namedcolor_table->memory = nongc_mem; /* Parse buffer and load the structure we will be searching */ buffptr = (char*) named_profile->buffer; buffer_count = named_profile->buffer_size; count = sscanf(buffptr,"%d",&num_entries); if (num_entries < 1 || count == 0) { - gs_free(pis->memory, namedcolor_table, 1, + gs_free(nongc_mem, namedcolor_table, 1, sizeof(gsicc_namedcolortable_t), "gsicc_transform_named_color"); - return (-1); + return -1; } code = get_to_next_line(&buffptr,&buffer_count); if (code < 0) { - gs_free(pis->memory, - namedcolor_table, 1, + gs_free(nongc_mem, namedcolor_table, 1, sizeof(gsicc_namedcolortable_t), "gsicc_transform_named_color"); - return (-1); + return -1; } namedcolor_data = - (gsicc_namedcolor_t*) gs_malloc(pis->memory->stable_memory, num_entries, + (gsicc_namedcolor_t*) gs_malloc(nongc_mem, num_entries, sizeof(gsicc_namedcolor_t), "gsicc_transform_named_color"); if (namedcolor_data == NULL) { - gs_free(pis->memory, namedcolor_table, 1, + gs_free(nongc_mem, namedcolor_table, num_entries, sizeof(gsicc_namedcolortable_t), "gsicc_transform_named_color"); - return (-1); + return_error(gs_error_VMerror); } namedcolor_table->number_entries = num_entries; namedcolor_table->named_color = namedcolor_data; for (k = 0; k < num_entries; k++) { if (k == 0) { - pch = strtok(buffptr,",;"); + pch = gs_strtok(buffptr,",;", &last); } else { - pch = strtok(NULL,",;"); + pch = gs_strtok(NULL,",;", &last); } /* Remove any /0d /0a stuff from start */ temp_ptr = pch; @@ -1161,13 +1508,14 @@ namedcolor_data[k].name_size = curr_name_size; /* +1 for the null */ namedcolor_data[k].colorant_name = - (char*) gs_malloc(pis->memory->stable_memory,1, - curr_name_size+1, + (char*)gs_malloc(nongc_mem, 1, curr_name_size + 1, "gsicc_transform_named_color"); + if (namedcolor_data[k].colorant_name == NULL) + return_error(gs_error_VMerror); strncpy(namedcolor_data[k].colorant_name,temp_ptr, namedcolor_data[k].name_size+1); for (j = 0; j < 3; j++) { - pch = strtok(NULL,",;"); + pch = gs_strtok(NULL,",;", &last); count = sscanf(pch,"%f",&(lab[j])); } lab[0] = lab[0]*65535/100.0; @@ -1178,59 +1526,68 @@ if (lab[j] < 0) lab[j] = 0; namedcolor_data[k].lab[j] = (unsigned short) lab[j]; } - if (code < 0) { - gs_free(pis->memory, namedcolor_table, 1, - sizeof(gsicc_namedcolortable_t), - "gsicc_transform_named_color"); - gs_free(pis->memory, namedcolor_data, num_entries, - sizeof(gsicc_namedcolordata_t), - "gsicc_transform_named_color"); - return (-1); - } } /* Assign to the profile pointer */ named_profile->profile_handle = namedcolor_table; + named_profile->release = gsicc_named_profile_release; } else { if (named_profile->profile_handle != NULL ) { namedcolor_table = (gsicc_namedcolortable_t*) named_profile->profile_handle; num_entries = namedcolor_table->number_entries; } else { - return(-1); + return -1; } } /* Go through each of our spot names, getting the color value for each one. */ + num_nonnone_names = num_names; for (n = 0; n < num_names; n++) { - /* Search our structure for the color name */ + /* Search our structure for the color name. Ignore the None + colorant names. All is a special case that someone may + want to detect and do some special handling for. In this + particular example we would punt with All and let the default + methods handle it */ found_match = false; - for (k = 0; k < num_entries; k++) { - if (color_names[n].name_size == - namedcolor_table->named_color[k].name_size) { - if( strncmp((const char *) namedcolor_table->named_color[k].colorant_name, - (const char *) color_names[n].colorant_name, color_names[n].name_size) == 0) { - found_match = true; - break; + + if (strncmp("None", (const char *)color_names[n].colorant_name, + color_names[n].name_size) == 0) { + num_nonnone_names--; + } else { + /* Colorant was not None */ + for (k = 0; k < num_entries; k++) { + if (color_names[n].name_size == + namedcolor_table->named_color[k].name_size) { + if (strncmp((const char *)namedcolor_table->named_color[k].colorant_name, + (const char *)color_names[n].colorant_name, color_names[n].name_size) == 0) { + found_match = true; + break; + } } } - } - if (found_match) { - indices[n] = k; - } else { - /* We do not know this colorant, return -1 */ - return -1; + if (found_match) { + indices[n] = k; + } else { + /* We do not know this colorant, return -1 */ + return -1; + } } } + if (num_nonnone_names < 1) + return -1; /* No non-None colorants. */ /* We have all the colorants. Lets go through and see if we can make something that looks like a merge of the various ones */ - /* Apply tint, blend LAB values */ - for (n = 0; n < num_names; n++) { + /* Apply tint, blend LAB values. Note that we may have wanted to + check if we even want to do this. It is possible that the + device directly supports this particular colorant. One may + want to check the alt tint transform boolean */ + for (n = 0; n < num_nonnone_names; n++) { for (j = 0; j < 3; j++) { temp = (float) namedcolor_table->named_color[indices[n]].lab[j] * tint_values[n] + (float) white_lab[j] * (1.0 - tint_values[n]); temp_lab[j] = (unsigned short) temp; } - /* Blend with the current color. Note this is just for + /* Blend with the current color. Note this is just for demonstration. Much better methods are possible for this */ if (n == 0) { for (j = 0; j < 3; j++) { @@ -1242,20 +1599,29 @@ psrc[2] = (psrc[2] + temp_lab[2]) / 2; /* b* */ } } - /* Push LAB value through CMM to get device values */ + /* Push LAB value through CMM to get CMYK device values */ + /* Note that there are several options here. You could us an NCLR + icc profile to compute the device colors that you want. For, + example if the output device had an NCLR profile. + However, what you MUST do here is set ALL the device values. + Hence, below we initialize all of them to zero and in this + particular example, set only the ones that were output from + the device profile */ if ( gs_output_profile != NULL ) { curr_output_profile = gs_output_profile; } else { - /* Use the device profile */ + /* Use the device profile. Note if one was not set for the + device, the default CMYK profile is used. Note that + if we specified and NCLR profile it will be used here */ code = dev_proc(dev, get_profile)(dev, &dev_profile); gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &(curr_output_profile), &render_cond); } - icc_link = gsicc_get_link_profile(pis, dev, - pis->icc_manager->lab_profile, + icc_link = gsicc_get_link_profile(pgs, dev, + pgs->icc_manager->lab_profile, curr_output_profile, rendering_params, - pis->memory, false); + pgs->memory, false); if (icc_link->is_identity) { psrc_temp = &(psrc[0]); } else { @@ -1264,23 +1630,38 @@ (icc_link->procs.map_color)(dev, icc_link, psrc, psrc_temp, 2); } gsicc_release_link(icc_link); - for ( k = 0; k < curr_output_profile->num_comps; k++){ + + /* Clear out ALL the color values */ + for (k = 0; k < dev->color_info.num_components; k++){ + device_values[k] = 0; + } + /* Set only the values that came from the profile. By default + this would generally be just CMYK values. For the equivalent + color computation case it certainly will be. If someone + specified an NCLR profile it could be more. Note that if an + NCLR profile is being used we will want to make sure the colorant + order is correct */ + for (k = 0; k < curr_output_profile->num_comps; k++){ device_values[k] = psrc_temp[k]; } return 0; } } - return -1; + return -1; /* Color not found */ } /* Used by gs to notify the ICC manager that we are done with this link for now */ -/* This may release elements waiting on a icc_link_cache slot */ +/* This may release elements waiting on an icc_link_cache slot */ void gsicc_release_link(gsicc_link_t *icclink) { gsicc_link_cache_t *icc_link_cache = icclink->icc_link_cache; +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_enter(icc_link_cache->lock); +#endif + if_debug3m('^', icclink->memory, "[^]%s 0x%lx -- => %ld\n", + "icclink", icclink, icclink->ref_count - 1); /* Decrement the reference count */ if (--(icclink->ref_count) == 0) { @@ -1316,18 +1697,13 @@ prev->next = icclink; icclink->next = curr; } - - /* now release any tasks waiting for a cache slot */ - while (icclink->icc_link_cache->num_waiting > 0) { - gx_semaphore_signal(icclink->icc_link_cache->wait); - icclink->icc_link_cache->num_waiting--; - } } +#ifndef MEMENTO_SQUEEZE_BUILD gx_monitor_leave(icc_link_cache->lock); +#endif } /* Used to initialize the buffer description prior to color conversion */ - void gsicc_init_buffer(gsicc_bufferdesc_t *buffer_desc, unsigned char num_chan, unsigned char bytes_per_chan, bool has_alpha, bool alpha_first, bool is_planar, int plane_stride, int row_stride, @@ -1351,8 +1727,8 @@ /* Return the proper component numbers based upon the profiles of the device. This is in here since it is usually called when creating and using a link from the link cache. */ -int -gsicc_get_device_profile_comps(cmm_dev_profile_t *dev_profile) +int +gsicc_get_device_profile_comps(const cmm_dev_profile_t *dev_profile) { if (dev_profile->link_profile == NULL) { return dev_profile->device_profile[0]->num_comps; @@ -1360,4 +1736,3 @@ return dev_profile->link_profile->num_comps_out; } } - diff -Nru ghostscript-9.10~dfsg/base/gsicc_cache.h ghostscript-9.25~dfsg+1/base/gsicc_cache.h --- ghostscript-9.10~dfsg/base/gsicc_cache.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_cache.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -18,9 +18,9 @@ #ifndef gsicccache_INCLUDED # define gsicccache_INCLUDED -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_device_DEFINED @@ -46,26 +46,29 @@ bool gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, gsicc_link_t **ret_link, gsicc_hashlink_t hash, bool include_softproof, bool include_devlink); -gsicc_link_t* gsicc_get_link(const gs_imager_state * pis, gx_device *dev, +gsicc_link_t* gsicc_get_link(const gs_gstate * pgs, gx_device *dev, const gs_color_space *input_colorspace, gs_color_space *output_colorspace, gsicc_rendering_param_t *rendering_params, gs_memory_t *memory); -gsicc_link_t* gsicc_get_link_profile(const gs_imager_state *pis, gx_device *dev, +gsicc_link_t* gsicc_get_link_profile(const gs_gstate *pgs, gx_device *dev, cmm_profile_t *gs_input_profile, cmm_profile_t *gs_output_profile, gsicc_rendering_param_t *rendering_params, gs_memory_t *memory, bool devicegraytok); void gsicc_release_link(gsicc_link_t *icclink); -void gsicc_link_free(gsicc_link_t *icc_link, gs_memory_t *memory); +void gsicc_link_free(gsicc_link_t *icc_link, const gs_memory_t *memory); void gsicc_get_icc_buff_hash(unsigned char *buffer, int64_t *hash, unsigned int buff_size); +int64_t gsicc_get_hash(cmm_profile_t *profile); int gsicc_transform_named_color(const float tint_values[], gsicc_namedcolor_t color_names[], uint num_names, gx_color_value device_values[], - const gs_imager_state *pis, gx_device *dev, + const gs_gstate *pgs, gx_device *dev, cmm_profile_t *gs_output_profile, gsicc_rendering_param_t *rendering_params); -int gsicc_get_device_profile_comps(cmm_dev_profile_t *dev_profile); - +int gsicc_get_device_profile_comps(const cmm_dev_profile_t *dev_profile); +gsicc_link_t * gsicc_alloc_link_dev(gs_memory_t *memory, cmm_profile_t *src_profile, + cmm_profile_t *des_profile, gsicc_rendering_param_t *rendering_params); +void gsicc_free_link_dev(gs_memory_t *memory, gsicc_link_t *link); #endif diff -Nru ghostscript-9.10~dfsg/base/gsicc_cms.h ghostscript-9.25~dfsg+1/base/gsicc_cms.h --- ghostscript-9.10~dfsg/base/gsicc_cms.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_cms.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,61 +32,69 @@ typedef void* gcmmhlink_t; #endif +/* Made to match lcms settings */ +#define GSICC_HIGHACCURACY cmsFLAGS_HIGHRESPRECALC +#define GSICC_MEDACCURACY 0 +#define GSICC_LOWACCURACY cmsFLAGS_LOWRESPRECALC + /* Prototypes */ bool gsicc_mcm_monitor_rgb(void *inputcolor, int num_bytes); bool gsicc_mcm_monitor_cmyk(void *inputcolor, int num_bytes); bool gsicc_mcm_monitor_lab(void *inputcolor, int num_bytes); void gsicc_mcm_set_link(gsicc_link_t* link); -void gsicc_mcm_end_monitor(gsicc_link_cache_t *cache, gx_device *dev); -void gsicc_mcm_begin_monitor(gsicc_link_cache_t *cache, gx_device *dev); -gsicc_link_t* gsicc_rcm_get_link(const gs_imager_state *pis, gx_device *dev, +int gsicc_mcm_end_monitor(gsicc_link_cache_t *cache, gx_device *dev); +int gsicc_mcm_begin_monitor(gsicc_link_cache_t *cache, gx_device *dev); +gsicc_link_t* gsicc_rcm_get_link(const gs_gstate *pgs, gx_device *dev, gsicc_colorbuffer_t data_cs); -gsicc_link_t* gsicc_nocm_get_link(const gs_imager_state *pis, gx_device *dev, - gs_color_space_index src_index); -gcmmhprofile_t gscms_get_profile_handle_mem(gs_memory_t *mem, - unsigned char *buffer, - unsigned int input_size); -gcmmhprofile_t gscms_get_profile_handle_file(gs_memory_t *mem, - const char *filename); -void gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, - gsicc_bufferdesc_t *input_buff_desc, - gsicc_bufferdesc_t *output_buff_desc, - void *inputbuffer, - void *outputbuffer); -int gscms_get_channel_count(gcmmhprofile_t profile); -int gscms_get_pcs_channel_count(gcmmhprofile_t profile); +gsicc_link_t* gsicc_nocm_get_link(const gs_gstate *pgs, gx_device *dev, + gs_color_space_index src_index ); +gcmmhprofile_t gscms_get_profile_handle_mem(unsigned char *buffer, + unsigned int input_size, + gs_memory_t *mem); +gcmmhprofile_t gscms_get_profile_handle_file(const char *filename, + gs_memory_t *mem); +int gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, + gsicc_bufferdesc_t *input_buff_desc, + gsicc_bufferdesc_t *output_buff_desc, + void *inputbuffer, void *outputbuffer); +int gscms_get_channel_count(gcmmhprofile_t profile, gs_memory_t *memory); +int gscms_get_pcs_channel_count(gcmmhprofile_t profile, gs_memory_t *memory); char* gscms_get_clrtname(gcmmhprofile_t profile, int colorcount, gs_memory_t *memory); -int gscms_get_numberclrtnames(gcmmhprofile_t profile); -bool gscms_is_device_link(gcmmhprofile_t profile); -gsicc_colorbuffer_t gscms_get_profile_data_space(gcmmhprofile_t profile); -void gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, - void *outputcolor, int num_bytes); +int gscms_get_numberclrtnames(gcmmhprofile_t profile, gs_memory_t *memory); +bool gscms_is_device_link(gcmmhprofile_t profile, gs_memory_t *memory); +int gscms_get_device_class(gcmmhprofile_t profile, gs_memory_t *memory); +bool gscms_is_input(gcmmhprofile_t profile, gs_memory_t *memory); +gsicc_colorbuffer_t gscms_get_profile_data_space(gcmmhprofile_t profile, + gs_memory_t *memory); +int gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, + void *outputcolor, int num_bytes); gcmmhlink_t gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, gsicc_rendering_param_t *rendering_params, + int cmm_flags, gs_memory_t *memory); gcmmhlink_t gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_proofhandle, - gcmmhprofile_t lcms_deshandle, + gcmmhprofile_t lcms_deshandle, gcmmhprofile_t lcms_devlinkhandle, gsicc_rendering_param_t *rendering_params, - bool src_dev_link, + bool src_dev_link, int cmm_flags, gs_memory_t *memory); int gscms_create(gs_memory_t *memory); void gscms_destroy(gs_memory_t *memory); void gscms_release_link(gsicc_link_t *icclink); -void gscms_release_profile(void *profile); +void gscms_release_profile(void *profile, gs_memory_t *memory); int gscms_transform_named_color(gsicc_link_t *icclink, float tint_value, const char* ColorName, - gx_color_value device_values[] ); + gx_color_value device_values[]); void gscms_get_name2device_link(gsicc_link_t *icclink, gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, gcmmhprofile_t lcms_proofhandle, - gsicc_rendering_param_t *rendering_params, - gs_memory_t *memory); -int gscms_get_input_channel_count(gcmmhprofile_t profile); -int gscms_get_output_channel_count(gcmmhprofile_t profile); -void gscms_get_link_dim(gcmmhlink_t link, int *num_inputs, int *num_outputs); - + gsicc_rendering_param_t *rendering_params); +int gscms_get_input_channel_count(gcmmhprofile_t profile, gs_memory_t *memory); +int gscms_get_output_channel_count(gcmmhprofile_t profile, gs_memory_t *memory); +void gscms_get_link_dim(gcmmhlink_t link, int *num_inputs, int *num_outputs, gs_memory_t *memory); +int gscms_avoid_white_fix_flag(gs_memory_t *memory); +bool gscms_is_threadsafe(void); #endif diff -Nru ghostscript-9.10~dfsg/base/gsicc_create.c ghostscript-9.25~dfsg+1/base/gsicc_create.c --- ghostscript-9.10~dfsg/base/gsicc_create.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_create.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -123,7 +123,7 @@ #include "gx.h" #include -#include "gxistate.h" +#include "gxgstate.h" #include "gstypes.h" #include "gscspace.h" #include "gscie.h" @@ -139,7 +139,6 @@ add_xyzdata(unsigned char *input_ptr, icS15Fixed16Number temp_XYZ[]); #define SAVEICCPROFILE 0 -#define USE_V4 1 #define HEADER_SIZE 128 #define TAG_SIZE 12 #define XYZPT_SIZE 12 @@ -149,12 +148,14 @@ #define NUMBER_COMMON_TAGS 2 #define icMultiUnicodeText 0x6d6c7563 /* 'mluc' v4 text type */ #define icMultiFunctionAtoBType 0x6d414220 /* 'mAB ' v4 lutAtoBtype type */ -#define icSigChromaticAdaptationTag 0x63686164 /* 'chad' */ #define D50_X 0.9642f #define D50_Y 1.0f #define D50_Z 0.8249f #define DEFAULT_TABLE_NSIZE 9 +#define FORWARD_V2_TABLE_SIZE 9 +#define BACKWARD_V2_TABLE_SIZE 33 #define DEFAULT_TABLE_GRAYSIZE 128 +#define V2_COMMON_TAGS NUMBER_COMMON_TAGS + 1 typedef unsigned short u1Fixed15Number; #if SAVEICCPROFILE @@ -211,7 +212,7 @@ static int get_padding(int x) { - return( (4 -x%4)%4 ); + return (4 -x%4)%4; } /* For some weird reason I cant link to the one in gscie.c */ @@ -239,11 +240,9 @@ matrix->is_identity = (vec->u == 1.0)&&(vec->v == 1.0)&&(vec->w == 1.0); } -/* This function maps a gs matrix type to an ICC CLUT. - This is required due to the multiple matrix and 1-D LUT - forms for postscript management, which the ICC does not - support (at least the older versions). clut is allocated - externally */ +/* This function maps a gs matrix type to an ICC CLUT. This is required due to the + multiple matrix and 1-D LUT forms for postscript management, which the ICC does not + support (at least the older versions). clut is allocated externally */ static void gsicc_matrix3_to_mlut(gs_matrix3 *mat, unsigned short *clut) { @@ -284,20 +283,12 @@ } } -static u1Fixed15Number -double2u1Fixed15Number(float number_in) +static void +apply_adaption(float matrix[], float in[], float out[]) { - float value; - - value = number_in/(1.0 + (32767.0/32768.0)); - value = value * 65535.0; - if (value < 0) { - value = 0; - } - if (value > 65535) { - value = 65535; - } - return((u1Fixed15Number) value); + out[0] = matrix[0] * in[0] + matrix[1] * in[1] + matrix[2] * in[2]; + out[1] = matrix[3] * in[0] + matrix[4] * in[1] + matrix[5] * in[2]; + out[2] = matrix[6] * in[0] + matrix[7] * in[1] + matrix[8] * in[2]; } /* This function mashes all the elements together into a single CLUT @@ -305,9 +296,10 @@ guaranteed to work. */ static int gsicc_create_clut(const gs_color_space *pcs, gsicc_clut *clut, gs_range *ranges, - gs_vector3 *white_point, bool range_adjust, gs_memory_t *memory) + gs_vector3 *white_point, bool range_adjust, float cam[], + gs_memory_t *memory) { - gs_imager_state *pis; + gs_gstate *pgs; int code; int num_points = clut->clut_num_entries; int table_size = clut->clut_dims[0]; /* Same resolution in each direction*/ @@ -324,10 +316,11 @@ /* This completes the joint cache inefficiently so that we can sample through it and get our table entries */ - code = gx_cie_to_xyz_alloc(&pis, pcs, memory); - cs_index = gs_color_space_get_index(pcs); + code = gx_cie_to_xyz_alloc(&pgs, pcs, memory); if (code < 0) - return code; + return gs_rethrow(code, "Allocation of cie to xyz transform failed"); + cs_index = gs_color_space_get_index(pcs); + /* Create the sample indices across the input ranges for each color component. When the concretization/remap occurs to be fed into this icc profile, we may will need to apply a linear @@ -335,6 +328,12 @@ for (i = 0; i < num_components; i++) { input_samples[i] = (float*) gs_alloc_bytes(memory, sizeof(float)*table_size,"gsicc_create_clut"); + if (input_samples[i] == NULL) { + for (j = 0; j < i; j++) { + gs_free_object(memory, input_samples[j], "gsicc_create_clut"); + } + return gs_throw(gs_error_VMerror, "Allocation of input_sample arrays failed"); + } fltptr = input_samples[i]; curr_range = &(ranges[i]); for (j = 0; j < table_size; j++ ) { @@ -386,46 +385,45 @@ the ICC mapping like the procs associated with the color space */ switch (cs_index) { case gs_color_space_index_CIEA: - gx_psconcretize_CIEA(&cc, pcs, xyz, pis); + gx_psconcretize_CIEA(&cc, pcs, xyz, xyz_float, pgs); /* AR forces this case to always be achromatic. We will do the same even though it does not match the PS specification */ /* Use the resulting Y value to scale the D50 Illumination. note that we scale to the whitepoint here. Matrix out handles mapping to CIE D50 */ - xyz_float[1] = frac2float(xyz[1]); xyz_float[0] = white_point->u * xyz_float[1]; xyz_float[2] = white_point->w * xyz_float[1]; break; case gs_color_space_index_CIEABC: - gx_psconcretize_CIEABC(&cc, pcs, xyz, pis); + gx_psconcretize_CIEABC(&cc, pcs, xyz, xyz_float, pgs); break; case gs_color_space_index_CIEDEF: - gx_psconcretize_CIEDEF(&cc, pcs, xyz, pis); + gx_psconcretize_CIEDEF(&cc, pcs, xyz, xyz_float, pgs); break; case gs_color_space_index_CIEDEFG: - gx_psconcretize_CIEDEFG(&cc, pcs, xyz, pis); + gx_psconcretize_CIEDEFG(&cc, pcs, xyz, xyz_float, pgs); break; default: - break; + return gs_throw(-1, "Invalid gs_color_space_index when creating ICC profile"); } + /* We need to map these values to D50 illuminant so that things work + correctly with ICC profile */ + //apply_adaption(cam, xyz_float, xyz_adapt); + /* Correct for range of ICC CIEXYZ table data */ for (j = 0; j < 3; j++) { - if ( cs_index == gs_color_space_index_CIEA) { - temp = xyz_float[j]/(1 + 32767.0/32768); - } else { - temp = frac2float(xyz[j])/(1 + 32767.0/32768); - } + temp = xyz_float[j]/(1 + 32767.0/32768); if (temp < 0) temp = 0; if (temp > 1) temp = 1; *ptr_short ++= (unsigned int)(temp * 65535); } } - gx_cie_to_xyz_free(pis); /* Free the joint cache we created */ + gx_cie_to_xyz_free(pgs); /* Free the joint cache we created */ for (i = 0; i < num_components; i++) { gs_free_object(memory, input_samples[i], "gsicc_create_clut"); } - return(0); + return 0; } /* This function maps a gs vector type to an ICC CLUT. @@ -436,13 +434,23 @@ gsicc_vec_to_mlut(gs_vector3 *vec, unsigned short *clut) { unsigned short *curr_ptr = clut; + int temp; *curr_ptr ++= 0; *curr_ptr ++= 0; *curr_ptr ++= 0; - *curr_ptr ++= double2u1Fixed15Number(vec->u); - *curr_ptr ++= double2u1Fixed15Number(vec->v); - *curr_ptr ++= double2u1Fixed15Number(vec->w); + temp = (int)(vec->u * 65535); + if (temp > 65535) temp = 65535; + if (temp < 0) temp = 0; + *curr_ptr ++= temp; + temp = (int)(vec->v * 65535); + if (temp > 65535) temp = 65535; + if (temp < 0) temp = 0; + *curr_ptr ++= temp; + temp = (int)(vec->w * 65535); + if (temp > 65535) temp = 65535; + if (temp < 0) temp = 0; + *curr_ptr ++= temp; } #if SAVEICCPROFILE @@ -503,7 +511,7 @@ s = (short) number_in; m = (unsigned short) ((number_in - s) * 65536.0); - return((icS15Fixed16Number) ((s << 16) | m) ); + return (icS15Fixed16Number) ((s << 16) | m); } static icS15Fixed16Number @@ -520,25 +528,22 @@ m = (unsigned short) ((number - s) * 65536.0); temp = (icS15Fixed16Number) ((s << 16) | m); temp = -temp; - return(temp); + return temp; } else { s = (short) number_in; m = (unsigned short) ((number_in - s) * 65536.0); - return((icS15Fixed16Number) ((s << 16) | m) ); + return (icS15Fixed16Number) ((s << 16) | m); } } static unsigned short float2u8Fixed8(float number_in) { - unsigned short m; - - m = (unsigned short) (number_in * 256); - return( m ); + return (unsigned short) (number_in * 256); } static -void init_common_tags(gsicc_tag tag_list[],int num_tags, int *last_tag) +void init_common_tags(gsicc_tag tag_list[],int num_tags, int *last_tag) { /* profileDescriptionTag copyrightTag */ @@ -605,23 +610,61 @@ } static void -add_common_tag_data(unsigned char *buffer,gsicc_tag tag_list[]) +add_desc_tag(unsigned char *buffer, const char text[], gsicc_tag tag_list[], + int curr_tag) { -#if USE_V4 unsigned char *curr_ptr; + int len = strlen(text) + 1; + int k; curr_ptr = buffer; - add_v4_text_tag(curr_ptr, desc_name, tag_list, 0); - curr_ptr += tag_list[0].size; - add_v4_text_tag(curr_ptr, copy_right, tag_list, 1); -#else + write_bigendian_4bytes(curr_ptr, icSigTextDescriptionType); + curr_ptr += 4; + memset(curr_ptr, 0, 4); + curr_ptr += 4; + write_bigendian_4bytes(curr_ptr, len); + curr_ptr += 4; + for (k = 0; k < strlen(text); k++) { + *curr_ptr++ = text[k]; + } + memset(curr_ptr, 0, 12 + 67 + 1); + memset(curr_ptr, 0, tag_list[curr_tag].byte_padding); /* padding */ +} + +static void +add_text_tag(unsigned char *buffer, const char text[], gsicc_tag tag_list[], + int curr_tag) +{ unsigned char *curr_ptr; + int k; curr_ptr = buffer; - add_desc_tag(curr_ptr, desc_name, tag_list, 0); - curr_ptr += tag_list[0].size; - add_text_tag(curr_ptr, copy_right, tag_list, 1); -#endif + write_bigendian_4bytes(curr_ptr, icSigTextType); + curr_ptr += 4; + memset(curr_ptr, 0, 4); + curr_ptr += 4; + for (k = 0; k < strlen(text); k++) { + *curr_ptr++ = text[k]; + } + memset(curr_ptr, 0, 1); + memset(curr_ptr, 0, tag_list[curr_tag].byte_padding); /* padding */ +} + +static void +add_common_tag_data(unsigned char *buffer,gsicc_tag tag_list[], int vers) +{ + unsigned char *curr_ptr; + curr_ptr = buffer; + + if (vers == 4) { + add_v4_text_tag(curr_ptr, desc_name, tag_list, 0); + curr_ptr += tag_list[0].size; + add_v4_text_tag(curr_ptr, copy_right, tag_list, 1); + } else { + add_desc_tag(curr_ptr, desc_name, tag_list, 0); + curr_ptr += tag_list[0].size; + add_text_tag(curr_ptr, copy_right, tag_list, 1); + } } static @@ -642,11 +685,14 @@ } static void -setheader_common(icHeader *header) +setheader_common(icHeader *header, int vers) { /* This needs to all be predefined for a simple copy. MJV todo */ header->cmmId = 0; - header->version = 0x04200000; + if (vers == 4) + header->version = 0x04200000; + else + header->version = 0x02200000; setdatetime(&(header->date)); header->magic = icMagicNumber; header->platform = icSigMacintosh; @@ -737,7 +783,7 @@ } static void -get_XYZ_floatptr(icS15Fixed16Number XYZ[], float *vector) +get_XYZ_doubletr(icS15Fixed16Number XYZ[], float *vector) { XYZ[0] = double2XYZtype(vector[0]); XYZ[1] = double2XYZtype(vector[1]); @@ -756,7 +802,7 @@ static void add_gammadata(unsigned char *input_ptr, unsigned short gamma, - icTagSignature curveType) + icTagTypeSignature curveType) { unsigned char *curr_ptr; @@ -883,26 +929,53 @@ matrixmult(&(cat02matrixinv[0]), 3, 3, &(temp_matrix[0]), 3, 3, &(cam[0])); } -/* Hardcoded chad for D65 to D50. This should be computed on the fly - based upon the PS specified white point and ICC D50. We don't use - the chad tag with littleCMS since it takes care of the chromatic - adaption itself based upon D50 and the media white point. */ -static void -add_chad_data(unsigned char *input_ptr, float *data) +static int +gsicc_compute_cam(gsicc_lutatob *icc_luta2bparts, gs_memory_t *memory) { - unsigned char *curr_ptr = input_ptr; - /* float data[] = {1.04790738171017, 0.0229333845542104, -0.0502016347980104, - 0.0296059594177168, 0.990456039910785, -0.01707552919587, - -0.00924679432678241, 0.0150626801401488, 0.751791232609078};*/ + gs_vector3 d50; - /* Signature should be sf32 */ - curr_ptr = input_ptr; - write_bigendian_4bytes(curr_ptr,icSigS15Fixed16ArrayType); - curr_ptr += 4; - /* Reserved */ - memset(curr_ptr,0,4); - curr_ptr += 4; - add_matrixwithbias(curr_ptr, &(data[0]), false); + d50.u = D50_X; + d50.v = D50_Y; + d50.w = D50_Z; + + /* Calculate the chromatic adaptation matrix */ + icc_luta2bparts->cam = (float*) gs_alloc_bytes(memory, + 9 * sizeof(float), "gsicc_compute_cam"); + if (icc_luta2bparts->cam == NULL) { + return gs_throw(gs_error_VMerror, "Allocation of ICC cam failed"); + } + gsicc_create_compute_cam(icc_luta2bparts->white_point, &(d50), icc_luta2bparts->cam); + return 0; +} + +/* Compute the CAT02 transformation to get us from the Cal White + point to the D50 white point. We could pack this in a chad tag + and let the CMM worry about applying but it is safer if we just + take care of it ourselves by mapping the primaries. This is what is + also done for the table based data */ +static float* +gsicc_get_cat02_cam(float *curr_wp, gs_memory_t *memory) +{ + gs_vector3 d50; + gs_vector3 wp; + float *cam; + + wp.u = curr_wp[0]; + wp.v = curr_wp[1]; + wp.w = curr_wp[2]; + + d50.u = D50_X; + d50.v = D50_Y; + d50.w = D50_Z; + + cam = (float*)gs_alloc_bytes(memory, 9 * sizeof(float), "gsicc_get_cat02_cam"); + if (cam == NULL) { + gs_throw(gs_error_VMerror, "Allocation of cat02 matrix failed"); + return NULL; + } + gsicc_create_compute_cam(&wp, &(d50), cam); + + return cam; } static void @@ -1027,7 +1100,7 @@ data_offset += (numin*(IDENT_CURVE_SIZE*2+12)); } } - return(data_offset); + return data_offset; } /* Note: ICC V4 fomat allows ONLY these forms @@ -1045,7 +1118,7 @@ /* We need to figure out all the offsets to the various objects based upon which ones are actually present */ unsigned char *curr_ptr; - long mlut_size; + long mlut_size = 0; /* silence compiler warning */ int data_offset; int k; int numout = lutatobparts->num_out; @@ -1187,9 +1260,11 @@ int trc_tag_size; unsigned char *buffer; cmm_profile_t *result; + float *cat02; + float black_adapt[3]; /* Fill in the common stuff */ - setheader_common(header); + setheader_common(header, 4); header->pcs = icSigXYZData; profile_size = HEADER_SIZE; header->deviceClass = icSigInputClass; @@ -1201,10 +1276,12 @@ num_tags = 5; /* common (2) + GrayTRC,bkpt,wtpt */ TRC_Tags[0] = icSigGrayTRCTag; } else { - return(NULL); + return NULL; } tag_list = (gsicc_tag*) gs_alloc_bytes(memory, sizeof(gsicc_tag)*num_tags,"gsicc_create_from_cal"); + if (tag_list == NULL) + return NULL; /* Let us precompute the sizes of everything and all our offsets */ profile_size += TAG_SIZE*num_tags; profile_size += 4; /* number of tags.... */ @@ -1229,6 +1306,10 @@ buffer data is in non-gc memory */ buffer = gs_alloc_bytes(memory->non_gc_memory, profile_size, "gsicc_create_from_cal"); + if (buffer == NULL) { + gs_free_object(memory, tag_list, "gsicc_create_from_cal"); + return NULL; + } curr_ptr = buffer; /* The header */ header->size = profile_size; @@ -1240,39 +1321,56 @@ curr_ptr += 4; /* Now the data. Must be in same order as we created the tag table */ /* First the common tags */ - add_common_tag_data(curr_ptr, tag_list); + add_common_tag_data(curr_ptr, tag_list, 4); for (k = 0; k< NUMBER_COMMON_TAGS; k++) { curr_ptr += tag_list[k].size; } tag_location = NUMBER_COMMON_TAGS; + + /* Get the cat02 matrix */ + cat02 = gsicc_get_cat02_cam(white, memory); + if (cat02 == NULL) + { + gs_rethrow(gs_error_VMerror, "Creation of cat02 matrix / ICC profile failed"); + return NULL; + } + /* The matrix */ if (num_colors == 3) { for ( k = 0; k < 3; k++ ) { - get_XYZ_floatptr(temp_XYZ,&(matrix[k*3])); - add_xyzdata(curr_ptr,temp_XYZ); + float primary[3]; + /* Apply the cat02 matrix to the primaries */ + apply_adaption(cat02, &(matrix[k * 3]), &(primary[0])); + get_XYZ_doubletr(temp_XYZ, &(primary[0])); + add_xyzdata(curr_ptr, temp_XYZ); curr_ptr += tag_list[tag_location].size; tag_location++; } } - /* White and black points */ - /* Need to adjust for the D65/D50 issue */ - get_XYZ_floatptr(temp_XYZ,white); + /* White and black points. WP is D50 */ + get_D50(temp_XYZ); add_xyzdata(curr_ptr,temp_XYZ); curr_ptr += tag_list[tag_location].size; tag_location++; - /* Black point */ - get_XYZ_floatptr(temp_XYZ,black); + /* Black point. Apply cat02*/ + apply_adaption(cat02, black, &(black_adapt[0])); + get_XYZ_doubletr(temp_XYZ, &(black_adapt[0])); add_xyzdata(curr_ptr,temp_XYZ); curr_ptr += tag_list[tag_location].size; tag_location++; /* Now the gamma values */ - for ( k = 0; k < num_colors; k++ ) { + for (k = 0; k < num_colors; k++) { encode_gamma = float2u8Fixed8(gamma[k]); add_gammadata(curr_ptr, encode_gamma, icSigCurveType); curr_ptr += tag_list[tag_location].size; tag_location++; } result = gsicc_profile_new(NULL, memory, NULL, 0); + if (result == NULL) + { + gs_throw(gs_error_VMerror, "Creation of ICC profile failed"); + return NULL; + } result->buffer = buffer; result->buffer_size = profile_size; result->num_comps = num_colors; @@ -1288,6 +1386,7 @@ result->hash_is_valid = true; /* Free up the tag list */ gs_free_object(memory, tag_list, "gsicc_create_from_cal"); + gs_free_object(memory, cat02, "gsicc_create_from_cal"); #if SAVEICCPROFILE /* Dump the buffer to a file for testing if its a valid ICC profile */ @@ -1296,7 +1395,7 @@ else save_profile(buffer,"from_calGray",profile_size); #endif - return(result); + return result; } static void @@ -1350,12 +1449,12 @@ } /* A common form used for most of the PS CIE color spaces */ -static void +static int create_lutAtoBprofile(unsigned char **pp_buffer_in, icHeader *header, - gsicc_lutatob *lutatobparts, bool yonly, + gsicc_lutatob *lutatobparts, bool yonly, bool mashedLUT, gs_memory_t *memory) { - int num_tags = 6; /* common (2), AToB0Tag,bkpt, wtpt and chad.*/ + int num_tags = 5; /* common (2), AToB0Tag,bkpt, wtpt */ int k; gsicc_tag *tag_list; int profile_size, last_tag, tag_location, tag_size; @@ -1367,8 +1466,11 @@ float lmn_vector[3],d50_cieA[3]; profile_size = HEADER_SIZE; - tag_list = (gsicc_tag*) gs_alloc_bytes(memory,sizeof(gsicc_tag)*num_tags, + tag_list = (gsicc_tag*) gs_alloc_bytes(memory, sizeof(gsicc_tag)*num_tags, "create_lutAtoBprofile"); + if (tag_list == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC tag list failed"); + /* Let us precompute the sizes of everything and all our offsets */ profile_size += TAG_SIZE*num_tags; profile_size += 4; /* number of tags.... */ @@ -1377,8 +1479,6 @@ init_tag(tag_list, &last_tag, icSigMediaWhitePointTag, XYZPT_SIZE); init_tag(tag_list, &last_tag, icSigMediaBlackPointTag, XYZPT_SIZE); - init_tag(tag_list, &last_tag, icSigChromaticAdaptationTag, 9*4); /* chad tag */ - /* Get the tag size of the A2B0 with the lutAtoBType */ /* Compensate for init_tag() adding DATATYPE_SIZE */ tag_size = getsize_lutAtoBtype(lutatobparts) - DATATYPE_SIZE; @@ -1391,19 +1491,23 @@ /* Now we can go ahead and fill our buffer with the data. Profile is in non-gc memory */ buffer = gs_alloc_bytes(memory->non_gc_memory, profile_size, - "create_lutAtoBprofile"); + "create_lutAtoBprofile"); + if (buffer == NULL) { + gs_free_object(memory, tag_list, "create_lutAtoBprofile"); + return gs_throw(gs_error_VMerror, "Allocation of ICC buffer failed"); + } curr_ptr = buffer; /* The header */ header->size = profile_size; copy_header(curr_ptr,header); curr_ptr += HEADER_SIZE; /* Tag table */ - copy_tagtable(curr_ptr,tag_list,num_tags); - curr_ptr += TAG_SIZE*num_tags; + copy_tagtable(curr_ptr, tag_list, num_tags); + curr_ptr += TAG_SIZE * num_tags; curr_ptr += 4; /* Now the data. Must be in same order as we created the tag table */ /* First the common tags */ - add_common_tag_data(curr_ptr, tag_list); + add_common_tag_data(curr_ptr, tag_list, 4); for (k = 0; k< NUMBER_COMMON_TAGS; k++) { curr_ptr += tag_list[k].size; } @@ -1414,25 +1518,26 @@ d50.u = D50_X; d50.v = D50_Y; d50.w = D50_Z; - cam = (float*) gs_alloc_bytes(memory,9*sizeof(float),"create_lutAtoBprofile"); + cam = (float*) gs_alloc_bytes(memory, 9 * sizeof(float), "create_lutAtoBprofile"); + if (cam == NULL) { + gs_free_object(memory, tag_list, "create_lutAtoBprofile"); + gs_free_object(memory->non_gc_memory, buffer, "create_lutAtoBprofile"); + return gs_throw(gs_error_VMerror, "Allocation of ICC cam failed"); + } gsicc_create_compute_cam(lutatobparts->white_point, &(d50), cam); lutatobparts->cam = cam; get_D50(temp_XYZ); /* See Appendix D6 in spec */ - /* get_XYZ(temp_XYZ,lutatobparts->white_point); */ - add_xyzdata(curr_ptr,temp_XYZ); - curr_ptr += tag_list[tag_location].size; - tag_location++; - get_XYZ(temp_XYZ,lutatobparts->black_point); - add_xyzdata(curr_ptr,temp_XYZ); + add_xyzdata(curr_ptr, temp_XYZ); curr_ptr += tag_list[tag_location].size; tag_location++; - add_chad_data(curr_ptr, cam); + get_XYZ(temp_XYZ, lutatobparts->black_point); + add_xyzdata(curr_ptr, temp_XYZ); curr_ptr += tag_list[tag_location].size; tag_location++; /* Multiply the matrix in the AtoB object by the cam so that the data is in D50 */ if (lutatobparts->matrix == NULL) { - gsicc_create_copy_matrix3(cam,&(temp_matrix.cu.u)); + gsicc_create_copy_matrix3(cam, &(temp_matrix.cu.u)); lutatobparts->matrix = &temp_matrix; } else { if (yonly) { @@ -1448,10 +1553,18 @@ lmn_vector[0] = lutatobparts->matrix->cv.u; lmn_vector[1] = lutatobparts->matrix->cv.v; lmn_vector[2] = lutatobparts->matrix->cv.w; - d50_cieA[0] = D50_X; - d50_cieA[1] = D50_Y; - d50_cieA[2] = D50_Z; - matrixmult(&(d50_cieA[0]),3,1,&(lmn_vector[0]), 1, 3, + if (mashedLUT) { + /* Table data already scaled */ + d50_cieA[0] = D50_X; + d50_cieA[1] = D50_Y; + d50_cieA[2] = D50_Z; + } else { + /* Need to do final scaling to ICC CIEXYZ range */ + d50_cieA[0] = (float)(D50_X / (1.0 + (32767.0/32768.0))); + d50_cieA[1] = (float)(D50_Y / (1.0 + (32767.0/32768.0))); + d50_cieA[2] = (float)(D50_Z / (1.0 + (32767.0/32768.0))); + } + matrixmult(&(d50_cieA[0]), 3, 1, &(lmn_vector[0]), 1, 3, &(lutatobparts->matrix->cu.u)); } else { matrixmult(cam, 3, 3, &(lutatobparts->matrix->cu.u), 3, 3, @@ -1465,13 +1578,13 @@ add_lutAtoBtype(curr_ptr, lutatobparts); *pp_buffer_in = buffer; gs_free_object(memory, tag_list, "create_lutAtoBprofile"); - + return 0; } /* Shared code between all the PS types whereby we mash together all the components into a single CLUT. Not preferable in general but necessary when the PS components do not map easily into the ICC forms */ -static void +static int gsicc_create_mashed_clut(gsicc_lutatob *icc_luta2bparts, icHeader *header, gx_color_lookup_table *Table, const gs_color_space *pcs, gs_range *ranges, @@ -1486,8 +1599,10 @@ /* A table is going to be mashed form of all the transform */ /* Allocate space for the clut */ - clut = (gsicc_clut*) gs_alloc_bytes(memory,sizeof(gsicc_clut), + clut = (gsicc_clut*) gs_alloc_bytes(memory, sizeof(gsicc_clut), "gsicc_create_mashed_clut"); + if (clut == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC clut failed"); icc_luta2bparts->clut = clut; if ( icc_luta2bparts->num_in == 1 ) { /* Use a larger sample for 1-D input */ @@ -1509,12 +1624,19 @@ clut->clut_word_width = 2; /* 16 bit */ gsicc_create_initialize_clut(clut); /* Allocate space for the table data */ - clut->data_short = - (unsigned short*) gs_alloc_bytes(memory, + clut->data_short = (unsigned short*) gs_alloc_bytes(memory, clut->clut_num_entries*3*sizeof(unsigned short),"gsicc_create_mashed_clut"); + if (clut->data_short == NULL) { + gs_free_object(memory, clut, "gsicc_create_mashed_clut"); + return gs_throw(gs_error_VMerror, "Allocation of ICC clut short data failed"); + } /* Create the table */ code = gsicc_create_clut(pcs, clut, ranges, icc_luta2bparts->white_point, - range_adjust, memory); + range_adjust, icc_luta2bparts->cam, memory); + if (code < 0) { + gs_free_object(memory, clut, "gsicc_create_mashed_clut"); + return gs_rethrow(code, "Creation of ICC clut failed"); + } /* Initialize other parts. Also make sure acurves are reset since they have been mashed into the table. */ gs_free_object(memory, icc_luta2bparts->a_curves, "gsicc_create_mashed_clut"); @@ -1528,17 +1650,20 @@ icc_luta2bparts->matrix = &ident_matrix; /* Now create the profile */ if (icc_luta2bparts->num_in == 1 ) { - create_lutAtoBprofile(pp_buffer_in, header, icc_luta2bparts, true, memory); + code = create_lutAtoBprofile(pp_buffer_in, header, icc_luta2bparts, true, + true, memory); } else { - create_lutAtoBprofile(pp_buffer_in, header, icc_luta2bparts, false, memory); + code = create_lutAtoBprofile(pp_buffer_in, header, icc_luta2bparts, false, + true, memory); } - + return code; } /* Shared code by ABC, DEF and DEFG compaction of ABC/LMN parts. This is used - when we either MatrixABC is identity, LMN Decode is identity or MatrixLMN - is identity */ -static void + when either MatrixABC is identity, LMN Decode is identity or MatrixLMN + is identity. This allows us to map into the ICC form and not have to mash + into a full CLUT */ +static int gsicc_create_abc_merge(gsicc_lutatob *atob_parts, gs_matrix3 *matrixLMN, gs_matrix3 *matrixABC, bool has_abc_procs, bool has_lmn_procs, gx_cie_vector_cache *abc_caches, @@ -1569,13 +1694,14 @@ merge_abc_lmn_curves(abc_caches, lmn_caches); has_lmn_procs = false; } - /* Figure out what curves get mapped to where. The only time - we will use the b curves is if matrixABC is not the identity and we have - lmn procs */ + /* Figure out what curves get mapped to where. The only time we will use the b + curves is if matrixABC is not the identity and we have lmn procs */ if ( !(matrixABC->is_identity) && has_lmn_procs) { /* A matrix followed by a curve */ atob_parts->b_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_abc_merge"); + if (atob_parts->b_curves == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC b curves failed"); curr_pos = atob_parts->b_curves; memcpy(curr_pos,&(lmn_caches[0].floats.values[0]),CURVE_SIZE*sizeof(float)); curr_pos += CURVE_SIZE; @@ -1586,6 +1712,10 @@ /* Also a curve before the matrix */ atob_parts->m_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_abc_merge"); + if (atob_parts->m_curves == NULL) { + gs_free_object(memory, atob_parts->b_curves, "gsicc_create_abc_merge"); + return gs_throw(gs_error_VMerror, "Allocation of ICC m curves failed"); + } curr_pos = atob_parts->m_curves; memcpy(curr_pos,&(abc_caches[0].floats.values[0]),CURVE_SIZE*sizeof(float)); curr_pos += CURVE_SIZE; @@ -1594,10 +1724,14 @@ memcpy(curr_pos,&(abc_caches[2].floats.values[0]),CURVE_SIZE*sizeof(float)); } } else { - /* Only one set of curves before a matrix */ + /* Only one set of curves before a matrix. Need to check this to make sure + there is not an issue here and we have has_abc_procs true and + has_lmn_procs true */ if (has_abc_procs) { atob_parts->m_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_abc_merge"); + if (atob_parts->m_curves == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC m curves failed"); curr_pos = atob_parts->m_curves; memcpy(curr_pos,&(abc_caches[0].floats.values[0]),CURVE_SIZE*sizeof(float)); curr_pos += CURVE_SIZE; @@ -1608,6 +1742,8 @@ if (has_lmn_procs) { atob_parts->m_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_abc_merge"); + if (atob_parts->m_curves == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC m curves failed"); curr_pos = atob_parts->m_curves; memcpy(curr_pos,&(lmn_caches[0].floats.values[0]),CURVE_SIZE*sizeof(float)); curr_pos += CURVE_SIZE; @@ -1623,8 +1759,9 @@ to the mapping of X=Y by the identity table. If there are b_curves these have an output that is 16 bit. */ if (atob_parts->b_curves == NULL) { - scale_matrix(&(atob_parts->matrix->cu.u),2.0); + scale_matrix(&(atob_parts->matrix->cu.u), 2.0); } + return 0; } /* The ABC color space is modeled using the V4 lutAtoBType which has the @@ -1654,12 +1791,13 @@ (lmn_caches)[2].floats.params.is_identity)); gs_cie_abc *pcie = pcs->params.abc; bool input_range_ok; + int code; gsicc_create_init_luta2bpart(&icc_luta2bparts); gsicc_matrix_init(&(pcie->common.MatrixLMN)); /* Need this set now */ gsicc_matrix_init(&(pcie->MatrixABC)); /* Need this set now */ /* Fill in the common stuff */ - setheader_common(header); + setheader_common(header, 4); /* We will use an input type class which keeps us from having to create an inverse. We will keep the data a generic 3 color. @@ -1672,7 +1810,13 @@ icc_luta2bparts.white_point = &(pcie->common.points.WhitePoint); icc_luta2bparts.black_point = &(pcie->common.points.BlackPoint); - /* Detect if the space is CIELAB. We don't have access to pis here though */ + /* Calculate the chromatic adaptation matrix */ + code = gsicc_compute_cam(&icc_luta2bparts, memory); + if (code < 0) { + return gs_rethrow(code, "Create ICC from CIEABC failed"); + } + + /* Detect if the space is CIELAB. We don't have access to pgs here though */ /* *islab = cie_is_lab(pcie); This is not working yet */ *islab = false; @@ -1683,26 +1827,33 @@ matrix. Also, if ABC is identity we can mash the ABC and LMN decode procs. If we have an ABC matrix, LMN procs and an LMN matrix we will need to create a small (2x2x2) CLUT for the ICC format. */ - input_range_ok = check_range(&(pcie->RangeABC.ranges[0]),3); + input_range_ok = check_range(&(pcie->RangeABC.ranges[0]), 3); if (!input_range_ok) { /* We have a range problem at input */ - gsicc_create_mashed_clut(&icc_luta2bparts, header, NULL, pcs, + code = gsicc_create_mashed_clut(&icc_luta2bparts, header, NULL, pcs, &(pcie->RangeABC.ranges[0]), pp_buffer_in, profile_size_out, true, memory); + if (code < 0) + return gs_rethrow(code, "Failed in ICC creation from ABC mashed. CLUT"); } else { if (pcie->MatrixABC.is_identity || !has_lmn_procs || pcie->common.MatrixLMN.is_identity) { /* The merging of these parts into the curves/matrix/curves of the lutAtoBtype portion can be used by abc, def and defg */ icc_luta2bparts.matrix = &matrix_input_trans; - gsicc_create_abc_merge(&(icc_luta2bparts), &(pcie->common.MatrixLMN), + code = gsicc_create_abc_merge(&(icc_luta2bparts), &(pcie->common.MatrixLMN), &(pcie->MatrixABC), has_abc_procs, has_lmn_procs, pcie->caches.DecodeABC.caches, pcie->common.caches.DecodeLMN, memory); + if (code < 0) + return gs_rethrow(code, "Failed in ICC creation from ABC. Merge"); icc_luta2bparts.clut = NULL; /* Create the profile. This is for the common generic form we will use for almost everything. */ - create_lutAtoBprofile(pp_buffer_in, header,&icc_luta2bparts,false, memory); + code = create_lutAtoBprofile(pp_buffer_in, header, &icc_luta2bparts, false, + false, memory); + if (code < 0) + return gs_rethrow(code, "Failed in ICC creation from ABC. Profile"); } else { /* This will be a bit more complex as we have an ABC matrix, LMN decode and an LMN matrix. We will need to create an MLUT to handle this properly. @@ -1712,6 +1863,9 @@ if (has_abc_procs) { icc_luta2bparts.a_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_fromabc"); + if (icc_luta2bparts.a_curves == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC a curves failed"); + curr_pos = icc_luta2bparts.a_curves; memcpy(curr_pos,&(pcie->caches.DecodeABC.caches->floats.values[0]), CURVE_SIZE*sizeof(float)); @@ -1725,6 +1879,11 @@ if (has_lmn_procs) { icc_luta2bparts.m_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_fromabc"); + if (icc_luta2bparts.m_curves == NULL) { + gs_free_object(memory, icc_luta2bparts.a_curves, + "gsicc_create_fromabc"); + return gs_throw(gs_error_VMerror, "Allocation of ICC m curves failed"); + } curr_pos = icc_luta2bparts.m_curves; memcpy(curr_pos,&(pcie->common.caches.DecodeLMN->floats.values[0]), CURVE_SIZE*sizeof(float)); @@ -1738,6 +1897,13 @@ /* Convert ABC matrix to 2x2x2 MLUT type */ icc_luta2bparts.clut = (gsicc_clut*) gs_alloc_bytes(memory, sizeof(gsicc_clut),"gsicc_create_fromabc"); + if (icc_luta2bparts.m_curves == NULL) { + gs_free_object(memory, icc_luta2bparts.a_curves, + "gsicc_create_fromabc"); + gs_free_object(memory, icc_luta2bparts.m_curves, + "gsicc_create_fromabc"); + return gs_throw(gs_error_VMerror, "Allocation of ICC clut failed"); + } for (k = 0; k < 3; k++) { icc_luta2bparts.clut->clut_dims[k] = 2; } @@ -1749,12 +1915,24 @@ icc_luta2bparts.clut->data_short = (unsigned short*) gs_alloc_bytes(memory, 8*3*sizeof(short),"gsicc_create_fromabc"); + if (icc_luta2bparts.clut->data_short == NULL) { + gs_free_object(memory, icc_luta2bparts.a_curves, + "gsicc_create_fromabc"); + gs_free_object(memory, icc_luta2bparts.m_curves, + "gsicc_create_fromabc"); + gs_free_object(memory, icc_luta2bparts.clut, + "gsicc_create_fromabc"); + return gs_throw(gs_error_VMerror, "Allocation of ICC clut data failed"); + } gsicc_matrix3_to_mlut(&(pcie->MatrixABC), icc_luta2bparts.clut->data_short); /* LMN Matrix */ cie_matrix_transpose3(&(pcie->common.MatrixLMN), &matrix_input_trans); icc_luta2bparts.matrix = &matrix_input_trans; /* Create the profile */ - create_lutAtoBprofile(pp_buffer_in, header, &icc_luta2bparts, false, memory); + code = create_lutAtoBprofile(pp_buffer_in, header, &icc_luta2bparts, + false, false, memory); + if (code < 0) + return code; } } gsicc_create_free_luta2bpart(memory, &icc_luta2bparts); @@ -1764,7 +1942,7 @@ if(debug_catch) save_profile(*pp_buffer_in,"fromabc",header->size); #endif - return(0); + return 0; } int @@ -1787,10 +1965,11 @@ bool common_range_ok; gs_cie_a *pcie = pcs->params.a; bool input_range_ok; + int code; gsicc_create_init_luta2bpart(&icc_luta2bparts); /* Fill in the common stuff */ - setheader_common(header); + setheader_common(header, 4); /* We will use an input type class which keeps us from having to create an inverse. We will keep the data a generic 3 color. Since we are doing PS color management the PCS is XYZ */ @@ -1801,6 +1980,12 @@ icc_luta2bparts.num_in = 1; icc_luta2bparts.white_point = &(pcie->common.points.WhitePoint); icc_luta2bparts.black_point = &(pcie->common.points.BlackPoint); + + code = gsicc_compute_cam(&icc_luta2bparts, memory); + if (code < 0) { + return gs_rethrow(code, "Create from CIEA failed"); + } + /* Check the range values. If the internal ranges are outside of 0 to 1 then we will need to sample as a full CLUT. The input range can be different, but we we will correct for this. Finally @@ -1809,9 +1994,11 @@ common_range_ok = check_range(&(pcie->common.RangeLMN.ranges[0]),3); if (!common_range_ok) { input_range_ok = check_range(&(pcie->RangeA),1); - gsicc_create_mashed_clut(&icc_luta2bparts, header, NULL, pcs, + code = gsicc_create_mashed_clut(&icc_luta2bparts, header, NULL, pcs, &(pcie->RangeA), pp_buffer_in, profile_size_out, !input_range_ok, memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC mashed CLUT"); } else { /* We do not need to create a massive CLUT. Try to maintain the objects as best we can */ @@ -1822,13 +2009,19 @@ if (has_a_proc) { icc_luta2bparts.a_curves = (float*) gs_alloc_bytes(memory, CURVE_SIZE*sizeof(float),"gsicc_create_froma"); - memcpy(icc_luta2bparts.a_curves, + if (icc_luta2bparts.a_curves == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC a curves failed"); + memcpy(icc_luta2bparts.a_curves, &(pcie->caches.DecodeA.floats.values[0]), CURVE_SIZE*sizeof(float)); } if (has_lmn_procs) { icc_luta2bparts.m_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_froma"); + if (icc_luta2bparts.m_curves == NULL) { + gs_free_object(memory, icc_luta2bparts.a_curves, "gsicc_create_froma"); + return gs_throw(gs_error_VMerror, "Allocation of ICC m curves failed"); + } curr_pos = icc_luta2bparts.m_curves; memcpy(curr_pos,&(pcie->common.caches.DecodeLMN->floats.values[0]), CURVE_SIZE*sizeof(float)); @@ -1842,6 +2035,11 @@ /* Convert diagonal A matrix to 2x1 MLUT type */ icc_luta2bparts.clut = (gsicc_clut*) gs_alloc_bytes(memory, sizeof(gsicc_clut),"gsicc_create_froma"); /* 2 grid points 3 outputs */ + if (icc_luta2bparts.clut == NULL) { + gs_free_object(memory, icc_luta2bparts.a_curves, "gsicc_create_froma"); + gs_free_object(memory, icc_luta2bparts.m_curves, "gsicc_create_froma"); + return gs_throw(gs_error_VMerror, "Allocation of ICC clut failed"); + } icc_luta2bparts.clut->clut_dims[0] = 2; icc_luta2bparts.clut->clut_num_input = 1; icc_luta2bparts.clut->clut_num_output = 3; @@ -1849,7 +2047,14 @@ gsicc_create_initialize_clut(icc_luta2bparts.clut); /* 2 grid points 3 outputs */ icc_luta2bparts.clut->data_short = (unsigned short*) - gs_alloc_bytes(memory,2*3*sizeof(short),"gsicc_create_froma"); + gs_alloc_bytes(memory, 2 * 3 * sizeof(short), + "gsicc_create_froma"); + if (icc_luta2bparts.clut == NULL) { + gs_free_object(memory, icc_luta2bparts.a_curves, "gsicc_create_froma"); + gs_free_object(memory, icc_luta2bparts.m_curves, "gsicc_create_froma"); + gs_free_object(memory, icc_luta2bparts.clut, "gsicc_create_froma"); + return gs_throw(gs_error_VMerror, "Allocation of ICC clut data failed"); + } /* Studies of CIEBasedA spaces and AR rendering of these reveals that they only look at the product sum of the MatrixA and the 2nd column of @@ -1859,13 +2064,17 @@ and a black point of 0 is used. */ gsicc_vec_to_mlut(&(pcie->MatrixA), icc_luta2bparts.clut->data_short); cie_matrix_transpose3(&(pcie->common.MatrixLMN), &matrix_input); + /* Encoding to ICC range happens in create_lutAtoBprofile */ icc_luta2bparts.matrix = &matrix_input; icc_luta2bparts.num_in = 1; icc_luta2bparts.num_out = 3; /* Create the profile */ /* Note Adobe only looks at the Y value for CIEBasedA spaces. we will do the same */ - create_lutAtoBprofile(pp_buffer_in, header, &icc_luta2bparts, true, memory); + code = create_lutAtoBprofile(pp_buffer_in, header, &icc_luta2bparts, true, + false, memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC AtoB Profile"); } *profile_size_out = header->size; gsicc_create_free_luta2bpart(memory, &icc_luta2bparts); @@ -1874,7 +2083,7 @@ if(debug_catch) save_profile(*pp_buffer_in,"froma",header->size); #endif - return(0); + return 0; } /* Common code shared by def and defg generation */ @@ -1889,10 +2098,11 @@ gs_matrix3 matrix_input_trans; int k; bool input_range_ok; + int code; gsicc_matrix_init(&(pcie->common.MatrixLMN)); /* Need this set now */ gsicc_matrix_init(&(pcie->MatrixABC)); /* Need this set now */ - setheader_common(header); + setheader_common(header, 4); /* We will use an input type class which keeps us from having to create an inverse. We will keep the data a generic 3 color. @@ -1903,6 +2113,12 @@ icc_luta2bparts->white_point = &(pcie->common.points.WhitePoint); icc_luta2bparts->black_point = &(pcie->common.points.BlackPoint); + /* Calculate the chromatic adaptation matrix */ + code = gsicc_compute_cam(icc_luta2bparts, memory); + if (code < 0) { + return gs_rethrow(code, "Create ICC from CIEABC failed"); + } + /* question now is, can we keep the table as it is, or do we need to merge some of the def(g) parts. Some merging or operators into the table must occur if we have MatrixABC, LMN Decode and Matrix LMN, otherwise we can encode @@ -1920,20 +2136,28 @@ } else { input_range_ok = check_range(&(pcs->params.defg->RangeDEFG.ranges[0]),4); } - gsicc_create_mashed_clut(icc_luta2bparts, header, Table, + code = gsicc_create_mashed_clut(icc_luta2bparts, header, Table, pcs, ranges, pp_buffer_in, profile_size_out, !input_range_ok, memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC clut"); } else { /* Table can stay as is. Handle the ABC/LMN portions via the curves matrix curves operation */ icc_luta2bparts->matrix = &matrix_input_trans; - gsicc_create_abc_merge(icc_luta2bparts, &(pcie->common.MatrixLMN), + code = gsicc_create_abc_merge(icc_luta2bparts, &(pcie->common.MatrixLMN), &(pcie->MatrixABC), has_abc_procs, has_lmn_procs, pcie->caches.DecodeABC.caches, pcie->common.caches.DecodeLMN, memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC abc merge"); + /* Get the table data */ icc_luta2bparts->clut = (gsicc_clut*) gs_alloc_bytes(memory, sizeof(gsicc_clut),"gsicc_create_defg_common"); + if (icc_luta2bparts->clut == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC clut failed"); + for (k = 0; k < icc_luta2bparts->num_in; k++) { icc_luta2bparts->clut->clut_dims[k] = Table->dims[k]; } @@ -1944,11 +2168,14 @@ /* Get the PS table data directly */ icc_luta2bparts->clut->data_byte = (byte*) Table->table->data; /* Create the profile. */ - create_lutAtoBprofile(pp_buffer_in, header, icc_luta2bparts, false, memory); + code = create_lutAtoBprofile(pp_buffer_in, header, icc_luta2bparts, false, + false, memory); + if (code < 0) + return gs_rethrow(code, "Failed to create ICC lutAtoB"); } gsicc_create_free_luta2bpart(memory, icc_luta2bparts); *profile_size_out = header->size; - return(0); + return 0; } /* If we have an ABC matrix, a DecodeLMN and an LMN matrix we have to mash @@ -1989,6 +2216,8 @@ if (has_defg_procs) { icc_luta2bparts.a_curves = (float*) gs_alloc_bytes(memory, 4*CURVE_SIZE*sizeof(float),"gsicc_create_fromdefg"); + if (icc_luta2bparts.a_curves == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC a curves failed"); curr_pos = icc_luta2bparts.a_curves; memcpy(curr_pos,&(pcie->caches_defg.DecodeDEFG->floats.values[0]), CURVE_SIZE*sizeof(float)); @@ -2013,7 +2242,7 @@ if(debug_catch) save_profile(*pp_buffer_in,"fromdefg",header->size); #endif - return(code); + return code; } int @@ -2051,6 +2280,8 @@ if (has_def_procs) { icc_luta2bparts.a_curves = (float*) gs_alloc_bytes(memory, 3*CURVE_SIZE*sizeof(float),"gsicc_create_fromdef"); + if (icc_luta2bparts.a_curves == NULL) + return gs_throw(gs_error_VMerror, "Allocation of ICC a curves failed"); curr_pos = icc_luta2bparts.a_curves; memcpy(curr_pos,&(pcie->caches_def.DecodeDEF->floats.values[0]), CURVE_SIZE*sizeof(float)); @@ -2070,7 +2301,7 @@ if(debug_catch) save_profile(*pp_buffer_in,"fromdef",header->size); #endif - return(code); + return code; } void @@ -2079,5 +2310,1080 @@ icProfile iccprofile; icHeader *header = &(iccprofile.header); - setheader_common(header); + setheader_common(header, 4); +} + +/* V2 creation from current profile */ + +#define TRC_V2_SIZE 256 + +static void +init_common_tagsv2(gsicc_tag tag_list[], int num_tags, int *last_tag) +{ + /* profileDescriptionTag copyrightTag */ + int curr_tag, temp_size; + + if (*last_tag < 0) + curr_tag = 0; + else + curr_tag = (*last_tag) + 1; + + tag_list[curr_tag].offset = HEADER_SIZE + num_tags * TAG_SIZE + 4; + tag_list[curr_tag].sig = icSigProfileDescriptionTag; + temp_size = DATATYPE_SIZE + 4 + strlen(desc_name) + 1 + 12 + 67; + tag_list[curr_tag].byte_padding = get_padding(temp_size); + tag_list[curr_tag].size = temp_size + tag_list[curr_tag].byte_padding; + + curr_tag++; + + tag_list[curr_tag].offset = tag_list[curr_tag - 1].offset + + tag_list[curr_tag - 1].size; + tag_list[curr_tag].sig = icSigCopyrightTag; + temp_size = DATATYPE_SIZE + strlen(copy_right) + 1; + tag_list[curr_tag].byte_padding = get_padding(temp_size); + tag_list[curr_tag].size = temp_size + tag_list[curr_tag].byte_padding; + *last_tag = curr_tag; +} + +static int +getsize_lut16Type(int tablesize, int num_inputs, int num_outputs) +{ + int clutsize; + + /* Header plus linear curves (2 points each of 2 bytes) */ + int size = 52 + 4 * num_inputs + 4 * num_outputs; + clutsize = (int) pow(tablesize, num_inputs) * num_outputs * 2; + return size + clutsize; +} + +static int +getsize_lut8Type(int tablesize, int num_inputs, int num_outputs) +{ + int clutsize; + + /* Header plus linear curves (2 points each of 2 bytes) */ + int size = 48 + 256 * num_inputs + 256 * num_outputs; + clutsize = (int)pow(tablesize, num_inputs) * num_outputs; + return size + clutsize; +} + + +static byte* +write_v2_common_data(byte *buffer, int profile_size, icHeader *header, + gsicc_tag *tag_list, int num_tags, byte *mediawhitept) +{ + byte *curr_ptr = buffer; + int k; + + /* The header */ + header->size = profile_size; + copy_header(curr_ptr, header); + curr_ptr += HEADER_SIZE; + + /* Tag table */ + copy_tagtable(curr_ptr, tag_list, num_tags); + curr_ptr += TAG_SIZE*num_tags; + curr_ptr += 4; + + /* Common tags */ + add_common_tag_data(curr_ptr, tag_list, 2); + for (k = 0; k< NUMBER_COMMON_TAGS; k++) { + curr_ptr += tag_list[k].size; + } + + /* Media white point. Get from current profile */ + write_bigendian_4bytes(curr_ptr, icSigXYZType); + curr_ptr += 4; + memset(curr_ptr, 0, 4); + curr_ptr += 4; + memcpy(curr_ptr, mediawhitept, 12); + curr_ptr += 12; + + return curr_ptr; +} + +static gsicc_link_t* +get_link(const gs_gstate *pgs, cmm_profile_t *src_profile, + cmm_profile_t *des_profile, gsicc_rendering_intents_t intent) +{ + gsicc_rendering_param_t rendering_params; + + /* Now the main colorants. Get them and the TRC data from using the link + between the source profile and the CIEXYZ profile */ + rendering_params.black_point_comp = gsBLACKPTCOMP_OFF; + rendering_params.override_icc = false; + rendering_params.preserve_black = gsBLACKPRESERVE_OFF; + rendering_params.rendering_intent = intent; + rendering_params.cmm = gsCMM_DEFAULT; + return gsicc_get_link_profile(pgs, NULL, src_profile, des_profile, + &rendering_params, pgs->memory, false); +} + +static void +get_colorant(int index, gsicc_link_t *link, icS15Fixed16Number XYZ_Data[]) +{ + unsigned short des[3], src[3]; + int k; + + src[0] = 0; + src[1] = 0; + src[2] = 0; + src[index] = 65535; + (link->procs.map_color)(NULL, link, &src, &des, 2); + for (k = 0; k < 3; k++) { + XYZ_Data[k] = double2XYZtype((float)des[k] / 65535.0); + } +} + +static void +get_trc(int index, gsicc_link_t *link, float **htrc, int trc_size) +{ + unsigned short des[3], src[3]; + float max; + float *ptrc = *htrc; + int k; + + src[0] = 0; + src[1] = 0; + src[2] = 0; + + /* First get the max value for Y on the range */ + src[index] = 65535; + (link->procs.map_color)(NULL, link, &src, &des, 2); + max = des[1]; + + for (k = 0; k < trc_size; k++) { + src[index] = (unsigned short)((double)k * (double)65535 / (double)(trc_size - 1)); + (link->procs.map_color)(NULL, link, &src, &des, 2); + /* Use Y */ + ptrc[k] = (float)des[1] / max; + } +} + +static void +clean_lut(gsicc_clut *clut, gs_memory_t *memory) +{ + if (clut->clut_word_width == 2) + gs_free_object(memory, clut->data_short, "clean_lut"); + else + gs_free_object(memory, clut->data_byte, "clean_lut"); +} + +/* This is used for the A2B0 type table and B2A0. */ +static int +create_clut_v2(gsicc_clut *clut, gsicc_link_t *link, int num_in, + int num_out, int table_size, gs_memory_t *memory, int bitdepth) +{ + unsigned short *input_samples, *indexptr; + unsigned short *ptr_short; + byte *ptr_byte; + int num_points, index; + unsigned short input[4], output[4]; + int kk, j, i; + + clut->clut_num_input = num_in; + clut->clut_num_output = num_out; + clut->clut_word_width = bitdepth; + for (kk = 0; kk < num_in; kk++) + clut->clut_dims[kk] = table_size; + clut->clut_num_entries = (int) pow(table_size, num_in); + num_points = clut->clut_num_entries; + if (bitdepth == 2) { + clut->data_byte = NULL; + clut->data_short = (unsigned short*)gs_alloc_bytes(memory, + clut->clut_num_entries * num_out * sizeof(unsigned short), + "create_clut_v2"); + if (clut->data_short == NULL) + return -1; + } else { + clut->data_short = NULL; + clut->data_byte = (byte*)gs_alloc_bytes(memory, + clut->clut_num_entries * num_out, "create_clut_v2"); + if (clut->data_byte == NULL) + return -1; + } + + /* Create the sample indices */ + input_samples = (unsigned short*) gs_alloc_bytes(memory, + sizeof(unsigned short)*table_size, "create_clut_v2"); + if (input_samples == NULL) { + return -1; + } + indexptr = input_samples; + for (j = 0; j < table_size; j++) + *indexptr++ = (unsigned short)(((double)j / (double)(table_size - 1)) * 65535.0); + + /* Now populate the table. Index 1 goes the slowest (e.g. R) */ + ptr_short = clut->data_short; + ptr_byte = clut->data_byte; + for (i = 0; i < num_points; i++) { + if (num_in == 1) { + index = i%table_size; + input[0] = input_samples[index]; + } + if (num_in == 3) { + index = i%table_size; + input[2] = input_samples[index]; + index = (unsigned int)floor((float)i / (float)table_size) % table_size; + input[1] = input_samples[index]; + index = (unsigned int)floor((float)i / (float)(table_size* + table_size)) % table_size; + input[0] = input_samples[index]; + } + if (num_in == 4) { + index = i%table_size; + input[3] = input_samples[index]; + index = (unsigned int)floor((float)i / (float)table_size) % table_size; + input[2] = input_samples[index]; + index = (unsigned int)floor((float)i / (float)(table_size* + table_size)) % table_size; + input[1] = input_samples[index]; + index = (unsigned int)floor((float)i / (float)(table_size* + table_size*table_size)) % table_size; + input[0] = input_samples[index]; + } + if (link == NULL) { + /* gamut table case */ + for (j = 0; j < num_out; j++) { + if (bitdepth == 2) + *ptr_short++ = 1; + else + *ptr_byte++ = 1; + } + } else { + double temp; + (link->procs.map_color)(NULL, link, input, output, 2); + + /* Note. We are using 16 bit for the forward table + (colorant to lab) and 8 bit for the backward table + (lab to colorant). A larger table is used for the backward + table to reduce quantization */ + + if (bitdepth == 2) { + /* Output is LAB 16 bit */ + /* Apply offset of 128 on a and b */ + output[1] = output[1] - 128; + output[2] = output[2] - 128; + /* Scale L to range 0 to 0xFF00 */ + temp = (double)output[0] / 65535.0; + temp = temp * 65280.0; + output[0] = (unsigned short)temp; + for (j = 0; j < num_out; j++) + *ptr_short++ = output[j]; + } else { + /* Output is colorant and 8 bit */ + for (j = 0; j < num_out; j++) { + double temp = (double)output[j] * 255.0 / 65535.0; + *ptr_byte++ = (byte) temp; + } + } + } + } + gs_free_object(memory, input_samples, "create_clut_v2"); + return 0; +} + + +/* Here we write out the lut16Type or lut8Type data V2. Curves are always linear, + matrix is the identity. Table data is unique and could be a forward + or inverse table */ +static void +add_lutType(byte *input_ptr, gsicc_clut *lut) +{ + byte *curr_ptr; + unsigned char numout = lut->clut_num_output; + unsigned char numin = lut->clut_num_input; + unsigned char tablesize = lut->clut_dims[0]; + float ident[9] = { 1.0, 0, 0, 0, 1.0, 0, 0, 0, 1.0 }; + int clut_size = lut->clut_num_entries * numout, k, j; + + /* Signature */ + curr_ptr = input_ptr; + if (lut->clut_word_width == 2) + write_bigendian_4bytes(curr_ptr, icSigLut16Type); + else + write_bigendian_4bytes(curr_ptr, icSigLut8Type); + curr_ptr += 4; + /* Reserved */ + memset(curr_ptr, 0, 4); + curr_ptr += 4; + /* Sizes padded */ + *curr_ptr++ = numin; + *curr_ptr++ = numout; + *curr_ptr++ = tablesize; + *curr_ptr++ = 0; + + /* Now the identity matrix */ + add_matrixwithbias(curr_ptr, &(ident[0]), false); + curr_ptr += (9 * 4); + + /* Input TRC are linear. 16 bit can have 2 points. 8 bit need 256 */ + if (lut->clut_word_width == 2) { + /* Sizes */ + write_bigendian_2bytes(curr_ptr, 2); + curr_ptr += 2; + write_bigendian_2bytes(curr_ptr, 2); + curr_ptr += 2; + + /* Input table data. Linear. */ + for (k = 0; k < numin; k++) { + write_bigendian_2bytes(curr_ptr, 0); + curr_ptr += 2; + write_bigendian_2bytes(curr_ptr, 65535); + curr_ptr += 2; + } + } else { + /* Input table data. Linear. */ + for (k = 0; k < numin; k++) + for (j = 0; j < 256; j++) + *curr_ptr++ = j; + } + + /* The CLUT. Write out each entry. */ + if (lut->clut_word_width == 2) { + for (k = 0; k < clut_size; k++) { + write_bigendian_2bytes(curr_ptr, lut->data_short[k]); + curr_ptr += 2; + } + } else { + for (k = 0; k < clut_size; k++) + *curr_ptr++ = lut->data_byte[k]; + } + + /* Output table data. Linear. */ + if (lut->clut_word_width == 2) { + for (k = 0; k < numout; k++) { + write_bigendian_2bytes(curr_ptr, 0); + curr_ptr += 2; + write_bigendian_2bytes(curr_ptr, 65535); + curr_ptr += 2; + } + } else { + for (k = 0; k < numout; k++) + for (j = 0; j < 256; j++) + *curr_ptr++ = j; + } +} + +static int +create_write_table_intent(const gs_gstate *pgs, gsicc_rendering_intents_t intent, + cmm_profile_t *src_profile, cmm_profile_t *des_profile, byte *curr_ptr, + int table_size, int bit_depth) +{ + gsicc_link_t *link; + int code; + gsicc_clut clut; + + link = get_link(pgs, src_profile, des_profile, intent); + code = create_clut_v2(&clut, link, src_profile->num_comps, + des_profile->num_comps, table_size, pgs->memory, bit_depth); + if (code < 0) + return code; + add_lutType(curr_ptr, &clut); + clean_lut(&clut, pgs->memory); + gsicc_release_link(link); + return 0; +} + +static void +gsicc_create_v2input(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src_profile, + byte *mediawhitept, cmm_profile_t *lab_profile) +{ + /* Need to create the forward table only (Gray, RGB, CMYK to LAB) */ + int num_tags = 4; /* 2 common + white + A2B0 */ + int profile_size = HEADER_SIZE; + gsicc_tag *tag_list; + gs_memory_t *memory = src_profile->memory; + int last_tag = -1; + byte *buffer, *curr_ptr; + gsicc_link_t *link; + int tag_size; + gsicc_clut clut; + int code, k; + + /* Profile description tag, copyright tag white point and grayTRC */ + tag_list = (gsicc_tag*)gs_alloc_bytes(memory, + sizeof(gsicc_tag)*num_tags, "gsicc_create_v2input"); + if (tag_list == NULL) + return; + /* Let us precompute the sizes of everything and all our offsets */ + profile_size += TAG_SIZE * num_tags; + profile_size += 4; /* number of tags.... */ + + /* Common tags */ + init_common_tagsv2(tag_list, num_tags, &last_tag); + init_tag(tag_list, &last_tag, icSigMediaWhitePointTag, XYZPT_SIZE); + + /* Get the tag size of the A2B0 with the lut16Type */ + tag_size = getsize_lut16Type(FORWARD_V2_TABLE_SIZE, src_profile->num_comps, 3); + init_tag(tag_list, &last_tag, icSigAToB0Tag, tag_size); + + /* Now get the profile size */ + for (k = 0; k < num_tags; k++) { + profile_size += tag_list[k].size; + } + + /* Allocate buffer */ + buffer = gs_alloc_bytes(memory, profile_size, "gsicc_create_v2input"); + if (buffer == NULL) { + gs_free_object(memory, tag_list, "gsicc_create_v2input"); + return; + } + + /* Write out data */ + curr_ptr = write_v2_common_data(buffer, profile_size, header, tag_list, + num_tags, mediawhitept); + + /* Now the A2B0 Tag */ + link = get_link(pgs, src_profile, lab_profile, gsPERCEPTUAL); + + /* First create the data */ + code = create_clut_v2(&clut, link, src_profile->num_comps, 3, + FORWARD_V2_TABLE_SIZE, pgs->memory, 2); + if (code < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2input"); + return; + } + + /* Now write it out */ + add_lutType(curr_ptr, &clut); + + /* Clean up */ + gsicc_release_link(link); + clean_lut(&clut, pgs->memory); + gs_free_object(memory, tag_list, "gsicc_create_v2input"); + /* Save the v2 data */ + src_profile->v2_data = buffer; + src_profile->v2_size = profile_size; + +#if SAVEICCPROFILE + /* Dump the buffer to a file for testing if its a valid ICC profile */ + save_profile(buffer, "V2InputType", profile_size); +#endif +} + +static void +gsicc_create_v2output(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src_profile, + byte *mediawhitept, cmm_profile_t *lab_profile) +{ + /* Need to create forward and backward table (Gray, RGB, CMYK to LAB and back) + and need to do this for all the intents */ + int num_tags = 10; /* 2 common + white + A2B0 + B2A0 + A2B1 + B2A1 + A2B2 + B2A2 + gamut */ + int profile_size = HEADER_SIZE; + gsicc_tag *tag_list; + gs_memory_t *memory = src_profile->memory; + int last_tag = -1; + byte *buffer, *curr_ptr; + int tag_location; + int tag_size; + gsicc_clut gamutlut; + int code, k; + + /* Profile description tag, copyright tag white point and grayTRC */ + tag_list = (gsicc_tag*)gs_alloc_bytes(memory, + sizeof(gsicc_tag)*num_tags, "gsicc_create_v2output"); + if (tag_list == NULL) + return; + /* Let us precompute the sizes of everything and all our offsets */ + profile_size += TAG_SIZE * num_tags; + profile_size += 4; /* number of tags.... */ + + /* Common tags */ + init_common_tagsv2(tag_list, num_tags, &last_tag); + init_tag(tag_list, &last_tag, icSigMediaWhitePointTag, XYZPT_SIZE); + + /* Get the tag size of the cluts with the lut16Type */ + /* Perceptual */ + tag_size = getsize_lut16Type(FORWARD_V2_TABLE_SIZE, src_profile->num_comps, 3); + init_tag(tag_list, &last_tag, icSigAToB0Tag, tag_size); + tag_size = getsize_lut8Type(BACKWARD_V2_TABLE_SIZE, 3, src_profile->num_comps); + init_tag(tag_list, &last_tag, icSigBToA0Tag, tag_size); + + /* Relative Colorimetric */ + tag_size = getsize_lut16Type(FORWARD_V2_TABLE_SIZE, src_profile->num_comps, 3); + init_tag(tag_list, &last_tag, icSigAToB1Tag, tag_size); + tag_size = getsize_lut8Type(BACKWARD_V2_TABLE_SIZE, 3, src_profile->num_comps); + init_tag(tag_list, &last_tag, icSigBToA1Tag, tag_size); + + /* Saturation */ + tag_size = getsize_lut16Type(FORWARD_V2_TABLE_SIZE, src_profile->num_comps, 3); + init_tag(tag_list, &last_tag, icSigAToB2Tag, tag_size); + tag_size = getsize_lut8Type(BACKWARD_V2_TABLE_SIZE, 3, src_profile->num_comps); + init_tag(tag_list, &last_tag, icSigBToA2Tag, tag_size); + + /* And finally the Gamut Tag. Since we can't determine gamut here this + is essentially a required place holder. Make it small */ + tag_size = getsize_lut8Type(2, src_profile->num_comps, 1); + init_tag(tag_list, &last_tag, icSigGamutTag, tag_size); + + /* Now get the profile size */ + for (k = 0; k < num_tags; k++) { + profile_size += tag_list[k].size; + } + + /* Allocate buffer */ + buffer = gs_alloc_bytes(memory, profile_size, "gsicc_create_v2output"); + if (buffer == NULL) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + + /* Write out data */ + curr_ptr = write_v2_common_data(buffer, profile_size, header, tag_list, + num_tags, mediawhitept); + tag_location = V2_COMMON_TAGS; + + /* A2B0 */ + if (create_write_table_intent(pgs, gsPERCEPTUAL, src_profile, lab_profile, + curr_ptr, FORWARD_V2_TABLE_SIZE, 2) < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + curr_ptr += tag_list[tag_location].size; + tag_location++; + /* B2A0 */ + if (create_write_table_intent(pgs, gsPERCEPTUAL, lab_profile, src_profile, + curr_ptr, BACKWARD_V2_TABLE_SIZE, 1) < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + curr_ptr += tag_list[tag_location].size; + tag_location++; + + /* A2B1 */ + if (create_write_table_intent(pgs, gsRELATIVECOLORIMETRIC, src_profile, + lab_profile, curr_ptr, FORWARD_V2_TABLE_SIZE, 2) < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + curr_ptr += tag_list[tag_location].size; + tag_location++; + /* B2A1 */ + if (create_write_table_intent(pgs, gsRELATIVECOLORIMETRIC, lab_profile, + src_profile, curr_ptr, BACKWARD_V2_TABLE_SIZE, 1) < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + curr_ptr += tag_list[tag_location].size; + tag_location++; + + /* A2B2 */ + if (create_write_table_intent(pgs, gsSATURATION, src_profile, lab_profile, + curr_ptr, FORWARD_V2_TABLE_SIZE, 2) < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + curr_ptr += tag_list[tag_location].size; + tag_location++; + /* B2A2 */ + if (create_write_table_intent(pgs, gsSATURATION, lab_profile, src_profile, + curr_ptr, BACKWARD_V2_TABLE_SIZE, 1) < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + curr_ptr += tag_list[tag_location].size; + tag_location++; + + /* Gamut tag, which is bogus */ + code = create_clut_v2(&gamutlut, NULL, src_profile->num_comps, 1, 2, pgs->memory, 1); + if (code < 0) { + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + return; + } + /* Now write it out */ + add_lutType(curr_ptr, &gamutlut); + + /* Done */ + gs_free_object(memory, tag_list, "gsicc_create_v2output"); + clean_lut(&gamutlut, pgs->memory); + /* Save the v2 data */ + src_profile->v2_data = buffer; + src_profile->v2_size = profile_size; + +#if SAVEICCPROFILE + /* Dump the buffer to a file for testing if its a valid ICC profile */ + save_profile(buffer, "V2OutputType", profile_size); +#endif +} + +static void +gsicc_create_v2displaygray(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src_profile, + byte *mediawhitept, cmm_profile_t *xyz_profile) +{ + int num_tags = 4; + int profile_size = HEADER_SIZE; + gsicc_tag *tag_list; + gs_memory_t *memory = src_profile->memory; + int last_tag = -1; + /* 4 for name, 4 reserved, 4 for number entries, 2*num_entries */ + int trc_tag_size = 12 + 2 * TRC_V2_SIZE; + byte *buffer, *curr_ptr; + unsigned short des[3], src; + float *trc; + int tag_location; + gsicc_link_t *link; + float max; + int k; + + /* Profile description tag, copyright tag white point and grayTRC */ + tag_list = (gsicc_tag*)gs_alloc_bytes(memory, + sizeof(gsicc_tag)*num_tags, "gsicc_createv2display_gray"); + if (tag_list == NULL) + return; + /* Let us precompute the sizes of everything and all our offsets */ + profile_size += TAG_SIZE * num_tags; + profile_size += 4; /* number of tags.... */ + + /* Common tags */ + init_common_tagsv2(tag_list, num_tags, &last_tag); + init_tag(tag_list, &last_tag, icSigMediaWhitePointTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigGrayTRCTag, trc_tag_size); + + /* Now get the profile size */ + for (k = 0; k < num_tags; k++) { + profile_size += tag_list[k].size; + } + /* Allocate buffer */ + buffer = gs_alloc_bytes(memory, profile_size, "gsicc_createv2display_gray"); + if (buffer == NULL) { + gs_free_object(memory, tag_list, "gsicc_createv2display_gray"); + return; + } + + /* Start writing out data to buffer */ + curr_ptr = write_v2_common_data(buffer, profile_size, header, tag_list, + num_tags, mediawhitept); + tag_location = V2_COMMON_TAGS; + + /* Now the TRC. First collect the curve data and then write it out */ + /* Get the link between our gray profile and XYZ profile */ + link = get_link(pgs, src_profile, xyz_profile, gsPERCEPTUAL); + /* First get the max value for Y on the range */ + src = 65535; + (link->procs.map_color)(NULL, link, &src, &(des[0]), 2); + max = des[1]; + + trc = (float*) gs_alloc_bytes(memory, TRC_V2_SIZE * sizeof(float), "gsicc_createv2display_gray"); + for (k = 0; k < TRC_V2_SIZE; k++) { + src = (unsigned short)((double)k * (double)65535 / (double)(TRC_V2_SIZE - 1)); + (link->procs.map_color)(NULL, link, &src, &(des[0]), 2); + trc[k] = (float)des[1] / max; + } + add_curve(curr_ptr, trc, TRC_V2_SIZE); + curr_ptr += tag_list[tag_location].size; + + /* Clean up */ + gsicc_release_link(link); + gs_free_object(memory, tag_list, "gsicc_createv2display_gray"); + gs_free_object(memory, trc, "gsicc_createv2display_gray"); + /* Save the v2 data */ + src_profile->v2_data = buffer; + src_profile->v2_size = profile_size; + +#if SAVEICCPROFILE + /* Dump the buffer to a file for testing if its a valid ICC profile */ + save_profile(buffer, "V2FromGray", profile_size); +#endif +} + +static void +gsicc_create_v2displayrgb(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src_profile, + byte *mediawhitept, cmm_profile_t *xyz_profile) +{ + int num_tags = 9; + int profile_size = HEADER_SIZE; + gsicc_tag *tag_list; + gs_memory_t *memory = src_profile->memory; + int last_tag = -1; + /* 4 for name, 4 reserved, 4 for number entries, 2*num_entries */ + int trc_tag_size = 12 + 2 * TRC_V2_SIZE; + byte *buffer, *curr_ptr; + float *trc; + int tag_location; + icS15Fixed16Number XYZ_Data[3]; + gsicc_link_t *link; + int k; + + /* Profile description tag, copyright tag white point RGB colorants and + RGB TRCs */ + tag_list = (gsicc_tag*)gs_alloc_bytes(memory, + sizeof(gsicc_tag)*num_tags, "gsicc_create_v2displayrgb"); + if (tag_list == NULL) + return; + /* Let us precompute the sizes of everything and all our offsets */ + profile_size += TAG_SIZE * num_tags; + profile_size += 4; /* number of tags.... */ + + /* Common tags + white point + RGB colorants + RGB TRCs */ + init_common_tagsv2(tag_list, num_tags, &last_tag); + init_tag(tag_list, &last_tag, icSigMediaWhitePointTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigRedColorantTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigGreenColorantTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigBlueColorantTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigRedTRCTag, trc_tag_size); + init_tag(tag_list, &last_tag, icSigGreenTRCTag, trc_tag_size); + init_tag(tag_list, &last_tag, icSigBlueTRCTag, trc_tag_size); + + /* Now get the profile size */ + for (k = 0; k < num_tags; k++) { + profile_size += tag_list[k].size; + } + + /* Allocate buffer */ + buffer = gs_alloc_bytes(memory, profile_size, "gsicc_create_v2displayrgb"); + if (buffer == NULL) { + gs_free_object(memory, tag_list, "gsicc_create_v2displayrgb"); + return; + } + + /* Start writing out data to buffer */ + curr_ptr = write_v2_common_data(buffer, profile_size, header, tag_list, + num_tags, mediawhitept); + tag_location = V2_COMMON_TAGS; + + /* Now the main colorants. Get them and the TRC data from using the link + between the source profile and the CIEXYZ profile */ + link = get_link(pgs, src_profile, xyz_profile, gsPERCEPTUAL); + + /* Get the Red, Green and Blue colorants */ + for (k = 0; k < 3; k++) { + get_colorant(k, link, XYZ_Data); + add_xyzdata(curr_ptr, XYZ_Data); + curr_ptr += tag_list[tag_location].size; + tag_location++; + } + + /* Now the TRCs */ + trc = (float*) gs_alloc_bytes(memory, TRC_V2_SIZE * sizeof(float), "gsicc_create_v2displayrgb"); + + for (k = 0; k < 3; k++) { + get_trc(k, link, &trc, TRC_V2_SIZE); + add_curve(curr_ptr, trc, TRC_V2_SIZE); + curr_ptr += tag_list[tag_location].size; + } + + /* Clean up */ + gsicc_release_link(link); + gs_free_object(memory, tag_list, "gsicc_create_v2displayrgb"); + gs_free_object(memory, trc, "gsicc_create_v2displayrgb"); + /* Save the v2 data */ + src_profile->v2_data = buffer; + src_profile->v2_size = profile_size; + +#if SAVEICCPROFILE + /* Dump the buffer to a file for testing if its a valid ICC profile */ + save_profile(buffer, "V2FromRGB", profile_size); +#endif +} + +static void +gsicc_create_v2display(const gs_gstate *pgs, icHeader *header, cmm_profile_t *src_profile, + byte *mediawhitept, cmm_profile_t *xyz_profile) +{ + /* Need to create matrix with the TRCs. Have to worry about gray + and RGB cases. */ + if (header->colorSpace == icSigGrayData) + gsicc_create_v2displaygray(pgs, header, src_profile, mediawhitept, xyz_profile); + else + gsicc_create_v2displayrgb(pgs, header, src_profile, mediawhitept, xyz_profile); +} + +static int +readint32(byte *buff) +{ + int out = 0; + byte *ptr = buff; + int k; + + for (k = 0; k < 4; k++) { + int temp = ptr[k]; + int shift = (3 - k) * 8; + out += temp << shift; + } + return out; +} + +/* Create special profile for going to/from CIEXYZ color space. We will use + this with lcms and the current profile to construct the structures in + a new V2 profile */ +static int +get_xyzprofile(cmm_profile_t *xyz_profile) +{ + icProfile iccprofile; + icHeader *header = &(iccprofile.header); + int num_tags = 9; /* common (2) + rXYZ,gXYZ,bXYZ,rTRC,gTRC,bTRC,wtpt */ + int profile_size = HEADER_SIZE; + gsicc_tag *tag_list; + int last_tag = -1; + /* 4 for name, 4 reserved, 4 for number entries. 0 entries implies linear */ + int trc_tag_size = 12; + byte *buffer, *curr_ptr, *tempptr; + int tag_location; + gs_memory_t *memory = xyz_profile->memory; + icS15Fixed16Number temp_XYZ[3]; + byte mediawhitept[12]; + icS15Fixed16Number one, zero; + int k, j; + int code; + + /* Fill in the common stuff */ + setheader_common(header, 2); + /* If we have to create a table we will do it in XYZ. If it is a matrix, + it is still XYZ */ + header->pcs = icSigXYZData; + header->colorSpace = icSigRgbData; + header->deviceClass = icSigDisplayClass; + + /* Profile description tag, copyright tag white point and grayTRC */ + tag_list = (gsicc_tag*)gs_alloc_bytes(memory, + sizeof(gsicc_tag) * num_tags, "get_xyzprofile"); + if (tag_list == NULL) + return -1; + /* Let us precompute the sizes of everything and all our offsets */ + profile_size += TAG_SIZE * num_tags; + profile_size += 4; /* number of tags.... */ + + /* Common tags + white point + RGB colorants + RGB TRCs */ + init_common_tagsv2(tag_list, num_tags, &last_tag); + init_tag(tag_list, &last_tag, icSigMediaWhitePointTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigRedColorantTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigGreenColorantTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigBlueColorantTag, XYZPT_SIZE); + init_tag(tag_list, &last_tag, icSigRedTRCTag, trc_tag_size); + init_tag(tag_list, &last_tag, icSigGreenTRCTag, trc_tag_size); + init_tag(tag_list, &last_tag, icSigBlueTRCTag, trc_tag_size); + + /* Now get the profile size */ + for (k = 0; k < num_tags; k++) { + profile_size += tag_list[k].size; + } + + /* Allocate buffer */ + buffer = gs_alloc_bytes(memory, profile_size, "get_xyzprofile"); + if (buffer == NULL) { + gs_free_object(memory, tag_list, "get_xyzprofile"); + return -1; + } + + /* Media white point for this profile is D50 */ + get_D50(temp_XYZ); /* See Appendix D6 in spec */ + tempptr = mediawhitept; + for (j = 0; j < 3; j++) { + write_bigendian_4bytes(tempptr, temp_XYZ[j]); + tempptr += 4; + } + + /* Start writing out data to buffer */ + curr_ptr = write_v2_common_data(buffer, profile_size, header, tag_list, + num_tags, mediawhitept); + tag_location = V2_COMMON_TAGS; + /* Now lets add the Red Green and Blue colorant information */ + one = double2XYZtype(1); + zero = double2XYZtype(0); + + temp_XYZ[0] = one; + temp_XYZ[1] = zero; + temp_XYZ[2] = zero; + add_xyzdata(curr_ptr, temp_XYZ); + curr_ptr += tag_list[tag_location].size; + tag_location++; + + temp_XYZ[0] = zero; + temp_XYZ[1] = one; + add_xyzdata(curr_ptr, temp_XYZ); + curr_ptr += tag_list[tag_location].size; + tag_location++; + + temp_XYZ[1] = zero; + temp_XYZ[2] = one; + add_xyzdata(curr_ptr, temp_XYZ); + curr_ptr += tag_list[tag_location].size; + tag_location++; + + /* And now the TRCs */ + add_curve(curr_ptr, NULL, 0); + curr_ptr += tag_list[tag_location].size; + tag_location++; + add_curve(curr_ptr, NULL, 0); + curr_ptr += tag_list[tag_location].size; + tag_location++; + add_curve(curr_ptr, NULL, 0); + + /* Done */ + gs_free_object(memory, tag_list, "get_xyzprofile"); + xyz_profile->buffer = buffer; + xyz_profile->buffer_size = profile_size; + code = gsicc_init_profile_info(xyz_profile); +#if SAVEICCPROFILE + /* Dump the buffer to a file for testing if its a valid ICC profile */ + save_profile(buffer, "XYZProfile", profile_size); +#endif + return code; +} + +static bool +get_mediawp(cmm_profile_t *src_profile, byte *mediawhitept) +{ + byte *buffer = &(src_profile->buffer[128]); + int num_tags = readint32(buffer); + int tag_signature; + int offset; + int k; + + buffer += 4; + + /* Get to the tag table */ + for (k = 0; k < num_tags; k++) { + tag_signature = readint32(buffer); + if (tag_signature == icSigMediaWhitePointTag) + break; + buffer += 12; + } + if (tag_signature != icSigMediaWhitePointTag) + return false; + buffer += 4; + offset = readint32(buffer); + buffer = &(src_profile->buffer[offset + 8]); /* Add offset of 8 for XYZ tag and padding */ + /* Data is already in the proper format. Just get the bytes */ + memcpy(mediawhitept, buffer, 12); + return true; +} + +static void +gsicc_create_v2(const gs_gstate *pgs, cmm_profile_t *src_profile) +{ + icProfile iccprofile; + icHeader *header = &(iccprofile.header); + byte mediawhitept[12]; + cmm_profile_t *xyz_profile; + + if (src_profile->v2_data != NULL) + return; + + /* Fill in the common stuff */ + setheader_common(header, 2); + + /* Get the data_cs of current profile */ + switch (src_profile->data_cs) { + case gsGRAY: + header->colorSpace = icSigGrayData; + break; + case gsRGB: + header->colorSpace = icSigRgbData; + break; + case gsCMYK: + header->colorSpace = icSigCmykData; + break; + default: +#ifdef DEBUG + gs_warn("Failed in creating V2 ICC profile"); +#endif + return; + break; + } + + /* Use the deviceClass from the source profile. */ + header->deviceClass = gsicc_get_device_class(src_profile); + + /* Unfortunately we have to get the media white point also. lcms wrapped + up the method internally when it went to release 2 so we will do our + own*/ + if (!get_mediawp(src_profile, &(mediawhitept[0]))) { +#ifdef DEBUG + gs_warn("Failed in creating V2 ICC profile"); +#endif + return; + } + + /* Also, we will want to create an XYZ ICC profile that we can use for + creating our data with lcms. If already created, this profile is + stored in the manager */ + if (pgs->icc_manager->xyz_profile != NULL) { + xyz_profile = pgs->icc_manager->xyz_profile; + } else { + xyz_profile = gsicc_profile_new(NULL, pgs->memory, NULL, 0); + if (xyz_profile == NULL) { +#ifdef DEBUG + gs_warn("Failed in creating V2 ICC profile"); +#endif + return; + } + if (get_xyzprofile(xyz_profile) != 0) { +#ifdef DEBUG + gs_warn("Failed in creating V2 ICC profile"); +#endif + return; + } + pgs->icc_manager->xyz_profile = xyz_profile; + } + + /* The type of stuff that we need to create */ + switch (header->deviceClass) { + case icSigInputClass: + header->pcs = icSigLabData; + gsicc_create_v2input(pgs, header, src_profile, mediawhitept, + pgs->icc_manager->lab_profile); + break; + case icSigDisplayClass: + header->pcs = icSigXYZData; + gsicc_create_v2display(pgs, header, src_profile, mediawhitept, + xyz_profile); + break; + case icSigOutputClass: + header->pcs = icSigLabData; + gsicc_create_v2output(pgs, header, src_profile, mediawhitept, + pgs->icc_manager->lab_profile); + break; + default: +#ifdef DEBUG + gs_warn("Failed in creating V2 ICC profile"); +#endif + return; + break; + } + return; +} + +/* While someone could create something that was not valid for now we will + just trust the version information in the header. Allow anything with + major version 2 */ +static bool +gsicc_create_isv2(cmm_profile_t *profile) +{ + if (profile->vers == ICCVERS_UNKNOWN) { + int majorvers = profile->buffer[8]; + + if (majorvers == 2) { + profile->vers = ICCVERS_2; + return true; + } else { + profile->vers = ICCVERS_NOT2; + return false; + } + } + if (profile->vers == ICCVERS_2) + return true; + else + return false; +} + +byte* +gsicc_create_getv2buffer(const gs_gstate *pgs, cmm_profile_t *srcprofile, + int *size) +{ + if (gsicc_create_isv2(srcprofile)) { + *size = srcprofile->buffer_size; + return srcprofile->buffer; + } + + if (srcprofile->profile_handle == NULL) + srcprofile->profile_handle = + gsicc_get_profile_handle_buffer(srcprofile->buffer, + srcprofile->buffer_size, pgs->memory); + + /* Need to create v2 profile */ + gsicc_create_v2(pgs, srcprofile); + + *size = srcprofile->v2_size; + return srcprofile->v2_data; } diff -Nru ghostscript-9.10~dfsg/base/gsicc_create.h ghostscript-9.25~dfsg+1/base/gsicc_create.h --- ghostscript-9.10~dfsg/base/gsicc_create.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_create.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -41,5 +41,7 @@ cmm_profile_t* gsicc_create_from_cal(float *white, float *black, float *gamma, float *matrix, gs_memory_t *memory, int num_colors); - +byte* gsicc_getv2buffer(cmm_profile_t *srcprofile, int *size); +byte* gsicc_create_getv2buffer(const gs_gstate *pgs, + cmm_profile_t *srcprofile, int *size); #endif diff -Nru ghostscript-9.10~dfsg/base/gsicc.h ghostscript-9.25~dfsg+1/base/gsicc.h --- ghostscript-9.10~dfsg/base/gsicc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -33,4 +33,6 @@ extern const gs_color_space_type gs_color_space_type_ICC; extern cs_proc_remap_color(gx_remap_ICC_imagelab); +int gx_change_color_model(gx_device *dev, int num_comps, int bit_depth); + #endif /* gsicc_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsicc_lcms2.c ghostscript-9.25~dfsg+1/base/gsicc_lcms2.c --- ghostscript-9.10~dfsg/base/gsicc_lcms2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_lcms2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,19 +9,29 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* gsicc interface to littleCMS */ +#include "memory_.h" #include "lcms2.h" #include "lcms2_plugin.h" #include "gslibctx.h" #include "gserrors.h" #include "gp.h" #include "gsicc_cms.h" +#include "gxdevice.h" + +#ifndef MEMENTO_SQUEEZE_BUILD +#define USE_LCMS2_LOCKING +#endif + +#ifdef USE_LCMS2_LOCKING +#include "gxsync.h" +#endif #define DUMP_CMS_BUFFER 0 #define DEBUG_LCMS_MEM 0 @@ -44,9 +54,16 @@ void *gs_lcms2_malloc(cmsContext id, unsigned int size) { void *ptr; - gs_memory_t *mem = (gs_memory_t *)id; +#if !(defined(SHARE_LCMS) && SHARE_LCMS==1) + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); +#endif +#if defined(SHARE_LCMS) && SHARE_LCMS==1 + ptr = malloc(size); +#else ptr = gs_alloc_bytes(mem, size, "lcms"); +#endif + #if DEBUG_LCMS_MEM gs_warn2("lcms malloc (%d) at 0x%x",size,ptr); #endif @@ -56,19 +73,29 @@ static void gs_lcms2_free(cmsContext id, void *ptr) { - gs_memory_t *mem = (gs_memory_t *)id; +#if !(defined(SHARE_LCMS) && SHARE_LCMS==1) + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); +#endif + if (ptr != NULL) { #if DEBUG_LCMS_MEM gs_warn1("lcms free at 0x%x",ptr); #endif + +#if defined(SHARE_LCMS) && SHARE_LCMS==1 + free(ptr); +#else gs_free_object(mem, ptr, "lcms"); +#endif } } static void *gs_lcms2_realloc(cmsContext id, void *ptr, unsigned int size) { - gs_memory_t *mem = (gs_memory_t *)id; +#if !(defined(SHARE_LCMS) && SHARE_LCMS==1) + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); +#endif void *ptr2; if (ptr == 0) @@ -78,7 +105,12 @@ gs_lcms2_free(id, ptr); return NULL; } +#if defined(SHARE_LCMS) && SHARE_LCMS==1 + ptr2 = realloc(ptr, size); +#else ptr2 = gs_resize_object(mem, ptr, size, "lcms"); +#endif + #if DEBUG_LCMS_MEM gs_warn3("lcms realloc (%x,%d) at 0x%x",ptr,size,ptr2); #endif @@ -98,13 +130,57 @@ gs_lcms2_realloc, NULL, NULL, - NULL + NULL, +}; + +#ifdef USE_LCMS2_LOCKING + +static +void *gs_lcms2_createMutex(cmsContext id) +{ + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + + return gx_monitor_label(gx_monitor_alloc(mem), "lcms2"); +} + +static +void gs_lcms2_destroyMutex(cmsContext id, void* mtx) +{ + gx_monitor_free((gx_monitor_t *)mtx); +} + +static +cmsBool gs_lcms2_lockMutex(cmsContext id, void* mtx) +{ + return !gx_monitor_enter((gx_monitor_t *)mtx); +} + +static +void gs_lcms2_unlockMutex(cmsContext id, void* mtx) +{ + gx_monitor_leave((gx_monitor_t *)mtx); +} + +static cmsPluginMutex gs_cms_mutexhandler = +{ + { + cmsPluginMagicNumber, + 2060, + cmsPluginMutexSig, + NULL + }, + gs_lcms2_createMutex, + gs_lcms2_destroyMutex, + gs_lcms2_lockMutex, + gs_lcms2_unlockMutex }; +#endif + /* Get the number of channels for the profile. Input count */ int -gscms_get_input_channel_count(gcmmhprofile_t profile) +gscms_get_input_channel_count(gcmmhprofile_t profile, gs_memory_t *memory) { cmsColorSpaceSignature colorspace; @@ -114,7 +190,7 @@ /* Get the number of output channels for the profile */ int -gscms_get_output_channel_count(gcmmhprofile_t profile) +gscms_get_output_channel_count(gcmmhprofile_t profile, gs_memory_t *memory) { cmsColorSpaceSignature colorspace; @@ -124,7 +200,7 @@ /* Get the number of colorant names in the clrt tag */ int -gscms_get_numberclrtnames(gcmmhprofile_t profile) +gscms_get_numberclrtnames(gcmmhprofile_t profile, gs_memory_t *memory) { cmsNAMEDCOLORLIST *lcms_names; @@ -154,7 +230,7 @@ NULL) == 0) return NULL; length = strlen(name); - buf = (char*) gs_alloc_bytes(memory, length, "gscms_get_clrtname"); + buf = (char*) gs_alloc_bytes(memory, length + 1, "gscms_get_clrtname"); if (buf) strcpy(buf, name); return buf; @@ -162,14 +238,28 @@ /* Check if the profile is a device link type */ bool -gscms_is_device_link(gcmmhprofile_t profile) +gscms_is_device_link(gcmmhprofile_t profile, gs_memory_t *memory) +{ + return cmsGetDeviceClass(profile) == cmsSigLinkClass; +} + +/* Needed for v2 profile creation */ +int +gscms_get_device_class(gcmmhprofile_t profile, gs_memory_t *memory) +{ + return cmsGetDeviceClass(profile); +} + +/* Check if the profile is a input type */ +bool +gscms_is_input(gcmmhprofile_t profile, gs_memory_t *memory) { - return (cmsGetDeviceClass(profile) == cmsSigLinkClass); + return (cmsGetDeviceClass(profile) == cmsSigInputClass); } /* Get the device space associated with this profile */ gsicc_colorbuffer_t -gscms_get_profile_data_space(gcmmhprofile_t profile) +gscms_get_profile_data_space(gcmmhprofile_t profile, gs_memory_t *memory) { cmsColorSpaceSignature colorspace; @@ -192,22 +282,26 @@ /* Get ICC Profile handle from buffer */ gcmmhprofile_t -gscms_get_profile_handle_mem(gs_memory_t *mem, unsigned char *buffer, - unsigned int input_size) +gscms_get_profile_handle_mem(unsigned char *buffer, + unsigned int input_size, gs_memory_t *mem) { - cmsSetLogErrorHandler(gscms_error); - return(cmsOpenProfileFromMemTHR((cmsContext)mem,buffer,input_size)); + cmsContext ctx = gs_lib_ctx_get_cms_context(mem); + + cmsSetLogErrorHandlerTHR(ctx, gscms_error); + return(cmsOpenProfileFromMemTHR(ctx,buffer,input_size)); } /* Get ICC Profile handle from file ptr */ gcmmhprofile_t -gscms_get_profile_handle_file(gs_memory_t *mem,const char *filename) +gscms_get_profile_handle_file(const char *filename, gs_memory_t *mem) { - return(cmsOpenProfileFromFileTHR((cmsContext)mem, filename, "r")); + cmsContext ctx = gs_lib_ctx_get_cms_context(mem); + + return(cmsOpenProfileFromFileTHR(ctx, filename, "r")); } /* Transform an entire buffer */ -void +int gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, @@ -215,10 +309,9 @@ void *outputbuffer) { cmsHTRANSFORM hTransform = (cmsHTRANSFORM)icclink->link_handle; - cmsUInt32Number dwInputFormat,dwOutputFormat, num_src_lcms, num_des_lcms; - int planar,numbytes,big_endian,hasalpha,k; + cmsUInt32Number dwInputFormat, dwOutputFormat, num_src_lcms, num_des_lcms; + int planar,numbytes, big_endian, hasalpha, k; unsigned char *inputpos, *outputpos; - int numchannels; #if DUMP_CMS_BUFFER FILE *fid_in, *fid_out; #endif @@ -260,7 +353,7 @@ if (num_src_lcms != input_buff_desc->num_chan || num_des_lcms != output_buff_desc->num_chan) { /* We can't transform this. Someone is doing something odd */ - return; + return_error(gs_error_unknownerror); } dwInputFormat = dwInputFormat | CHANNELS_SH(num_src_lcms); dwOutputFormat = dwOutputFormat | CHANNELS_SH(num_des_lcms); @@ -280,20 +373,73 @@ this row by row adjusting for our stride. Output buffer must already be allocated. ToDo: Check issues with plane and row stride and word boundry */ - inputpos = (unsigned char *) inputbuffer; - outputpos = (unsigned char *) outputbuffer; + inputpos = (byte *) inputbuffer; + outputpos = (byte *) outputbuffer; if(input_buff_desc->is_planar){ - /* Do entire buffer. Care must be taken here - with respect to row stride, word boundry and number - of source versus output channels. We may - need to take a closer look at this. */ - cmsDoTransform(hTransform,inputpos,outputpos, - input_buff_desc->plane_stride); + /* Determine if we can do this in one operation or if we have to break + it up. Essentially if the width * height = plane_stride then yes. If + we are doing some subsection of a plane then no. */ + if (input_buff_desc->num_rows * input_buff_desc->pixels_per_row == + input_buff_desc->plane_stride && + output_buff_desc->num_rows * output_buff_desc->pixels_per_row == + output_buff_desc->plane_stride) { + /* Do entire buffer.*/ + cmsDoTransform(hTransform, inputpos, outputpos, + input_buff_desc->plane_stride); + } else { + /* We have to do this row by row, with memory transfers */ + byte *temp_des, *temp_src; + int source_size = input_buff_desc->bytes_per_chan * + input_buff_desc->pixels_per_row; + + int des_size = output_buff_desc->bytes_per_chan * + output_buff_desc->pixels_per_row; + int y, i; + + temp_src = (byte*)gs_alloc_bytes(dev->memory->non_gc_memory, + source_size * input_buff_desc->num_chan, + "gscms_transform_color_buffer"); + if (temp_src == NULL) + return_error(gs_error_VMerror); + temp_des = (byte*) gs_alloc_bytes(dev->memory->non_gc_memory, + des_size * output_buff_desc->num_chan, + "gscms_transform_color_buffer"); + if (temp_des == NULL) + return_error(gs_error_VMerror); + for (y = 0; y < input_buff_desc->num_rows; y++) { + byte *src_cm = temp_src; + byte *src_buff = inputpos; + byte *des_cm = temp_des; + byte *des_buff = outputpos; + + /* Put into planar temp buffer */ + for (i = 0; i < input_buff_desc->num_chan; i ++) { + memcpy(src_cm, src_buff, source_size); + src_cm += source_size; + src_buff += input_buff_desc->plane_stride; + } + /* Transform */ + cmsDoTransform(hTransform, temp_src, temp_des, + input_buff_desc->pixels_per_row); + /* Get out of temp planar buffer */ + for (i = 0; i < output_buff_desc->num_chan; i ++) { + memcpy(des_buff, des_cm, des_size); + des_cm += des_size; + des_buff += output_buff_desc->plane_stride; + } + inputpos += input_buff_desc->row_stride; + outputpos += output_buff_desc->row_stride; + } + gs_free_object(dev->memory->non_gc_memory, temp_src, + "gscms_transform_color_buffer"); + gs_free_object(dev->memory->non_gc_memory, temp_des, + "gscms_transform_color_buffer"); + } } else { /* Do row by row. */ for(k = 0; k < input_buff_desc->num_rows ; k++){ - cmsDoTransform(hTransform,inputpos,outputpos, - input_buff_desc->pixels_per_row); + cmsDoTransform(hTransform, inputpos, outputpos, + input_buff_desc->pixels_per_row); inputpos += input_buff_desc->row_stride; outputpos += output_buff_desc->row_stride; } @@ -308,16 +454,15 @@ fclose(fid_in); fclose(fid_out); #endif + return 0; } /* Transform a single color. We assume we have passed to us the proper number of elements of size gx_device_color. It is up to the caller to make sure the proper allocations for the colors are there. */ -void -gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, - void *inputcolor, - void *outputcolor, - int num_bytes) +int +gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, + void *outputcolor, int num_bytes) { cmsHTRANSFORM hTransform = (cmsHTRANSFORM)icclink->link_handle; cmsUInt32Number dwInputFormat,dwOutputFormat; @@ -334,10 +479,21 @@ cmsChangeBuffersFormat(hTransform,dwInputFormat,dwOutputFormat); /* Do conversion */ cmsDoTransform(hTransform,inputcolor,outputcolor,1); + + return 0; +} + +/* Get the flag to avoid having to the cmm do any white fix up, it such a flag + exists for the cmm */ +int +gscms_avoid_white_fix_flag(gs_memory_t *memory) +{ + return cmsFLAGS_NOWHITEONWHITEFIXUP; } void -gscms_get_link_dim(gcmmhlink_t link, int *num_inputs, int *num_outputs) +gscms_get_link_dim(gcmmhlink_t link, int *num_inputs, int *num_outputs, + gs_memory_t *memory) { *num_inputs = T_CHANNELS(cmsGetTransformInputFormat(link)); *num_outputs = T_CHANNELS(cmsGetTransformOutputFormat(link)); @@ -347,7 +503,7 @@ gcmmhlink_t gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, - gsicc_rendering_param_t *rendering_params, + gsicc_rendering_param_t *rendering_params, int cmm_flags, gs_memory_t *memory) { cmsUInt32Number src_data_type,des_data_type; @@ -355,6 +511,7 @@ int src_nChannels,des_nChannels; int lcms_src_color_space, lcms_des_color_space; unsigned int flag; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); /* Check for case of request for a transfrom from a device link profile in that case, the destination profile is NULL */ @@ -375,8 +532,8 @@ if (lcms_deshandle != NULL) { des_color_space = cmsGetColorSpace(lcms_deshandle); } else { - /* We must have a device link profile. */ - des_color_space = cmsGetPCS(lcms_deshandle); + /* We must have a device link profile. Use it's PCS space. */ + des_color_space = cmsGetPCS(lcms_srchandle); } lcms_des_color_space = _cmsLCMScolorSpace(des_color_space); if (lcms_des_color_space < 0) lcms_des_color_space = 0; @@ -424,41 +581,42 @@ } } /* Create the link */ - return cmsCreateTransformTHR((cmsContext)memory, + return cmsCreateTransformTHR(ctx, lcms_srchandle, src_data_type, lcms_deshandle, des_data_type, - rendering_params->rendering_intent,flag); + rendering_params->rendering_intent, flag | cmm_flags); /* cmsFLAGS_HIGHRESPRECALC) cmsFLAGS_NOTPRECALC cmsFLAGS_LOWRESPRECALC*/ } -/* Get the link from the CMS, but include proofing and/or a device link +/* Get the link from the CMS, but include proofing and/or a device link profile. Note also, that the source may be a device link profile, in which case we will not have a destination profile but could still have a proof profile or an additional device link profile */ gcmmhlink_t gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_proofhandle, - gcmmhprofile_t lcms_deshandle, - gcmmhprofile_t lcms_devlinkhandle, + gcmmhprofile_t lcms_deshandle, + gcmmhprofile_t lcms_devlinkhandle, gsicc_rendering_param_t *rendering_params, - bool src_dev_link, + bool src_dev_link, int cmm_flags, gs_memory_t *memory) { cmsUInt32Number src_data_type,des_data_type; cmsColorSpaceSignature src_color_space,des_color_space; int src_nChannels,des_nChannels; int lcms_src_color_space, lcms_des_color_space; - cmsHPROFILE hProfiles[5]; + cmsHPROFILE hProfiles[5]; int nProfiles = 0; unsigned int flag; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); /* Check if the rendering intent is something other than relative colorimetric - and if we have a proofing profile. In this case we need to create the + and if we have a proofing profile. In this case we need to create the combined profile a bit different. LCMS does not allow us to use different intents in the cmsCreateMultiprofileTransform transform. Also, don't even think about doing this if someone has snuck in a source based device link profile into the mix */ - if (lcms_proofhandle != NULL && + if (lcms_proofhandle != NULL && rendering_params->rendering_intent != gsRELATIVECOLORIMETRIC && !src_dev_link) { /* First handle the source to proof profile with its particular intent as @@ -466,15 +624,15 @@ cmsHPROFILE src_to_proof; cmsHTRANSFORM temptransform; - temptransform = gscms_get_link(lcms_srchandle, lcms_proofhandle, - rendering_params, memory); + temptransform = gscms_get_link(lcms_srchandle, lcms_proofhandle, + rendering_params, cmm_flags, memory); /* Now mash that to a device link profile */ flag = cmsFLAGS_HIGHRESPRECALC; - if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON || + if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) { flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); } - src_to_proof = cmsTransform2DeviceLink(temptransform, 3.4, flag); + src_to_proof = cmsTransform2DeviceLink(temptransform, 3.4, flag); /* Free up the link handle */ cmsDeleteTransform(temptransform); src_color_space = cmsGetColorSpace(src_to_proof); @@ -485,7 +643,7 @@ /* For now, just do single byte data, interleaved. We can change this when we use the transformation. */ src_data_type = (COLORSPACE_SH(lcms_src_color_space)| - CHANNELS_SH(src_nChannels)|BYTES_SH(2)); + CHANNELS_SH(src_nChannels)|BYTES_SH(2)); if (lcms_devlinkhandle == NULL) { des_color_space = cmsGetColorSpace(lcms_deshandle); } else { @@ -500,7 +658,7 @@ destination and then to the device link profile if there was one. */ hProfiles[nProfiles++] = src_to_proof; /* Src to proof with special intent */ hProfiles[nProfiles++] = lcms_proofhandle; /* Proof to CIELAB */ - if (lcms_deshandle != NULL) { + if (lcms_deshandle != NULL) { hProfiles[nProfiles++] = lcms_deshandle; /* Our destination */ } /* The output device link profile */ @@ -513,7 +671,7 @@ flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); } /* Use relative colorimetric here */ - temptransform = cmsCreateMultiprofileTransformTHR((cmsContext)memory, + temptransform = cmsCreateMultiprofileTransformTHR(ctx, hProfiles, nProfiles, src_data_type, des_data_type, gsRELATIVECOLORIMETRIC, flag); cmsCloseProfile(src_to_proof); @@ -528,7 +686,7 @@ /* For now, just do single byte data, interleaved. We can change this when we use the transformation. */ src_data_type = (COLORSPACE_SH(lcms_src_color_space)| - CHANNELS_SH(src_nChannels)|BYTES_SH(2)); + CHANNELS_SH(src_nChannels)|BYTES_SH(2)); if (lcms_devlinkhandle == NULL) { if (src_dev_link) { des_color_space = cmsGetPCS(lcms_srchandle); @@ -543,8 +701,8 @@ des_nChannels = cmsChannelsOf(des_color_space); des_data_type = (COLORSPACE_SH(lcms_des_color_space)| CHANNELS_SH(des_nChannels)|BYTES_SH(2)); - /* lcms proofing transform has a clunky API and can't include the device - link profile if we have both. So use cmsCreateMultiprofileTransform + /* lcms proofing transform has a clunky API and can't include the device + link profile if we have both. So use cmsCreateMultiprofileTransform instead and round trip the proofing profile. */ hProfiles[nProfiles++] = lcms_srchandle; /* Note if source is device link, we cannot do any proofing */ @@ -566,7 +724,7 @@ || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) { flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); } - return cmsCreateMultiprofileTransformTHR((cmsContext)memory, + return cmsCreateMultiprofileTransformTHR(ctx, hProfiles, nProfiles, src_data_type, des_data_type, rendering_params->rendering_intent, flag); } @@ -576,15 +734,19 @@ int gscms_create(gs_memory_t *memory) { + cmsContext ctx; + /* Set our own error handling function */ - cmsSetLogErrorHandler(gscms_error); - cmsPluginTHR(memory, (void *)&gs_cms_memhandler); - /* If we had created any persitent state that we needed access to in the - * other functions, we should store that by calling: - * gs_lib_ctx_set_cms_context(memory, state); - * We can then retrieve it anywhere else by calling: - * gs_lib_ctx_get_cms_context(memory); - * LCMS currently uses no such state. */ + ctx = cmsCreateContext((void *)&gs_cms_memhandler, memory); + if (ctx == NULL) + return_error(gs_error_VMerror); + +#ifdef USE_LCMS2_LOCKING + cmsPluginTHR(ctx, (void *)&gs_cms_mutexhandler); +#endif + + cmsSetLogErrorHandlerTHR(ctx, gscms_error); + gs_lib_ctx_set_cms_context(memory, ctx); return 0; } @@ -592,7 +754,12 @@ void gscms_destroy(gs_memory_t *memory) { - /* Nothing to do here for lcms */ + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + if (ctx == NULL) + return; + + cmsDeleteContext(ctx); + gs_lib_ctx_set_cms_context(memory, NULL); } /* Have the CMS release the link */ @@ -601,17 +768,18 @@ { if (icclink->link_handle != NULL ) cmsDeleteTransform(icclink->link_handle); + + icclink->link_handle = NULL; } /* Have the CMS release the profile handle */ void -gscms_release_profile(void *profile) +gscms_release_profile(void *profile, gs_memory_t *memory) { cmsHPROFILE profile_handle; - cmsBool notok; profile_handle = (cmsHPROFILE) profile; - notok = cmsCloseProfile(profile_handle); + cmsCloseProfile(profile_handle); } /* Named color, color management */ @@ -663,13 +831,13 @@ gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, gcmmhprofile_t lcms_proofhandle, - gsicc_rendering_param_t *rendering_params, - gs_memory_t *memory) + gsicc_rendering_param_t *rendering_params) { cmsHTRANSFORM hTransform; cmsUInt32Number dwOutputFormat; cmsUInt32Number lcms_proof_flag; int number_colors; + cmsContext ctx = gs_lib_ctx_get_cms_context(icclink->memory); /* NOTE: We need to add a test here to check that we even HAVE device values in here and NOT just CIELAB values */ @@ -680,7 +848,7 @@ } /* Create the transform */ /* ToDo: Adjust rendering intent */ - hTransform = cmsCreateProofingTransformTHR(memory, + hTransform = cmsCreateProofingTransformTHR(ctx, lcms_srchandle, TYPE_NAMED_COLOR_INDEX, lcms_deshandle, TYPE_CMYK_8, lcms_proofhandle,INTENT_PERCEPTUAL, @@ -701,3 +869,9 @@ if(lcms_proofhandle) cmsCloseProfile(lcms_proofhandle); return; } + +bool +gscms_is_threadsafe(void) +{ + return false; +} diff -Nru ghostscript-9.10~dfsg/base/gsicc_lcms2mt.c ghostscript-9.25~dfsg+1/base/gsicc_lcms2mt.c --- ghostscript-9.10~dfsg/base/gsicc_lcms2mt.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_lcms2mt.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,1109 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* gsicc interface to LittleCMS2-MT */ + +#include "memory_.h" +#include "lcms2mt.h" +#include "lcms2mt_plugin.h" +#include "gslibctx.h" +#include "gserrors.h" +#include "gp.h" +#include "gsicc_cms.h" +#include "gxdevice.h" + +#ifndef MEMENTO_SQUEEZE_BUILD +#define USE_LCMS2_LOCKING +#endif + +#ifdef USE_LCMS2_LOCKING +#include "gxsync.h" +#endif + +#define DUMP_CMS_BUFFER 0 +#define DEBUG_LCMS_MEM 0 +#define LCMS_BYTES_MASK T_BYTES(-1) /* leaves only mask for the BYTES (currently 7) */ +#define LCMS_ENDIAN16_MASK T_ENDIAN16(-1) /* similarly, for ENDIAN16 bit */ + +#define gsicc_link_flags(hasalpha, planarIN, planarOUT, bigendianIN, bigendianOUT, bytesIN, bytesOUT) \ + ((hasalpha != 0) << 2 | \ + (planarIN != 0) << 5 | (planarOUT != 0) << 4 | \ + (bigendianIN != 0) << 3 | (bigendianOUT != 0) << 2 | \ + (bytesIN == 1) << 1 | (bytesOUT == 1)) + +typedef struct gsicc_lcms2mt_link_list_s { + int flags; + cmsHTRANSFORM *hTransform; + struct gsicc_lcms2mt_link_list_s *next; +} gsicc_lcms2mt_link_list_t; + +/* Only provide warning about issues in lcms if debug build */ +static void +gscms_error(cmsContext ContextID, + cmsUInt32Number error_code, + const char *error_text) +{ +#ifdef DEBUG + gs_warn1("cmm error : %s",error_text); +#endif +} + +static +void *gs_lcms2_malloc(cmsContext id, unsigned int size) +{ + void *ptr; + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + +#if defined(SHARE_LCMS) && SHARE_LCMS==1 + ptr = malloc(size); +#else + ptr = gs_alloc_bytes(mem, size, "lcms"); +#endif + +#if DEBUG_LCMS_MEM + gs_warn2("lcms malloc (%d) at 0x%x",size,ptr); +#endif + return ptr; +} + +static +void gs_lcms2_free(cmsContext id, void *ptr) +{ + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + if (ptr != NULL) { +#if DEBUG_LCMS_MEM + gs_warn1("lcms free at 0x%x",ptr); +#endif + +#if defined(SHARE_LCMS) && SHARE_LCMS==1 + free(ptr); +#else + gs_free_object(mem, ptr, "lcms"); +#endif + } +} + +static +void *gs_lcms2_realloc(cmsContext id, void *ptr, unsigned int size) +{ + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + void *ptr2; + + if (ptr == 0) + return gs_lcms2_malloc(id, size); + if (size == 0) + { + gs_lcms2_free(id, ptr); + return NULL; + } +#if defined(SHARE_LCMS) && SHARE_LCMS==1 + ptr2 = realloc(ptr, size); +#else + ptr2 = gs_resize_object(mem, ptr, size, "lcms"); +#endif + +#if DEBUG_LCMS_MEM + gs_warn3("lcms realloc (%x,%d) at 0x%x",ptr,size,ptr2); +#endif + return ptr2; +} + +static cmsPluginMemHandler gs_cms_memhandler = +{ + { + cmsPluginMagicNumber, + LCMS_VERSION, + cmsPluginMemHandlerSig, + NULL + }, + gs_lcms2_malloc, + gs_lcms2_free, + gs_lcms2_realloc, + NULL, + NULL, + NULL, +}; + +#ifdef USE_LCMS2_LOCKING + +static +void *gs_lcms2_createMutex(cmsContext id) +{ + gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + + return gx_monitor_label(gx_monitor_alloc(mem), "lcms2"); +} + +static +void gs_lcms2_destroyMutex(cmsContext id, void* mtx) +{ + gx_monitor_free((gx_monitor_t *)mtx); +} + +static +cmsBool gs_lcms2_lockMutex(cmsContext id, void* mtx) +{ + return !gx_monitor_enter((gx_monitor_t *)mtx); +} + +static +void gs_lcms2_unlockMutex(cmsContext id, void* mtx) +{ + gx_monitor_leave((gx_monitor_t *)mtx); +} + +static cmsPluginMutex gs_cms_mutexhandler = +{ + { + cmsPluginMagicNumber, + 2060, + cmsPluginMutexSig, + NULL + }, + gs_lcms2_createMutex, + gs_lcms2_destroyMutex, + gs_lcms2_lockMutex, + gs_lcms2_unlockMutex +}; + +#endif + +static int +gscms_get_accuracy(gs_memory_t *mem) +{ + gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem); + + switch (ctx->icc_color_accuracy) { + case 0: + return cmsFLAGS_LOWRESPRECALC; + case 1: + return 0; + case 2: + default: + return cmsFLAGS_HIGHRESPRECALC; + } +} + +/* Get the number of channels for the profile. + Input count */ +int +gscms_get_input_channel_count(gcmmhprofile_t profile, gs_memory_t *memory) +{ + cmsColorSpaceSignature colorspace; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + colorspace = cmsGetColorSpace(ctx, profile); + return cmsChannelsOf(ctx, colorspace); +} + +/* Get the number of output channels for the profile */ +int +gscms_get_output_channel_count(gcmmhprofile_t profile, gs_memory_t *memory) +{ + cmsColorSpaceSignature colorspace; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + colorspace = cmsGetPCS(ctx, profile); + return cmsChannelsOf(ctx, colorspace); +} + +/* Get the number of colorant names in the clrt tag */ +int +gscms_get_numberclrtnames(gcmmhprofile_t profile, gs_memory_t *memory) +{ + cmsNAMEDCOLORLIST *lcms_names; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + lcms_names = (cmsNAMEDCOLORLIST *)cmsReadTag(ctx, profile, + cmsSigColorantTableTag); + return cmsNamedColorCount(ctx, lcms_names); +} + +/* Get the nth colorant name in the clrt tag */ +char* +gscms_get_clrtname(gcmmhprofile_t profile, int colorcount, gs_memory_t *memory) +{ + cmsNAMEDCOLORLIST *lcms_names; + char name[256]; + char *buf; + int length; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + lcms_names = (cmsNAMEDCOLORLIST *)cmsReadTag(ctx, profile, + cmsSigColorantTableTag); + if (colorcount >= cmsNamedColorCount(ctx, lcms_names)) return(NULL); + if (cmsNamedColorInfo(ctx, lcms_names, colorcount, name, NULL, NULL, NULL, + NULL) == 0) + return NULL; + length = strlen(name); + buf = (char*) gs_alloc_bytes(memory, length + 1, "gscms_get_clrtname"); + if (buf) + strcpy(buf, name); + return buf; +} + +/* Check if the profile is a device link type */ +bool +gscms_is_device_link(gcmmhprofile_t profile, gs_memory_t *memory) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + return cmsGetDeviceClass(ctx, profile) == cmsSigLinkClass; +} + +/* Needed for v2 profile creation */ +int +gscms_get_device_class(gcmmhprofile_t profile, gs_memory_t *memory) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + return cmsGetDeviceClass(ctx, profile); +} + +/* Check if the profile is a input type */ +bool +gscms_is_input(gcmmhprofile_t profile, gs_memory_t *memory) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + return cmsGetDeviceClass(ctx, profile) == cmsSigInputClass; +} + +/* Get the device space associated with this profile */ +gsicc_colorbuffer_t +gscms_get_profile_data_space(gcmmhprofile_t profile, gs_memory_t *memory) +{ + cmsColorSpaceSignature colorspace; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + colorspace = cmsGetColorSpace(ctx, profile); + switch (colorspace) { + case cmsSigXYZData: + return gsCIEXYZ; + case cmsSigLabData: + return gsCIELAB; + case cmsSigRgbData: + return gsRGB; + case cmsSigGrayData: + return gsGRAY; + case cmsSigCmykData: + return gsCMYK; + default: + return gsNCHANNEL; + } +} + +/* Get ICC Profile handle from buffer */ +gcmmhprofile_t +gscms_get_profile_handle_mem(unsigned char *buffer, unsigned int input_size, + gs_memory_t *mem) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(mem); + + cmsSetLogErrorHandlerTHR(ctx, gscms_error); + return cmsOpenProfileFromMemTHR(ctx,buffer,input_size); +} + +/* Get ICC Profile handle from file ptr */ +gcmmhprofile_t +gscms_get_profile_handle_file(const char *filename, gs_memory_t *mem) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(mem); + + return cmsOpenProfileFromFileTHR(ctx, filename, "r"); +} + +/* Transform an entire buffer */ +int +gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, + gsicc_bufferdesc_t *input_buff_desc, + gsicc_bufferdesc_t *output_buff_desc, + void *inputbuffer, void *outputbuffer) +{ + gsicc_lcms2mt_link_list_t *link_handle = (gsicc_lcms2mt_link_list_t *)(icclink->link_handle); + cmsHTRANSFORM hTransform = (cmsHTRANSFORM)link_handle->hTransform; + cmsUInt32Number dwInputFormat, dwOutputFormat, num_src_lcms, num_des_lcms; + int hasalpha, planarIN, planarOUT, numbytesIN, numbytesOUT, big_endianIN, big_endianOUT; + int k, needed_flags = 0; + unsigned char *inputpos, *outputpos; + cmsContext ctx = gs_lib_ctx_get_cms_context(icclink->memory); + +#if DUMP_CMS_BUFFER + FILE *fid_in, *fid_out; +#endif + /* Although little CMS does make assumptions about data types in its + transformations we can change it after the fact by cloning from any + other transform. We always create [0] which is no_alpha, chunky IN/OUT, + little_endian IN/OUT, 2-bytes_per_component IN/OUT. */ + /* Set us to the proper output type */ + /* Note, we could speed this up by passing back the encoded data type + to the caller so that we could avoid having to go through this + computation each time if they are doing multiple calls to this + operation, but this is working on a buffer at a time. */ + + /* Now set if we have planar, num bytes, endian case, and alpha data to skip */ + /* Planar -- pdf14 case for example */ + planarIN = input_buff_desc->is_planar; + planarOUT = output_buff_desc->is_planar; + + /* 8 or 16 byte input and output */ + numbytesIN = input_buff_desc->bytes_per_chan; + numbytesOUT = output_buff_desc->bytes_per_chan; + if (numbytesIN > 2 || numbytesOUT > 2) + return_error(gs_error_rangecheck); /* TODO: we don't support float */ + + /* endian */ + big_endianIN = !input_buff_desc->little_endian; + big_endianOUT = !output_buff_desc->little_endian; + + /* alpha, which is passed through unmolested */ + /* TODO: Right now we always must have alpha last */ + /* This is really only going to be an issue when we have interleaved alpha data */ + hasalpha = input_buff_desc->has_alpha; + + needed_flags = gsicc_link_flags(hasalpha, planarIN, planarOUT, + big_endianIN, big_endianOUT, + numbytesIN, numbytesOUT); + while (link_handle->flags != needed_flags) { + if (link_handle->next == NULL) { + hTransform = NULL; + break; + } else { + link_handle = link_handle->next; + hTransform = link_handle->hTransform; + } + } + if (hTransform == NULL) { + /* the variant we want wasn't present, clone it from the last on the list */ + gsicc_lcms2mt_link_list_t *new_link_handle = + (gsicc_lcms2mt_link_list_t *)gs_alloc_bytes(icclink->memory->non_gc_memory, + sizeof(gsicc_lcms2mt_link_list_t), + "gscms_transform_color_buffer"); + if (new_link_handle == NULL) { + return_error(gs_error_VMerror); + } + new_link_handle->next = NULL; /* new end of list */ + new_link_handle->flags = needed_flags; + hTransform = link_handle->hTransform; /* doesn't really matter which we start with */ + /* Color space MUST be the same */ + dwInputFormat = COLORSPACE_SH(T_COLORSPACE(cmsGetTransformInputFormat(ctx, hTransform))); + dwOutputFormat = COLORSPACE_SH(T_COLORSPACE(cmsGetTransformOutputFormat(ctx, hTransform))); + /* number of channels. This should not really be changing! */ + num_src_lcms = T_CHANNELS(cmsGetTransformInputFormat(ctx, hTransform)); + num_des_lcms = T_CHANNELS(cmsGetTransformOutputFormat(ctx, hTransform)); + if (num_src_lcms != input_buff_desc->num_chan || + num_des_lcms != output_buff_desc->num_chan) { + /* We can't transform this. Someone is doing something odd */ + return_error(gs_error_unknownerror); + } + dwInputFormat = dwInputFormat | CHANNELS_SH(num_src_lcms); + dwOutputFormat = dwOutputFormat | CHANNELS_SH(num_des_lcms); + /* set the remaining parameters, alpha, planar, num_bytes */ + dwInputFormat = dwInputFormat | EXTRA_SH(hasalpha); + dwOutputFormat = dwOutputFormat | EXTRA_SH(hasalpha); + dwInputFormat = dwInputFormat | PLANAR_SH(planarIN); + dwOutputFormat = dwOutputFormat | PLANAR_SH(planarOUT); + dwInputFormat = dwInputFormat | ENDIAN16_SH(big_endianIN); + dwOutputFormat = dwOutputFormat | ENDIAN16_SH(big_endianOUT); + dwInputFormat = dwInputFormat | BYTES_SH(numbytesIN); + dwOutputFormat = dwOutputFormat | BYTES_SH(numbytesOUT); + + hTransform = cmsCloneTransformChangingFormats(ctx, hTransform, dwInputFormat, dwOutputFormat); + if (hTransform == NULL) + return_error(gs_error_unknownerror); + /* Now we have a new hTransform to add to the list, BUT some other thread */ + /* may have been working in the same one. Lock, check again and add to */ + /* the (potentially new) end of the list */ + gx_monitor_enter(icclink->lock); + while (link_handle->next != NULL) { + if (link_handle->flags == needed_flags) { + /* OOPS. Someone else did it while we were building it */ + cmsDeleteTransform(ctx, hTransform); + hTransform = link_handle->hTransform; + new_link_handle = NULL; + break; + } + link_handle = link_handle->next; + } + gx_monitor_leave(icclink->lock); + if (new_link_handle != NULL) { + new_link_handle->hTransform = hTransform; + link_handle->next = new_link_handle; /* link to end of list */ + } + } + + /* littleCMS knows nothing about word boundarys. As such, we need to do + this row by row adjusting for our stride. Output buffer must already + be allocated. ToDo: Check issues with plane and row stride and word + boundry */ + inputpos = (byte *) inputbuffer; + outputpos = (byte *) outputbuffer; + if(input_buff_desc->is_planar){ + /* Determine if we can do this in one operation or if we have to break + it up. Essentially if the width * height = plane_stride then yes. If + we are doing some subsection of a plane then no. */ + if (input_buff_desc->num_rows * input_buff_desc->pixels_per_row == + input_buff_desc->plane_stride && + output_buff_desc->num_rows * output_buff_desc->pixels_per_row == + output_buff_desc->plane_stride) { + /* Do entire buffer.*/ + cmsDoTransform(ctx, hTransform, inputpos, outputpos, + input_buff_desc->plane_stride); + } else { + /* We have to do this row by row, with memory transfers */ + byte *temp_des, *temp_src; + int source_size = input_buff_desc->bytes_per_chan * + input_buff_desc->pixels_per_row; + + int des_size = output_buff_desc->bytes_per_chan * + output_buff_desc->pixels_per_row; + int y, i; + + temp_src = (byte*)gs_alloc_bytes(icclink->memory->non_gc_memory, + source_size * input_buff_desc->num_chan, + "gscms_transform_color_buffer"); + if (temp_src == NULL) + return_error(gs_error_VMerror); + temp_des = (byte*) gs_alloc_bytes(icclink->memory->non_gc_memory, + des_size * output_buff_desc->num_chan, + "gscms_transform_color_buffer"); + if (temp_des == NULL) + return_error(gs_error_VMerror); + for (y = 0; y < input_buff_desc->num_rows; y++) { + byte *src_cm = temp_src; + byte *src_buff = inputpos; + byte *des_cm = temp_des; + byte *des_buff = outputpos; + + /* Put into planar temp buffer */ + for (i = 0; i < input_buff_desc->num_chan; i ++) { + memcpy(src_cm, src_buff, source_size); + src_cm += source_size; + src_buff += input_buff_desc->plane_stride; + } + /* Transform */ + cmsDoTransform(ctx, hTransform, temp_src, temp_des, + input_buff_desc->pixels_per_row); + /* Get out of temp planar buffer */ + for (i = 0; i < output_buff_desc->num_chan; i ++) { + memcpy(des_buff, des_cm, des_size); + des_cm += des_size; + des_buff += output_buff_desc->plane_stride; + } + inputpos += input_buff_desc->row_stride; + outputpos += output_buff_desc->row_stride; + } + gs_free_object(icclink->memory->non_gc_memory, temp_src, + "gscms_transform_color_buffer"); + gs_free_object(icclink->memory->non_gc_memory, temp_des, + "gscms_transform_color_buffer"); + } + } else { + /* Do row by row. */ + for(k = 0; k < input_buff_desc->num_rows ; k++){ + cmsDoTransform(ctx, hTransform, inputpos, outputpos, + input_buff_desc->pixels_per_row); + inputpos += input_buff_desc->row_stride; + outputpos += output_buff_desc->row_stride; + } + } +#if DUMP_CMS_BUFFER + fid_in = gp_fopen("CM_Input.raw","ab"); + fid_out = gp_fopen("CM_Output.raw","ab"); + fwrite((unsigned char*) inputbuffer,sizeof(unsigned char), + input_buff_desc->row_stride,fid_in); + fwrite((unsigned char*) outputbuffer,sizeof(unsigned char), + output_buff_desc->row_stride,fid_out); + fclose(fid_in); + fclose(fid_out); +#endif + return 0; +} + +/* Transform a single color. We assume we have passed to us the proper number + of elements of size gx_device_color. It is up to the caller to make sure + the proper allocations for the colors are there. */ +int +gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, + void *outputcolor, int num_bytes) +{ + gsicc_lcms2mt_link_list_t *link_handle = (gsicc_lcms2mt_link_list_t *)(icclink->link_handle); + cmsHTRANSFORM hTransform = (cmsHTRANSFORM)link_handle->hTransform; + cmsUInt32Number dwInputFormat, dwOutputFormat; + cmsContext ctx = gs_lib_ctx_get_cms_context(icclink->memory); + int big_endianIN, big_endianOUT, needed_flags; + + /* For a single color, we are going to use the link as it is + with the exception of taking care of the word size. */ + if (num_bytes > 2) + return_error(gs_error_rangecheck); /* TODO: we don't support float */ + + dwInputFormat = cmsGetTransformInputFormat(ctx, hTransform); + big_endianIN = T_ENDIAN16(dwInputFormat); + dwOutputFormat = cmsGetTransformOutputFormat(ctx, hTransform); + big_endianOUT = T_ENDIAN16(dwOutputFormat); + + needed_flags = gsicc_link_flags(0, 0, 0, /* alpha and planar not used for single color */ + big_endianIN, big_endianOUT, + num_bytes, num_bytes); + while (link_handle->flags != needed_flags) { + if (link_handle->next == NULL) { + hTransform = NULL; + break; + } else { + link_handle = link_handle->next; + hTransform = link_handle->hTransform; + } + } + if (hTransform == NULL) { + gsicc_lcms2mt_link_list_t *new_link_handle = + (gsicc_lcms2mt_link_list_t *)gs_alloc_bytes(icclink->memory->non_gc_memory, + sizeof(gsicc_lcms2mt_link_list_t), + "gscms_transform_color_buffer"); + if (new_link_handle == NULL) { + return_error(gs_error_VMerror); + } + new_link_handle->next = NULL; /* new end of list */ + new_link_handle->flags = needed_flags; + hTransform = link_handle->hTransform; + + /* the variant we want wasn't present, clone it from the HEAD (no alpha, not planar) */ + dwInputFormat = COLORSPACE_SH(T_COLORSPACE(cmsGetTransformInputFormat(ctx, hTransform))); + dwOutputFormat = COLORSPACE_SH(T_COLORSPACE(cmsGetTransformOutputFormat(ctx, hTransform))); + dwInputFormat = dwInputFormat | CHANNELS_SH(T_CHANNELS(cmsGetTransformInputFormat(ctx, hTransform))); + dwOutputFormat = dwOutputFormat | CHANNELS_SH(T_CHANNELS(cmsGetTransformOutputFormat(ctx, hTransform))); + dwInputFormat = dwInputFormat | ENDIAN16_SH(big_endianIN); + dwOutputFormat = dwOutputFormat | ENDIAN16_SH(big_endianOUT); + dwInputFormat = dwInputFormat | BYTES_SH(num_bytes); + dwOutputFormat = dwOutputFormat | BYTES_SH(num_bytes); + + /* Get the transform with the settings we need */ + hTransform = cmsCloneTransformChangingFormats(ctx, hTransform, dwInputFormat, dwOutputFormat); + + if (hTransform == NULL) + return_error(gs_error_unknownerror); + + /* Now we have a new hTransform to add to the list, BUT some other thread */ + /* may have been working in the same one. Lock, check again and add to */ + /* the (potentially new) end of the list */ + gx_monitor_enter(icclink->lock); + while (link_handle->next != NULL) { + if (link_handle->flags == needed_flags) { + /* OOPS. Someone else did it while we were building it */ + cmsDeleteTransform(ctx, hTransform); + hTransform = link_handle->hTransform; + new_link_handle = NULL; + break; + } + link_handle = link_handle->next; + } + gx_monitor_leave(icclink->lock); + if (new_link_handle != NULL) { + new_link_handle->hTransform = hTransform; + link_handle->next = new_link_handle; /* link to end of list */ + } + } + + /* Do conversion */ + cmsDoTransform(ctx, hTransform, inputcolor, outputcolor, 1); + + return 0; +} + +/* Get the flag to avoid having to the cmm do any white fix up, it such a flag + exists for the cmm */ +int +gscms_avoid_white_fix_flag(gs_memory_t *memory) +{ + return cmsFLAGS_NOWHITEONWHITEFIXUP; +} + +void +gscms_get_link_dim(gcmmhlink_t link, int *num_inputs, int *num_outputs, + gs_memory_t *memory) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + gsicc_lcms2mt_link_list_t *link_handle = (gsicc_lcms2mt_link_list_t *)(link); + cmsHTRANSFORM hTransform = (cmsHTRANSFORM)link_handle->hTransform; + + *num_inputs = T_CHANNELS(cmsGetTransformInputFormat(ctx, hTransform)); + *num_outputs = T_CHANNELS(cmsGetTransformOutputFormat(ctx, hTransform)); +} + +/* Get the link from the CMS. TODO: Add error checking */ +gcmmhlink_t +gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, + gsicc_rendering_param_t *rendering_params, int cmm_flags, + gs_memory_t *memory) +{ + cmsUInt32Number src_data_type,des_data_type; + cmsColorSpaceSignature src_color_space,des_color_space; + int src_nChannels,des_nChannels; + int lcms_src_color_space, lcms_des_color_space; + unsigned int flag; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + gsicc_lcms2mt_link_list_t *link_handle; + + /* Check for case of request for a transfrom from a device link profile + in that case, the destination profile is NULL */ + + /* First handle all the source stuff */ + src_color_space = cmsGetColorSpace(ctx, lcms_srchandle); + lcms_src_color_space = _cmsLCMScolorSpace(ctx, src_color_space); + + /* littlecms returns -1 for types it does not (but should) understand */ + if (lcms_src_color_space < 0) + lcms_src_color_space = 0; + src_nChannels = cmsChannelsOf(ctx, src_color_space); + + /* For now, just do single byte data, interleaved. We can change this + when we use the transformation. */ + src_data_type = (COLORSPACE_SH(lcms_src_color_space)| + CHANNELS_SH(src_nChannels)|BYTES_SH(2)); +#if 0 + src_data_type = src_data_type | ENDIAN16_SH(1); +#endif + if (lcms_deshandle != NULL) { + des_color_space = cmsGetColorSpace(ctx, lcms_deshandle); + } else { + /* We must have a device link profile. Use it's PCS space. */ + des_color_space = cmsGetPCS(ctx, lcms_srchandle); + } + lcms_des_color_space = _cmsLCMScolorSpace(ctx, des_color_space); + if (lcms_des_color_space < 0) + lcms_des_color_space = 0; + des_nChannels = cmsChannelsOf(ctx, des_color_space); + des_data_type = (COLORSPACE_SH(lcms_des_color_space)| + CHANNELS_SH(des_nChannels)|BYTES_SH(2)); + /* endian */ +#if 0 + des_data_type = des_data_type | ENDIAN16_SH(1); +#endif + /* Set up the flags */ + flag = gscms_get_accuracy(memory); + if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON + || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) { + flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); + } + if (rendering_params->preserve_black == gsBLACKPRESERVE_KONLY) { + switch (rendering_params->rendering_intent) { + case INTENT_PERCEPTUAL: + rendering_params->rendering_intent = INTENT_PRESERVE_K_ONLY_PERCEPTUAL; + break; + case INTENT_RELATIVE_COLORIMETRIC: + rendering_params->rendering_intent = INTENT_PRESERVE_K_ONLY_RELATIVE_COLORIMETRIC; + break; + case INTENT_SATURATION: + rendering_params->rendering_intent = INTENT_PRESERVE_K_ONLY_SATURATION; + break; + default: + break; + } + } + if (rendering_params->preserve_black == gsBLACKPRESERVE_KPLANE) { + switch (rendering_params->rendering_intent) { + case INTENT_PERCEPTUAL: + rendering_params->rendering_intent = INTENT_PRESERVE_K_PLANE_PERCEPTUAL; + break; + case INTENT_RELATIVE_COLORIMETRIC: + rendering_params->rendering_intent = INTENT_PRESERVE_K_PLANE_RELATIVE_COLORIMETRIC; + break; + case INTENT_SATURATION: + rendering_params->rendering_intent = INTENT_PRESERVE_K_PLANE_SATURATION; + break; + default: + break; + } + } + + /* Create the link */ + link_handle = (gsicc_lcms2mt_link_list_t *)gs_alloc_bytes(memory->non_gc_memory, + sizeof(gsicc_lcms2mt_link_list_t), + "gscms_transform_color_buffer"); + if (link_handle == NULL) + return NULL; + link_handle->hTransform = cmsCreateTransformTHR(ctx, lcms_srchandle, src_data_type, + lcms_deshandle, des_data_type, + rendering_params->rendering_intent, + flag | cmm_flags); + if (link_handle->hTransform == NULL) { + gs_free_object(memory, link_handle, "gscms_get_link"); + return NULL; + } + link_handle->next = NULL; + link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, little-endian */ + sizeof(gx_color_value), sizeof(gx_color_value)); + return link_handle; + /* cmsFLAGS_HIGHRESPRECALC) cmsFLAGS_NOTPRECALC cmsFLAGS_LOWRESPRECALC*/ +} + +/* Get the link from the CMS, but include proofing and/or a device link + profile. Note also, that the source may be a device link profile, in + which case we will not have a destination profile but could still have + a proof profile or an additional device link profile */ +gcmmhlink_t +gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, + gcmmhprofile_t lcms_proofhandle, + gcmmhprofile_t lcms_deshandle, + gcmmhprofile_t lcms_devlinkhandle, + gsicc_rendering_param_t *rendering_params, + bool src_dev_link, int cmm_flags, + gs_memory_t *memory) +{ + cmsUInt32Number src_data_type,des_data_type; + cmsColorSpaceSignature src_color_space,des_color_space; + int src_nChannels,des_nChannels; + int lcms_src_color_space, lcms_des_color_space; + cmsHPROFILE hProfiles[5]; + int nProfiles = 0; + unsigned int flag; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + gsicc_lcms2mt_link_list_t *link_handle; + + link_handle = (gsicc_lcms2mt_link_list_t *)gs_alloc_bytes(memory->non_gc_memory, + sizeof(gsicc_lcms2mt_link_list_t), + "gscms_transform_color_buffer"); + if (link_handle == NULL) + return NULL; + link_handle->next = NULL; + link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, little-endian */ + sizeof(gx_color_value), sizeof(gx_color_value)); + /* Check if the rendering intent is something other than relative colorimetric + and if we have a proofing profile. In this case we need to create the + combined profile a bit different. LCMS does not allow us to use different + intents in the cmsCreateMultiprofileTransform transform. Also, don't even + think about doing this if someone has snuck in a source based device link + profile into the mix */ + if (lcms_proofhandle != NULL && + rendering_params->rendering_intent != gsRELATIVECOLORIMETRIC && + !src_dev_link) { + + /* First handle the source to proof profile with its particular intent as + a device link profile */ + cmsHPROFILE src_to_proof; + + link_handle = gscms_get_link(lcms_srchandle, lcms_proofhandle, + rendering_params, cmm_flags, memory); + if (link_handle->hTransform == NULL) { + gs_free_object(memory, link_handle, "gscms_get_link_proof_devlink"); + return NULL; + } + + /* Now mash that to a device link profile */ + flag = gscms_get_accuracy(memory); + if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON || + rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) { + flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); + } + src_to_proof = cmsTransform2DeviceLink(ctx, link_handle->hTransform, 3.4, flag); + cmsDeleteTransform(ctx, link_handle->hTransform); + + src_color_space = cmsGetColorSpace(ctx, src_to_proof); + lcms_src_color_space = _cmsLCMScolorSpace(ctx, src_color_space); + + /* littlecms returns -1 for types it does not (but should) understand */ + if (lcms_src_color_space < 0) + lcms_src_color_space = 0; + src_nChannels = cmsChannelsOf(ctx, src_color_space); + + /* For now, just do single byte data, interleaved. We can change this + when we use the transformation. */ + src_data_type = (COLORSPACE_SH(lcms_src_color_space)| + CHANNELS_SH(src_nChannels)|BYTES_SH(2)); + if (lcms_devlinkhandle == NULL) { + des_color_space = cmsGetColorSpace(ctx, lcms_deshandle); + } else { + des_color_space = cmsGetPCS(ctx, lcms_devlinkhandle); + } + lcms_des_color_space = _cmsLCMScolorSpace(ctx, des_color_space); + if (lcms_des_color_space < 0) lcms_des_color_space = 0; + des_nChannels = cmsChannelsOf(ctx, des_color_space); + des_data_type = (COLORSPACE_SH(lcms_des_color_space)| + CHANNELS_SH(des_nChannels)|BYTES_SH(2)); + + /* Now, we need to go back through the proofing profile, to the + destination and then to the device link profile if there was one. */ + hProfiles[nProfiles++] = src_to_proof; /* Src to proof with special intent */ + hProfiles[nProfiles++] = lcms_proofhandle; /* Proof to CIELAB */ + if (lcms_deshandle != NULL) { + hProfiles[nProfiles++] = lcms_deshandle; /* Our destination */ + } + + /* The output device link profile */ + if (lcms_devlinkhandle != NULL) { + hProfiles[nProfiles++] = lcms_devlinkhandle; + } + flag = gscms_get_accuracy(memory); + if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON + || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) { + flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); + } + + /* Use relative colorimetric here */ + link_handle->hTransform = cmsCreateMultiprofileTransformTHR(ctx, + hProfiles, nProfiles, src_data_type, des_data_type, + gsRELATIVECOLORIMETRIC, flag); + cmsCloseProfile(ctx, src_to_proof); + } else { + /* First handle all the source stuff */ + src_color_space = cmsGetColorSpace(ctx, lcms_srchandle); + lcms_src_color_space = _cmsLCMScolorSpace(ctx, src_color_space); + + /* littlecms returns -1 for types it does not (but should) understand */ + if (lcms_src_color_space < 0) + lcms_src_color_space = 0; + src_nChannels = cmsChannelsOf(ctx, src_color_space); + + /* For now, just do single byte data, interleaved. We can change this + when we use the transformation. */ + src_data_type = (COLORSPACE_SH(lcms_src_color_space)| + CHANNELS_SH(src_nChannels)|BYTES_SH(2)); + if (lcms_devlinkhandle == NULL) { + if (src_dev_link) { + des_color_space = cmsGetPCS(ctx, lcms_srchandle); + } else { + des_color_space = cmsGetColorSpace(ctx, lcms_deshandle); + } + } else { + des_color_space = cmsGetPCS(ctx, lcms_devlinkhandle); + } + lcms_des_color_space = _cmsLCMScolorSpace(ctx, des_color_space); + if (lcms_des_color_space < 0) lcms_des_color_space = 0; + des_nChannels = cmsChannelsOf(ctx, des_color_space); + des_data_type = (COLORSPACE_SH(lcms_des_color_space)| + CHANNELS_SH(des_nChannels)|BYTES_SH(2)); + + /* lcms proofing transform has a clunky API and can't include the device + link profile if we have both. So use cmsCreateMultiprofileTransform + instead and round trip the proofing profile. */ + hProfiles[nProfiles++] = lcms_srchandle; + + /* Note if source is device link, we cannot do any proofing */ + if (lcms_proofhandle != NULL && !src_dev_link) { + hProfiles[nProfiles++] = lcms_proofhandle; + hProfiles[nProfiles++] = lcms_proofhandle; + } + + /* This should be NULL if we have a source device link */ + if (lcms_deshandle != NULL) { + hProfiles[nProfiles++] = lcms_deshandle; + } + + /* Someone could have a device link at the output, giving us possibly two + device link profiles to smash together */ + if (lcms_devlinkhandle != NULL) { + hProfiles[nProfiles++] = lcms_devlinkhandle; + } + flag = gscms_get_accuracy(memory); + if (rendering_params->black_point_comp == gsBLACKPTCOMP_ON + || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) { + flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); + } + link_handle->hTransform = cmsCreateMultiprofileTransformTHR(ctx, + hProfiles, nProfiles, src_data_type, + des_data_type, rendering_params->rendering_intent, flag); + } + if (link_handle->hTransform == NULL) { + gs_free_object(memory, link_handle, "gscms_get_link_proof_devlink"); + return NULL; + } + return link_handle; +} + +/* Do any initialization if needed to the CMS */ +int +gscms_create(gs_memory_t *memory) +{ + cmsContext ctx; + + /* Set our own error handling function */ + ctx = cmsCreateContext((void *)&gs_cms_memhandler, memory); + if (ctx == NULL) + return_error(gs_error_VMerror); + +#ifdef USE_LCMS2_LOCKING + cmsPluginTHR(ctx, (void *)&gs_cms_mutexhandler); +#endif + + cmsSetLogErrorHandlerTHR(ctx, gscms_error); + gs_lib_ctx_set_cms_context(memory, ctx); + return 0; +} + +/* Do any clean up when done with the CMS if needed */ +void +gscms_destroy(gs_memory_t *memory) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + if (ctx == NULL) + return; + + cmsDeleteContext(ctx); + gs_lib_ctx_set_cms_context(memory, NULL); +} + +/* Have the CMS release the link */ +void +gscms_release_link(gsicc_link_t *icclink) +{ + cmsContext ctx = gs_lib_ctx_get_cms_context(icclink->memory); + gsicc_lcms2mt_link_list_t *link_handle = (gsicc_lcms2mt_link_list_t *)(icclink->link_handle); + + while (link_handle != NULL) { + gsicc_lcms2mt_link_list_t *next_handle; + cmsDeleteTransform(ctx, link_handle->hTransform); + next_handle = link_handle->next; + gs_free_object(icclink->memory->non_gc_memory, link_handle, "gscms_release_link"); + link_handle = next_handle; + } + icclink->link_handle = NULL; +} + +/* Have the CMS release the profile handle */ +void +gscms_release_profile(void *profile, gs_memory_t *memory) +{ + cmsHPROFILE profile_handle; + cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + profile_handle = (cmsHPROFILE) profile; + cmsCloseProfile(ctx, profile_handle); +} + +/* Named color, color management */ +/* Get a device value for the named color. Since there exist named color + ICC profiles and littleCMS supports them, we will use + that format in this example. However it should be noted + that this object need not be an ICC named color profile + but can be a proprietary type table. Some CMMs do not + support named color profiles. In that case, or if + the named color is not found, the caller should use an alternate + tint transform or other method. If a proprietary + format (nonICC) is being used, the operators given below must + be implemented. In every case that I can imagine, this should be + straight forward. Note that we allow the passage of a tint + value also. Currently the ICC named color profile does not provide + tint related information, only a value for 100% coverage. + It is provided here for use in proprietary + methods, which may be able to provide the desired effect. We will + at the current time apply a direct tint operation to the returned + device value. + Right now I don't see any reason to have the named color profile + ever return CIELAB. It will either return device values directly or + it will return values defined by the output device profile */ + +int +gscms_transform_named_color(gsicc_link_t *icclink, float tint_value, + const char* ColorName, gx_color_value device_values[]) +{ + gsicc_lcms2mt_link_list_t *link_handle = (gsicc_lcms2mt_link_list_t *)(icclink->link_handle); + cmsHTRANSFORM hTransform = (cmsHTRANSFORM)link_handle->hTransform; + unsigned short *deviceptr = device_values; + int index; + cmsContext ctx = gs_lib_ctx_get_cms_context(icclink->memory); + + /* Check if name is present in the profile */ + /* If it is not return -1. Caller will need to use an alternate method */ + if((index = cmsNamedColorIndex(ctx, hTransform, ColorName)) < 0) + return -1; + + /* Get the device value. */ +/* FIXME: This looks WRONG. Doesn't it need to use tint_value??? */ +/* Also, the hTransform from link_handle is 2-byte IN, *NOT* float */ + cmsDoTransform(ctx, hTransform,&index,deviceptr,1); + return 0; +} + +/* Create a link to return device values inside the named color profile or link + it with a destination profile and potentially a proofing profile. If the + output_colorspace and the proof_color space are NULL, then we will be + returning the device values that are contained in the named color profile. + i.e. in namedcolor_information. Note that an ICC named color profile + need NOT contain the device values but must contain the CIELAB values. */ +void +gscms_get_name2device_link(gsicc_link_t *icclink, + gcmmhprofile_t lcms_srchandle, + gcmmhprofile_t lcms_deshandle, + gcmmhprofile_t lcms_proofhandle, + gsicc_rendering_param_t *rendering_params) +{ + cmsHTRANSFORM hTransform, hTransformNew; + cmsUInt32Number dwOutputFormat; + cmsUInt32Number lcms_proof_flag; + int number_colors; + cmsContext ctx = gs_lib_ctx_get_cms_context(icclink->memory); + gsicc_lcms2mt_link_list_t *link_handle; + + icclink->link_handle = NULL; /* in case of failure */ + /* NOTE: We need to add a test here to check that we even HAVE + device values in here and NOT just CIELAB values */ + if ( lcms_proofhandle != NULL ){ + lcms_proof_flag = cmsFLAGS_GAMUTCHECK | cmsFLAGS_SOFTPROOFING; + } else { + lcms_proof_flag = 0; + } + + /* Create the transform */ + /* ToDo: Adjust rendering intent */ + hTransform = cmsCreateProofingTransformTHR(ctx, + lcms_srchandle, TYPE_NAMED_COLOR_INDEX, + lcms_deshandle, TYPE_CMYK_8, + lcms_proofhandle,INTENT_PERCEPTUAL, + INTENT_ABSOLUTE_COLORIMETRIC, + lcms_proof_flag); + if (hTransform == NULL) + return; /* bail */ + + /* In littleCMS there is no easy way to find out the size of the device + space returned by the named color profile until after the transform is made. + Hence we adjust our output format after creating the transform. It is + set to CMYK8 initially. */ + number_colors = cmsNamedColorCount(ctx, cmsGetNamedColorList(hTransform)); + + /* NOTE: Output size of gx_color_value with no color space type check */ + dwOutputFormat = (CHANNELS_SH(number_colors)|BYTES_SH(sizeof(gx_color_value))); + + /* Change the formatters */ + hTransformNew = cmsCloneTransformChangingFormats(ctx, hTransform,TYPE_NAMED_COLOR_INDEX,dwOutputFormat); + cmsDeleteTransform(ctx, hTransform); /* release the original after cloning */ + if (hTransformNew == NULL) + return; /* bail */ + link_handle = (gsicc_lcms2mt_link_list_t *)gs_alloc_bytes(icclink->memory->non_gc_memory, + sizeof(gsicc_lcms2mt_link_list_t), + "gscms_transform_color_buffer"); + if (link_handle == NULL) { + cmsDeleteTransform(ctx, hTransformNew); + return; /* bail */ + } + link_handle->flags = gsicc_link_flags(0, 0, 0, 0, 0, /* no alpha, not planar, little-endian */ + sizeof(gx_color_value), sizeof(gx_color_value)); + link_handle->hTransform = hTransformNew; + link_handle->next = NULL; + icclink->link_handle = link_handle; + + cmsCloseProfile(ctx, lcms_srchandle); + if(lcms_deshandle) + cmsCloseProfile(ctx, lcms_deshandle); + if(lcms_proofhandle) + cmsCloseProfile(ctx, lcms_proofhandle); + return; +} + +bool +gscms_is_threadsafe(void) +{ + return true; /* threads work correctly */ +} diff -Nru ghostscript-9.10~dfsg/base/gsicc_lcms.c ghostscript-9.25~dfsg+1/base/gsicc_lcms.c --- ghostscript-9.10~dfsg/base/gsicc_lcms.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_lcms.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,539 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* gsicc interface to littleCMS */ - -#ifndef LCMS_USER_ALLOC -#define LCMS_USER_ALLOC 1 -#endif - -#include "gsicc_cms.h" -#include "lcms.h" -#include "gslibctx.h" -#include "gserrors.h" -#include "gp.h" - - -#define DUMP_CMS_BUFFER 0 -#define DEBUG_LCMS_MEM 0 -#define LCMS_BYTES_MASK 0x7 - -/* Only provide warning about issues in lcms if debug build */ -static int -gscms_error(int error_code, const char *error_text){ -#ifdef DEBUG - gs_warn1("cmm error : %s",error_text); -#endif - return(1); -} - -/* Get the number of channels for the profile. - Input count */ -int -gscms_get_input_channel_count(gcmmhprofile_t profile) -{ - icColorSpaceSignature colorspace; - - colorspace = cmsGetColorSpace(profile); - return(_cmsChannelsOf(colorspace)); -} - -/* Get the number of output channels for the profile */ -int -gscms_get_output_channel_count(gcmmhprofile_t profile) -{ - icColorSpaceSignature colorspace; - - colorspace = cmsGetPCS(profile); - return(_cmsChannelsOf(colorspace)); -} - -/* Get the number of colorant names in the clrt tag */ -int -gscms_get_numberclrtnames(gcmmhprofile_t profile) -{ - LPcmsNAMEDCOLORLIST lcms_names; - - lcms_names = cmsReadColorantTable(profile, icSigColorantTableTag); - return(lcms_names->nColors); -} - -/* Get the nth colorant name in the clrt tag */ -char* -gscms_get_clrtname(gcmmhprofile_t profile, int colorcount, gs_memory_t *memory) -{ - LPcmsNAMEDCOLORLIST lcms_names; - int length; - char *name; - - lcms_names = cmsReadColorantTable(profile, icSigColorantTableTag); - if (colorcount+1 > lcms_names->nColors) return(NULL); - length = strlen(lcms_names->List[colorcount].Name); - name = (char*) gs_alloc_bytes(memory, length, "gscms_get_clrtname"); - if (name) - strcpy(name, lcms_names->List[colorcount].Name); - return name; -} - -/* Get the device space associated with this profile */ - -gsicc_colorbuffer_t -gscms_get_profile_data_space(gcmmhprofile_t profile) -{ - icColorSpaceSignature colorspace; - - colorspace = cmsGetColorSpace(profile); - switch( colorspace ) { - case icSigXYZData: - return(gsCIEXYZ); - case icSigLabData: - return(gsCIELAB); - case icSigRgbData: - return(gsRGB); - case icSigGrayData: - return(gsGRAY); - case icSigCmykData: - return(gsCMYK); - default: - return(gsNCHANNEL); - } -} - -/* Get ICC Profile handle from buffer */ -gcmmhprofile_t -gscms_get_profile_handle_mem(gs_memory_t *mem, unsigned char *buffer, unsigned int input_size) -{ - cmsSetErrorHandler((cmsErrorHandlerFunction) gscms_error); - return(cmsOpenProfileFromMem(buffer,input_size)); -} - -/* Get ICC Profile handle from file ptr */ -gcmmhprofile_t -gscms_get_profile_handle_file(gs_memory_t *mem, const char *filename) -{ - return(cmsOpenProfileFromFile(filename, "r")); -} - -/* Transform an entire buffer */ -void -gscms_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, - gsicc_bufferdesc_t *input_buff_desc, - gsicc_bufferdesc_t *output_buff_desc, - void *inputbuffer, - void *outputbuffer) -{ - - cmsHTRANSFORM hTransform = (cmsHTRANSFORM) icclink->link_handle; - DWORD dwInputFormat,dwOutputFormat,curr_input,curr_output; - int planar,numbytes,big_endian,hasalpha,k; - unsigned char *inputpos, *outputpos; - int numchannels; -#if DUMP_CMS_BUFFER - FILE *fid_in, *fid_out; -#endif - /* Although little CMS does make assumptions about data types in its - transformations you can change it after the fact. */ - /* Set us to the proper output type */ - /* Note, we could speed this up by passing back the encoded data type - to the caller so that we could avoid having to go through this - computation each time if they are doing multiple calls to this - operation */ - _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) (LPSTR) hTransform; - - curr_input = p->InputFormat; - curr_output = p->OutputFormat; - - /* Color space MUST be the same */ - dwInputFormat = COLORSPACE_SH(T_COLORSPACE(curr_input)); - dwOutputFormat = COLORSPACE_SH(T_COLORSPACE(curr_output)); - - /* Now set if we have planar, num bytes, endian case, and alpha data to skip */ - /* Planar -- pdf14 case for example */ - planar = input_buff_desc->is_planar; - dwInputFormat = dwInputFormat | PLANAR_SH(planar); - planar = output_buff_desc->is_planar; - dwOutputFormat = dwOutputFormat | PLANAR_SH(planar); - - /* 8 or 16 byte input and output */ - numbytes = input_buff_desc->bytes_per_chan; - if (numbytes>2) numbytes = 0; /* littleCMS encodes float with 0 ToDO. */ - dwInputFormat = dwInputFormat | BYTES_SH(numbytes); - numbytes = output_buff_desc->bytes_per_chan; - if (numbytes>2) numbytes = 0; - dwOutputFormat = dwOutputFormat | BYTES_SH(numbytes); - - /* endian */ - big_endian = !input_buff_desc->little_endian; - dwInputFormat = dwInputFormat | ENDIAN16_SH(big_endian); - big_endian = !output_buff_desc->little_endian; - dwOutputFormat = dwOutputFormat | ENDIAN16_SH(big_endian); - - /* number of channels */ - numchannels = input_buff_desc->num_chan; - dwInputFormat = dwInputFormat | CHANNELS_SH(numchannels); - numchannels = output_buff_desc->num_chan; - dwOutputFormat = dwOutputFormat | CHANNELS_SH(numchannels); - - /* alpha, which is passed through unmolested */ - /* ToDo: Right now we always must have alpha last */ - /* This is really only going to be an issue when we have - interleaved alpha data */ - hasalpha = input_buff_desc->has_alpha; - dwInputFormat = dwInputFormat | EXTRA_SH(hasalpha); - dwOutputFormat = dwOutputFormat | EXTRA_SH(hasalpha); - - /* Change the formaters */ - cmsChangeBuffersFormat(hTransform,dwInputFormat,dwOutputFormat); - - /* littleCMS knows nothing about word boundarys. As such, we need to do - this row by row adjusting for our stride. Output buffer must already - be allocated. ToDo: Check issues with plane and row stride and word - boundry */ - inputpos = (unsigned char *) inputbuffer; - outputpos = (unsigned char *) outputbuffer; - if(input_buff_desc->is_planar){ - /* Do entire buffer. Care must be taken here - with respect to row stride, word boundry and number - of source versus output channels. We may - need to take a closer look at this. */ - cmsDoTransform(hTransform,inputpos,outputpos, - input_buff_desc->plane_stride); -#if DUMP_CMS_BUFFER - fid_in = gp_fopen("CM_Input.raw","ab"); - fid_out = fp_fopen("CM_Output.raw","ab"); - fwrite((unsigned char*) inputbuffer,sizeof(unsigned char), - input_buff_desc->plane_stride * - input_buff_desc->num_chan, fid_in); - fwrite((unsigned char*) outputbuffer,sizeof(unsigned char), - output_buff_desc->plane_stride * - output_buff_desc->num_chan, fid_out); - fclose(fid_in); - fclose(fid_out); -#endif - } else { - /* Do row by row. */ - for(k = 0; k < input_buff_desc->num_rows ; k++){ - cmsDoTransform(hTransform,inputpos,outputpos, - input_buff_desc->pixels_per_row); - inputpos += input_buff_desc->row_stride; - outputpos += output_buff_desc->row_stride; - } -#if DUMP_CMS_BUFFER - fid_in = gp_fopen("CM_Input.raw","ab"); - fid_out = gp_fopen("CM_Output.raw","ab"); - fwrite((unsigned char*) inputbuffer,sizeof(unsigned char), - input_buff_desc->row_stride,fid_in); - fwrite((unsigned char*) outputbuffer,sizeof(unsigned char), - output_buff_desc->row_stride,fid_out); - fclose(fid_in); - fclose(fid_out); -#endif - } -} - -/* Transform a single color. We assume we have passed to us the proper number - of elements of size gx_device_color. It is up to the caller to make sure - the proper allocations for the colors are there. */ -void -gscms_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, - void *outputcolor, int num_bytes) -{ - cmsHTRANSFORM hTransform = (cmsHTRANSFORM) icclink->link_handle; - DWORD dwInputFormat,dwOutputFormat,curr_input,curr_output; - - /* For a single color, we are going to use the link as it is - with the exception of taking care of the word size. */ - _LPcmsTRANSFORM p = (_LPcmsTRANSFORM) (LPSTR) hTransform; - curr_input = p->InputFormat; - curr_output = p->OutputFormat; - /* numbytes = sizeof(gx_color_value); */ - if (num_bytes>2) num_bytes = 0; /* littleCMS encodes float with 0 ToDO. */ - dwInputFormat = (curr_input & (~LCMS_BYTES_MASK)) | BYTES_SH(num_bytes); - dwOutputFormat = (curr_output & (~LCMS_BYTES_MASK)) | BYTES_SH(num_bytes); - /* Change the formatters */ - cmsChangeBuffersFormat(hTransform,dwInputFormat,dwOutputFormat); - /* Do conversion */ - cmsDoTransform(hTransform,inputcolor,outputcolor,1); -} - -/* Get the link from the CMS. TODO: Add error checking */ -gcmmhlink_t -gscms_get_link(gcmmhprofile_t lcms_srchandle, - gcmmhprofile_t lcms_deshandle, - gsicc_rendering_param_t *rendering_params, - gs_memory_t *mem) -{ - DWORD src_data_type,des_data_type; - icColorSpaceSignature src_color_space,des_color_space; - int src_nChannels,des_nChannels; - int lcms_src_color_space, lcms_des_color_space; - - /* First handle all the source stuff */ - src_color_space = cmsGetColorSpace(lcms_srchandle); - lcms_src_color_space = _cmsLCMScolorSpace(src_color_space); - /* littlecms returns -1 for types it does not (but should) understand */ - if (lcms_src_color_space < 0) lcms_src_color_space = 0; - src_nChannels = _cmsChannelsOf(src_color_space); - /* For now, just do single byte data, interleaved. We can change this - when we use the transformation. */ - src_data_type = (COLORSPACE_SH(lcms_src_color_space)| - CHANNELS_SH(src_nChannels)|BYTES_SH(2)); - - if (lcms_deshandle != NULL) { - des_color_space = cmsGetColorSpace(lcms_deshandle); - } else { - /* We must have a device link profile. */ - des_color_space = cmsGetPCS(lcms_deshandle); - } - lcms_des_color_space = _cmsLCMScolorSpace(des_color_space); - if (lcms_des_color_space < 0) lcms_des_color_space = 0; - des_nChannels = _cmsChannelsOf(des_color_space); - des_data_type = (COLORSPACE_SH(lcms_des_color_space)| - CHANNELS_SH(des_nChannels)|BYTES_SH(2)); -/* Create the link */ - return(cmsCreateTransform(lcms_srchandle, src_data_type, lcms_deshandle, - des_data_type, rendering_params->rendering_intent, - (cmsFLAGS_BLACKPOINTCOMPENSATION | cmsFLAGS_HIGHRESPRECALC | - cmsFLAGS_NOTCACHE ))); - /* cmsFLAGS_HIGHRESPRECALC) cmsFLAGS_NOTPRECALC cmsFLAGS_LOWRESPRECALC*/ -} - -/* Get the link from the CMS, but include proofing and/or a device link - profile. */ -gcmmhlink_t -gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, - gcmmhprofile_t lcms_proofhandle, - gcmmhprofile_t lcms_deshandle, - gcmmhprofile_t lcms_devlinkhandle, - gsicc_rendering_param_t *rendering_params, - bool src_dev_link, - gs_memory_t *mem) -{ - DWORD src_data_type,des_data_type; - icColorSpaceSignature src_color_space,des_color_space; - int src_nChannels,des_nChannels; - int lcms_src_color_space, lcms_des_color_space; - cmsHPROFILE hProfiles[5]; - int nProfiles = 0; - - /* First handle all the source stuff */ - src_color_space = cmsGetColorSpace(lcms_srchandle); - lcms_src_color_space = _cmsLCMScolorSpace(src_color_space); - /* littlecms returns -1 for types it does not (but should) understand */ - if (lcms_src_color_space < 0) lcms_src_color_space = 0; - src_nChannels = _cmsChannelsOf(src_color_space); - /* For now, just do single byte data, interleaved. We can change this - when we use the transformation. */ - src_data_type = (COLORSPACE_SH(lcms_src_color_space)| - CHANNELS_SH(src_nChannels)|BYTES_SH(2)); - if (lcms_deshandle != NULL) { - des_color_space = cmsGetColorSpace(lcms_deshandle); - } else { - /* We must have a device link profile. */ - des_color_space = cmsGetPCS(lcms_deshandle); - } - lcms_des_color_space = _cmsLCMScolorSpace(des_color_space); - if (lcms_des_color_space < 0) lcms_des_color_space = 0; - des_nChannels = _cmsChannelsOf(des_color_space); - des_data_type = (COLORSPACE_SH(lcms_des_color_space)| - CHANNELS_SH(des_nChannels)|BYTES_SH(2)); - /* lcms proofing transform has a clunky API and can't include the device - link profile if we have both. So use cmsCreateMultiprofileTransform - instead and round trip the proofing profile. */ - hProfiles[nProfiles++] = lcms_srchandle; - if (lcms_proofhandle != NULL) { - hProfiles[nProfiles++] = lcms_proofhandle; - hProfiles[nProfiles++] = lcms_proofhandle; - } - hProfiles[nProfiles++] = lcms_deshandle; - if (lcms_devlinkhandle != NULL) { - hProfiles[nProfiles++] = lcms_devlinkhandle; - } - return(cmsCreateMultiprofileTransform(hProfiles, nProfiles, src_data_type, - des_data_type, rendering_params->rendering_intent, - (cmsFLAGS_BLACKPOINTCOMPENSATION | - cmsFLAGS_HIGHRESPRECALC | - cmsFLAGS_NOTCACHE))); -} - -/* Do any initialization if needed to the CMS */ -int -gscms_create(gs_memory_t *memory) -{ - /* Set our own error handling function */ - cmsSetErrorHandler((cmsErrorHandlerFunction) gscms_error); - return 0; -} - -/* Do any clean up when done with the CMS if needed */ -void -gscms_destroy(gs_memory_t *memory) -{ - /* Nothing to do here for lcms */ -} - -/* Have the CMS release the link */ -void -gscms_release_link(gsicc_link_t *icclink) -{ - if (icclink->link_handle !=NULL ) - cmsDeleteTransform(icclink->link_handle); -} - -/* Have the CMS release the profile handle */ -void -gscms_release_profile(void *profile) -{ - cmsHPROFILE profile_handle; - LCMSBOOL notok; - - profile_handle = (cmsHPROFILE) profile; - notok = cmsCloseProfile(profile_handle); -} - -/* Named color, color management */ -/* Get a device value for the named color. Since there exist named color - ICC profiles and littleCMS supports them, we will use - that format in this example. However it should be noted - that this object need not be an ICC named color profile - but can be a proprietary type table. Some CMMs do not - support named color profiles. In that case, or if - the named color is not found, the caller should use an alternate - tint transform or other method. If a proprietary - format (nonICC) is being used, the operators given below must - be implemented. In every case that I can imagine, this should be - straight forward. Note that we allow the passage of a tint - value also. Currently the ICC named color profile does not provide - tint related information, only a value for 100% coverage. - It is provided here for use in proprietary - methods, which may be able to provide the desired effect. We will - at the current time apply a direct tint operation to the returned - device value. - Right now I don't see any reason to have the named color profile - ever return CIELAB. It will either return device values directly or - it will return values defined by the output device profile */ - -int -gscms_transform_named_color(gsicc_link_t *icclink, float tint_value, - const char* ColorName, gx_color_value device_values[] ) -{ - cmsHPROFILE hTransform = icclink->link_handle; - unsigned short *deviceptr = device_values; - int index; - - /* Check if name is present in the profile */ - /* If it is not return -1. Caller will need to use an alternate method */ - if((index = cmsNamedColorIndex(hTransform, ColorName)) < 0) return -1; - /* Get the device value. */ - cmsDoTransform(hTransform,&index,deviceptr,1); - return(0); -} - -/* Create a link to return device values inside the named color profile or link - it with a destination profile and potentially a proofing profile. If the - output_colorspace and the proof_color space are NULL, then we will be - returning the device values that are contained in the named color profile. - i.e. in namedcolor_information. Note that an ICC named color profile - need NOT contain the device values but must contain the CIELAB values. */ -void -gscms_get_name2device_link(gsicc_link_t *icclink, gcmmhprofile_t lcms_srchandle, - gcmmhprofile_t lcms_deshandle, gcmmhprofile_t lcms_proofhandle, - gsicc_rendering_param_t *rendering_params) -{ - cmsHPROFILE hTransform; - _LPcmsTRANSFORM p; - DWORD dwOutputFormat; - DWORD lcms_proof_flag; - int number_colors; - - /* NOTE: We need to add a test here to check that we even HAVE - device values in here and NOT just CIELAB values */ - if ( lcms_proofhandle != NULL ){ - lcms_proof_flag = cmsFLAGS_GAMUTCHECK | cmsFLAGS_SOFTPROOFING; - } else { - lcms_proof_flag = 0; - } - /* Create the transform */ - /* ToDo: Adjust rendering intent */ - hTransform = cmsCreateProofingTransform(lcms_srchandle, TYPE_NAMED_COLOR_INDEX, - lcms_deshandle, TYPE_CMYK_8, - lcms_proofhandle,INTENT_PERCEPTUAL, - INTENT_ABSOLUTE_COLORIMETRIC, - lcms_proof_flag); - /* In littleCMS there is no easy way to find out the size of the device - space returned by the named color profile until after the transform is made. - Hence we adjust our output format after creating the transform. It is - set to CMYK8 initially. */ - p = (_LPcmsTRANSFORM) hTransform; - number_colors = p->NamedColorList->ColorantCount; - /* NOTE: Output size of gx_color_value with no color space type check */ - dwOutputFormat = (CHANNELS_SH(number_colors)|BYTES_SH(sizeof(gx_color_value))); - /* Change the formaters */ - cmsChangeBuffersFormat(hTransform,TYPE_NAMED_COLOR_INDEX,dwOutputFormat); - icclink->link_handle = hTransform; - cmsCloseProfile(lcms_srchandle); - if(lcms_deshandle) cmsCloseProfile(lcms_deshandle); - if(lcms_proofhandle) cmsCloseProfile(lcms_proofhandle); - return; -} - -/* Interface of littlecms memory alloc calls hooked into gs allocator. - For this to be used lcms is built with LCMS_USER_ALLOC. See lcms.mak */ -#if DEBUG_LCMS_MEM -void* _cmsMalloc(unsigned int size) -{ - void *ptr; - - ptr = gs_alloc_bytes(gs_lib_ctx_get_non_gc_memory_t(), size, "lcms"); - gs_warn2("lcms malloc (%d) at 0x%x",size,ptr); - return ptr; -} - -void* _cmsCalloc(unsigned int nelts, unsigned int size) -{ - void *ptr; - - ptr = gs_alloc_byte_array(gs_lib_ctx_get_non_gc_memory_t(), nelts, size, "lcms"); - gs_warn2("lcms calloc (%d) at 0x%x",nelts*size,ptr); - return ptr; -} - -void _cmsFree(void *ptr) -{ - if (ptr != NULL) { - gs_warn1("lcms free at 0x%x",ptr); - gs_free_object(gs_lib_ctx_get_non_gc_memory_t(), ptr, "lcms"); - } -} - -#else - -void* _cmsMalloc(unsigned int size) -{ - return gs_alloc_bytes(gs_lib_ctx_get_non_gc_memory_t(), size, "lcms"); -} - -void* _cmsCalloc(unsigned int nelts, unsigned int size) -{ - return gs_alloc_byte_array(gs_lib_ctx_get_non_gc_memory_t(), nelts, size, "lcms"); -} - -void _cmsFree(void *ptr) -{ - if (ptr != NULL) - gs_free_object(gs_lib_ctx_get_non_gc_memory_t(), ptr, "lcms"); -} -#endif diff -Nru ghostscript-9.10~dfsg/base/gsicc_manage.c ghostscript-9.25~dfsg+1/base/gsicc_manage.c --- ghostscript-9.10~dfsg/base/gsicc_manage.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_manage.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* GS ICC Manager. Initial stubbing of functions. */ @@ -24,7 +24,7 @@ #include "strmio.h" #include "gx.h" #include "gp.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxcspace.h" #include "gscms.h" #include "gsicc_manage.h" @@ -39,8 +39,10 @@ #include "gsicc_create.h" #include "gpmisc.h" #include "gxdevice.h" +#include "gxdevsop.h" #define ICC_HEADER_SIZE 128 +#define CREATE_V2_DATA 0 #if ICC_DUMP unsigned int global_icc_index = 0; @@ -52,11 +54,14 @@ /* Static prototypes */ static void gsicc_set_default_cs_value(cmm_profile_t *picc_profile, - gs_imager_state *pis); + gs_gstate *pgs); static gsicc_namelist_t* gsicc_new_namelist(gs_memory_t *memory); static gsicc_colorname_t* gsicc_new_colorname(gs_memory_t *memory); static gsicc_namelist_t* gsicc_get_spotnames(gcmmhprofile_t profile, gs_memory_t *memory); +static void gsicc_manager_free_contents(gsicc_manager_t *icc_man, + client_name_t cname); + static void rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in, client_name_t cname); static void rc_free_icc_profile(gs_memory_t * mem, void *ptr_in, @@ -74,28 +79,29 @@ static cmm_srcgtag_profile_t* gsicc_new_srcgtag_profile(gs_memory_t *memory); static void gsicc_free_spotnames(gsicc_namelist_t *spotnames, gs_memory_t * mem); +static void +gsicc_manager_finalize(const gs_memory_t *memory, void * vptr); + +static void +gsicc_smask_finalize(const gs_memory_t *memory, void * vptr); + /* profile data structure */ /* profile_handle should NOT be garbage collected since it is allocated by the external CMS */ gs_private_st_ptrs2(st_gsicc_colorname, gsicc_colorname_t, "gsicc_colorname", gsicc_colorname_enum_ptrs, gsicc_colorname_reloc_ptrs, name, next); -gs_private_st_ptrs1(st_gsicc_manager, gsicc_manager_t, "gsicc_manager", +gs_private_st_ptrs2_final(st_gsicc_manager, gsicc_manager_t, "gsicc_manager", gsicc_manager_enum_ptrs, gsicc_manager_profile_reloc_ptrs, - smask_profiles); + gsicc_manager_finalize, smask_profiles, device_n); + +gs_private_st_simple_final(st_gsicc_smask, gsicc_smask_t, "gsicc_smask", gsicc_smask_finalize); gs_private_st_ptrs2(st_gsicc_devicen, gsicc_devicen_t, "gsicc_devicen", gsicc_devicen_enum_ptrs, gsicc_devicen_reloc_ptrs, head, final); -gs_private_st_ptrs2(st_gsicc_devicen_entry, gsicc_devicen_entry_t, +gs_private_st_ptrs1(st_gsicc_devicen_entry, gsicc_devicen_entry_t, "gsicc_devicen_entry", gsicc_devicen_entry_enum_ptrs, - gsicc_devicen_entry_reloc_ptrs, iccprofile, next); - -static const gs_color_space_type gs_color_space_type_icc = { - gs_color_space_index_ICC, /* index */ - true, /* can_be_base_space */ - true, /* can_be_alt_space */ - NULL /* This is going to be outside the norm. struct union*/ -}; + gsicc_devicen_entry_reloc_ptrs, next); typedef struct default_profile_def_s { const char *path; @@ -110,14 +116,46 @@ {LAB_ICC, LAB_TYPE} }; +void +gsicc_setcoloraccuracy(gs_memory_t *mem, uint level) +{ + gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem); + + ctx->icc_color_accuracy = level; +} + +uint +gsicc_currentcoloraccuracy(gs_memory_t *mem) +{ + gs_lib_ctx_t *ctx = gs_lib_ctx_get_interp_instance(mem); + + return ctx->icc_color_accuracy; +} + /* Get the size of the ICC profile that is in the buffer */ -unsigned int gsicc_getprofilesize(unsigned char *buffer) +unsigned int +gsicc_getprofilesize(unsigned char *buffer) { return ( (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3] ); } -void gscms_set_icc_range(cmm_profile_t **icc_profile) +/* Get major and minor ICC version number */ +int +gsicc_getprofilevers(cmm_profile_t *icc_profile, unsigned char *major, + unsigned char *minor) +{ + if (icc_profile == NULL || icc_profile->buffer == NULL) + return -1; + + *major = icc_profile->buffer[8]; + *minor = icc_profile->buffer[9]; + + return 0; +} + +void +gsicc_set_icc_range(cmm_profile_t **icc_profile) { int num_comp = (*icc_profile)->num_comps; int k; @@ -160,21 +198,34 @@ icc_profile->buffer_size); icc_profile->hash_is_valid = true; icc_profile->num_comps = - gscms_get_input_channel_count(icc_profile->profile_handle); + gscms_get_input_channel_count(icc_profile->profile_handle, icc_profile->memory); icc_profile->num_comps_out = - gscms_get_output_channel_count(icc_profile->profile_handle); + gscms_get_output_channel_count(icc_profile->profile_handle, icc_profile->memory); icc_profile->data_cs = - gscms_get_profile_data_space(icc_profile->profile_handle); - gscms_set_icc_range(&icc_profile); + gscms_get_profile_data_space(icc_profile->profile_handle, icc_profile->memory); + gsicc_set_icc_range(&icc_profile); return icc_profile; } +static void +gsicc_smask_finalize(const gs_memory_t *memory, void * vptr) +{ + gsicc_smask_t *iccsmask = (gsicc_smask_t *)vptr; + + gsicc_adjust_profile_rc(iccsmask->smask_gray, -1, + "gsicc_smask_finalize"); + gsicc_adjust_profile_rc(iccsmask->smask_rgb, -1, + "gsicc_smask_finalize"); + gsicc_adjust_profile_rc(iccsmask->smask_cmyk, -1, + "gsicc_smask_finalize"); +} + gsicc_smask_t* gsicc_new_iccsmask(gs_memory_t *memory) { gsicc_smask_t *result; - result = (gsicc_smask_t *) gs_alloc_bytes(memory, sizeof(gsicc_smask_t), "gsicc_new_iccsmask"); + result = (gsicc_smask_t *) gs_alloc_struct(memory, gsicc_smask_t, &st_gsicc_smask, "gsicc_new_iccsmask"); if (result != NULL) { result->smask_gray = NULL; result->smask_rgb = NULL; @@ -182,7 +233,7 @@ result->memory = memory; result->swapped = false; } - return(result); + return result; } /* Allocate a new structure to hold the profiles that contains the profiles @@ -196,7 +247,7 @@ the smask_profiles object */ icc_manager->smask_profiles = gsicc_new_iccsmask(stable_mem); if (icc_manager->smask_profiles == NULL) - return gs_throw(-1, "insufficient memory to allocate smask profiles"); + return gs_throw(gs_error_VMerror, "insufficient memory to allocate smask profiles"); /* Load the gray, rgb, and cmyk profiles */ if ((icc_manager->smask_profiles->smask_gray = gsicc_set_iccsmaskprofile(SMASK_GRAY_ICC, strlen(SMASK_GRAY_ICC), @@ -219,7 +270,7 @@ icc_manager->smask_profiles->smask_gray->default_match = DEFAULT_GRAY; icc_manager->smask_profiles->smask_rgb->default_match = DEFAULT_RGB; icc_manager->smask_profiles->smask_cmyk->default_match = DEFAULT_CMYK; - return(0); + return 0; } static int @@ -230,7 +281,7 @@ gs_alloc_struct(icc_manager->memory, gsicc_devicen_entry_t, &st_gsicc_devicen_entry, "gsicc_new_devicen"); if (device_n_entry == NULL) - return gs_throw(-1, "insufficient memory to allocate device n profile"); + return gs_throw(gs_error_VMerror, "insufficient memory to allocate device n profile"); device_n_entry->next = NULL; device_n_entry->iccprofile = NULL; /* Check if we already have one in the manager */ @@ -240,18 +291,18 @@ gsicc_devicen_t, &st_gsicc_devicen, "gsicc_new_devicen"); if (icc_manager->device_n == NULL) - return gs_throw(-1, "insufficient memory to allocate device n profile"); + return gs_throw(gs_error_VMerror, "insufficient memory to allocate device n profile"); icc_manager->device_n->head = device_n_entry; icc_manager->device_n->final = device_n_entry; icc_manager->device_n->count = 1; - return(0); + return 0; } else { /* We have one or more in the list. */ icc_manager->device_n->final->next = device_n_entry; icc_manager->device_n->final = device_n_entry; icc_manager->device_n->count++; - return(0); + return 0; } } @@ -319,7 +370,7 @@ match_count = 0; } } - return(NULL); + return NULL; } /* Populate the color names entries that should @@ -334,7 +385,7 @@ int num_colors; char *clr_name; - num_colors = gscms_get_numberclrtnames(profile); + num_colors = gscms_get_numberclrtnames(profile, memory); if (num_colors == 0) return(NULL); /* Allocate structure for managing this */ @@ -365,7 +416,7 @@ gsicc_free_spotnames(list, memory); return NULL; } - return(list); + return list; } static void @@ -419,7 +470,7 @@ result->length = 0; result->name = NULL; result->next = NULL; - return(result); + return result; } /* If the profile is one of the default types that were set in the iccmanager, @@ -429,71 +480,123 @@ gs_color_space_index gsicc_get_default_type(cmm_profile_t *profile_data) { - switch ( profile_data->default_match ) { + switch (profile_data->default_match) { case DEFAULT_GRAY: - return(gs_color_space_index_DeviceGray); + return gs_color_space_index_DeviceGray; case DEFAULT_RGB: - return(gs_color_space_index_DeviceRGB); + return gs_color_space_index_DeviceRGB; case DEFAULT_CMYK: - return(gs_color_space_index_DeviceCMYK); + return gs_color_space_index_DeviceCMYK; + case CIE_A: + return gs_color_space_index_CIEA; + case CIE_ABC: + return gs_color_space_index_CIEABC; + case CIE_DEF: + return gs_color_space_index_CIEDEF; + case CIE_DEFG: + return gs_color_space_index_CIEDEFG; + default: + return gs_color_space_index_ICC; + } +} + +bool +gsicc_profile_from_ps(cmm_profile_t *profile_data) +{ + switch ( profile_data->default_match ) { case CIE_A: - return(gs_color_space_index_CIEA); case CIE_ABC: - return(gs_color_space_index_CIEABC); case CIE_DEF: - return(gs_color_space_index_CIEDEF); case CIE_DEFG: - return(gs_color_space_index_CIEDEFG); + return true; default: - return(gs_color_space_index_ICC); + return false; + } +} + +/* + * Adjust the reference count of the profile. This is intended to support + * applications (such as XPS) which maintain ICC profiles outside of the + * graphic state. + */ +/* for multi-threaded use, we need to adjust the ref_count safely */ +void +gsicc_adjust_profile_rc(cmm_profile_t *profile_data, int delta, const char *name_str) +{ + if (profile_data != NULL) { +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_enter(profile_data->lock); +#endif + if (profile_data->rc.ref_count == 1 && delta < 0) { + profile_data->rc.ref_count = 0; /* while locked */ +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_leave(profile_data->lock); +#endif + rc_free_struct(profile_data, name_str); + } else { + rc_adjust(profile_data, delta, name_str); +#ifndef MEMENTO_SQUEEZE_BUILD + gx_monitor_leave(profile_data->lock); +#endif + } } } /* Fill in the actual source structure rending information */ -static void -gsicc_fill_srcgtag_item(gsicc_rendering_param_t *r_params, bool cmyk) +static int +gsicc_fill_srcgtag_item(gsicc_rendering_param_t *r_params, char **pstrlast, bool cmyk) { char *curr_ptr; int blackptcomp; int or_icc, preserve_k; - int ri, count; + int ri; /* Get the intent */ - curr_ptr = strtok(NULL, "\t,\32\n\r"); - count = sscanf(curr_ptr, "%d", &ri); + curr_ptr = gs_strtok(NULL, "\t,\32\n\r", pstrlast); + if (sscanf(curr_ptr, "%d", &ri) != 1) + return_error(gs_error_unknownerror); r_params->rendering_intent = ri | gsRI_OVERRIDE; /* Get the black point compensation setting */ - curr_ptr = strtok(NULL, "\t,\32\n\r"); - count = sscanf(curr_ptr, "%d", &blackptcomp); + curr_ptr = gs_strtok(NULL, "\t,\32\n\r", pstrlast); + if (sscanf(curr_ptr, "%d", &blackptcomp) != 1) + return_error(gs_error_unknownerror); r_params->black_point_comp = blackptcomp | gsBP_OVERRIDE; /* Get the over-ride embedded ICC boolean */ - curr_ptr = strtok(NULL, "\t,\32\n\r"); - count = sscanf(curr_ptr, "%d", &or_icc); + curr_ptr = gs_strtok(NULL, "\t,\32\n\r", pstrlast); + if (sscanf(curr_ptr, "%d", &or_icc) != 1) + return_error(gs_error_unknownerror); r_params->override_icc = or_icc; if (cmyk) { /* Get the preserve K control */ - curr_ptr = strtok(NULL, "\t,\32\n\r"); - count = sscanf(curr_ptr, "%d", &preserve_k); + curr_ptr = gs_strtok(NULL, "\t,\32\n\r", pstrlast); + if (sscanf(curr_ptr, "%d", &preserve_k) < 1) + return_error(gs_error_unknownerror); r_params->preserve_black = preserve_k | gsKP_OVERRIDE; } else { r_params->preserve_black = gsBKPRESNOTSPECIFIED; } + return 0; } static int -gsicc_check_device_link(cmm_profile_t *icc_profile) -{ +gsicc_check_device_link(cmm_profile_t *icc_profile, gs_memory_t *memory) +{ bool value; - value = gscms_is_device_link(icc_profile->profile_handle); + value = gscms_is_device_link(icc_profile->profile_handle, memory); icc_profile->isdevlink = value; - + return value; } +int +gsicc_get_device_class(cmm_profile_t *icc_profile) +{ + return gscms_get_device_class(icc_profile->profile_handle, icc_profile->memory); +} /* This inititializes the srcgtag structure in the ICC manager */ -int +static int gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname, int namelen) { @@ -501,9 +604,8 @@ stream *str; int code; int info_size; - char *buffer_ptr, *curr_ptr; + char *buffer_ptr, *curr_ptr, *last; int num_bytes; - char str_format_key[6], str_format_file[6]; int k; static const char *const srcgtag_keys[] = {GSICC_SRCGTAG_KEYS}; cmm_profile_t *icc_profile; @@ -526,21 +628,27 @@ if (str != NULL) { /* Get the information in the file */ code = sfseek(str,0,SEEK_END); + if (code < 0) + return code; info_size = sftell(str); code = srewind(str); + if (code < 0) + return code; if (info_size > (GSICC_NUM_SRCGTAG_KEYS + 1) * FILENAME_MAX) { return gs_throw1(-1, "setting of %s src obj color info failed", pname); } /* Allocate the buffer, stuff with the data */ - buffer_ptr = (char*) gs_alloc_bytes(mem, info_size+1, + buffer_ptr = (char*) gs_alloc_bytes(mem, info_size+1, "gsicc_set_srcgtag_struct"); if (buffer_ptr == NULL) { - return gs_throw1(-1, "setting of %s src obj color info failed", + return gs_throw1(gs_error_VMerror, "setting of %s src obj color info failed", pname); } num_bytes = sfread(buffer_ptr,sizeof(unsigned char), info_size, str); code = sfclose(str); + if (code < 0) + return code; buffer_ptr[info_size] = 0; if (num_bytes != info_size) { gs_free_object(mem, buffer_ptr, "gsicc_set_srcgtag_struct"); @@ -550,9 +658,6 @@ /* Create the structure in which we will store this data */ srcgtag = gsicc_new_srcgtag_profile(mem); /* Now parse through the data opening the profiles that are needed */ - /* First create the format that we should read for the key */ - gs_sprintf(str_format_key, "%%%ds", GSICC_SRCGTAG_MAX_KEY); - gs_sprintf(str_format_file, "%%%ds", FILENAME_MAX); curr_ptr = buffer_ptr; /* Initialize that we want color management. Then if profile is not present we know we did not want anything special done with that @@ -561,36 +666,37 @@ for (k = 0; k < NUM_SOURCE_PROFILES; k++) { srcgtag->rgb_rend_cond[k].cmm = gsCMM_DEFAULT; srcgtag->cmyk_rend_cond[k].cmm = gsCMM_DEFAULT; + srcgtag->gray_rend_cond[k].cmm = gsCMM_DEFAULT; } while (start || strlen(curr_ptr) > 0) { if (start) { - curr_ptr = strtok(buffer_ptr, "\t,\32\n\r"); + curr_ptr = gs_strtok(buffer_ptr, "\t,\32\n\r", &last); start = false; } else { - curr_ptr = strtok(NULL, "\t,\32\n\r"); + curr_ptr = gs_strtok(NULL, "\t,\32\n\r", &last); } if (curr_ptr == NULL) break; /* Now go ahead and see if we have a match */ for (k = 0; k < GSICC_NUM_SRCGTAG_KEYS; k++) { if (strncmp(curr_ptr, srcgtag_keys[k], strlen(srcgtag_keys[k])) == 0 ) { /* Check if the curr_ptr is None which indicates that this - object is not to be color managed. Also, if the + object is not to be color managed. Also, if the curr_ptr is Replace which indicates we will be doing direct replacement of the colors. */ - curr_ptr = strtok(NULL, "\t,\32\n\r"); + curr_ptr = gs_strtok(NULL, "\t,\32\n\r", &last); if (strncmp(curr_ptr, GSICC_SRCTAG_NOCM, strlen(GSICC_SRCTAG_NOCM)) == 0 && strlen(curr_ptr) == strlen(GSICC_SRCTAG_NOCM)) { cmm = gsCMM_NONE; icc_profile = NULL; break; } else if ((strncmp(curr_ptr, GSICC_SRCTAG_REPLACE, strlen(GSICC_SRCTAG_REPLACE)) == 0 && - strlen(curr_ptr) == strlen(GSICC_SRCTAG_REPLACE))) { + strlen(curr_ptr) == strlen(GSICC_SRCTAG_REPLACE))) { cmm = gsCMM_REPLACE; icc_profile = NULL; break; } else { /* Try to open the file and set the profile */ - code = gsicc_open_search(curr_ptr, strlen(curr_ptr), mem, + code = gsicc_open_search(curr_ptr, strlen(curr_ptr), mem, mem->gs_lib_ctx->profiledir, mem->gs_lib_ctx->profiledir_len, &str); if (code < 0) @@ -599,12 +705,18 @@ icc_profile = gsicc_profile_new(str, mem, curr_ptr, strlen(curr_ptr)); code = sfclose(str); - gsicc_init_profile_info(icc_profile); + if (code < 0) + return code; + } + if (str != NULL && icc_profile != NULL) { + code = gsicc_init_profile_info(icc_profile); + if (code < 0) + return code; cmm = gsCMM_DEFAULT; - /* Check if this object is a devicelink profile. + /* Check if this object is a devicelink profile. If it is then the intent, blackpoint etc. are not read nor used when dealing with these profiles */ - gsicc_check_device_link(icc_profile); + gsicc_check_device_link(icc_profile, icc_profile->memory); break; } else { /* Failed to open profile file. End this now. */ @@ -627,42 +739,81 @@ srcgtag->cmyk_profiles[gsSRC_GRAPPRO] = icc_profile; srcgtag->cmyk_rend_cond[gsSRC_GRAPPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { - gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_GRAPPRO]), true); + code = gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_GRAPPRO]), &last, true); + if (code < 0) + return code; } break; case IMAGE_CMYK: srcgtag->cmyk_profiles[gsSRC_IMAGPRO] = icc_profile; srcgtag->cmyk_rend_cond[gsSRC_IMAGPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { - gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_IMAGPRO]), true); + code = gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_IMAGPRO]), &last, true); + if (code < 0) + return code; } break; case TEXT_CMYK: srcgtag->cmyk_profiles[gsSRC_TEXTPRO] = icc_profile; srcgtag->cmyk_rend_cond[gsSRC_TEXTPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { - gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_TEXTPRO]), true); + code = gsicc_fill_srcgtag_item(&(srcgtag->cmyk_rend_cond[gsSRC_TEXTPRO]), &last, true); + if (code < 0) + return code; } break; case GRAPHIC_RGB: srcgtag->rgb_profiles[gsSRC_GRAPPRO] = icc_profile; srcgtag->rgb_rend_cond[gsSRC_GRAPPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { - gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_GRAPPRO]), false); + code = gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_GRAPPRO]), &last, false); + if (code < 0) + return code; } break; case IMAGE_RGB: srcgtag->rgb_profiles[gsSRC_IMAGPRO] = icc_profile; srcgtag->rgb_rend_cond[gsSRC_IMAGPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { - gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_IMAGPRO]), false); + code = gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_IMAGPRO]), &last, false); + if (code < 0) + return code; } break; case TEXT_RGB: srcgtag->rgb_profiles[gsSRC_TEXTPRO] = icc_profile; srcgtag->rgb_rend_cond[gsSRC_TEXTPRO].cmm = cmm; if (cmm == gsCMM_DEFAULT) { - gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_TEXTPRO]), false); + code = gsicc_fill_srcgtag_item(&(srcgtag->rgb_rend_cond[gsSRC_TEXTPRO]), &last, false); + if (code < 0) + return code; + } + break; + case GRAPHIC_GRAY: + srcgtag->gray_profiles[gsSRC_GRAPPRO] = icc_profile; + srcgtag->gray_rend_cond[gsSRC_GRAPPRO].cmm = cmm; + if (cmm == gsCMM_DEFAULT) { + code = gsicc_fill_srcgtag_item(&(srcgtag->gray_rend_cond[gsSRC_GRAPPRO]), &last, false); + if (code < 0) + return code; + } + break; + case IMAGE_GRAY: + srcgtag->gray_profiles[gsSRC_IMAGPRO] = icc_profile; + srcgtag->gray_rend_cond[gsSRC_IMAGPRO].cmm = cmm; + if (cmm == gsCMM_DEFAULT) { + code = gsicc_fill_srcgtag_item(&(srcgtag->gray_rend_cond[gsSRC_IMAGPRO]), &last, false); + if (code < 0) + return code; + } + break; + case TEXT_GRAY: + srcgtag->gray_profiles[gsSRC_TEXTPRO] = icc_profile; + srcgtag->gray_rend_cond[gsSRC_TEXTPRO].cmm = cmm; + if (cmm == gsCMM_DEFAULT) { + code = gsicc_fill_srcgtag_item(&(srcgtag->gray_rend_cond[gsSRC_TEXTPRO]), &last, false); + if (code < 0) + return code; } break; case GSICC_NUM_SRCGTAG_KEYS: @@ -686,6 +837,8 @@ srcgtag->name_length = strlen(pname); srcgtag->name = (char*) gs_alloc_bytes(mem, srcgtag->name_length, "gsicc_set_srcgtag_struct"); + if (srcgtag->name == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for tag name"); strncpy(srcgtag->name, pname, srcgtag->name_length); icc_manager->srcgtag_profile = srcgtag; return 0; @@ -742,14 +895,8 @@ default_space = gsCIELAB; break; case DEVICEN_TYPE: - code = gsicc_new_devicen(icc_manager); - default_space = gsNCHANNEL; - if (code == 0) { - manager_default_profile = - &(icc_manager->device_n->final->iccprofile); - } else { - return code; - } + manager_default_profile = NULL; + default_space = gsNCHANNEL; break; case DEFAULT_NONE: default: @@ -758,13 +905,13 @@ } } /* If it is not NULL then it has already been set. If it is different than - what we already have then we will want to free it. Since other imager - states could have different default profiles, this is done via reference + what we already have then we will want to free it. Since other + gs_gstates could have different default profiles, this is done via reference counting. If it is the same as what we already have then we DONT - increment, since that is done when the imager state is duplicated. It + increment, since that is done when the gs_gstate is duplicated. It could be the same, due to a resetting of the user params. To avoid recreating the profile data, we compare the string names. */ - if ((*manager_default_profile) != NULL) { + if (defaulttype != DEVICEN_TYPE && (*manager_default_profile) != NULL) { /* Check if this is what we already have. Also check if it is the output intent profile. */ icc_profile = *manager_default_profile; @@ -772,25 +919,54 @@ if( memcmp(pname, icc_profile->name, namelen) == 0) return 0; } - if (strncmp(icc_profile->name, OI_PROFILE, + if (strncmp(icc_profile->name, OI_PROFILE, strlen(icc_profile->name)) == 0) { return 0; } - rc_decrement(icc_profile,"gsicc_set_profile"); + gsicc_adjust_profile_rc(icc_profile, -1,"gsicc_set_profile"); + /* Icky - if the creation of the new profile fails, we end up with a dangling + pointer, or a wrong reference count - so NULL the appropriate entry here + */ + switch(defaulttype) { + case DEFAULT_GRAY: + icc_manager->default_gray = NULL; + break; + case DEFAULT_RGB: + icc_manager->default_rgb = NULL; + break; + case DEFAULT_CMYK: + icc_manager->default_cmyk = NULL; + break; + case NAMED_TYPE: + icc_manager->device_named = NULL; + break; + case LAB_TYPE: + icc_manager->lab_profile = NULL; + break; + default: + break; + } } /* We need to do a special check for DeviceN since we have a linked list of profiles and we can have multiple specifications */ - if ( defaulttype == DEVICEN_TYPE ) { - gsicc_devicen_entry_t *current_entry = icc_manager->device_n->head; - for ( k = 0; k < icc_manager->device_n->count; k++ ) { - if ( current_entry->iccprofile != NULL ) { - icc_profile = current_entry->iccprofile; - if ( namelen == icc_profile->name_length ) - if( memcmp(pname, icc_profile->name, namelen) == 0) + if (defaulttype == DEVICEN_TYPE) { + if (icc_manager->device_n != NULL) { + gsicc_devicen_entry_t *current_entry = icc_manager->device_n->head; + for (k = 0; k < icc_manager->device_n->count; k++) { + if (current_entry->iccprofile != NULL) { + icc_profile = current_entry->iccprofile; + if (namelen == icc_profile->name_length) + if (memcmp(pname, icc_profile->name, namelen) == 0) return 0; + } + current_entry = current_entry->next; } - current_entry = current_entry->next; } + /* An entry was not found. We need to create a new one to use */ + code = gsicc_new_devicen(icc_manager); + if (code < 0) + return code; + manager_default_profile = &(icc_manager->device_n->final->iccprofile); } code = gsicc_open_search(pname, namelen, mem_gc, mem_gc->gs_lib_ctx->profiledir, mem_gc->gs_lib_ctx->profiledir_len, &str); @@ -809,12 +985,16 @@ char *nameptr; icc_profile = gsicc_profile_new(NULL, mem_gc, NULL, 0); + if (icc_profile == NULL) + return gs_throw(gs_error_VMerror, "Creation of ICC profile failed"); icc_profile->data_cs = gsNAMED; code = gsicc_load_namedcolor_buffer(icc_profile, str, mem_gc); if (code < 0) return gs_throw1(-1, "problems with profile %s", pname); *manager_default_profile = icc_profile; nameptr = (char*) gs_alloc_bytes(icc_profile->memory, namelen+1, "gsicc_set_profile"); + if (nameptr == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for profile name"); memcpy(nameptr, pname, namelen); nameptr[namelen] = '\0'; icc_profile->name = nameptr; @@ -836,13 +1016,18 @@ The names are in the order such that the fastest index in the table is the first name */ gsicc_get_devicen_names(icc_profile, icc_manager->memory); + /* Init this profile now */ + code = gsicc_init_profile_info(icc_profile); + if (code < 0) return gs_throw1(-1, "problems with profile %s", pname); + } else { + /* Delay the loading of the handle buffer until we need the profile. + But set some basic stuff that we need. Take care of DeviceN + profile now, since we don't know the number of components etc */ + icc_profile->num_comps = num_comps; + icc_profile->num_comps_out = 3; + gsicc_set_icc_range(&icc_profile); + icc_profile->data_cs = default_space; } - /* Delay the loading of the handle buffer until we need the profile. - But set some basic stuff that we need */ - icc_profile->num_comps = num_comps; - icc_profile->num_comps_out = 3; - gscms_set_icc_range(&icc_profile); - icc_profile->data_cs = default_space; return 0; } return -1; @@ -854,21 +1039,21 @@ the *only* profiles that are delayed in this manner. All embedded profiles and internally generated profiles have their handles found immediately */ int -gsicc_initialize_default_profile(cmm_profile_t *icc_profile) +gsicc_initialize_default_profile(cmm_profile_t *icc_profile) { gsicc_profile_t defaulttype = icc_profile->default_match; gsicc_colorbuffer_t default_space = gsUNDEFINED; int num_comps, num_comps_out; - const gs_memory_t *mem = icc_profile->memory; + gs_memory_t *mem = icc_profile->memory; /* Get the profile handle if it is not already set */ - if (icc_profile->profile_handle != NULL) { - icc_profile->profile_handle = + if (icc_profile->profile_handle == NULL) { + icc_profile->profile_handle = gsicc_get_profile_handle_buffer(icc_profile->buffer, icc_profile->buffer_size, mem); if (icc_profile->profile_handle == NULL) { - return gs_rethrow1(-1, "allocation of profile %s handle failed", + return gs_rethrow1(gs_error_VMerror, "allocation of profile %s handle failed", icc_profile->name); } } @@ -880,16 +1065,19 @@ } num_comps = icc_profile->num_comps; icc_profile->num_comps = - gscms_get_input_channel_count(icc_profile->profile_handle); + gscms_get_input_channel_count(icc_profile->profile_handle, + icc_profile->memory); num_comps_out = icc_profile->num_comps_out; icc_profile->num_comps_out = - gscms_get_output_channel_count(icc_profile->profile_handle); + gscms_get_output_channel_count(icc_profile->profile_handle, + icc_profile->memory); icc_profile->data_cs = - gscms_get_profile_data_space(icc_profile->profile_handle); - if_debug0m(gs_debug_flag_icc,mem,"[icc] Setting ICC profile in Manager\n"); + gscms_get_profile_data_space(icc_profile->profile_handle, + icc_profile->memory); + if_debug0m(gs_debug_flag_icc,mem,"[icc] Setting ICC profile in Manager\n"); switch(defaulttype) { case DEFAULT_GRAY: - if_debug0m(gs_debug_flag_icc,mem,"[icc] Default Gray\n"); + if_debug0m(gs_debug_flag_icc,mem,"[icc] Default Gray\n"); default_space = gsGRAY; break; case DEFAULT_RGB: @@ -901,21 +1089,21 @@ default_space = gsCMYK; break; case NAMED_TYPE: - if_debug0m(gs_debug_flag_icc,mem,"[icc] Named Color\n"); + if_debug0m(gs_debug_flag_icc,mem,"[icc] Named Color\n"); break; case LAB_TYPE: - if_debug0m(gs_debug_flag_icc,mem,"[icc] CIELAB Profile\n"); + if_debug0m(gs_debug_flag_icc,mem,"[icc] CIELAB Profile\n"); break; case DEVICEN_TYPE: - if_debug0m(gs_debug_flag_icc,mem,"[icc] DeviceN Profile\n"); + if_debug0m(gs_debug_flag_icc,mem,"[icc] DeviceN Profile\n"); break; case DEFAULT_NONE: default: - return(0); + return 0; break; } - if_debug1m(gs_debug_flag_icc,mem,"[icc] name = %s\n", icc_profile->name); - if_debug1m(gs_debug_flag_icc,mem,"[icc] num_comps = %d\n", icc_profile->num_comps); + if_debug1m(gs_debug_flag_icc,mem,"[icc] name = %s\n", icc_profile->name); + if_debug1m(gs_debug_flag_icc,mem,"[icc] num_comps = %d\n", icc_profile->num_comps); /* Check that we have the proper color space for the ICC profiles that can be externally set */ if (default_space != gsUNDEFINED || @@ -938,17 +1126,27 @@ /* First see if we can get the stream. NOTE icc directory not used! */ code = gsicc_open_search(pname, namelen, mem, NULL, 0, &str); - if (code < 0 || str == NULL) + if (code < 0 || str == NULL) { + gs_throw(gs_error_VMerror, "Creation of ICC profile failed"); return NULL; + } result = gsicc_profile_new(str, mem, pname, namelen); code = sfclose(str); - gsicc_init_profile_info(result); - return(result); + if (result == NULL) { + gs_throw(gs_error_VMerror, "Creation of ICC profile failed"); + return NULL; + } + code = gsicc_init_profile_info(result); + if (code < 0) { + gs_throw(gs_error_VMerror, "Creation of ICC profile failed"); + return NULL; + } + return result; } /* Given that we already have a profile in a buffer (e.g. generated from a PS object) this gets the handle and initializes the various member variables that we need */ -void +int gsicc_init_profile_info(cmm_profile_t *profile) { int k; @@ -958,21 +1156,27 @@ gsicc_get_profile_handle_buffer(profile->buffer, profile->buffer_size, profile->memory); + if (profile->profile_handle == NULL) + return -1; /* Compute the hash code of the profile. */ gsicc_get_icc_buff_hash(profile->buffer, &(profile->hashcode), profile->buffer_size); profile->hash_is_valid = true; profile->default_match = DEFAULT_NONE; - profile->num_comps = gscms_get_input_channel_count(profile->profile_handle); - profile->num_comps_out = gscms_get_output_channel_count(profile->profile_handle); - profile->data_cs = gscms_get_profile_data_space(profile->profile_handle); + profile->num_comps = gscms_get_input_channel_count(profile->profile_handle, + profile->memory); + profile->num_comps_out = gscms_get_output_channel_count(profile->profile_handle, + profile->memory); + profile->data_cs = gscms_get_profile_data_space(profile->profile_handle, + profile->memory); /* Initialize the range to default values */ for ( k = 0; k < profile->num_comps; k++) { profile->Range.ranges[k].rmin = 0.0; profile->Range.ranges[k].rmax = 1.0; } + return 0; } /* This is used to try to find the specified or default ICC profiles */ @@ -997,22 +1201,31 @@ if (buffer == NULL) return_error(gs_error_VMerror); strcpy(buffer, dirname); + buffer[dirlen] = '\0'; strcat(buffer, pname); /* Just to make sure we were null terminated */ buffer[namelen + dirlen] = '\0'; - str = sfopen(buffer, "rb", mem_gc); - gs_free_object(mem_gc, buffer, "gsicc_open_search"); - if (str != NULL) { - *strp = str; - return 0; + + if (gs_check_file_permission(mem_gc, buffer, strlen(buffer), "r") >= 0) { + str = sfopen(buffer, "r", mem_gc); + gs_free_object(mem_gc, buffer, "gsicc_open_search"); + if (str != NULL) { + *strp = str; + return 0; + } + } + else { + gs_free_object(mem_gc, buffer, "gsicc_open_search"); } } /* First just try it like it is */ - str = sfopen(pname, "rb", mem_gc); - if (str != NULL) { - *strp = str; - return 0; + if (gs_check_file_permission(mem_gc, pname, namelen, "r") >= 0) { + str = sfopen(pname, "r", mem_gc); + if (str != NULL) { + *strp = str; + return 0; + } } /* If that fails, try %rom% */ /* FIXME: Not sure this is needed or correct */ @@ -1025,7 +1238,7 @@ strcat(buffer, pname); /* Just to make sure we were null terminated */ buffer[namelen + strlen(DEFAULT_DIR_ICC)] = '\0'; - str = sfopen(buffer, "rb", mem_gc); + str = sfopen(buffer, "r", mem_gc); gs_free_object(mem_gc, buffer, "gsicc_open_search"); if (str == NULL) { gs_warn1("Could not find %s ",pname); @@ -1045,17 +1258,21 @@ if (srcgtag_profile->rc.ref_count <= 1 ) { /* Decrement any profiles. */ for (k = 0; k < NUM_SOURCE_PROFILES; k++) { + if (srcgtag_profile->gray_profiles[k] != NULL) { + gsicc_adjust_profile_rc(srcgtag_profile->gray_profiles[k], -1, + "rc_free_srcgtag_profile(gray)"); + } if (srcgtag_profile->rgb_profiles[k] != NULL) { - rc_decrement(srcgtag_profile->rgb_profiles[k], - "rc_free_srcgtag_profile"); + gsicc_adjust_profile_rc(srcgtag_profile->rgb_profiles[k], -1, + "rc_free_srcgtag_profile(rgb)"); } if (srcgtag_profile->cmyk_profiles[k] != NULL) { - rc_decrement(srcgtag_profile->cmyk_profiles[k], - "rc_free_srcgtag_profile"); + gsicc_adjust_profile_rc(srcgtag_profile->cmyk_profiles[k], -1, + "rc_free_srcgtag_profile(cmyk)"); } if (srcgtag_profile->color_warp_profile != NULL) { - rc_decrement(srcgtag_profile->color_warp_profile, - "rc_free_srcgtag_profile"); + gsicc_adjust_profile_rc(srcgtag_profile->color_warp_profile, -1, + "rc_free_srcgtag_profile(warp)"); } } gs_free_object(mem_nongc, srcgtag_profile->name, "rc_free_srcgtag_profile"); @@ -1073,11 +1290,19 @@ result = (cmm_srcgtag_profile_t *) gs_alloc_bytes(memory->non_gc_memory, sizeof(cmm_srcgtag_profile_t), "gsicc_new_srcgtag_profile"); + if (result == NULL) + return NULL; result->memory = memory->non_gc_memory; for (k = 0; k < NUM_SOURCE_PROFILES; k++) { result->rgb_profiles[k] = NULL; result->cmyk_profiles[k] = NULL; + result->gray_profiles[k] = NULL; + result->gray_rend_cond[k].black_point_comp = gsBPNOTSPECIFIED; + result->gray_rend_cond[k].rendering_intent = gsRINOTSPECIFIED; + result->gray_rend_cond[k].override_icc = false; + result->gray_rend_cond[k].preserve_black = gsBKPRESNOTSPECIFIED; + result->gray_rend_cond[k].cmm = gsCMM_DEFAULT; result->rgb_rend_cond[k].black_point_comp = gsBPNOTSPECIFIED; result->rgb_rend_cond[k].rendering_intent = gsRINOTSPECIFIED; result->rgb_rend_cond[k].override_icc = false; @@ -1093,11 +1318,11 @@ result->name = NULL; result->name_length = 0; rc_init_free(result, memory->non_gc_memory, 1, rc_free_srcgtag_profile); - return(result); + return result; } static void -gsicc_free_spotnames(gsicc_namelist_t *spotnames, gs_memory_t * mem) +gsicc_free_spotnames(gsicc_namelist_t *spotnames, gs_memory_t * mem) { int k; gsicc_colorname_t *curr_name, *next_name; @@ -1133,26 +1358,34 @@ if (icc_struct->device_profile[k] != NULL) { if_debug1m(gs_debug_flag_icc, mem_nongc, "[icc] Releasing device profile %d\n", k); - rc_decrement(icc_struct->device_profile[k], + gsicc_adjust_profile_rc(icc_struct->device_profile[k], -1, "rc_free_profile_array"); } } if (icc_struct->link_profile != NULL) { if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing link profile\n"); - rc_decrement(icc_struct->link_profile, "rc_free_profile_array"); + gsicc_adjust_profile_rc(icc_struct->link_profile, -1, "rc_free_profile_array"); } if (icc_struct->proof_profile != NULL) { if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing proof profile\n"); - rc_decrement(icc_struct->proof_profile, "rc_free_profile_array"); + gsicc_adjust_profile_rc(icc_struct->proof_profile, -1, "rc_free_profile_array"); } if (icc_struct->oi_profile != NULL) { if_debug0m(gs_debug_flag_icc,mem_nongc,"[icc] Releasing oi profile\n"); - rc_decrement(icc_struct->oi_profile, "rc_free_profile_array"); + gsicc_adjust_profile_rc(icc_struct->oi_profile, -1, "rc_free_profile_array"); + } + if (icc_struct->postren_profile != NULL) { + if_debug0m(gs_debug_flag_icc, mem_nongc, "[icc] Releasing postren profile\n"); + gsicc_adjust_profile_rc(icc_struct->postren_profile, -1, "rc_free_profile_array"); + } + if (icc_struct->blend_profile != NULL) { + if_debug0m(gs_debug_flag_icc, mem_nongc, "[icc] Releasing blend profile\n"); + gsicc_adjust_profile_rc(icc_struct->blend_profile, -1, "rc_free_profile_array"); } if (icc_struct->spotnames != NULL) { if_debug0m(gs_debug_flag_icc, mem_nongc, "[icc] Releasing spotnames\n"); /* Free the linked list in this object */ - gsicc_free_spotnames(icc_struct->spotnames, mem_nongc); + gsicc_free_spotnames(icc_struct->spotnames, mem_nongc); /* Free the main object */ gs_free_object(mem_nongc, icc_struct->spotnames, "rc_free_profile_array"); } @@ -1187,6 +1420,8 @@ } result->proof_profile = NULL; result->link_profile = NULL; + result->postren_profile = NULL; + result->blend_profile = NULL; result->oi_profile = NULL; result->spotnames = NULL; result->devicegraytok = true; /* Default is to map gray to pure K */ @@ -1195,9 +1430,9 @@ result->usefastcolor = false; /* Default is to not use fast color */ result->prebandthreshold = true; result->supports_devn = false; - result->sim_overprint = true; + result->sim_overprint = false; /* Default is now not to simulate overprint */ rc_init_free(result, memory->non_gc_memory, 1, rc_free_profile_array); - return(result); + return result; } int @@ -1206,11 +1441,17 @@ { int code; cmm_dev_profile_t *profile_struct; - - if (dev->procs.get_profile == NULL) { + + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { profile_struct = dev->icc_struct; } else { code = dev_proc(dev, get_profile)(dev, &profile_struct); + if (code < 0) + return code; } if (profile_struct == NULL) return 0; @@ -1224,11 +1465,17 @@ { int code; cmm_dev_profile_t *profile_struct; - - if (dev->procs.get_profile == NULL) { + + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { profile_struct = dev->icc_struct; } else { code = dev_proc(dev, get_profile)(dev, &profile_struct); + if (code < 0) + return code; } if (profile_struct == NULL) return 0; @@ -1240,10 +1487,14 @@ gsicc_set_device_blackptcomp(gx_device *dev, gsicc_blackptcomp_t blackptcomp, gsicc_profile_types_t profile_type) { - int code; + int code = 0; cmm_dev_profile_t *profile_struct; - - if (dev->procs.get_profile == NULL) { + + /* Although device methods should not be NULL, they are not completely filled in until + * gx_device_fill_in_procs is called, and its possible for us to get here before this + * happens, so we *must* make sure the method is not NULL before we use it. + */ + if (dev_proc(dev, get_profile) == NULL) { profile_struct = dev->icc_struct; } else { code = dev_proc(dev, get_profile)(dev, &profile_struct); @@ -1251,43 +1502,44 @@ if (profile_struct == NULL) return 0; profile_struct->rendercond[profile_type].black_point_comp = blackptcomp; - return 0; + return code; } /* This is used to set up the equivalent cmyk colors for the spots that may exist in an output DeviceN profile. We do this by faking a new separation space for each one */ -void -gsicc_set_devicen_equiv_colors(gx_device *dev, const gs_imager_state * pis, +int +gsicc_set_devicen_equiv_colors(gx_device *dev, const gs_gstate * pgs, cmm_profile_t *profile) { - int code; - gs_state temp_state = *((gs_state*)pis); - gs_color_space *pcspace = gs_cspace_alloc(pis->memory->non_gc_memory, + gs_gstate temp_state = *((gs_gstate*)pgs); + gs_color_space *pcspace = gs_cspace_alloc(pgs->memory->non_gc_memory, &gs_color_space_type_ICC); + if (pcspace == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for devn equiv colors"); pcspace->cmm_icc_profile_data = profile; temp_state.color[0].color_space = pcspace; - code = dev_proc(dev, update_spot_equivalent_colors)(dev, &temp_state); + return dev_proc(dev, update_spot_equivalent_colors)(dev, &temp_state); } #define DEFAULT_ICC_PROCESS "Cyan, Magenta, Yellow, Black," #define DEFAULT_ICC_PROCESS_LENGTH 30 #define DEFAULT_ICC_COLORANT_NAME "ICC_COLOR_" -#define DEFAULT_ICC_COLORANT_LENGTH 12 +#define DEFAULT_ICC_COLORANT_LENGTH 12 /* allow at most 16 colorants */ -/* This sets the colorants structure up in the device profile for when +/* This sets the colorants structure up in the device profile for when we are dealing with DeviceN type output profiles. Note that this feature is only used with the tiffsep and psdcmyk devices. If name_str is null it will use default names for the colorants */ int gsicc_set_device_profile_colorants(gx_device *dev, char *name_str) -{ +{ int code; cmm_dev_profile_t *profile_struct; gsicc_colorname_t *name_entry; gsicc_colorname_t **curr_entry; gs_memory_t *mem; - char *temp_ptr; + char *temp_ptr, *last = NULL; int done; gsicc_namelist_t *spot_names; char *pch; @@ -1306,12 +1558,18 @@ int num_comps = profile_struct->device_profile[0]->num_comps; char temp_str[DEFAULT_ICC_COLORANT_LENGTH+2]; + /* If names are already set then we do not want to set default ones */ + if (profile_struct->spotnames != NULL) + return 0; + free_str = true; /* Assume first 4 are CMYK */ total_len = ((DEFAULT_ICC_COLORANT_LENGTH + 1) * (num_comps-4)) + DEFAULT_ICC_PROCESS_LENGTH - 1; /* -1 due to no comma at end */ - name_str = (char*) gs_alloc_bytes(dev->memory, total_len+1, + name_str = (char*) gs_alloc_bytes(dev->memory, total_len+1, "gsicc_set_device_profile_colorants"); + if (name_str == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for colorant name"); gs_sprintf(name_str, DEFAULT_ICC_PROCESS); for (kk = 0; kk < num_comps-5; kk++) { gs_sprintf(temp_str,"ICC_COLOR_%d,",kk); @@ -1320,14 +1578,15 @@ /* Last one no comma */ gs_sprintf(temp_str,"ICC_COLOR_%d",kk); strcat(name_str,temp_str); - } + } str_len = strlen(name_str); if (profile_struct->spotnames != NULL && profile_struct->spotnames->name_str != NULL && strlen(profile_struct->spotnames->name_str) == str_len) { + /* Here we check if the names are the same */ if (strncmp(name_str, profile_struct->spotnames->name_str, str_len) == 0) { - if (free_str) - gs_free_object(dev->memory, name_str, + if (free_str) + gs_free_object(dev->memory, name_str, "gsicc_set_device_profile_colorants"); return 0; } @@ -1336,21 +1595,23 @@ /* We need to free the existing one if there was one */ if (profile_struct->spotnames != NULL) { /* Free the linked list in this object */ - gsicc_free_spotnames(profile_struct->spotnames, mem); + gsicc_free_spotnames(profile_struct->spotnames, mem); /* Free the main object */ - gs_free_object(mem, profile_struct->spotnames, + gs_free_object(mem, profile_struct->spotnames, "gsicc_set_device_profile_colorants"); } /* Allocate structure for managing names */ spot_names = gsicc_new_namelist(mem); profile_struct->spotnames = spot_names; - spot_names->name_str = (char*) gs_alloc_bytes(mem, str_len+1, + spot_names->name_str = (char*) gs_alloc_bytes(mem, str_len+1, "gsicc_set_device_profile_colorants"); + if (spot_names->name_str == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for spot name"); memcpy(spot_names->name_str, name_str, strlen(name_str)); spot_names->name_str[str_len] = 0; curr_entry = &(spot_names->head); /* Go ahead and tokenize now */ - pch = strtok(name_str, ","); + pch = gs_strtok(name_str, ",", &last); count = 0; while (pch != NULL) { temp_ptr = pch; @@ -1368,47 +1629,51 @@ /* Set our current entry to this one */ *curr_entry = name_entry; name_entry->length = strlen(temp_ptr); - name_entry->name = (char *) gs_alloc_bytes(mem, name_entry->length, + name_entry->name = (char *) gs_alloc_bytes(mem, name_entry->length, "gsicc_set_device_profile_colorants"); + if (spot_names->name_str == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for spot name"); memcpy(name_entry->name, temp_ptr, name_entry->length); /* Get the next entry location */ curr_entry = &((*curr_entry)->next); count += 1; - pch = strtok(NULL, ","); + pch = gs_strtok(NULL, ",", &last); } spot_names->count = count; - /* Create the color map. Query the device to find out where these + /* Create the color map. Query the device to find out where these colorants are located. It is possible that the device may - not be opened yet. In which case, we need to make sure that - when it is opened that it checks this entry and gets itself + not be opened yet. In which case, we need to make sure that + when it is opened that it checks this entry and gets itself properly initialized if it is a separation device. */ - spot_names->color_map = - (gs_devicen_color_map*) gs_alloc_bytes(mem, + spot_names->color_map = + (gs_devicen_color_map*) gs_alloc_bytes(mem, sizeof(gs_devicen_color_map), "gsicc_set_device_profile_colorants"); + if (spot_names->color_map == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for spot color map"); spot_names->color_map->num_colorants = count; spot_names->color_map->num_components = count; name_entry = spot_names->head; for (k = 0; k < count; k++) { int colorant_number = (*dev_proc(dev, get_color_comp_index)) - (dev, (const char *)name_entry->name, name_entry->length, + (dev, (const char *)name_entry->name, name_entry->length, SEPARATION_NAME); name_entry = name_entry->next; spot_names->color_map->color_map[k] = colorant_number; } /* We need to set the equivalent CMYK color for this colorant. This is done by faking out the update spot equivalent call with a special - imager state and color space that makes it seem like the + gs_gstate and color space that makes it seem like the spot color is a separation color space. Unfortunately, we need the - graphic state to do this so we save it for later when we try to do + graphic state to do this so we save it for later when we try to do our first mapping. We then use this flag to know if we did it yet */ spot_names->equiv_cmyk_set = false; - if (free_str) - gs_free_object(dev->memory, name_str, + if (free_str) + gs_free_object(dev->memory, name_str, "gsicc_set_device_profile_colorants"); } - return 0; + return code; } /* This sets the device profiles. If the device does not have a defined @@ -1430,28 +1695,49 @@ if (profile_struct != NULL) { /* Get the profile of interest */ if (profile_type < gsPROOFPROFILE) { - curr_profile = profile_struct->device_profile[profile_type]; + curr_profile = profile_struct->device_profile[profile_type]; } else { - /* The proof or link profile */ + /* The proof, link profile or post render */ if (profile_type == gsPROOFPROFILE) { - curr_profile = profile_struct->proof_profile; - } else { - curr_profile = profile_struct->link_profile; - } + curr_profile = profile_struct->proof_profile; + } else if (profile_type == gsLINKPROFILE) { + curr_profile = profile_struct->link_profile; + } else if (profile_type == gsPRPROFILE) { + curr_profile = profile_struct->postren_profile; + } else + curr_profile = profile_struct->blend_profile; + } /* See if we have the same profile in this location */ if (curr_profile != NULL) { /* There is something there now. See if what we have coming in is different and it is not the output intent. In this */ - if (profile_name != NULL) { + if (profile_name != NULL && curr_profile->name != NULL) { if (strncmp(curr_profile->name, profile_name, strlen(profile_name)) != 0 && - strncmp(curr_profile->name, OI_PROFILE, + strncmp(curr_profile->name, OI_PROFILE, strlen(curr_profile->name)) != 0) { - /* A change in the profile. rc decrement this one as it + /* A change in the profile. rc decrement this one as it will be replaced */ - rc_decrement(dev->icc_struct->device_profile[profile_type], - "gsicc_init_device_profile_struct"); + gsicc_adjust_profile_rc(curr_profile, -1, "gsicc_init_device_profile_struct"); + /* Icky - if the creation of the new profile fails, we end up with a dangling + pointer, or a wrong reference count - so NULL the appropriate entry here + */ + if (profile_type < gsPROOFPROFILE) { + profile_struct->device_profile[profile_type] = NULL; + } else { + /* The proof, link profile or post render */ + if (profile_type == gsPROOFPROFILE) { + profile_struct->proof_profile = NULL; + } else if (profile_type == gsLINKPROFILE) { + profile_struct->link_profile = NULL; + } else if (profile_type == gsPRPROFILE) { + profile_struct->postren_profile = NULL; + } else + profile_struct->blend_profile = NULL; + + } + } else { /* Nothing to change. It was either the same or is the output intent */ @@ -1469,8 +1755,8 @@ } /* Either use the incoming or a default */ if (profile_name == NULL) { - profile_name = - (char *) gs_alloc_bytes(dev->memory, + profile_name = + (char *) gs_alloc_bytes(dev->memory, MAX_DEFAULT_ICC_LENGTH, "gsicc_init_device_profile_struct"); if (profile_name == NULL) @@ -1494,46 +1780,149 @@ break; } /* Go ahead and set the profile */ - code = gsicc_set_device_profile(dev, dev->memory, profile_name, + code = gsicc_set_device_profile(dev, dev->memory, profile_name, profile_type); - gs_free_object(dev->memory, profile_name, + gs_free_object(dev->memory, profile_name, "gsicc_init_device_profile_struct"); return code; } else { /* Go ahead and set the profile */ - code = gsicc_set_device_profile(dev, dev->memory, profile_name, + code = gsicc_set_device_profile(dev, dev->memory, profile_name, profile_type); return code; } } -/* This is used in getting a list of colorant names for the intepreters +/* This is used in getting a list of colorant names for the intepreters device parameter list. */ char* gsicc_get_dev_icccolorants(cmm_dev_profile_t *dev_profile) { - if (dev_profile == NULL || dev_profile->spotnames == NULL || - dev_profile->spotnames->name_str == NULL) + if (dev_profile == NULL || dev_profile->spotnames == NULL || + dev_profile->spotnames->name_str == NULL) return 0; - else + else return dev_profile->spotnames->name_str; } +/* Check that the current state of the profiles is fine. Proof profile is of no + concern since it is doing a CIELAB to CIELAB mapping in the mashed up + transform. */ +static int +gsicc_verify_device_profiles(gx_device * pdev) +{ + int k; + cmm_dev_profile_t *dev_icc = pdev->icc_struct; + bool is_sep = false; + bool can_postrender = false; + bool objects = false; + + if (pdev->procs.dev_spec_op != NULL) { + is_sep = dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_devn, NULL, 0); + can_postrender = dev_proc(pdev, dev_spec_op)(pdev, gxdso_supports_iccpostrender, NULL, 0); + } + + if (dev_icc->device_profile[0] == NULL) + return 0; + + if (dev_icc->postren_profile != NULL && dev_icc->link_profile != NULL) { + return gs_rethrow(-1, "Post render profile not allowed with device link profile"); + } + + if (dev_icc->blend_profile != NULL) { + if (!(dev_icc->blend_profile->data_cs == gsGRAY || + dev_icc->blend_profile->data_cs == gsRGB || + dev_icc->blend_profile->data_cs == gsCMYK)) + return gs_rethrow(-1, "Blending color space must be Gray, RGB or CMYK"); + } + + if (dev_icc->postren_profile != NULL) { + if (!can_postrender) { + return gs_rethrow(-1, "Post render profile not supported by device"); + } + if (!is_sep) { + if (dev_icc->postren_profile->num_comps != + pdev->color_info.num_components) { + return gs_rethrow(-1, "Post render profile does not match the device color model"); + } + return 0; + } + return 0; /* An interesting case with sep device. Need to do a bit of testing here */ + } + + for (k = 1; k < NUM_DEVICE_PROFILES; k++) { + if (dev_icc->device_profile[k] != NULL) { + objects = true; + break; + } + } + + if (dev_icc->link_profile == NULL) { + if (!objects) { + if (!is_sep && dev_icc->device_profile[0]->num_comps != + pdev->color_info.num_components) + return gs_rethrow(-1, "Mismatch of ICC profiles and device color model"); + else + return 0; /* Currently sep devices have some leeway here */ + } else { + for (k = 1; k < NUM_DEVICE_PROFILES; k++) + if (!is_sep && dev_icc->device_profile[k] != NULL) { + if (dev_icc->device_profile[k]->num_comps != + pdev->color_info.num_components) + return gs_rethrow(-1, "Mismatch of object dependent ICC profiles and device color model"); + } + return 0; + } + } else { + /* The input of the device link must match the output of the device + profile and the device link output must match the device color + model */ + if (!is_sep && dev_icc->link_profile->num_comps_out != + pdev->color_info.num_components) { + return gs_rethrow(-1, "Mismatch of device link profile and device color model"); + } + for (k = 0; k < NUM_DEVICE_PROFILES; k++) { + if (!is_sep && dev_icc->device_profile[k] != NULL) { + if (dev_icc->device_profile[k]->num_comps != + dev_icc->link_profile->num_comps) { + return gs_rethrow(-1, "Mismatch of device link profile and device ICC profile"); + } + } + } + return 0; + } +} + /* This computes the hash code for the device profile and assigns the profile in the icc_struct member variable of the device. This should really occur only one time, but may occur twice if a color model is specified or a nondefault profile is specified on the command line */ int -gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, +gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, char *file_name, gsicc_profile_types_t pro_enum) { cmm_profile_t *icc_profile; stream *str; int code; + /* This is slightly silly, we have a device method for 'get_profile' we really ought to + * have one for 'set_profile' as well. In its absence, make sure we are setting the profile + * of the bootm level device. + */ + while(pdev->child) + pdev = pdev->child; + /* Check if device has a profile for this slot. Note that we already decremented for any profile that we might be replacing in gsicc_init_device_profile_struct */ - if (file_name != '\0') { + if (file_name != NULL) { + /* Silent on failure if this is an output intent profile that + * could not be found. Bug 695042. Multi-threaded rendering + * set up will try to find the file for the profile during the set + * up via put/get params. but one does not exist. The OI profile + * will be cloned after the put/get params */ + if (strncmp(file_name, OI_PROFILE, strlen(OI_PROFILE)) == 0) + return -1; + code = gsicc_open_search(file_name, strlen(file_name), mem, mem->gs_lib_ctx->profiledir, mem->gs_lib_ctx->profiledir_len, &str); @@ -1544,21 +1933,29 @@ gsicc_profile_new(str, mem, file_name, strlen(file_name)); code = sfclose(str); if (icc_profile == NULL) - return_error(gs_error_VMerror); + return gs_throw(gs_error_VMerror, "Creation of ICC profile failed"); if (pro_enum < gsPROOFPROFILE) { if_debug1m(gs_debug_flag_icc, mem, "[icc] Setting device profile %d\n", pro_enum); pdev->icc_struct->device_profile[pro_enum] = icc_profile; } else { - /* The proof, link or output intent profile */ + /* The proof, link or post render profile. Output intent + profile is set in zicc.c */ if (pro_enum == gsPROOFPROFILE) { if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting proof profile\n"); pdev->icc_struct->proof_profile = icc_profile; - } else { + } else if (pro_enum == gsLINKPROFILE) { if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting link profile\n"); pdev->icc_struct->link_profile = icc_profile; - } + } else if (pro_enum == gsPRPROFILE) { + if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting postrender profile\n"); + pdev->icc_struct->postren_profile = icc_profile; + } else { + if_debug0m(gs_debug_flag_icc, mem, "[icc] Setting blend profile\n"); + pdev->icc_struct->blend_profile = icc_profile; + } } + /* Get the profile handle */ icc_profile->profile_handle = gsicc_get_profile_handle_buffer(icc_profile->buffer, @@ -1566,21 +1963,32 @@ mem); if (icc_profile->profile_handle == NULL) return_error(gs_error_unknownerror); + /* Compute the hash code of the profile. Everything in the ICC manager will have it's hash code precomputed */ gsicc_get_icc_buff_hash(icc_profile->buffer, &(icc_profile->hashcode), icc_profile->buffer_size); icc_profile->hash_is_valid = true; + /* Get the number of channels in the output profile */ icc_profile->num_comps = - gscms_get_input_channel_count(icc_profile->profile_handle); - if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile has %d components\n", + gscms_get_input_channel_count(icc_profile->profile_handle, + icc_profile->memory); + if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile has %d components\n", icc_profile->num_comps); icc_profile->num_comps_out = - gscms_get_output_channel_count(icc_profile->profile_handle); + gscms_get_output_channel_count(icc_profile->profile_handle, + icc_profile->memory); icc_profile->data_cs = - gscms_get_profile_data_space(icc_profile->profile_handle); + gscms_get_profile_data_space(icc_profile->profile_handle, + icc_profile->memory); + + /* Check that everything is OK with regard to the number of + components. */ + if (gsicc_verify_device_profiles(pdev) < 0) + return gs_rethrow(-1, "Error in device profiles"); + /* We need to know if this is one of the "default" profiles or if someone has externally set it. The reason is that if there is an output intent in the file, and someone wants to use the @@ -1589,19 +1997,19 @@ output profile */ switch (icc_profile->num_comps) { case 1: - if (strncmp(icc_profile->name, DEFAULT_GRAY_ICC, + if (strncmp(icc_profile->name, DEFAULT_GRAY_ICC, strlen(icc_profile->name)) == 0) { icc_profile->default_match = DEFAULT_GRAY; } break; case 3: - if (strncmp(icc_profile->name, DEFAULT_RGB_ICC, + if (strncmp(icc_profile->name, DEFAULT_RGB_ICC, strlen(icc_profile->name)) == 0) { icc_profile->default_match = DEFAULT_RGB; } break; case 4: - if (strncmp(icc_profile->name, DEFAULT_CMYK_ICC, + if (strncmp(icc_profile->name, DEFAULT_CMYK_ICC, strlen(icc_profile->name)) == 0) { icc_profile->default_match = DEFAULT_CMYK; } @@ -1611,12 +2019,12 @@ gsicc_set_device_profile_colorants(pdev, NULL); break; } - if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile data CS is %d\n", + if_debug1m(gs_debug_flag_icc, mem, "[icc] Profile data CS is %d\n", icc_profile->data_cs); } else return gs_rethrow(-1, "cannot find device profile"); } - return(0); + return 0; } /* Set the icc profile in the gs_color_space object */ @@ -1625,7 +2033,7 @@ gs_memory_t * mem) { if (pcs == NULL) - return (-1); + return -1; #if ICC_DUMP if (icc_profile->buffer) { dump_icc_buffer(icc_profile->buffer_size, "set_gscs", @@ -1634,16 +2042,37 @@ } #endif - rc_increment(icc_profile); + gsicc_adjust_profile_rc(icc_profile, 1, "gsicc_set_gscs_profile"); if (pcs->cmm_icc_profile_data != NULL) { /* There is already a profile set there */ /* free it and then set to the new one. */ /* should we check the hash code and retain if the same or place this job on the caller? */ - rc_decrement(pcs->cmm_icc_profile_data, "gsicc_set_gscs_profile"); + gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "gsicc_set_gscs_profile"); } pcs->cmm_icc_profile_data = icc_profile; - return(0); + return 0; +} + +int +gsicc_clone_profile(cmm_profile_t *source, cmm_profile_t **destination, + gs_memory_t *memory) +{ + cmm_profile_t *des = gsicc_profile_new(NULL, memory, source->name, + source->name_length); + + if (des == NULL) + return gs_throw(gs_error_VMerror, "Profile clone failed"); + des->buffer = gs_alloc_bytes(memory, source->buffer_size, "gsicc_clone_profile"); + if (des->buffer == NULL) { + gsicc_adjust_profile_rc(des, -1, "gsicc_clone_profile"); + return gs_throw(gs_error_VMerror, "Profile clone failed"); + } + memcpy(des->buffer, source->buffer, source->buffer_size); + des->buffer_size = source->buffer_size; + gsicc_init_profile_info(des); + *destination = des; + return 0; } cmm_profile_t * @@ -1696,15 +2125,25 @@ result->isdevlink = false; /* only used for srcgtag profiles */ result->dev = NULL; result->memory = mem_nongc; - result->lock = gx_monitor_alloc(mem_nongc); - if (result->lock == NULL ) { + result->vers = ICCVERS_UNKNOWN; + result->v2_data = NULL; + result->v2_size = 0; + result->release = gscms_release_profile; /* Default case */ + +#ifdef MEMENTO_SQUEEZE_BUILD + result->lock = NULL; +#else + result->lock = gx_monitor_label(gx_monitor_alloc(mem_nongc), + "gsicc_manage"); + if (result->lock == NULL) { gs_free_object(mem_nongc, result, "gsicc_profile_new"); gs_free_object(mem_nongc, nameptr, "gsicc_profile_new"); - return(NULL); + return NULL; } +#endif if_debug1m(gs_debug_flag_icc, mem_nongc, - "[icc] allocating ICC profile = 0x%x\n", result); - return(result); + "[icc] allocating ICC profile = 0x%p\n", result); + return result; } static void @@ -1714,37 +2153,43 @@ gs_memory_t *mem_nongc = profile->memory; if_debug2m(gs_debug_flag_icc, mem, - "[icc] rc decrement profile = 0x%x rc = %ld\n", + "[icc] rc decrement profile = 0x%p rc = %ld\n", ptr_in, profile->rc.ref_count); if (profile->rc.ref_count <= 1 ) { /* Clear out the buffer if it is full */ - if(profile->buffer != NULL) { - gs_free_object(mem_nongc, profile->buffer, "rc_free_icc_profile"); + if (profile->buffer != NULL) { + gs_free_object(mem_nongc, profile->buffer, "rc_free_icc_profile(buffer)"); profile->buffer = NULL; } if_debug0m(gs_debug_flag_icc, mem, "[icc] profile freed\n"); /* Release this handle if it has been set */ - if(profile->profile_handle != NULL) { - gscms_release_profile(profile->profile_handle); + if (profile->profile_handle != NULL) { + profile->release(profile->profile_handle, profile->memory); profile->profile_handle = NULL; } /* Release the name if it has been set */ - if(profile->name != NULL) { - gs_free_object(mem_nongc, profile->name,"rc_free_icc_profile"); + if (profile->name != NULL) { + gs_free_object(mem_nongc, profile->name,"rc_free_icc_profile(name)"); profile->name = NULL; profile->name_length = 0; } profile->hash_is_valid = 0; +#ifndef MEMENTO_SQUEEZE_BUILD if (profile->lock != NULL) { - gs_free_object(mem_nongc, profile->lock,"rc_free_icc_profile"); + gx_monitor_free(profile->lock); + profile->lock = NULL; } - /* If we had a DeviceN profile with names - deallocate that now */ +#endif + /* If we had a DeviceN profile with names deallocate that now */ if (profile->spotnames != NULL) { /* Free the linked list in this object */ - gsicc_free_spotnames(profile->spotnames, mem_nongc); + gsicc_free_spotnames(profile->spotnames, mem_nongc); /* Free the main object */ - gs_free_object(mem_nongc, profile->spotnames, "rc_free_icc_profile"); + gs_free_object(mem_nongc, profile->spotnames, "rc_free_icc_profile(spotnames)"); + } + /* If we allocated a buffer to hold the v2 profile then free that */ + if (profile->v2_data != NULL) { + gs_free_object(mem_nongc, profile->v2_data, "rc_free_icc_profile(v2_data)"); } gs_free_object(mem_nongc, profile, "rc_free_icc_profile"); } @@ -1753,7 +2198,7 @@ /* We are just starting up. We need to set the initial color space in the graphic state at this time */ int -gsicc_init_gs_colors(gs_state *pgs) +gsicc_init_gs_colors(gs_gstate *pgs) { int code = 0; gs_color_space *cs_old; @@ -1767,6 +2212,8 @@ /* First do color space 0 */ cs_old = pgs->color[k].color_space; cs_new = gs_cspace_new_DeviceGray(pgs->memory); + if (cs_new == NULL) + return_error(gs_error_VMerror); rc_increment_cs(cs_new); pgs->color[k].color_space = cs_new; if ( (code = cs_new->type->install_cspace(cs_new, pgs)) < 0 ) { @@ -1782,13 +2229,13 @@ /* Only set those that have not already been set. */ int -gsicc_init_iccmanager(gs_state * pgs) +gsicc_init_iccmanager(gs_gstate * pgs) { int code = 0, k; const char *pname; int namelen; gsicc_manager_t *iccmanager = pgs->icc_manager; - cmm_profile_t *profile; + cmm_profile_t *profile; for (k = 0; k < 4; k++) { pname = default_profile_params[k].path; @@ -1813,9 +2260,41 @@ if (code < 0) return gs_rethrow(code, "cannot find default icc profile"); } +#if CREATE_V2_DATA + /* Test bed for V2 creation from V4 */ + for (int j = 2; j < 3; j++) + { + byte *data; + int size; + + switch (default_profile_params[j].default_type) { + case DEFAULT_GRAY: + profile = iccmanager->default_gray; + break; + case DEFAULT_RGB: + profile = iccmanager->default_rgb; + break; + case DEFAULT_CMYK: + profile = iccmanager->default_cmyk; + break; + default: + profile = NULL; + } + gsicc_initialize_default_profile(profile); + data = gsicc_create_getv2buffer(pgs, profile, &size); + } +#endif return 0; } +static void +gsicc_manager_finalize(const gs_memory_t *memory, void * vptr) +{ + gsicc_manager_t *icc_man = (gsicc_manager_t *)vptr; + + gsicc_manager_free_contents(icc_man, "gsicc_manager_finalize"); +} + gsicc_manager_t * gsicc_manager_new(gs_memory_t *memory) { @@ -1826,12 +2305,13 @@ result = gs_alloc_struct(memory->stable_memory, gsicc_manager_t, &st_gsicc_manager, "gsicc_manager_new"); if ( result == NULL ) - return(NULL); + return NULL; rc_init_free(result, memory->stable_memory, 1, rc_gsicc_manager_free); result->default_gray = NULL; result->default_rgb = NULL; result->default_cmyk = NULL; result->lab_profile = NULL; + result->xyz_profile = NULL; result->graytok_profile = NULL; result->device_named = NULL; result->device_n = NULL; @@ -1839,47 +2319,50 @@ result->memory = memory->stable_memory; result->srcgtag_profile = NULL; result->override_internal = false; - return(result); + return result; } -static void -rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in, client_name_t cname) +static void gsicc_manager_free_contents(gsicc_manager_t *icc_manager, + client_name_t cname) { - /* Ending the manager. Decrement the ref counts of the profiles - and then free the structure */ - gsicc_manager_t *icc_manager = (gsicc_manager_t * ) ptr_in; int k; gsicc_devicen_entry_t *device_n, *device_n_next; - rc_decrement(icc_manager->default_cmyk, "rc_gsicc_manager_free"); - rc_decrement(icc_manager->default_gray, "rc_gsicc_manager_free"); - rc_decrement(icc_manager->default_rgb, "rc_gsicc_manager_free"); - rc_decrement(icc_manager->device_named, "rc_gsicc_manager_free"); - rc_decrement(icc_manager->lab_profile, "rc_gsicc_manager_free"); - rc_decrement(icc_manager->graytok_profile, "rc_gsicc_manager_free"); - rc_decrement(icc_manager->srcgtag_profile, "rc_gsicc_manager_free"); + gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "gsicc_manager_free_contents"); + gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "gsicc_manager_free_contents"); + gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "gsicc_manager_free_contents"); + gsicc_adjust_profile_rc(icc_manager->device_named, -1, "gsicc_manager_free_contents"); + gsicc_adjust_profile_rc(icc_manager->lab_profile, -1, "gsicc_manager_free_contents"); + gsicc_adjust_profile_rc(icc_manager->graytok_profile, -1, "gsicc_manager_free_contents"); + rc_decrement(icc_manager->srcgtag_profile, "gsicc_manager_free_contents"); /* Loop through the DeviceN profiles */ if ( icc_manager->device_n != NULL) { device_n = icc_manager->device_n->head; for ( k = 0; k < icc_manager->device_n->count; k++) { - rc_decrement(device_n->iccprofile, "rc_gsicc_manager_free"); + gsicc_adjust_profile_rc(device_n->iccprofile, -1, "gsicc_manager_free_contents"); device_n_next = device_n->next; - gs_free_object(icc_manager->memory, device_n, "rc_gsicc_manager_free"); + gs_free_object(icc_manager->memory, device_n, "gsicc_manager_free_contents"); device_n = device_n_next; } gs_free_object(icc_manager->memory, icc_manager->device_n, - "rc_gsicc_manager_free"); + "gsicc_manager_free_contents"); } + /* The soft mask profiles */ - if ( icc_manager->smask_profiles != NULL) { - rc_decrement(icc_manager->smask_profiles->smask_gray, - "rc_gsicc_manager_free"); - rc_decrement(icc_manager->smask_profiles->smask_rgb, - "rc_gsicc_manager_free"); - rc_decrement(icc_manager->smask_profiles->smask_cmyk, - "rc_gsicc_manager_free"); + if (icc_manager->smask_profiles != NULL) { + gs_free_object(icc_manager->smask_profiles->memory, icc_manager->smask_profiles, "gsicc_manager_free_contents"); + icc_manager->smask_profiles = NULL; } +} + +static void +rc_gsicc_manager_free(gs_memory_t * mem, void *ptr_in, client_name_t cname) +{ + /* Ending the manager. Decrement the ref counts of the profiles + and then free the structure */ + gsicc_manager_t *icc_manager = (gsicc_manager_t * ) ptr_in; + gs_free_object(icc_manager->memory, icc_manager, "rc_gsicc_manager_free"); } @@ -1896,26 +2379,32 @@ and not doing a retry if there is an issue. This is a bug in the stream logic or strmio layer. Occurs with smask_withicc.pdf on linux 64 bit system */ + if (code < 0) + return code; /* Get the size from doing a seek to the end and then a rewind instead of relying upon the profile size indicated in the header */ code = sfseek(s,0,SEEK_END); + if (code < 0) + return code; profile_size = sftell(s); code = srewind(s); + if (code < 0) + return code; if (profile_size < ICC_HEADER_SIZE) - return(-1); + return_error(gs_error_VMerror); /* Allocate the buffer, stuff with the profile */ buffer_ptr = gs_alloc_bytes(memory, profile_size, "gsicc_load_profile"); if (buffer_ptr == NULL) - return(-1); + return gs_throw(gs_error_VMerror, "Insufficient memory for profile buffer"); num_bytes = sfread(buffer_ptr,sizeof(unsigned char),profile_size,s); if( num_bytes != profile_size) { gs_free_object(memory, buffer_ptr, "gsicc_load_profile"); - return(-1); + return -1; } profile->buffer = buffer_ptr; profile->buffer_size = num_bytes; - return(0); + return 0; } /* Allocates and loads the named color structure from the stream. */ @@ -1928,28 +2417,35 @@ int code; code = srewind(s); + if (code < 0) + return code; code = sfseek(s,0,SEEK_END); + if (code < 0) + return code; profile_size = sftell(s); code = srewind(s); + if (code < 0) + return code; /* Allocate the buffer, stuff with the profile */ - buffer_ptr = gs_alloc_bytes(memory, profile_size, + buffer_ptr = gs_alloc_bytes(memory->non_gc_memory, profile_size, "gsicc_load_profile"); - if (buffer_ptr == NULL) - return(-1); - num_bytes = sfread(buffer_ptr,sizeof(unsigned char),profile_size,s); - if( num_bytes != profile_size) { - gs_free_object(memory, buffer_ptr, "gsicc_load_profile"); - return(-1); - } - profile->buffer = buffer_ptr; - profile->buffer_size = num_bytes; - return(0); + if (buffer_ptr == NULL) + return gs_throw(gs_error_VMerror, "Insufficient memory for profile buffer"); + num_bytes = sfread(buffer_ptr,sizeof(unsigned char),profile_size,s); + if( num_bytes != profile_size) { + gs_free_object(memory->non_gc_memory, buffer_ptr, "gsicc_load_profile"); + return -1; + } + profile->buffer = buffer_ptr; + profile->buffer_size = num_bytes; + return 0; } + /* Check if the embedded profile is the same as any of the default profiles */ static void -gsicc_set_default_cs_value(cmm_profile_t *picc_profile, gs_imager_state *pis) +gsicc_set_default_cs_value(cmm_profile_t *picc_profile, gs_gstate *pgs) { - gsicc_manager_t *icc_manager = pis->icc_manager; + gsicc_manager_t *icc_manager = pgs->icc_manager; int64_t hashcode = picc_profile->hashcode; if ( picc_profile->default_match == DEFAULT_NONE ) { @@ -1984,14 +2480,14 @@ /* Initialize the hash code value */ void -gsicc_init_hash_cs(cmm_profile_t *picc_profile, gs_imager_state *pis) +gsicc_init_hash_cs(cmm_profile_t *picc_profile, gs_gstate *pgs) { if ( !(picc_profile->hash_is_valid) ) { gsicc_get_icc_buff_hash(picc_profile->buffer, &(picc_profile->hashcode), picc_profile->buffer_size); picc_profile->hash_is_valid = true; } - gsicc_set_default_cs_value(picc_profile, pis); + gsicc_set_default_cs_value(picc_profile, pgs); } /* Interface code to get the profile handle for data @@ -2015,7 +2511,7 @@ position = gsicc_search_icc_table(pcrdev->icc_table, picc_profile->hashcode, &size); if ( position < 0 ) - return(0); /* Not found. */ + return 0; /* Not found. */ /* Get the ICC buffer. We really want to avoid this transfer. I need to write an interface to the CMM to do this through @@ -2026,15 +2522,15 @@ buffer_ptr = gs_alloc_bytes(memory->non_gc_memory, profile_size, "gsicc_get_profile_handle_clist"); if (buffer_ptr == NULL) - return(0); - picc_profile->buffer = buffer_ptr; + return 0; clist_read_chunk(pcrdev, position + GSICC_SERIALIZED_SIZE, profile_size, (unsigned char *) buffer_ptr); - profile_handle = gscms_get_profile_handle_mem(memory->non_gc_memory, buffer_ptr, profile_size); + profile_handle = gscms_get_profile_handle_mem(buffer_ptr, profile_size, memory->non_gc_memory); /* We also need to get some of the serialized information */ clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE, (unsigned char *) (&profile_header)); - picc_profile->buffer_size = profile_header.buffer_size; + picc_profile->buffer = NULL; + picc_profile->buffer_size = 0; picc_profile->data_cs = profile_header.data_cs; picc_profile->default_match = profile_header.default_match; picc_profile->hash_is_valid = profile_header.hash_is_valid; @@ -2050,9 +2546,10 @@ picc_profile->Range.ranges[k].rmin = profile_header.Range.ranges[k].rmin; } - return(profile_handle); + gs_free_object(memory->non_gc_memory, buffer_ptr, "gsicc_get_profile_handle_clist"); + return profile_handle; } - return(0); + return 0; } gcmmhprofile_t @@ -2063,12 +2560,12 @@ if( buffer != NULL) { if (profile_size < ICC_HEADER_SIZE) { - return(0); + return 0; } - profile_handle = gscms_get_profile_handle_mem(memory->non_gc_memory, buffer, profile_size); - return(profile_handle); + profile_handle = gscms_get_profile_handle_mem(buffer, profile_size, memory->non_gc_memory); + return profile_handle; } - return(0); + return 0; } /* If we have a profile for the color space already, then we use that. @@ -2081,21 +2578,21 @@ cmm_profile_t *profile = gs_colorspace->cmm_icc_profile_data; gs_color_space_index color_space_index = gs_color_space_get_index(gs_colorspace); - int code; + int code = 0; bool islab; if (profile != NULL ) - return(profile); + return profile; /* else, return the default types */ switch( color_space_index ) { case gs_color_space_index_DeviceGray: - return(icc_manager->default_gray); + return icc_manager->default_gray; break; case gs_color_space_index_DeviceRGB: - return(icc_manager->default_rgb); + return icc_manager->default_rgb; break; case gs_color_space_index_DeviceCMYK: - return(icc_manager->default_cmyk); + return icc_manager->default_cmyk; break; /* Only used in 3x types */ case gs_color_space_index_DevicePixel: @@ -2109,20 +2606,24 @@ case gs_color_space_index_CIEDEFG: /* For now just use default CMYK to avoid segfault. MJV to fix */ gs_colorspace->cmm_icc_profile_data = icc_manager->default_cmyk; - rc_increment(icc_manager->default_cmyk); - return(gs_colorspace->cmm_icc_profile_data); + gsicc_adjust_profile_rc(icc_manager->default_cmyk, 1, "gsicc_get_gscs_profile"); + return gs_colorspace->cmm_icc_profile_data; /* Need to convert to an ICC form */ break; case gs_color_space_index_CIEDEF: /* For now just use default RGB to avoid segfault. MJV to fix */ gs_colorspace->cmm_icc_profile_data = icc_manager->default_rgb; - rc_increment(icc_manager->default_rgb); - return(gs_colorspace->cmm_icc_profile_data); + gsicc_adjust_profile_rc(icc_manager->default_rgb, 1, "gsicc_get_gscs_profile"); + return gs_colorspace->cmm_icc_profile_data; /* Need to convert to an ICC form */ break; case gs_color_space_index_CIEABC: gs_colorspace->cmm_icc_profile_data = gsicc_profile_new(NULL, icc_manager->memory, NULL, 0); + if (gs_colorspace->cmm_icc_profile_data == NULL) { + gs_throw(gs_error_VMerror, "Creation of ICC profile for CIEABC failed"); + return NULL; + } code = gsicc_create_fromabc(gs_colorspace, &(gs_colorspace->cmm_icc_profile_data->buffer), @@ -2131,19 +2632,30 @@ &(gs_colorspace->params.abc->caches.DecodeABC.caches[0]), &(gs_colorspace->params.abc->common.caches.DecodeLMN[0]), &islab); + if (code < 0) { + gs_warn("Failed to create ICC profile from CIEABC"); + gsicc_adjust_profile_rc(gs_colorspace->cmm_icc_profile_data, -1, + "gsicc_get_gscs_profile"); + return NULL; + } + if (islab) { /* Destroy the profile */ - rc_decrement(gs_colorspace->cmm_icc_profile_data, + gsicc_adjust_profile_rc(gs_colorspace->cmm_icc_profile_data, -1, "gsicc_get_gscs_profile"); /* This may be an issue for pdfwrite */ - return(icc_manager->lab_profile); + return icc_manager->lab_profile; } gs_colorspace->cmm_icc_profile_data->default_match = CIE_ABC; - return(gs_colorspace->cmm_icc_profile_data); + return gs_colorspace->cmm_icc_profile_data; break; case gs_color_space_index_CIEA: gs_colorspace->cmm_icc_profile_data = gsicc_profile_new(NULL, icc_manager->memory, NULL, 0); + if (gs_colorspace->cmm_icc_profile_data == NULL) { + gs_throw(gs_error_VMerror, "Creation of ICC profile for CIEA failed"); + return NULL; + } code = gsicc_create_froma(gs_colorspace, &(gs_colorspace->cmm_icc_profile_data->buffer), @@ -2152,24 +2664,24 @@ &(gs_colorspace->params.a->caches.DecodeA), &(gs_colorspace->params.a->common.caches.DecodeLMN[0])); gs_colorspace->cmm_icc_profile_data->default_match = CIE_A; - return(gs_colorspace->cmm_icc_profile_data); + return gs_colorspace->cmm_icc_profile_data; break; case gs_color_space_index_Separation: /* Caller should use named color path */ - return(0); + return 0; break; case gs_color_space_index_Pattern: case gs_color_space_index_Indexed: /* Caller should use the base space for these */ - return(0); + return 0; break; case gs_color_space_index_ICC: /* This should not occur, as the space should have had a populated profile handle */ - return(0); + return 0; break; } - return(0); + return 0; } static int64_t @@ -2182,14 +2694,14 @@ for (k = 0; k < tablesize; k++ ) { if ( curr_entry->serial_data.hashcode == icc_hashcode ) { *size = curr_entry->serial_data.size; - return(curr_entry->serial_data.file_position); + return curr_entry->serial_data.file_position; } curr_entry = curr_entry->next; } /* Did not find it! */ *size = 0; - return(-1); + return -1; } /* This is used to get only the serial data from the clist. We don't bother @@ -2207,7 +2719,7 @@ /* Create a new ICC profile structure */ profile = gsicc_profile_new(NULL, pcrdev->memory, NULL, 0); if (profile == NULL) - return(NULL); + return NULL; /* Check ICC table for hash code and get the whole size icc raw buffer plus serialized header information. Make sure the icc_table has @@ -2215,16 +2727,16 @@ if (pcrdev->icc_table == NULL) { code = clist_read_icctable(pcrdev); if (code<0) - return(NULL); + return NULL; } position = gsicc_search_icc_table(pcrdev->icc_table, icc_hashcode, &size); if ( position < 0 ) - return(NULL); + return NULL; /* Get the serialized portion of the ICC profile information */ - clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE, + clist_read_chunk(pcrdev, position, GSICC_SERIALIZED_SIZE, (unsigned char *) profile); - return(profile); + return profile; } void @@ -2241,62 +2753,8 @@ int gsicc_getsrc_channel_count(cmm_profile_t *icc_profile) { - return(gscms_get_input_channel_count(icc_profile->profile_handle)); -} - -/* - * Adjust the reference count of the profile. This is intended to support - * applications (such as XPS) which maintain ICC profiles outside of the - * graphic state. - */ -void -gsicc_profile_reference(cmm_profile_t *icc_profile, int delta) -{ - if (icc_profile != NULL) - rc_adjust(icc_profile, delta, "gsicc_profile_reference"); -} - -void -gsicc_get_srcprofile(gsicc_colorbuffer_t data_cs, - gs_graphics_type_tag_t graphics_type_tag, - cmm_srcgtag_profile_t *srcgtag_profile, - cmm_profile_t **profile, gsicc_rendering_param_t *render_cond) -{ - (*profile) = NULL; - (*render_cond).rendering_intent = gsPERCEPTUAL; - switch (graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS) { - case GS_UNKNOWN_TAG: - case GS_UNTOUCHED_TAG: - default: - break; - case GS_PATH_TAG: - if (data_cs == gsRGB) { - (*profile) = srcgtag_profile->rgb_profiles[gsSRC_GRAPPRO]; - *render_cond = srcgtag_profile->rgb_rend_cond[gsSRC_GRAPPRO]; - } else if (data_cs == gsCMYK) { - (*profile) = srcgtag_profile->cmyk_profiles[gsSRC_GRAPPRO]; - *render_cond = srcgtag_profile->cmyk_rend_cond[gsSRC_GRAPPRO]; - } - break; - case GS_IMAGE_TAG: - if (data_cs == gsRGB) { - (*profile) = srcgtag_profile->rgb_profiles[gsSRC_IMAGPRO]; - *render_cond = srcgtag_profile->rgb_rend_cond[gsSRC_IMAGPRO]; - } else if (data_cs == gsCMYK) { - (*profile) = srcgtag_profile->cmyk_profiles[gsSRC_IMAGPRO]; - *render_cond = srcgtag_profile->cmyk_rend_cond[gsSRC_IMAGPRO]; - } - break; - case GS_TEXT_TAG: - if (data_cs == gsRGB) { - (*profile) = srcgtag_profile->rgb_profiles[gsSRC_TEXTPRO]; - *render_cond = srcgtag_profile->rgb_rend_cond[gsSRC_TEXTPRO]; - } else if (data_cs == gsCMYK) { - (*profile) = srcgtag_profile->cmyk_profiles[gsSRC_TEXTPRO]; - *render_cond = srcgtag_profile->cmyk_rend_cond[gsSRC_TEXTPRO]; - } - break; - } + return gscms_get_input_channel_count(icc_profile->profile_handle, + icc_profile->memory); } void @@ -2340,21 +2798,22 @@ /* internal ICC and rendering intent override control */ void -gs_setoverrideicc(gs_imager_state *pis, bool value) +gs_setoverrideicc(gs_gstate *pgs, bool value) { - if (pis->icc_manager != NULL) { - pis->icc_manager->override_internal = value; + if (pgs->icc_manager != NULL) { + pgs->icc_manager->override_internal = value; } } bool -gs_currentoverrideicc(const gs_imager_state *pis) +gs_currentoverrideicc(const gs_gstate *pgs) { - if (pis->icc_manager != NULL) { - return pis->icc_manager->override_internal; + if (pgs->icc_manager != NULL) { + return pgs->icc_manager->override_internal; } else { return false; } } + void gsicc_setrange_lab(cmm_profile_t *profile) { @@ -2384,7 +2843,7 @@ /* The following are for setting the system/user params */ /* No default for the deviceN profile. */ void -gs_currentdevicenicc(const gs_state * pgs, gs_param_string * pval) +gs_currentdevicenicc(const gs_gstate * pgs, gs_param_string * pval) { static const char *const rfs = ""; @@ -2394,7 +2853,7 @@ pval->data = (const byte *) rfs; pval->persistent = true; } else { - pval->data = + pval->data = (const byte *) (pgs->icc_manager->device_n->head->iccprofile->name); pval->persistent = false; } @@ -2402,10 +2861,10 @@ } int -gs_setdevicenprofileicc(const gs_state * pgs, gs_param_string * pval) +gs_setdevicenprofileicc(const gs_gstate * pgs, gs_param_string * pval) { int code = 0; - char *pname, *pstr, *pstrend; + char *pname, *pstr, *pstrend, *last = NULL; int namelen = (pval->size)+1; gs_memory_t *mem = pgs->memory; @@ -2423,7 +2882,7 @@ return_error(gs_error_VMerror); memcpy(pname,pval->data,namelen-1); pname[namelen-1] = 0; - pstr = strtok(pname, ",;"); + pstr = gs_strtok(pname, ",;", &last); while (pstr != NULL) { namelen = strlen(pstr); /* Remove leading and trailing spaces from the name */ @@ -2440,7 +2899,7 @@ code = gsicc_set_profile(pgs->icc_manager, (const char*) pstr, namelen, DEVICEN_TYPE); if (code < 0) return gs_throw(code, "cannot find devicen icc profile"); - pstr = strtok(NULL, ",;"); + pstr = gs_strtok(NULL, ",;", &last); } gs_free_object(mem, pname, "set_devicen_profile_icc"); @@ -2450,7 +2909,7 @@ } void -gs_currentdefaultgrayicc(const gs_state * pgs, gs_param_string * pval) +gs_currentdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval) { static const char *const rfs = DEFAULT_GRAY_ICC; @@ -2465,7 +2924,7 @@ } int -gs_setdefaultgrayicc(const gs_state * pgs, gs_param_string * pval) +gs_setdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval) { int code; char *pname; @@ -2494,7 +2953,7 @@ /* if this is our first time in here then we need to properly install the color spaces that were initialized in the graphic state at this time */ if (not_initialized) { - code = gsicc_init_gs_colors((gs_state*) pgs); + code = gsicc_init_gs_colors((gs_gstate*) pgs); } if (code < 0) return gs_throw(code, "error initializing gstate color spaces to icc"); @@ -2502,7 +2961,7 @@ } void -gs_currenticcdirectory(const gs_state * pgs, gs_param_string * pval) +gs_currenticcdirectory(const gs_gstate * pgs, gs_param_string * pval) { static const char *const rfs = DEFAULT_DIR_ICC; /* as good as any other */ const gs_lib_ctx_t *lib_ctx = pgs->memory->gs_lib_ctx; @@ -2513,34 +2972,37 @@ pval->persistent = true; } else { pval->data = (const byte *)(lib_ctx->profiledir); - pval->size = lib_ctx->profiledir_len; + pval->size = lib_ctx->profiledir_len - 1; pval->persistent = false; } } int -gs_seticcdirectory(const gs_state * pgs, gs_param_string * pval) +gs_seticcdirectory(const gs_gstate * pgs, gs_param_string * pval) { char *pname; int namelen = (pval->size)+1; - const gs_memory_t *mem = pgs->memory; + gs_memory_t *mem = (gs_memory_t *)pgs->memory; /* Check if it was "NULL" */ if (pval->size != 0 ) { - pname = (char *)gs_alloc_bytes((gs_memory_t *)mem, namelen, - "set_icc_directory"); + pname = (char *)gs_alloc_bytes(mem, namelen, + "gs_seticcdirectory"); if (pname == NULL) return gs_rethrow(-1, "cannot allocate directory name"); memcpy(pname,pval->data,namelen-1); pname[namelen-1] = 0; - gs_lib_ctx_set_icc_directory(mem, (const char*) pname, namelen); - gs_free_object((gs_memory_t *)mem, pname, "set_icc_directory"); + if (gs_lib_ctx_set_icc_directory(mem, (const char*) pname, namelen) < 0) { + gs_free_object(mem, pname, "gs_seticcdirectory"); + return -1; + } + gs_free_object(mem, pname, "gs_seticcdirectory"); } return 0; } void -gs_currentsrcgtagicc(const gs_state * pgs, gs_param_string * pval) +gs_currentsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval) { if (pgs->icc_manager->srcgtag_profile == NULL) { pval->data = NULL; @@ -2554,7 +3016,7 @@ } int -gs_setsrcgtagicc(const gs_state * pgs, gs_param_string * pval) +gs_setsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval) { int code; char *pname; @@ -2567,7 +3029,7 @@ return_error(gs_error_VMerror); memcpy(pname,pval->data,namelen-1); pname[namelen-1] = 0; - code = gsicc_set_srcgtag_struct(pgs->icc_manager, (const char*) pname, + code = gsicc_set_srcgtag_struct(pgs->icc_manager, (const char*) pname, namelen); gs_free_object(mem, pname, "set_srcgtag_icc"); if (code < 0) @@ -2576,7 +3038,7 @@ } void -gs_currentdefaultrgbicc(const gs_state * pgs, gs_param_string * pval) +gs_currentdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval) { static const char *const rfs = DEFAULT_RGB_ICC; @@ -2591,7 +3053,7 @@ } int -gs_setdefaultrgbicc(const gs_state * pgs, gs_param_string * pval) +gs_setdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval) { int code; char *pname; @@ -2614,7 +3076,7 @@ } void -gs_currentnamedicc(const gs_state * pgs, gs_param_string * pval) +gs_currentnamedicc(const gs_gstate * pgs, gs_param_string * pval) { static const char *const rfs = ""; @@ -2629,7 +3091,7 @@ } int -gs_setnamedprofileicc(const gs_state * pgs, gs_param_string * pval) +gs_setnamedprofileicc(const gs_gstate * pgs, gs_param_string * pval) { int code; char* pname; @@ -2656,7 +3118,7 @@ } void -gs_currentdefaultcmykicc(const gs_state * pgs, gs_param_string * pval) +gs_currentdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval) { static const char *const rfs = DEFAULT_CMYK_ICC; @@ -2671,7 +3133,7 @@ } int -gs_setdefaultcmykicc(const gs_state * pgs, gs_param_string * pval) +gs_setdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval) { int code; char* pname; @@ -2694,7 +3156,7 @@ } void -gs_currentlabicc(const gs_state * pgs, gs_param_string * pval) +gs_currentlabicc(const gs_gstate * pgs, gs_param_string * pval) { static const char *const rfs = LAB_ICC; @@ -2705,7 +3167,7 @@ } int -gs_setlabicc(const gs_state * pgs, gs_param_string * pval) +gs_setlabicc(const gs_gstate * pgs, gs_param_string * pval) { int code; char* pname; diff -Nru ghostscript-9.10~dfsg/base/gsicc_manage.h ghostscript-9.25~dfsg+1/base/gsicc_manage.h --- ghostscript-9.10~dfsg/base/gsicc_manage.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_manage.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,20 +9,17 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ - -/* Header for the ICC Manager */ - #ifndef gsiccmanage_INCLUDED # define gsiccmanage_INCLUDED #define ICC_DUMP 0 /* Define the default ICC profiles in the file system */ -#define OI_PROFILE "OIProfile" /* Keyword to indicate use of OI profile */ +#define OI_PROFILE "\xffOIProfile" /* Keyword to indicate use of OI profile */ #define DEFAULT_GRAY_ICC "default_gray.icc" #define DEFAULT_RGB_ICC "default_rgb.icc" #define DEFAULT_CMYK_ICC "default_cmyk.icc" @@ -34,9 +31,10 @@ #define DEFAULT_DIR_ICC "%rom%iccprofiles/" #define MAX_DEFAULT_ICC_LENGTH 17 -/* Key names for special common canned profiles. - These are found in some image file formats as - a magic number. */ +#define MAX_COLOR_ACCURACY 2 + +/* Key names for special common canned profiles. These are found in some image + file formats as a magic number. */ #define GSICC_STANDARD_PROFILES_KEYS\ "srgb", "sgray" @@ -45,13 +43,16 @@ #define GSICC_NUMBER_STANDARD_PROFILES 2 /* This enumeration has to be in sync with GSICC_SRCGTAG_KEYS */ typedef enum { - COLOR_TUNE, + COLOR_TUNE, GRAPHIC_CMYK, IMAGE_CMYK, TEXT_CMYK, GRAPHIC_RGB, IMAGE_RGB, - TEXT_RGB + TEXT_RGB, + GRAPHIC_GRAY, + IMAGE_GRAY, + TEXT_GRAY } gsicc_srcgtagkey_t; #define GSICC_SRCTAG_NOCM "None" @@ -59,98 +60,104 @@ #define GSICC_SRCGTAG_KEYS\ "ColorTune", "Graphic_CMYK", "Image_CMYK", "Text_CMYK",\ - "Graphic_RGB", "Image_RGB", "Text_RGB" -#define GSICC_NUM_SRCGTAG_KEYS 7 -#define GSICC_SRCGTAG_MAX_KEY 12 + "Graphic_RGB", "Image_RGB", "Text_RGB",\ + "Graphic_GRAY", "Image_GRAY", "Text_GRAY" +#define GSICC_NUM_SRCGTAG_KEYS 10 #include "gsicc_cms.h" -/* Prototypes */ -void gsicc_profile_reference(cmm_profile_t *icc_profile, int delta); -void gsicc_extract_profile(gs_graphics_type_tag_t graphics_type_tag, - cmm_dev_profile_t *profile_struct, - cmm_profile_t **profile, gsicc_rendering_param_t *render_cond); -void gsicc_get_srcprofile(gsicc_colorbuffer_t data_cs, - gs_graphics_type_tag_t graphics_type_tag, - cmm_srcgtag_profile_t *srcgtag_profile, - cmm_profile_t **profile, gsicc_rendering_param_t *render_cond); -int gsicc_getsrc_channel_count(cmm_profile_t *icc_profile); -int gsicc_init_iccmanager(gs_state * pgs); -int gsicc_init_gs_colors(gs_state *pgs); -void gsicc_profile_serialize(gsicc_serialized_profile_t *profile_data, - cmm_profile_t *iccprofile); -int gsicc_set_device_profile_intent(gx_device *dev, - gsicc_rendering_intents_t intent, - gsicc_profile_types_t profile_type); -int gsicc_set_device_blackptcomp(gx_device *dev, - gsicc_blackptcomp_t blackptcomp, - gsicc_profile_types_t profile_type); -int gsicc_set_device_blackpreserve(gx_device *dev, - gsicc_blackpreserve_t blackpreserve, - gsicc_profile_types_t profile_type); -void gsicc_set_devicen_equiv_colors(gx_device *dev, const gs_imager_state * pis, - cmm_profile_t *profile); -int gsicc_set_device_profile_colorants(gx_device *dev, char *name_str); -int gsicc_init_device_profile_struct(gx_device * dev, char *profile_name, - gsicc_profile_types_t profile_type); -int gsicc_set_profile(gsicc_manager_t *icc_manager, const char *pname, - int namelen, gsicc_profile_t defaulttype); -int gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname, - int namelen); -cmm_profile_t* gsicc_get_profile_handle_file(const char* pname, int namelen, - gs_memory_t *mem); -void gsicc_init_profile_info(cmm_profile_t *profile); -int gsicc_initialize_default_profile(cmm_profile_t *icc_profile); +/* Manager related */ gsicc_manager_t* gsicc_manager_new(gs_memory_t *memory); +int gsicc_init_iccmanager(gs_gstate * pgs); +int gsicc_set_profile(gsicc_manager_t *icc_manager, const char *pname, + int namelen, gsicc_profile_t defaulttype); +cmm_profile_t* gsicc_finddevicen(const gs_color_space *pcs, + gsicc_manager_t *icc_manager); + +/* Soft mask profile related */ +gsicc_smask_t* gsicc_new_iccsmask(gs_memory_t *memory); +int gsicc_initialize_iccsmask(gsicc_manager_t *icc_manager); +cmm_profile_t* gsicc_set_iccsmaskprofile(const char *pname, int namelen, + gsicc_manager_t *icc_manager, gs_memory_t *mem); + +/* Start up related */ +int gsicc_init_gs_colors(gs_gstate *pgs); + +/* Profile related */ cmm_profile_t* gsicc_profile_new(stream *s, gs_memory_t *memory, - const char* pname, int namelen); -int gsicc_set_gscs_profile(gs_color_space *pcs, cmm_profile_t *icc_profile, - gs_memory_t * mem); -cmm_profile_t* gsicc_get_gscs_profile(gs_color_space *gs_colorspace, - gsicc_manager_t *icc_manager); -void gsicc_init_hash_cs(cmm_profile_t *picc_profile, gs_imager_state *pis); + const char* pname, int namelen); +int gsicc_clone_profile(cmm_profile_t *source, cmm_profile_t **destination, + gs_memory_t *memory); +void gsicc_init_hash_cs(cmm_profile_t *picc_profile, gs_gstate *pgs); gcmmhprofile_t gsicc_get_profile_handle_clist(cmm_profile_t *picc_profile, - gs_memory_t *memory); + gs_memory_t *memory); gcmmhprofile_t gsicc_get_profile_handle_buffer(unsigned char *buffer, - int profile_size, - gs_memory_t *memory); -gsicc_smask_t* gsicc_new_iccsmask(gs_memory_t *memory); -int gsicc_initialize_iccsmask(gsicc_manager_t *icc_manager); + int profile_size, gs_memory_t *memory); +cmm_profile_t* gsicc_get_profile_handle_file(const char* pname, int namelen, + gs_memory_t *mem); +void gsicc_setrange_lab(cmm_profile_t *profile); +void gsicc_set_icc_range(cmm_profile_t **icc_profile); +void gsicc_profile_serialize(gsicc_serialized_profile_t *profile_data, + cmm_profile_t *iccprofile); +int gsicc_getsrc_channel_count(cmm_profile_t *icc_profile); unsigned int gsicc_getprofilesize(unsigned char *buffer); -void gscms_set_icc_range(cmm_profile_t **icc_profile); +int gsicc_getprofilevers(cmm_profile_t *icc_profile, unsigned char *major, + unsigned char *minor); cmm_profile_t* gsicc_read_serial_icc(gx_device * dev, int64_t icc_hashcode); -cmm_profile_t* gsicc_finddevicen(const gs_color_space *pcs, - gsicc_manager_t *icc_manager); +int gsicc_set_gscs_profile(gs_color_space *pcs, cmm_profile_t *icc_profile, + gs_memory_t * mem); +cmm_profile_t* gsicc_get_gscs_profile(gs_color_space *gs_colorspace, + gsicc_manager_t *icc_manager); +cmm_profile_t* gsicc_get_profile_handle_file(const char* pname, int namelen, + gs_memory_t *mem); +int gsicc_init_profile_info(cmm_profile_t *profile); +int gsicc_initialize_default_profile(cmm_profile_t *icc_profile); gs_color_space_index gsicc_get_default_type(cmm_profile_t *profile_data); +bool gsicc_profile_from_ps(cmm_profile_t *profile_data); +void gsicc_adjust_profile_rc(cmm_profile_t *profile_data, int delta, const char *name_str); + +/* Device related */ cmm_dev_profile_t* gsicc_new_device_profile_array(gs_memory_t *memory); -void gs_setoverrideicc(gs_imager_state *pis, bool value); -bool gs_currentoverrideicc(const gs_imager_state *pis); -cmm_profile_t* gsicc_set_iccsmaskprofile(const char *pname, int namelen, - gsicc_manager_t *icc_manager, - gs_memory_t *mem); -int gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, - char *file_name, gsicc_profile_types_t defaulttype); +int gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, + char *file_name, gsicc_profile_types_t defaulttype); char* gsicc_get_dev_icccolorants(cmm_dev_profile_t *dev_profile); -void gsicc_setrange_lab(cmm_profile_t *profile); -/* system and user params */ -void gs_currentdevicenicc(const gs_state * pgs, gs_param_string * pval); -int gs_setdevicenprofileicc(const gs_state * pgs, gs_param_string * pval); -void gs_currentdefaultgrayicc(const gs_state * pgs, gs_param_string * pval); -int gs_setdefaultgrayicc(const gs_state * pgs, gs_param_string * pval); -void gs_currenticcdirectory(const gs_state * pgs, gs_param_string * pval); -int gs_seticcdirectory(const gs_state * pgs, gs_param_string * pval); -void gs_currentsrcgtagicc(const gs_state * pgs, gs_param_string * pval); -int gs_setsrcgtagicc(const gs_state * pgs, gs_param_string * pval); -void gs_currentdefaultrgbicc(const gs_state * pgs, gs_param_string * pval); -int gs_setdefaultrgbicc(const gs_state * pgs, gs_param_string * pval); -void gs_currentnamedicc(const gs_state * pgs, gs_param_string * pval); -int gs_setnamedprofileicc(const gs_state * pgs, gs_param_string * pval); -void gs_currentdefaultcmykicc(const gs_state * pgs, gs_param_string * pval); -int gs_setdefaultcmykicc(const gs_state * pgs, gs_param_string * pval); -void gs_currentlabicc(const gs_state * pgs, gs_param_string * pval); -int gs_setlabicc(const gs_state * pgs, gs_param_string * pval); - +int gsicc_set_device_profile_colorants(gx_device *dev, char *name_str); +int gsicc_set_device_profile_intent(gx_device *dev, + gsicc_rendering_intents_t intent, gsicc_profile_types_t profile_type); +int gsicc_set_device_blackptcomp(gx_device *dev, gsicc_blackptcomp_t blackptcomp, + gsicc_profile_types_t profile_type); +int gsicc_set_device_blackpreserve(gx_device *dev, + gsicc_blackpreserve_t blackpreserve, gsicc_profile_types_t profile_type); +int gsicc_set_devicen_equiv_colors(gx_device *dev, const gs_gstate * pgs, + cmm_profile_t *profile); +int gsicc_init_device_profile_struct(gx_device * dev, char *profile_name, + gsicc_profile_types_t profile_type); +void gsicc_extract_profile(gs_graphics_type_tag_t graphics_type_tag, + cmm_dev_profile_t *profile_struct, cmm_profile_t **profile, + gsicc_rendering_param_t *render_cond); +/* System and user params */ +void gs_setoverrideicc(gs_gstate *pgs, bool value); +bool gs_currentoverrideicc(const gs_gstate *pgs); +void gs_currentdevicenicc(const gs_gstate * pgs, gs_param_string * pval); +int gs_setdevicenprofileicc(const gs_gstate * pgs, gs_param_string * pval); +void gs_currentdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval); +int gs_setdefaultgrayicc(const gs_gstate * pgs, gs_param_string * pval); +void gs_currenticcdirectory(const gs_gstate * pgs, gs_param_string * pval); +int gs_seticcdirectory(const gs_gstate * pgs, gs_param_string * pval); +void gs_currentsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval); +int gs_setsrcgtagicc(const gs_gstate * pgs, gs_param_string * pval); +void gs_currentdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval); +int gs_setdefaultrgbicc(const gs_gstate * pgs, gs_param_string * pval); +void gs_currentnamedicc(const gs_gstate * pgs, gs_param_string * pval); +int gs_setnamedprofileicc(const gs_gstate * pgs, gs_param_string * pval); +void gs_currentdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval); +int gs_setdefaultcmykicc(const gs_gstate * pgs, gs_param_string * pval); +void gs_currentlabicc(const gs_gstate * pgs, gs_param_string * pval); +int gs_setlabicc(const gs_gstate * pgs, gs_param_string * pval); +int gsicc_get_device_class(cmm_profile_t *icc_profile); +uint gsicc_currentcoloraccuracy(gs_memory_t *mem); +void gsicc_setcoloraccuracy(gs_memory_t *mem, uint level); #if ICC_DUMP static void dump_icc_buffer(int buffersize, char filename[],byte *Buffer); diff -Nru ghostscript-9.10~dfsg/base/gsicc_monitorcm.c ghostscript-9.25~dfsg+1/base/gsicc_monitorcm.c --- ghostscript-9.10~dfsg/base/gsicc_monitorcm.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_monitorcm.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2013 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,13 +9,15 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* gsicc handling for monitoring colors. Used for detecting gray only pages */ +#include /* abs() */ + #include "std.h" #include "stdpre.h" #include "gstypes.h" @@ -28,16 +30,15 @@ #include "gxdevsop.h" #include "gdevp14.h" #include "string_.h" -#include /* abs() */ -static void gsicc_mcm_transform_general(gx_device *dev, gsicc_link_t *icclink, - void *inputcolor, void *outputcolor, - int num_bytes_in, int num_bytes_out); +static int gsicc_mcm_transform_general(gx_device *dev, gsicc_link_t *icclink, + void *inputcolor, void *outputcolor, + int num_bytes_in, int num_bytes_out); /* Functions that should be optimized later to do planar/chunky with color conversions. Just putting in something that should work right now */ -static void +static int gsicc_mcm_planar_to_planar(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, @@ -49,12 +50,13 @@ byte *in_buffer_ptr = (byte *) inputbuffer; byte *out_buffer_ptr = (byte *) outputbuffer; byte in_color[4], out_color[4]; + int code; for (k = 0; k < input_buff_desc->num_chan; k++) { inputpos[k] = in_buffer_ptr + k * input_buff_desc->plane_stride; } for (k = 0; k < output_buff_desc->num_chan; k++) { - outputpos[k] = out_buffer_ptr + k * input_buff_desc->plane_stride; + outputpos[k] = out_buffer_ptr + k * output_buff_desc->plane_stride; } /* Note to self. We currently only do this in the transparency buffer case which has byte representation so just stepping through @@ -64,29 +66,32 @@ in_color[j] = *(inputpos[j]); inputpos[j] += input_buff_desc->bytes_per_chan; } - gsicc_mcm_transform_general(dev, icclink, (void*) &(in_color[0]), - (void*) &(out_color[0]), 1, 1); + code = gsicc_mcm_transform_general(dev, icclink, + (void*) &(in_color[0]), + (void*) &(out_color[0]), 1, 1); + if (code < 0) + return code; for (j = 0; j < output_buff_desc->num_chan; j++) { *(outputpos[j]) = out_color[j]; outputpos[j] += output_buff_desc->bytes_per_chan; } } + return 0; } /* This is not really used yet */ -static void +static int gsicc_mcm_planar_to_chunky(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, void *inputbuffer, void *outputbuffer) { - - + return 0; } /* This is used with the fast thresholding code when doing -dUseFastColor and going out to a planar device */ -static void +static int gsicc_mcm_chunky_to_planar(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, @@ -103,6 +108,7 @@ int num_bytes_out = output_buff_desc->bytes_per_chan; int pixel_in_step = num_bytes_in * input_buff_desc->num_chan; int plane_stride = output_buff_desc->plane_stride; + int code; /* Do row by row. */ for (k = 0; k < input_buff_desc->num_rows ; k++) { @@ -112,9 +118,13 @@ /* split the 2 byte 1 byte case here to avoid decision in inner loop */ if (output_buff_desc->bytes_per_chan == 1) { for (j = 0; j < input_buff_desc->pixels_per_row; j++) { - gsicc_mcm_transform_general(dev, icclink, (void*) inputcolor, - (void*) &(outputcolor[0]), num_bytes_in, - num_bytes_out); + code = gsicc_mcm_transform_general(dev, icclink, + (void*) inputcolor, + (void*) &(outputcolor[0]), + num_bytes_in, + num_bytes_out); + if (code < 0) + return code; /* Stuff the output in the proper planar location */ for (m = 0; m < output_buff_desc->num_chan; m++) { *(output_loc + m * plane_stride + j) = outputcolor[m]; @@ -125,9 +135,13 @@ outputpos += output_buff_desc->row_stride; } else { for (j = 0; j < input_buff_desc->pixels_per_row; j++) { - gsicc_mcm_transform_general(dev, icclink, (void*) inputcolor, - (void*) &(outputcolor[0]), num_bytes_in, - num_bytes_out); + code = gsicc_mcm_transform_general(dev, icclink, + (void*) inputcolor, + (void*) &(outputcolor[0]), + num_bytes_in, + num_bytes_out); + if (code < 0) + return code; /* Stuff the output in the proper planar location */ pos_in_short = (unsigned short*) &(outputcolor[0]); pos_out_short = (unsigned short*) (output_loc); @@ -140,9 +154,10 @@ outputpos += output_buff_desc->row_stride; } } + return 0; } -static void +static int gsicc_mcm_chunky_to_chunky(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, @@ -156,25 +171,31 @@ int num_bytes_out = output_buff_desc->bytes_per_chan; int pixel_in_step = num_bytes_in * input_buff_desc->num_chan; int pixel_out_step = num_bytes_out * output_buff_desc->num_chan; + int code; /* Do row by row. */ for (k = 0; k < input_buff_desc->num_rows ; k++) { inputcolor = inputpos; outputcolor = outputpos; for (j = 0; j < input_buff_desc->pixels_per_row; j++) { - gsicc_mcm_transform_general(dev, icclink, (void*) inputcolor, - (void*) outputcolor, num_bytes_in, - num_bytes_out); + code = gsicc_mcm_transform_general(dev, icclink, + (void*) inputcolor, + (void*) outputcolor, + num_bytes_in, + num_bytes_out); + if (code < 0) + return code; inputcolor += pixel_in_step; outputcolor += pixel_out_step; } inputpos += input_buff_desc->row_stride; outputpos += output_buff_desc->row_stride; } + return 0; } /* Transform an entire buffer monitoring and transforming the colors */ -static void +static int gsicc_mcm_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, @@ -182,30 +203,29 @@ { if (input_buff_desc->is_planar) { if (output_buff_desc->is_planar) { - gsicc_mcm_planar_to_planar(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + return gsicc_mcm_planar_to_planar(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } else { - gsicc_mcm_planar_to_chunky(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + return gsicc_mcm_planar_to_chunky(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } } else { if (output_buff_desc->is_planar) { - gsicc_mcm_chunky_to_planar(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + return gsicc_mcm_chunky_to_planar(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } else { - gsicc_mcm_chunky_to_chunky(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + return gsicc_mcm_chunky_to_chunky(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } } - return; } /* This is where we do the monitoring and the conversion if needed */ -static void +static int gsicc_mcm_transform_general(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes_in, int num_bytes_out) @@ -218,6 +238,8 @@ int k; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; /* Monitor only if gray detection is still true */ if (dev_profile->pageneutralcolor) @@ -230,7 +252,11 @@ /* Reset all links so that they will no longer monitor. This one will finish the buffer but we will not have any additional ones */ if (!dev_profile->pageneutralcolor) - gsicc_mcm_end_monitor(icclink->icc_link_cache, dev); + { + code = gsicc_mcm_end_monitor(icclink->icc_link_cache, dev); + if (code < 0) + return code; + } /* Now apply the color transform using the original color procs, but don't do this if we had the identity. We also have to worry about 8 and 16 bit @@ -239,7 +265,6 @@ if (num_bytes_in == num_bytes_out) { /* The easy case */ memcpy(outputcolor, inputcolor, num_bytes_in * icclink->num_input); - return; } else { if (num_bytes_in == 2) { unsigned short *in_ptr = (unsigned short*) inputcolor; @@ -254,13 +279,11 @@ out_ptr[k] = gx_color_value_to_byte(in_ptr[k]); } } - return; } } else { if (num_bytes_in == num_bytes_out) { icclink->orig_procs.map_color(dev, icclink, inputcolor, outputcolor, num_bytes_in); - return; } else { icclink->orig_procs.map_color(dev, icclink, inputcolor, outputcolor_cm_ptr, num_bytes_in); @@ -277,18 +300,18 @@ out_ptr[k] = gx_color_value_to_byte(in_ptr[k]); } } - return; } } + return 0; } /* Monitor for color */ -static void +static int gsicc_mcm_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes) { - gsicc_mcm_transform_general(dev, icclink, inputcolor, outputcolor, - num_bytes, num_bytes); + return gsicc_mcm_transform_general(dev, icclink, inputcolor, outputcolor, + num_bytes, num_bytes); } bool gsicc_mcm_monitor_rgb(void *inputcolor, int num_bytes) @@ -384,7 +407,7 @@ } /* This gets rid of the monitoring */ -void +int gsicc_mcm_end_monitor(gsicc_link_cache_t *cache, gx_device *dev) { gx_monitor_t *lock = cache->lock; @@ -392,19 +415,21 @@ int code; cmm_dev_profile_t *dev_profile; - /* Lock the cache as we remove monitoring from the links */ - gx_monitor_enter(lock); /* Get the device profile */ code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; dev_profile->pageneutralcolor = false; /* If this device is a pdf14 device, then we may need to take care of the profile in the target device also. This is a special case since the pdf14 device has its own profile different from the target device */ - if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0)) { + if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0) > 0) { gs_pdf14_device_color_mon_set(dev, false); } + /* Lock the cache as we remove monitoring from the links */ + gx_monitor_enter(lock); curr = cache->head; while (curr != NULL ) { if (curr->is_monitored) { @@ -414,19 +439,17 @@ curr->is_monitored = false; } /* Now release any tasks/threads waiting for these contents */ - while (curr->num_waiting > 0) { - gx_semaphore_signal(curr->wait); - curr->num_waiting--; - } + gx_monitor_leave(curr->lock); curr = curr->next; } gx_monitor_leave(lock); /* done with updating, let everyone run */ + return 0; } /* Conversely to the above, this gets restores monitoring, needed after * monitoring was turned off above (for the next page) */ -void +int gsicc_mcm_begin_monitor(gsicc_link_cache_t *cache, gx_device *dev) { gx_monitor_t *lock = cache->lock; @@ -434,29 +457,30 @@ int code; cmm_dev_profile_t *dev_profile; - /* Lock the cache as we remove monitoring from the links */ - gx_monitor_enter(lock); - /* Get the device profile */ code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; dev_profile->pageneutralcolor = true; /* If this device is a pdf14 device, then we may need to take care of the profile in the target device also. This is a special case since the pdf14 device has its own profile different from the target device */ - if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0)) { + if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0) > 0) { gs_pdf14_device_color_mon_set(dev, true); } + /* Lock the cache as we remove monitoring from the links */ + gx_monitor_enter(lock); + curr = cache->head; while (curr != NULL ) { - if (curr->data_cs != gsGRAY) + if (curr->data_cs != gsGRAY) { gsicc_mcm_set_link(curr); - /* Now release any tasks/threads waiting for these contents */ - while (curr->num_waiting > 0) { - gx_semaphore_signal(curr->wait); - curr->num_waiting--; + /* Now release any tasks/threads waiting for these contents */ + gx_monitor_leave(curr->lock); } curr = curr->next; } gx_monitor_leave(lock); /* done with updating, let everyone run */ + return 0; } diff -Nru ghostscript-9.10~dfsg/base/gsicc_nocm.c ghostscript-9.25~dfsg+1/base/gsicc_nocm.c --- ghostscript-9.10~dfsg/base/gsicc_nocm.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_nocm.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,18 +25,16 @@ #include "scommon.h" #include "strmio.h" #include "gx.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxcspace.h" #include "gsicc_cms.h" #include "gsicc_cache.h" /* A link structure for our non-cm color transform */ typedef struct nocm_link_s { - /* device (or default) procs to do the transformation */ - gx_cm_color_map_procs cm_procs; /* Since RGB to CMYK requires BG and UCR, we need to have the - imager state available */ - gs_imager_state *pis; + gs_gstate available */ + gs_gstate *pgs; byte num_in; byte num_out; gs_memory_t *memory; @@ -69,7 +67,7 @@ inputpos[k] = in_buffer_ptr + k * input_buff_desc->plane_stride; } for (k = 0; k < output_buff_desc->num_chan; k++) { - outputpos[k] = out_buffer_ptr + k * input_buff_desc->plane_stride; + outputpos[k] = out_buffer_ptr + k * output_buff_desc->plane_stride; } /* Note to self. We currently only do this in the transparency buffer case which has byte representation so just stepping through @@ -190,7 +188,7 @@ /* Transform an entire buffer using the generic (non color managed) transformations */ -static void +static int gsicc_nocm_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, @@ -221,7 +219,7 @@ outputbuffer); } } - return; + return 0; } /* Shared function between the single and buffer conversions */ @@ -252,20 +250,21 @@ frac_in[k] = byte2frac(data[k]); } } - /* Use the device procedure */ + /* Use the device procedures to do the mapping */ switch (num_in) { case 1: - (link->cm_procs.map_gray)(dev, frac_in[0], frac_out); + dev_proc(dev, get_color_mapping_procs)(dev)->map_gray(dev, frac_in[0], frac_out); break; case 3: - (link->cm_procs.map_rgb)(dev, link->pis, frac_in[0], frac_in[1], - frac_in[2], frac_out); + dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, link->pgs, frac_in[0], frac_in[1], + frac_in[2], frac_out); break; case 4: - (link->cm_procs.map_cmyk)(dev, frac_in[0], frac_in[1], frac_in[2], - frac_in[3], frac_out); + dev_proc(dev, get_color_mapping_procs)(dev)->map_cmyk(dev, frac_in[0], frac_in[1], + frac_in[2], frac_in[3], frac_out); break; default: + memset(&(frac_out[0]), 0, sizeof(frac_out)); break; } if (num_bytes_out == 2) { @@ -284,13 +283,14 @@ /* Transform a single color using the generic (non color managed) transformations */ -static void +static int gsicc_nocm_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes) { gsicc_nocm_transform_general(dev, icclink, inputcolor, outputcolor, num_bytes, num_bytes); + return 0; } static void @@ -298,18 +298,21 @@ { nocm_link_t *nocm_link = (nocm_link_t*) icclink->link_handle; - if (nocm_link->pis != NULL) { - if (nocm_link->pis->black_generation != NULL) { - gs_free_object(nocm_link->memory, nocm_link->pis->black_generation, - "gsicc_nocm_freelink"); - } - if (nocm_link->pis->undercolor_removal != NULL) { - gs_free_object(nocm_link->memory, nocm_link->pis->undercolor_removal, - "gsicc_nocm_freelink"); + if (nocm_link) { + if (nocm_link->pgs != NULL) { + if (nocm_link->pgs->black_generation != NULL) { + gs_free_object(nocm_link->memory, nocm_link->pgs->black_generation, + "gsicc_nocm_freelink"); + } + if (nocm_link->pgs->undercolor_removal != NULL) { + gs_free_object(nocm_link->memory, nocm_link->pgs->undercolor_removal, + "gsicc_nocm_freelink"); + } + gs_free_object(nocm_link->memory, nocm_link->pgs, "gsicc_nocm_freelink"); } - gs_free_object(nocm_link->memory, nocm_link->pis, "gsicc_nocm_freelink"); + gs_free_object(nocm_link->memory, nocm_link, "gsicc_nocm_freelink"); + icclink->link_handle = NULL; } - gs_free_object(nocm_link->memory, nocm_link, "gsicc_nocm_freelink"); } /* Since this is the only occurence of this object we are not going to @@ -325,10 +328,13 @@ } else { out_map = (gx_transfer_map*) gs_alloc_bytes(mem, sizeof(gx_transfer_map), "gsicc_nocm_copy_curve"); - out_map->proc = in_map->proc; - memcpy(&(out_map->values[0]), &(in_map->values[0]), - sizeof(frac) * transfer_map_size); - out_map->id = gs_no_id; + if (out_map) { + memset(out_map, 0, sizeof(gx_transfer_map)); + out_map->proc = in_map->proc; + memcpy(&(out_map->values[0]), &(in_map->values[0]), + sizeof(frac) * transfer_map_size); + out_map->id = gs_no_id; + } return out_map; } } @@ -336,34 +342,29 @@ /* Get the link, which is the mapping procedure in this non color managed transformation case. */ gsicc_link_t* -gsicc_nocm_get_link(const gs_imager_state *pis, gx_device *dev, +gsicc_nocm_get_link(const gs_gstate *pgs, gx_device *dev, gs_color_space_index src_index) { gsicc_link_t *result; gsicc_hashlink_t hash; nocm_link_t *nocm_link; - gs_memory_t *mem = pis->memory->non_gc_memory; - const gx_cm_color_map_procs * cm_procs; + gs_memory_t *mem = pgs->icc_link_cache->memory->non_gc_memory; bool pageneutralcolor = false; cmm_dev_profile_t *dev_profile; int code; gsicc_colorbuffer_t data_cs = gsRGB; + if (dev == NULL) + return NULL; + /* Need to check if we need to monitor for color */ - if (dev != NULL ) { - code = dev_proc(dev, get_profile)(dev, &dev_profile); - if (dev_profile != NULL) { - pageneutralcolor = dev_profile->pageneutralcolor; - } - } - - /* If the cm_procs are forwarding due to the overprint device or other - odd thing, drill down now and get the proper ones */ - if (fwd_uses_fwd_cmap_procs(dev)) { - cm_procs = fwd_get_target_cmap_procs(dev); - } else { - cm_procs = dev_proc(dev, get_color_mapping_procs)(dev); + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return NULL; + if (dev_profile != NULL) { + pageneutralcolor = dev_profile->pageneutralcolor; } + /* We will add this to the link cache so that we can avoid the issue of black_generation and undercolor removal being GC values. Since the link is not GC we would need to copy the contents over @@ -375,21 +376,20 @@ hash.link_hashcode = src_index + hash.des_hash * 256 + hash.rend_hash * 4096; /* Check the cache for a hit. */ - result = gsicc_findcachelink(hash, pis->icc_link_cache, false, false); + result = gsicc_findcachelink(hash, pgs->icc_link_cache, false, false); if (result != NULL) { return result; } /* If not, then lets create a new one. This may actually return a link if another thread has already created it while we were trying to do so */ - if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) + if (gsicc_alloc_link_entry(pgs->icc_link_cache, &result, hash, false, false)) return result; if (result == NULL) return NULL; /* Now compute the link contents */ - /* Lock the cache as we alter the procs */ - gx_monitor_enter(pis->icc_link_cache->lock); + /* We (this thread) owns the lock on the new link just created. */ result->procs.map_buffer = gsicc_nocm_transform_color_buffer; result->procs.map_color = gsicc_nocm_transform_color; @@ -397,27 +397,29 @@ result->hashcode = hash; nocm_link = (nocm_link_t *) gs_alloc_bytes(mem, sizeof(nocm_link_t), "gsicc_nocm_get_link"); + if (nocm_link == NULL) + return NULL; result->link_handle = (void*) nocm_link; nocm_link->memory = mem; - /* Create a dummy imager state and populate the ucr/bg values. This + /* Create a dummy gs_gstate and populate the ucr/bg values. This is the only part that we need */ - if (pis == NULL || - (pis->black_generation == NULL && pis->undercolor_removal == NULL)) { - nocm_link->pis = NULL; + if ((pgs->black_generation == NULL && pgs->undercolor_removal == NULL)) { + nocm_link->pgs = NULL; } else { - nocm_link->pis = (gs_imager_state*) - gs_alloc_bytes(mem, sizeof(gs_imager_state), + nocm_link->pgs = (gs_gstate*) + gs_alloc_bytes(mem, sizeof(gs_gstate), "gsicc_nocm_get_link"); - nocm_link->pis->black_generation = (gx_transfer_map*) - gsicc_nocm_copy_curve(pis->black_generation, mem); - nocm_link->pis->undercolor_removal = (gx_transfer_map*) - gsicc_nocm_copy_curve(pis->undercolor_removal, mem); + if (nocm_link->pgs == NULL) + return NULL; + memset(nocm_link->pgs, 0, sizeof(gs_gstate)); + /* Note if allocation of either of the maps fails, just use NULL */ + nocm_link->pgs->black_generation = (gx_transfer_map*) + gsicc_nocm_copy_curve(pgs->black_generation, mem); + nocm_link->pgs->undercolor_removal = (gx_transfer_map*) + gsicc_nocm_copy_curve(pgs->undercolor_removal, mem); } nocm_link->num_out = min(dev->color_info.num_components, GS_CLIENT_COLOR_MAX_COMPONENTS); - nocm_link->cm_procs.map_cmyk = cm_procs->map_cmyk; - nocm_link->cm_procs.map_rgb = cm_procs->map_rgb; - nocm_link->cm_procs.map_gray = cm_procs->map_gray; nocm_link->num_in = src_index; result->num_input = nocm_link->num_in; @@ -434,7 +436,6 @@ } else { result->is_identity = false; } - result->valid = true; if (nocm_link->num_in == 4) data_cs = gsCMYK; else if (nocm_link->num_in == 1) @@ -445,13 +446,9 @@ if (pageneutralcolor && nocm_link->num_in != 1) { gsicc_mcm_set_link(result); } - - /* Now release any tasks/threads waiting for these contents */ - while (result->num_waiting > 0) { - gx_semaphore_signal(result->wait); - result->num_waiting--; - } - gx_monitor_leave(pis->icc_link_cache->lock); /* done with updating, let everyone run */ + result->valid = true; + /* Now release any tasks/threads waiting for these contents by unlocking */ + gx_monitor_leave(result->lock); /* done with updating, let everyone run */ return result; } diff -Nru ghostscript-9.10~dfsg/base/gsicc_profilecache.c ghostscript-9.25~dfsg+1/base/gsicc_profilecache.c --- ghostscript-9.10~dfsg/base/gsicc_profilecache.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_profilecache.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* A cache for icc colorspaces that were created from PS CIE color @@ -89,7 +89,7 @@ } void -gsicc_add_cs(gs_state * pgs, gs_color_space * colorspace, ulong dictkey) +gsicc_add_cs(gs_gstate * pgs, gs_color_space * colorspace, ulong dictkey) { gsicc_profile_entry_t *result; gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache; @@ -99,6 +99,9 @@ to be maintained across the gsave and grestore process */ result = gs_alloc_struct(memory->stable_memory, gsicc_profile_entry_t, &st_profile_entry, "gsicc_add_cs"); + if (result == NULL) + return; /* FIXME */ + /* If needed, remove an entry (the last one) */ if (profile_cache->num_entries >= ICC_CACHE_MAXPROFILE) { gsicc_remove_cs_entry(profile_cache); @@ -114,7 +117,7 @@ } gs_color_space* -gsicc_find_cs(ulong key_test, gs_state * pgs) +gsicc_find_cs(ulong key_test, gs_gstate * pgs) { gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache; gsicc_profile_entry_t *prev = NULL, *curr = profile_cache->head; diff -Nru ghostscript-9.10~dfsg/base/gsicc_profilecache.h ghostscript-9.25~dfsg+1/base/gsicc_profilecache.h --- ghostscript-9.10~dfsg/base/gsicc_profilecache.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_profilecache.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,7 +21,7 @@ # define gsicc_profilecache_INCLUDED gsicc_profile_cache_t* gsicc_profilecache_new(gs_memory_t *memory); -gs_color_space* gsicc_find_cs(ulong key_test, gs_state * pgs); -void gsicc_add_cs(gs_state * pgs, gs_color_space * pcs, ulong dictkey); +gs_color_space* gsicc_find_cs(ulong key_test, gs_gstate * pgs); +void gsicc_add_cs(gs_gstate * pgs, gs_color_space * pcs, ulong dictkey); #endif diff -Nru ghostscript-9.10~dfsg/base/gsicc_replacecm.c ghostscript-9.25~dfsg+1/base/gsicc_replacecm.c --- ghostscript-9.10~dfsg/base/gsicc_replacecm.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsicc_replacecm.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,7 @@ #include "scommon.h" #include "strmio.h" #include "gx.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxcspace.h" #include "gsicc_cms.h" #include "gsicc_cache.h" @@ -40,12 +40,12 @@ void *context; /* For a table and or a set of procs */ } rcm_link_t; -static void gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, - void *inputcolor, void *outputcolor, +static void gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, + void *inputcolor, void *outputcolor, int num_bytes_in, int num_bytes_out); -/* Functions that should be optimized later to do planar/chunky with - color conversions. Just putting in something that should work +/* Functions that should be optimized later to do planar/chunky with + color conversions. Just putting in something that should work right now */ static void gsicc_rcm_planar_to_planar(gx_device *dev, gsicc_link_t *icclink, @@ -64,17 +64,17 @@ inputpos[k] = in_buffer_ptr + k * input_buff_desc->plane_stride; } for (k = 0; k < output_buff_desc->num_chan; k++) { - outputpos[k] = out_buffer_ptr + k * input_buff_desc->plane_stride; + outputpos[k] = out_buffer_ptr + k * output_buff_desc->plane_stride; } /* Note to self. We currently only do this in the transparency buffer - case which has byte representation so just stepping through + case which has byte representation so just stepping through plane_stride is ok at this time. */ for (k = 0; k < input_buff_desc->plane_stride ; k++) { for (j = 0; j < input_buff_desc->num_chan; j++) { in_color[j] = *(inputpos[j]); inputpos[j] += input_buff_desc->bytes_per_chan; } - gsicc_rcm_transform_general(dev, icclink, (void*) &(in_color[0]), + gsicc_rcm_transform_general(dev, icclink, (void*) &(in_color[0]), (void*) &(out_color[0]), 1, 1); for (j = 0; j < output_buff_desc->num_chan; j++) { *(outputpos[j]) = out_color[j]; @@ -122,8 +122,8 @@ /* split the 2 byte 1 byte case here to avoid decision in inner loop */ if (output_buff_desc->bytes_per_chan == 1) { for (j = 0; j < input_buff_desc->pixels_per_row; j++) { - gsicc_rcm_transform_general(dev, icclink, (void*) inputcolor, - (void*) &(outputcolor[0]), num_bytes_in, + gsicc_rcm_transform_general(dev, icclink, (void*) inputcolor, + (void*) &(outputcolor[0]), num_bytes_in, num_bytes_out); /* Stuff the output in the proper planar location */ for (m = 0; m < output_buff_desc->num_chan; m++) { @@ -132,11 +132,11 @@ inputcolor += pixel_in_step; } inputpos += input_buff_desc->row_stride; - outputpos += output_buff_desc->row_stride; + outputpos += output_buff_desc->row_stride; } else { for (j = 0; j < input_buff_desc->pixels_per_row; j++) { - gsicc_rcm_transform_general(dev, icclink, (void*) inputcolor, - (void*) &(outputcolor[0]), num_bytes_in, + gsicc_rcm_transform_general(dev, icclink, (void*) inputcolor, + (void*) &(outputcolor[0]), num_bytes_in, num_bytes_out); /* Stuff the output in the proper planar location */ pos_in_short = (unsigned short*) &(outputcolor[0]); @@ -172,8 +172,8 @@ inputcolor = inputpos; outputcolor = outputpos; for (j = 0; j < input_buff_desc->pixels_per_row; j++) { - gsicc_rcm_transform_general(dev, icclink, (void*) inputcolor, - (void*) outputcolor, num_bytes_in, + gsicc_rcm_transform_general(dev, icclink, (void*) inputcolor, + (void*) outputcolor, num_bytes_in, num_bytes_out); inputcolor += pixel_in_step; outputcolor += pixel_out_step; @@ -184,7 +184,7 @@ } /* Transform an entire buffer using replacement method */ -static void +static int gsicc_rcm_transform_color_buffer(gx_device *dev, gsicc_link_t *icclink, gsicc_bufferdesc_t *input_buff_desc, gsicc_bufferdesc_t *output_buff_desc, @@ -193,38 +193,38 @@ /* Since we have to do the mappings to and from frac colors we will for now just call the gsicc_rcm_transform_color as we step through the buffers. This process can be significantly sped up */ - + if (input_buff_desc->is_planar) { if (output_buff_desc->is_planar) { - gsicc_rcm_planar_to_planar(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + gsicc_rcm_planar_to_planar(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } else { - gsicc_rcm_planar_to_chunky(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + gsicc_rcm_planar_to_chunky(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } } else { if (output_buff_desc->is_planar) { - gsicc_rcm_chunky_to_planar(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + gsicc_rcm_chunky_to_planar(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } else { - gsicc_rcm_chunky_to_chunky(dev, icclink, input_buff_desc, - output_buff_desc, inputbuffer, - outputbuffer); + gsicc_rcm_chunky_to_chunky(dev, icclink, input_buff_desc, + output_buff_desc, inputbuffer, + outputbuffer); } } - return; + return 0; } /* Shared function between the single and buffer conversions. This is where - we do the actual replacement. For now, we make the replacement a + we do the actual replacement. For now, we make the replacement a negative to show the effect of what using color replacement. We also use the device procs to map to the device value. */ static void -gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, - void *inputcolor, void *outputcolor, +gsicc_rcm_transform_general(gx_device *dev, gsicc_link_t *icclink, + void *inputcolor, void *outputcolor, int num_bytes_in, int num_bytes_out) { /* Input data is either single byte or 2 byte color values. */ @@ -234,6 +234,7 @@ frac frac_in[4]; frac frac_out[GX_DEVICE_COLOR_MAX_COMPONENTS]; int k; + gx_device *parentmost_dev = subclass_parentmost_device(dev); /* Make the negative for the demo.... */ if (num_bytes_in == 2) { @@ -250,25 +251,26 @@ /* Use the device procedure */ switch (num_in) { case 1: - (link->cm_procs.map_gray)(dev, frac_in[0], frac_out); + (link->cm_procs.map_gray)(parentmost_dev, frac_in[0], frac_out); break; case 3: - (link->cm_procs.map_rgb)(dev, NULL, frac_in[0], frac_in[1], + (link->cm_procs.map_rgb)(parentmost_dev, NULL, frac_in[0], frac_in[1], frac_in[2], frac_out); break; case 4: - (link->cm_procs.map_cmyk)(dev, frac_in[0], frac_in[1], frac_in[2], - frac_in[3], frac_out); + (link->cm_procs.map_cmyk)(parentmost_dev, frac_in[0], frac_in[1], frac_in[2], + frac_in[3], frac_out); break; default: + memset(&(frac_out[0]), 0, sizeof(frac_out)); break; - } + } if (num_bytes_out == 2) { unsigned short *data = (unsigned short *) outputcolor; for (k = 0; k < num_out; k++) { data[k] = frac2ushort(frac_out[k]); } - } else { + } else { byte *data = (byte *) outputcolor; for (k = 0; k < num_out; k++) { data[k] = frac2byte(frac_out[k]); @@ -277,14 +279,15 @@ return; } -/* Transform a single color using the generic (non color managed) +/* Transform a single color using the generic (non color managed) transformations */ -static void +static int gsicc_rcm_transform_color(gx_device *dev, gsicc_link_t *icclink, void *inputcolor, void *outputcolor, int num_bytes) { - gsicc_rcm_transform_general(dev, icclink, inputcolor, outputcolor, + gsicc_rcm_transform_general(dev, icclink, inputcolor, outputcolor, num_bytes, num_bytes); + return 0; } static void @@ -295,35 +298,42 @@ } /* Get the replacement color management link. It basically needs to store - the number of components for the source so that we know what we are + the number of components for the source so that we know what we are coming from (e.g. RGB, CMYK, Gray) */ gsicc_link_t* -gsicc_rcm_get_link(const gs_imager_state *pis, gx_device *dev, +gsicc_rcm_get_link(const gs_gstate *pgs, gx_device *dev, gsicc_colorbuffer_t data_cs) { gsicc_link_t *result; gsicc_hashlink_t hash; rcm_link_t *rcm_link; - gs_memory_t *mem = dev->memory->non_gc_memory; + gs_memory_t *mem; const gx_cm_color_map_procs * cm_procs; bool pageneutralcolor = false; cmm_dev_profile_t *dev_profile; int code; + subclass_color_mappings scm; + if (dev == NULL) + return NULL; + + mem = dev->memory->non_gc_memory; /* Need to check if we need to monitor for color */ - if (dev != NULL ) { - code = dev_proc(dev, get_profile)(dev, &dev_profile); - if (dev_profile != NULL) { - pageneutralcolor = dev_profile->pageneutralcolor; - } - } + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return NULL; + if (dev_profile != NULL) { + pageneutralcolor = dev_profile->pageneutralcolor; + } + /* FIXME: What if we have a subclassed forwarding device? */ /* If the cm_procs are forwarding due to the overprint device or other odd thing, drill down now and get the proper ones */ if (fwd_uses_fwd_cmap_procs(dev)) { cm_procs = fwd_get_target_cmap_procs(dev); } else { - cm_procs = dev_proc(dev, get_color_mapping_procs)(dev); + scm = get_color_mapping_procs_subclass(dev); + cm_procs = scm.procs; } hash.rend_hash = gsCMM_REPLACE; @@ -332,22 +342,20 @@ hash.link_hashcode = data_cs + hash.des_hash * 256 + hash.rend_hash * 4096; /* Check the cache for a hit. */ - result = gsicc_findcachelink(hash, pis->icc_link_cache, false, false); + result = gsicc_findcachelink(hash, pgs->icc_link_cache, false, false); if (result != NULL) { return result; } - /* If not, then lets create a new one. This may actually return a link if - another thread has already created it while we were trying to do so */ - if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) + /* If not, then lets create a new one. This may actually return a link if + another thread has already created it while we were trying to do so */ + if (gsicc_alloc_link_entry(pgs->icc_link_cache, &result, hash, false, false)) return result; if (result == NULL) return result; /* Now compute the link contents */ - /* Lock the cache as we alter the procs */ - gx_monitor_enter(pis->icc_link_cache->lock); - + /* We (this thread) owns this link, so we can update it */ result->procs.map_buffer = gsicc_rcm_transform_color_buffer; result->procs.map_color = gsicc_rcm_transform_color; result->procs.free_link = gsicc_rcm_freelink; @@ -355,9 +363,11 @@ result->is_identity = false; rcm_link = (rcm_link_t *) gs_alloc_bytes(mem, sizeof(rcm_link_t), "gsicc_rcm_get_link"); + if (rcm_link == NULL) + return NULL; result->link_handle = (void*) rcm_link; rcm_link->memory = mem; - rcm_link->num_out = min(dev->color_info.num_components, + rcm_link->num_out = min(dev->color_info.num_components, GS_CLIENT_COLOR_MAX_COMPONENTS); rcm_link->data_cs_in = data_cs; rcm_link->cm_procs.map_cmyk = cm_procs->map_cmyk; @@ -379,8 +389,8 @@ result->procs.free_link(result); return NULL; } - /* Likely set if we have something like a table or procs */ - rcm_link->context = NULL; + /* Likely set if we have something like a table or procs */ + rcm_link->context = NULL; result->num_input = rcm_link->num_in; result->num_output = rcm_link->num_out; @@ -396,18 +406,14 @@ } else { result->is_identity = false; } - result->valid = true; /* Set up for monitoring non gray color spaces */ if (pageneutralcolor && data_cs != gsGRAY) gsicc_mcm_set_link(result); - /* Now release any tasks/threads waiting for these contents */ - while (result->num_waiting > 0) { - gx_semaphore_signal(result->wait); - result->num_waiting--; - } - gx_monitor_leave(pis->icc_link_cache->lock); /* done with updating, let everyone run */ + result->valid = true; + /* Now release any tasks/threads waiting for these contents by unlocking it */ + gx_monitor_leave(result->lock); /* done with updating, let everyone run */ return result; } diff -Nru ghostscript-9.10~dfsg/base/gsimage.c ghostscript-9.25~dfsg+1/base/gsimage.c --- ghostscript-9.10~dfsg/base/gsimage.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsimage.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,8 +30,8 @@ #include "gximask.h" #include "gzstate.h" #include "gsutil.h" -#include "vdtrace.h" #include "gxdevsop.h" +#include "gximage.h" /* The main internal invariant for the gs_image machinery is @@ -152,7 +152,7 @@ RELOC_PTRS_END static int -is_image_visible(const gs_image_common_t * pic, gs_state * pgs, gx_clip_path *pcpath) +is_image_visible(const gs_image_common_t * pic, gs_gstate * pgs, gx_clip_path *pcpath) { /* HACK : We need the source image size here, but gs_image_common_t doesn't pass it. @@ -201,8 +201,8 @@ /* Create an image enumerator given image parameters and a graphics state. */ int -gs_image_begin_typed(const gs_image_common_t * pic, gs_state * pgs, - bool uses_color, gx_image_enum_common_t ** ppie) +gs_image_begin_typed(const gs_image_common_t * pic, gs_gstate * pgs, + bool uses_color, bool image_is_text, gx_image_enum_common_t ** ppie) { gx_device *dev = gs_currentdevice(pgs); gx_clip_path *pcpath; @@ -212,36 +212,50 @@ if (code < 0) return code; - /* Processing an image object operation */ - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_IMAGE_TAG); + /* Processing an image object operation, but this may be for a text object */ + ensure_tag_is_set(pgs, pgs->device, image_is_text ? GS_TEXT_TAG : GS_IMAGE_TAG); /* NB: may unset_dev_color */ if (uses_color) { code = gx_set_dev_color(pgs); if (code != 0) return code; - code = gs_state_color_load(pgs); + code = gs_gstate_color_load(pgs); if (code < 0) return code; } /* Imagemask with shading color needs a special optimization with converting the image into a clipping. - Check for such case after gs_state_color_load is done, + Check for such case after gs_gstate_color_load is done, because it can cause interpreter callout. */ if (pic->type->begin_typed_image == &gx_begin_image1) { gs_image_t *image = (gs_image_t *)pic; if(image->ImageMask) { - code = gx_image_fill_masked_start(dev, gs_currentdevicecolor_inline(pgs), pcpath, pgs->memory, &dev2); + bool transpose = false; + gs_matrix_double mat; + + if((code = gx_image_compute_mat(pgs, NULL, &(image->ImageMatrix), &mat)) < 0) + return code; + if ((any_abs(mat.xy) > any_abs(mat.xx)) && (any_abs(mat.yx) > any_abs(mat.yy))) + transpose = true; /* pure landscape */ + code = gx_image_fill_masked_start(dev, gs_currentdevicecolor_inline(pgs), transpose, + pcpath, pgs->memory, pgs->log_op, &dev2); if (code < 0) return code; } + if (dev->interpolate_control < 0) { /* Force interpolation before begin_typed_image */ + ((gs_data_image_t *)pic)->Interpolate = true; + } + else if (dev->interpolate_control == 0) { + ((gs_data_image_t *)pic)->Interpolate = false; /* Suppress interpolation */ + } if (dev2 != dev) { set_nonclient_dev_color(&dc_temp, 1); pdevc = &dc_temp; } } - code = gx_device_begin_typed_image(dev2, (const gs_imager_state *)pgs, + code = gx_device_begin_typed_image(dev2, (const gs_gstate *)pgs, NULL, pic, NULL, pdevc, pcpath, pgs->memory, ppie); if (code < 0) return code; @@ -279,7 +293,7 @@ /* Start processing an ImageType 1 image. */ int gs_image_init(gs_image_enum * penum, const gs_image_t * pim, bool multi, - gs_state * pgs) + bool image_is_text, gs_gstate * pgs) { gs_image_t image; gx_image_enum_common_t *pie; @@ -299,11 +313,13 @@ * incorrect, but it appears this case doesn't arise. */ image.ColorSpace = gs_cspace_new_DeviceGray(pgs->memory); + if (image.ColorSpace == NULL) + return_error(gs_error_VMerror); } } code = gs_image_begin_typed((const gs_image_common_t *)&image, pgs, image.ImageMask | image.CombineWithColor, - &pie); + image_is_text, &pie); if (code < 0) return code; return gs_image_enum_init(penum, pie, (const gs_data_image_t *)&image, @@ -411,7 +427,7 @@ */ int gs_image_enum_init(gs_image_enum * penum, gx_image_enum_common_t * pie, - const gs_data_image_t * pim, gs_state *pgs) + const gs_data_image_t * pim, gs_gstate *pgs) { pgs->device->sgr.stroke_stored = false; return gs_image_common_init(penum, pie, pim, @@ -500,10 +516,6 @@ int code = 0; #ifdef DEBUG - vd_get_dc('i'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); if (gs_debug_c('b')) { int pi; @@ -582,8 +594,12 @@ penum->image_planes[i].data = penum->planes[i].row.data; } else if (pos == 0 && size >= raster) { /* We can transfer 1 or more planes from the source. */ - h = min(h, size / raster); - penum->image_planes[i].data = penum->planes[i].source.data; + if (raster) { + h = min(h, size / raster); + penum->image_planes[i].data = penum->planes[i].source.data; + } + else + h = 0; } else h = 0; /* not enough data in this plane */ } @@ -634,14 +650,13 @@ /* Return the retained data pointers. */ for (i = 0; i < num_planes; ++i) plane_data[i] = penum->planes[i].source; - vd_release_dc; return code; } /* Clean up after processing an image. */ /* Public for ghostpcl. */ int -gs_image_cleanup(gs_image_enum * penum, gs_state *pgs) +gs_image_cleanup(gs_image_enum * penum, gs_gstate *pgs) { int code = 0, code1; @@ -666,7 +681,7 @@ /* Clean up after processing an image and free the enumerator. */ int -gs_image_cleanup_and_free_enum(gs_image_enum * penum, gs_state *pgs) +gs_image_cleanup_and_free_enum(gs_image_enum * penum, gs_gstate *pgs) { int code = gs_image_cleanup(penum, pgs); diff -Nru ghostscript-9.10~dfsg/base/gsimage.h ghostscript-9.25~dfsg+1/base/gsimage.h --- ghostscript-9.10~dfsg/base/gsimage.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsimage.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -119,8 +119,9 @@ #endif typedef struct gs_image_enum_s gs_image_enum; -int gs_image_begin_typed(const gs_image_common_t * pic, gs_state * pgs, - bool uses_color, gx_image_enum_common_t ** ppie); +int gs_image_begin_typed(const gs_image_common_t * pic, gs_gstate * pgs, + bool uses_color, bool image_is_text, + gx_image_enum_common_t ** ppie); gs_image_enum *gs_image_enum_alloc(gs_memory_t *, client_name_t); @@ -145,14 +146,14 @@ /* Initialize an enumerator for an ImageType 1 image. */ int gs_image_init(gs_image_enum * penum, const gs_image_t * pim, - bool MultipleDataSources, gs_state * pgs); + bool MultipleDataSources, bool image_is_text, gs_gstate * pgs); /* Initialize an enumerator for a general image. penum->memory must be initialized in advance. */ int gs_image_enum_init(gs_image_enum * penum, gx_image_enum_common_t * pie, - const gs_data_image_t * pim, gs_state *pgs); + const gs_data_image_t * pim, gs_gstate *pgs); /* * Return the number of bytes of data per row @@ -196,9 +197,9 @@ uint dsize, uint * pused); /* Clean up after processing an image. */ -int gs_image_cleanup(gs_image_enum * penum, gs_state *pgs); +int gs_image_cleanup(gs_image_enum * penum, gs_gstate *pgs); /* Clean up after processing an image and free the enumerator. */ -int gs_image_cleanup_and_free_enum(gs_image_enum * penum, gs_state *pgs); +int gs_image_cleanup_and_free_enum(gs_image_enum * penum, gs_gstate *pgs); #endif /* gsimage_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsimpath.c ghostscript-9.25~dfsg+1/base/gsimpath.c --- ghostscript-9.10~dfsg/base/gsimpath.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsimpath.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,7 @@ /* Define the state of the conversion process. */ typedef struct { /* The following are set at the beginning of the conversion. */ - gs_state *pgs; + gs_gstate *pgs; const byte *data; /* image data */ int width, height, raster; /* The following are updated dynamically. */ @@ -48,7 +48,7 @@ if ( (code = add_dxdy(s, dx, dy, n)) < 0 ) return code /* Append an outline derived from an image to the current path. */ int -gs_imagepath(gs_state * pgs, int width, int height, const byte * data) +gs_imagepath(gs_gstate * pgs, int width, int height, const byte * data) { status stat; status *out = &stat; diff -Nru ghostscript-9.10~dfsg/base/gsinit.c ghostscript-9.25~dfsg+1/base/gsinit.c --- ghostscript-9.10~dfsg/base/gsinit.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsinit.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsiodev.c ghostscript-9.25~dfsg+1/base/gsiodev.c --- ghostscript-9.10~dfsg/base/gsiodev.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiodev.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -48,7 +48,7 @@ const gx_io_device gs_iodev_os = { "%os%", "FileSystem", - {iodev_no_init, iodev_no_open_device, + {iodev_no_init, iodev_no_finit, iodev_no_open_device, NULL /*iodev_os_open_file */ , iodev_os_gp_fopen, iodev_os_fclose, os_delete, os_rename, os_status, os_enumerate, gp_enumerate_files_next, gp_enumerate_files_close, @@ -58,12 +58,11 @@ /* ------ Initialization ------ */ -init_proc(gs_iodev_init); /* check prototype */ int gs_iodev_init(gs_memory_t * mem) { /* Make writable copies of all IODevices. */ gx_io_device **table = - gs_alloc_struct_array(mem, gx_io_device_table_count, + gs_alloc_struct_array_immovable(mem, gx_io_device_table_count + NUM_RUNTIME_IODEVS, gx_io_device *, &st_io_device_ptr_element, "gs_iodev_init(table)"); gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem); @@ -73,18 +72,26 @@ if ((table == NULL) || (libctx == NULL)) return_error(gs_error_VMerror); + libctx->io_device_table_size = gx_io_device_table_count + NUM_RUNTIME_IODEVS; + libctx->io_device_table_count = 0; + libctx->io_device_table = table; + for (i = 0; i < gx_io_device_table_count; ++i) { gx_io_device *iodev = - gs_alloc_struct(mem, gx_io_device, &st_io_device, + gs_alloc_struct_immovable(mem, gx_io_device, &st_io_device, "gs_iodev_init(iodev)"); if (iodev == 0) goto fail; table[i] = iodev; memcpy(table[i], gx_io_device_table[i], sizeof(gx_io_device)); + libctx->io_device_table_count++; } - libctx->io_device_table = table; - code = gs_register_struct_root(mem, NULL, + for (;i < gx_io_device_table_count + NUM_RUNTIME_IODEVS; i++) { + table[i] = NULL; + } + + code = gs_register_struct_root(mem, mem->gs_lib_ctx->io_device_table_root, (void **)&libctx->io_device_table, "io_device_table"); if (code < 0) @@ -98,21 +105,97 @@ /****** CAN'T FIND THE ROOT ******/ /*gs_unregister_root(mem, root, "io_device_table");*/ fail: - for (; i > 0; --i) + return (code < 0 ? code : gs_note_error(gs_error_VMerror)); +} + +void +gs_iodev_finit(gs_memory_t * mem) +{ + gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem); + if (libctx && libctx->io_device_table) { + gs_free_object(mem, libctx->io_device_table, "gs_iodev_finit"); + libctx->io_device_table = NULL; + } + return; +} + +/* + * Register io devices *after* lib initialisation +*/ +int +gs_iodev_register_dev(gs_memory_t * mem, const gx_io_device *newiodev) +{ + gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem); + gx_io_device **table = libctx->io_device_table; + int code = 0; + gx_io_device *iodev; + int i; + + if (libctx->io_device_table_count >= libctx->io_device_table_size) { + /* FIXME: table size should be dynamic - deregistering the root node is a problem */ + return_error(gs_error_limitcheck); + } + + iodev = gs_alloc_struct(mem, gx_io_device, &st_io_device, + "gs_iodev_register_dev(iodev)"); + + if (iodev == 0) { + code = gs_note_error(gs_error_VMerror); + goto fail; + } + table[libctx->io_device_table_count] = iodev; + memcpy(table[libctx->io_device_table_count], newiodev, sizeof(gx_io_device)); + + if ((code = (table[libctx->io_device_table_count]->procs.init)(table[libctx->io_device_table_count], mem)) < 0) + goto fail2; + libctx->io_device_table_count++; + + return(code); + fail2: + for (i = libctx->io_device_table_count; i > 0; --i) gs_free_object(mem, table[i - 1], "gs_iodev_init(iodev)"); gs_free_object(mem, table, "gs_iodev_init(table)"); libctx->io_device_table = NULL; - return (code < 0 ? code : gs_note_error(gs_error_VMerror)); + + fail: + return(code); } static void gs_iodev_finalize(const gs_memory_t *cmem, void *vptr) { - if (cmem->gs_lib_ctx->io_device_table == vptr) { - cmem->gs_lib_ctx->io_device_table = NULL; + /* discard const for gs_free_object */ + gs_memory_t *mem = (gs_memory_t *)cmem; + if (mem->gs_lib_ctx->io_device_table == vptr) { + gx_io_device **table = mem->gs_lib_ctx->io_device_table; + while (mem->gs_lib_ctx->io_device_table_count-- > 0) { + gs_free_object(mem, + table[mem->gs_lib_ctx->io_device_table_count], + "gs_iodev_finalize"); + table[mem->gs_lib_ctx->io_device_table_count] = NULL; + } + mem->gs_lib_ctx->io_device_table = NULL; + mem->gs_lib_ctx->io_device_table_size = + mem->gs_lib_ctx->io_device_table_count = 0; } } +void +io_device_finalize(const gs_memory_t *cmem, void *vptr) +{ + /* discard const for gs_free_object */ + gs_memory_t *mem = (gs_memory_t *)cmem; + if (mem->gs_lib_ctx->io_device_table_count > 0) { + int i; + for (i = 0; i < mem->gs_lib_ctx->io_device_table_count + && mem->gs_lib_ctx->io_device_table[i] != vptr; i++) + ; + + (mem->gs_lib_ctx->io_device_table[i]->procs.finit)(mem->gs_lib_ctx->io_device_table[i], mem); + mem->gs_lib_ctx->io_device_table[i] = NULL; + } + return; +} /* ------ Default (unimplemented) IODevice procedures ------ */ @@ -122,6 +205,12 @@ return 0; } +void +iodev_no_finit(gx_io_device * iodev, gs_memory_t * mem) +{ + return; +} + int iodev_no_open_device(gx_io_device * iodev, const char *access, stream ** ps, gs_memory_t * mem) @@ -226,7 +315,7 @@ os_status(gx_io_device * iodev, const char *fname, struct stat *pstat) { /* The RS/6000 prototype for stat doesn't include const, */ /* so we have to explicitly remove the const modifier. */ - return (stat((char *)fname, pstat) < 0 ? gs_error_undefinedfilename : 0); + return (gp_stat((char *)fname, pstat) < 0 ? gs_error_undefinedfilename : 0); } static file_enum * @@ -278,7 +367,7 @@ gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem); if (libctx == NULL || libctx->io_device_table == NULL || - index < 0 || index >= gx_io_device_table_count) + index < 0 || index >= libctx->io_device_table_count) return 0; /* index out of range */ return libctx->io_device_table[index]; } @@ -295,7 +384,7 @@ return 0; if (len > 1 && str[len - 1] == '%') len--; - for (i = 0; i < gx_io_device_table_count; ++i) { + for (i = 0; i < libctx->io_device_table_count; ++i) { gx_io_device *iodev = libctx->io_device_table[i]; const char *dname = iodev->dname; @@ -409,7 +498,10 @@ pgs_file_enum = gs_alloc_struct(mem, gs_file_enum, &st_gs_file_enum, "gs_enumerate_files_init"); if (pgs_file_enum == 0) + { + iodev->procs.enumerate_close(pfen); return NULL; + } pgs_file_enum->memory = mem; pgs_file_enum->piodev = iodev; pgs_file_enum->pfile_enum = pfen; @@ -421,10 +513,15 @@ gs_enumerate_files_next(file_enum * pfen, char *ptr, uint maxlen) { gs_file_enum *pgs_file_enum = (gs_file_enum *)pfen; - int iodev_name_len = pgs_file_enum->prepend_iodev_name ? - strlen(pgs_file_enum->piodev->dname) : 0; + int iodev_name_len; uint return_len; + if (pgs_file_enum == NULL) + return ~0; + + iodev_name_len = pgs_file_enum->prepend_iodev_name ? + strlen(pgs_file_enum->piodev->dname) : 0; + if (iodev_name_len > maxlen) return maxlen + 1; /* signal overflow error */ if (iodev_name_len > 0) diff -Nru ghostscript-9.10~dfsg/base/gsiodevs.c ghostscript-9.25~dfsg+1/base/gsiodevs.c --- ghostscript-9.10~dfsg/base/gsiodevs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiodevs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ const char iodev_dtype_stdio[] = "Special"; #define iodev_stdio(dname, open) {\ dname, iodev_dtype_stdio,\ - { iodev_no_init, open, iodev_no_open_file,\ + { iodev_no_init, iodev_no_finit, open, iodev_no_open_file,\ iodev_no_fopen, iodev_no_fclose,\ iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,\ iodev_no_enumerate_files, NULL, NULL,\ diff -Nru ghostscript-9.10~dfsg/base/gsiodisk.c ghostscript-9.25~dfsg+1/base/gsiodisk.c --- ghostscript-9.10~dfsg/base/gsiodisk.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiodisk.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -110,7 +110,8 @@ /* Function prototypes */ static iodev_proc_init(iodev_diskn_init); -static iodev_proc_gp_fopen(iodev_diskn_gp_fopen); +static iodev_proc_finit(iodev_diskn_finit); +static iodev_proc_fopen(iodev_diskn_fopen); static iodev_proc_delete_file(diskn_delete); static iodev_proc_rename_file(diskn_rename); static iodev_proc_file_status(diskn_status); @@ -126,8 +127,8 @@ const gx_io_device varname = \ { \ diskname, "FileSystem", \ - {iodev_diskn_init, iodev_no_open_device, \ - NULL /* no longer used */ , iodev_diskn_gp_fopen, iodev_os_fclose, \ + {iodev_diskn_init, iodev_diskn_finit, iodev_no_open_device, \ + NULL /* no longer used */ , iodev_diskn_fopen, iodev_os_fclose, \ diskn_delete, diskn_rename, diskn_status, \ iodev_no_enumerate_files, /* Only until we have a root location */ \ diskn_enumerate_next, diskn_enumerate_close, \ @@ -163,7 +164,6 @@ #define TEMP_FILE_NAME "Tmp.txt" #define MAP_FILE_VERSION 1 #define InitialNumber 0 -#define BUFFER_LENGTH gp_file_name_sizeof typedef struct map_file_enum_s { FILE * stream; /* stream to map file */ @@ -175,13 +175,13 @@ gs_private_st_ptrs2(st_map_file_enum, struct map_file_enum_s, "map_file_enum", map_file_enum_enum_ptrs, map_file_enum_reloc_ptrs, pattern, root); -static void * map_file_enum_init(gs_memory_t *, const char *, const char *); +static void * map_file_enum_init(gs_memory_t *, const char *, const char *, uint); static bool map_file_enum_next(void *, char *); static void map_file_enum_close(void *); -static bool map_file_name_get(const char *, const char *, char *); -static void map_file_name_add(const char *, const char *); -static void map_file_name_ren(const char*, const char *, const char *); -static void map_file_name_del(const char *, const char *); +static bool map_file_name_get(gs_memory_t *, const char *, const char *, char *); +static void map_file_name_add(gs_memory_t *, const char *, const char *); +static void map_file_name_ren(gs_memory_t *, const char*, const char *, const char *); +static void map_file_name_del(gs_memory_t *, const char *, const char *); static int iodev_diskn_init(gx_io_device * iodev, gs_memory_t * mem) @@ -189,7 +189,7 @@ diskn_state * pstate = gs_alloc_struct(mem, diskn_state, &st_diskn_state, "iodev_diskn_init(state)"); if (!pstate) - return gs_error_VMerror; + return_error(gs_error_VMerror); pstate->root_size = 0; pstate->root = NULL; pstate->memory = mem; @@ -197,102 +197,168 @@ return 0; } +static void +iodev_diskn_finit(gx_io_device * iodev, gs_memory_t * mem) +{ + gs_object_free(mem, iodev->state, "iodev_diskn_finit"); + iodev->state = NULL; + return; +} + static int -iodev_diskn_gp_fopen(gx_io_device * iodev, const char *fname, const char *access, +iodev_diskn_fopen(gx_io_device * iodev, const char *fname, const char *access, FILE ** pfile, char *rfname, uint rnamelen) { - char realname[gp_file_name_sizeof]; diskn_state * pstate = (diskn_state *)iodev->state; + char *realname = (char *)gs_alloc_bytes(pstate->memory, gp_file_name_sizeof, "iodev_diskn_fopen(realname)"); + int code = 0; + + if (realname == NULL) { + code = gs_note_error(gs_error_VMerror); + goto done; + } /* Exit if we do not have a root location */ - if (!pstate->root) - return_error(gs_error_undefinedfilename); + if (!pstate->root) { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } /* Remap filename (if it exists). */ - if (!map_file_name_get((char *)pstate->root, fname, realname)) { + if (!map_file_name_get(pstate->memory, (char *)pstate->root, fname, realname)) { if (strchr(access, 'w')) { - map_file_name_add(pstate->root, fname); - map_file_name_get(pstate->root, fname, realname); + map_file_name_add(pstate->memory, pstate->root, fname); + map_file_name_get(pstate->memory, pstate->root, fname, realname); } - else - return_error(gs_error_undefinedfilename); - } + else { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } + } + + code = iodev_os_gp_fopen(iodev_default(pstate->memory), realname, access, pfile, rfname, rnamelen); + +done: + if (realname != NULL) + gs_free_object(pstate->memory, realname, "iodev_diskn_fopen(realname)"); - return iodev_os_gp_fopen(iodev_default(pstate->memory), realname, access, pfile, rfname, rnamelen); + return(code); } static int diskn_delete(gx_io_device * iodev, const char *fname) { - char realname[gp_file_name_sizeof]; diskn_state * pstate = (diskn_state *)iodev->state; + char *realname = (char *)gs_alloc_bytes(pstate->memory, gp_file_name_sizeof, "diskn_delete(realname)"); + int code = 0; + + if (realname == NULL) { + code = gs_note_error(gs_error_VMerror); + goto done; + } /* Exit if we do not have a root location */ - if (!pstate->root) - return_error(gs_error_undefinedfilename); + if (!pstate->root) { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } /* Map filename (if it exists). */ - if (!map_file_name_get((char *)pstate->root, fname, realname)) - return_error(gs_error_undefinedfilename); + if (!map_file_name_get(pstate->memory, (char *)pstate->root, fname, realname)) { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } + + map_file_name_del(pstate->memory, (char *)pstate->root, fname); + code = (unlink(realname) == 0 ? 0 : gs_note_error(gs_error_ioerror)); - map_file_name_del((char *)pstate->root, fname); - return (unlink(realname) == 0 ? 0 : gs_error_ioerror); +done: + if (realname != NULL) + gs_free_object(pstate->memory, realname, "diskn_delete(realname)"); + + return(code); } static int diskn_rename(gx_io_device * iodev, const char *from, const char *to) { - char toreal[gp_file_name_sizeof]; - int code = 0; diskn_state * pstate = (diskn_state *)iodev->state; + char *toreal = (char *)gs_alloc_bytes(pstate->memory, gp_file_name_sizeof, "diskn_rename(toreal)"); + int code = 0; + + if (toreal == NULL) { + code = gs_note_error(gs_error_VMerror); + goto done; + } /* Exit if we do not have a root location */ - if (!pstate->root) - return_error(gs_error_undefinedfilename); + if (!pstate->root) { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } /* if filenames are the same them we are done. */ - if (strcmp(to, from) == 0) - return 0; + if (strcmp(to, from) == 0) { + code = 0; + goto done; + } /* * If the destination file already exists, then we want to delete it. */ - if (map_file_name_get((char *)pstate->root, to, toreal)) { - map_file_name_del((char *)pstate->root, to); - code = unlink(toreal) == 0 ? 0 : gs_error_ioerror; + if (map_file_name_get(pstate->memory, (char *)pstate->root, to, toreal)) { + map_file_name_del(pstate->memory, (char *)pstate->root, to); + code = unlink(toreal) == 0 ? 0 : gs_note_error(gs_error_ioerror); } - map_file_name_ren((char *)pstate->root, from, to); - return code; + map_file_name_ren(pstate->memory, (char *)pstate->root, from, to); + +done: + if (toreal != NULL) + gs_free_object(pstate->memory, toreal, "diskn_rename(toreal)"); + + return(code); } static int diskn_status(gx_io_device * iodev, const char *fname, struct stat *pstat) { - char realname[gp_file_name_sizeof]; diskn_state * pstate = (diskn_state *)iodev->state; + char *realname = (char *)gs_alloc_bytes(pstate->memory, gp_file_name_sizeof, "diskn_status(realname)"); + int code = 0; + + if (realname == NULL) { + code = gs_note_error(gs_error_VMerror); + goto done; + } /* Exit if we do not have a root location */ - if (!pstate->root) - return_error(gs_error_undefinedfilename); + if (!pstate->root) { + code = gs_note_error(gs_error_undefinedfilename); + goto done; + } /* Map filename (if it exists). */ - if (!map_file_name_get((char *)pstate->root, fname, realname)) - return_error(gs_error_undefinedfilename); + if (!map_file_name_get(pstate->memory, (char *)pstate->root, fname, realname)) { + code = gs_note_error(gs_error_undefinedfilename); + } + + code = stat((char *)realname, pstat) < 0 ? gs_note_error(gs_error_undefinedfilename) : 0; + +done: + if (realname != NULL) + gs_free_object(pstate->memory, realname, "diskn_status(realname)"); - return (stat((char *)realname, pstat) < 0 ? gs_error_undefinedfilename : 0); + return(code); } static file_enum * -diskn_enumerate_files_init(gx_io_device * iodev, const char *pat, uint patlen, +diskn_enumerate_files(gx_io_device * iodev, const char *pat, uint patlen, gs_memory_t * mem) { - char patstr[gp_file_name_sizeof]; diskn_state * pstate = (diskn_state *)iodev->state; - - memcpy(patstr, pat, patlen); /* Copy string to buffer */ - patstr[patlen]=0; /* Terminate string */ - return (file_enum *)map_file_enum_init(mem, (char *)pstate->root, patstr); + + return (file_enum *)map_file_enum_init(mem, (char *)pstate->root, pat, patlen); } static void @@ -388,10 +454,10 @@ pstate->root = (char *)gs_alloc_byte_array(pstate->memory, gp_file_name_sizeof, sizeof(char), "diskn(rootdir)"); if (!pstate->root) - return gs_error_VMerror; + return_error(gs_error_VMerror); pstate->root_size = rootstr.size + 1; /* Now allow enumeration of files on the disk */ - iodev->procs.enumerate_files = diskn_enumerate_files_init; + iodev->procs.enumerate_files = diskn_enumerate_files; } memcpy(pstate->root, rootstr.data, rootstr.size); @@ -409,14 +475,25 @@ * Returns - NULL if error, file structure pointer if no error */ static FILE * -MapFileOpen(const char * rootpath, const char * filename, const char * attributes) +MapFileOpen(gs_memory_t *mem, const char * rootpath, const char * filename, const char * attributes) { - char fullname[BUFFER_LENGTH]; + char *fullname = NULL; + FILE *f = NULL; + int totlen = strlen(rootpath) + strlen(filename) + 1; - if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH) + if (totlen >= gp_file_name_sizeof) return NULL; - gs_sprintf(fullname, "%s%s", rootpath, filename); - return gp_fopen(fullname, attributes); + + fullname = (char *)gs_alloc_bytes(mem, totlen, "MapFileOpen(fullname)"); + if (fullname) { + + gs_sprintf(fullname, "%s%s", rootpath, filename); + f = gp_fopen(fullname, attributes); + + gs_free_object(mem, fullname , "MapFileOpen(fullname)"); + } + + return(f); } /* @@ -479,7 +556,7 @@ /* Get the file name */ do { namebuf[count++] = c = fgetc(mapfile); - } while (count < BUFFER_LENGTH && c != EOF && c != '\n' && c != '\r'); + } while (count < gp_file_name_sizeof && c != EOF && c != '\n' && c != '\r'); namebuf[--count] = 0; /* Terminate file name */ /* Clean up any trailing linefeeds or carriage returns */ @@ -510,14 +587,21 @@ * filename - File name string */ static void -MapFileUnlink(const char * rootpath, const char * filename) +MapFileUnlink(gs_memory_t *mem, const char * rootpath, const char * filename) { - char fullname[BUFFER_LENGTH]; + char *fullname = NULL; + int totlen = strlen(rootpath) + strlen(filename) + 1; - if (strlen(rootpath) + strlen(filename) >= BUFFER_LENGTH) + if (totlen >= gp_file_name_sizeof) return; - gs_sprintf(fullname, "%s%s", rootpath, filename); - unlink(fullname); + fullname = (char *)gs_alloc_bytes(mem, totlen, "MapFileUnlink(fullname)"); + if (fullname) { + gs_sprintf(fullname, "%s%s", rootpath, filename); + + unlink(fullname); + + gs_free_object(mem, fullname , "MapFileUnlink(fullname)"); + } } /* @@ -528,18 +612,28 @@ * newfilename - New file name string */ static void -MapFileRename(const char * rootpath, const char * newfilename, const char * oldfilename) +MapFileRename(gs_memory_t *mem, const char * rootpath, const char * newfilename, const char * oldfilename) { - char oldfullname[BUFFER_LENGTH]; - char newfullname[BUFFER_LENGTH]; + char *oldfullname = NULL; + char *newfullname = NULL; + int ototlen = strlen(rootpath) + strlen(oldfilename) + 1; + int ntotlen = strlen(rootpath) + strlen(newfilename) + 1; - if (strlen(rootpath) + strlen(oldfilename) >= BUFFER_LENGTH) + if (ototlen >= gp_file_name_sizeof) return; - if (strlen(rootpath) + strlen(newfilename) >= BUFFER_LENGTH) + if (ntotlen >= gp_file_name_sizeof) return; - gs_sprintf(oldfullname, "%s%s", rootpath, oldfilename); - gs_sprintf(newfullname, "%s%s", rootpath, newfilename); - rename(oldfullname, newfullname); + oldfullname = (char *)gs_alloc_bytes(mem, ototlen, "MapFileRename(oldfullname)"); + newfullname = (char *)gs_alloc_bytes(mem, ntotlen, "MapFileRename(newfullname)"); + + if (oldfullname && newfullname) { + gs_sprintf(oldfullname, "%s%s", rootpath, oldfilename); + gs_sprintf(newfullname, "%s%s", rootpath, newfilename); + rename(oldfullname, newfullname); + } + + gs_free_object(mem, oldfullname , "MapFileRename(oldfullname)"); + gs_free_object(mem, newfullname , "MapFileRename(newfullname)"); } /* @@ -552,14 +646,14 @@ * returns -1 if file not found, file number if found. */ static int -MapToFile(const char* rootpath, const char* name) +MapToFile(gs_memory_t *mem, const char* rootpath, const char* name) { FILE * mapfile; int d = -1; - char filename[BUFFER_LENGTH]; + char *filename = NULL; int file_version; - mapfile = MapFileOpen(rootpath, MAP_FILE_NAME, "r"); + mapfile = MapFileOpen(mem, rootpath, MAP_FILE_NAME, "r"); if (mapfile == NULL) return -1; @@ -568,13 +662,15 @@ if (MapFileReadVersion(mapfile, &file_version) && file_version == MAP_FILE_VERSION) { + filename = (char *)gs_alloc_bytes(mem, gp_file_name_sizeof, "MapToFile(filename)"); /* Scan the file looking for the given name */ - while (MapFileRead(mapfile, filename, &d)) { + while (filename && MapFileRead(mapfile, filename, &d)) { if (strcmp(filename, name) == 0) break; d = -1; } + gs_free_object(mem, filename, "MapToFile(filename)"); } fclose(mapfile); return d; @@ -591,7 +687,7 @@ * Returns: NULL if error, else pointer to enumeration structure. */ static void * -map_file_enum_init(gs_memory_t * mem, const char * root_name, const char * search_pattern) +map_file_enum_init(gs_memory_t *mem, const char * root_name, const char * search_pattern, uint search_pattern_len) { int file_version; map_file_enum * mapfileenum = gs_alloc_struct(mem, map_file_enum, &st_map_file_enum, @@ -603,13 +699,15 @@ mapfileenum->memory = mem; if (search_pattern) { - mapfileenum->pattern = (char *)gs_alloc_bytes(mem, strlen(search_pattern) + 1, + mapfileenum->pattern = (char *)gs_alloc_bytes(mem, search_pattern_len + 1, "diskn:enum_init(pattern)"); if (mapfileenum->pattern == NULL) { map_file_enum_close((file_enum *) mapfileenum); return NULL; } - strcpy(mapfileenum->pattern, search_pattern); + memcpy(mapfileenum->pattern, search_pattern, search_pattern_len); + /* Terminate string */ + mapfileenum->pattern[search_pattern_len] = '\0'; } mapfileenum->root = (char *)gs_alloc_bytes(mem, strlen(root_name) + 1, @@ -619,10 +717,10 @@ return NULL; } - if (strlen(root_name) >= BUFFER_LENGTH) + if (strlen(root_name) >= gp_file_name_sizeof) return NULL; strcpy(mapfileenum->root, root_name); - mapfileenum->stream = MapFileOpen(root_name, MAP_FILE_NAME, "r"); + mapfileenum->stream = MapFileOpen(mem, root_name, MAP_FILE_NAME, "r"); /* Check the mapping file version number */ if (mapfileenum->stream != NULL @@ -704,13 +802,13 @@ * osname char* resulting os specific path to the file */ static bool -map_file_name_get(const char * root_name, const char * Fname, char * osname) +map_file_name_get(gs_memory_t *mem, const char * root_name, const char * Fname, char * osname) { - int d = MapToFile(root_name, Fname); + int d = MapToFile(mem, root_name, Fname); if (d != -1) { /* 20 characters are enough for even a 64 bit integer */ - if ((strlen(root_name) + 20) < BUFFER_LENGTH) { + if ((strlen(root_name) + 20) < gp_file_name_sizeof) { gs_sprintf(osname, "%s%d", root_name, d); return true; } @@ -729,32 +827,37 @@ * Fname char* name of the entry to add to the map */ static void -map_file_name_del(const char * root_name, const char * Fname) +map_file_name_del(gs_memory_t *mem, const char * root_name, const char * Fname) { /* search for target entry */ - int d = MapToFile(root_name, Fname); + int d = MapToFile(mem, root_name, Fname); int file_version; + char *name = NULL; - if (d != -1) { /* if the file exists ... */ - char name[BUFFER_LENGTH]; + name = (char *)gs_alloc_bytes(mem, gp_file_name_sizeof, "map_file_name_del(name)"); + + if (name && d != -1) { /* if the file exists ... */ FILE* newMap; FILE* oldMap; /* Open current map file and a working file */ - MapFileUnlink(root_name, TEMP_FILE_NAME ); - newMap = MapFileOpen(root_name, TEMP_FILE_NAME, "w"); - if (newMap == NULL) + MapFileUnlink(mem, root_name, TEMP_FILE_NAME ); + newMap = MapFileOpen(mem, root_name, TEMP_FILE_NAME, "w"); + if (newMap == NULL) { + gs_free_object(mem, name , "map_file_name_del(name)"); return; - oldMap = MapFileOpen(root_name, MAP_FILE_NAME, "r"); + } + oldMap = MapFileOpen(mem, root_name, MAP_FILE_NAME, "r"); if (oldMap != NULL && (!MapFileReadVersion(oldMap, &file_version) || file_version != MAP_FILE_VERSION)) { fclose(oldMap); oldMap= NULL; } if (oldMap == NULL) { + gs_free_object(mem, name , "map_file_name_del(name)"); fclose(newMap); - MapFileUnlink(root_name, TEMP_FILE_NAME); + MapFileUnlink(mem, root_name, TEMP_FILE_NAME); return; } @@ -766,9 +869,10 @@ MapFileWrite(newMap, name, d); fclose(newMap); fclose(oldMap); - MapFileUnlink(root_name, MAP_FILE_NAME); - MapFileRename(root_name, MAP_FILE_NAME, TEMP_FILE_NAME); + MapFileUnlink(mem, root_name, MAP_FILE_NAME); + MapFileRename(mem, root_name, MAP_FILE_NAME, TEMP_FILE_NAME); } + gs_free_object(mem, name, "map_file_name_del(name)"); } /* @@ -780,51 +884,55 @@ * Fname char* name of the entry to add to the map */ static void -map_file_name_add(const char * root_name, const char * Fname) +map_file_name_add(gs_memory_t *mem, const char * root_name, const char * Fname) { /* * add entry to map file * entry number is one greater than biggest number */ - char name[BUFFER_LENGTH]; + char *name = NULL; int d; int dmax = -1; int file_version; FILE* newMap; FILE* oldMap; - oldMap = MapFileOpen(root_name, MAP_FILE_NAME, "r"); - if (oldMap != NULL && (!MapFileReadVersion(oldMap, &file_version) - || file_version != MAP_FILE_VERSION)) { - fclose(oldMap); - oldMap = NULL; - } - if (oldMap == NULL) { - oldMap = MapFileOpen(root_name, MAP_FILE_NAME, "w"); - if (!oldMap) - return; - MapFileWriteVersion(oldMap, MAP_FILE_VERSION); - MapFileWrite(oldMap, Fname, InitialNumber); - fclose(oldMap); - } - else { - MapFileUnlink(root_name, TEMP_FILE_NAME); - newMap = MapFileOpen(root_name, TEMP_FILE_NAME, "w"); - if (newMap != NULL) { - MapFileWriteVersion(newMap, MAP_FILE_VERSION); - while (MapFileRead(oldMap, name, &d)) { - MapFileWrite(newMap, name, d); - if (dmax < d) - dmax = d; - } - - dmax += 1; - MapFileWrite(newMap, Fname, dmax); - fclose(newMap); + name = (char *)gs_alloc_bytes(mem, gp_file_name_sizeof, "map_file_name_add(name)"); + if (name) { + oldMap = MapFileOpen(mem, root_name, MAP_FILE_NAME, "r"); + if (oldMap != NULL && (!MapFileReadVersion(oldMap, &file_version) + || file_version != MAP_FILE_VERSION)) { + fclose(oldMap); + oldMap = NULL; + } + if (oldMap == NULL) { + oldMap = MapFileOpen(mem, root_name, MAP_FILE_NAME, "w"); + if (!oldMap) + return; + MapFileWriteVersion(oldMap, MAP_FILE_VERSION); + MapFileWrite(oldMap, Fname, InitialNumber); fclose(oldMap); - MapFileUnlink(root_name, MAP_FILE_NAME); - MapFileRename(root_name, MAP_FILE_NAME, TEMP_FILE_NAME); } + else { + MapFileUnlink(mem, root_name, TEMP_FILE_NAME); + newMap = MapFileOpen(mem, root_name, TEMP_FILE_NAME, "w"); + if (newMap != NULL) { + MapFileWriteVersion(newMap, MAP_FILE_VERSION); + while (MapFileRead(oldMap, name, &d)) { + MapFileWrite(newMap, name, d); + if (dmax < d) + dmax = d; + } + + dmax += 1; + MapFileWrite(newMap, Fname, dmax); + fclose(newMap); + fclose(oldMap); + MapFileUnlink(mem, root_name, MAP_FILE_NAME); + MapFileRename(mem, root_name, MAP_FILE_NAME, TEMP_FILE_NAME); + } + } + gs_free_object(mem, name , "map_file_name_add(name)"); } } @@ -838,25 +946,25 @@ * newname char* name to change the entry indicated by oldname into */ static void -map_file_name_ren(const char* root_name, const char * oldname, const char * newname) +map_file_name_ren(gs_memory_t *mem, const char* root_name, const char * oldname, const char * newname) { /* search for target entry */ - int d = MapToFile(root_name, oldname); + int d = MapToFile(mem, root_name, oldname); int file_version; + char *name = (char *)gs_alloc_bytes(mem, gp_file_name_sizeof, "map_file_name_ren(name)"); - if (d != -1) { /* if target exists ... */ - char name[BUFFER_LENGTH]; + if (name && d != -1) { /* if target exists ... */ FILE* newMap; FILE* oldMap; /* Open current map file and a working file */ - MapFileUnlink(root_name, TEMP_FILE_NAME ); - newMap = MapFileOpen(root_name, TEMP_FILE_NAME, "w"); + MapFileUnlink(mem, root_name, TEMP_FILE_NAME ); + newMap = MapFileOpen(mem, root_name, TEMP_FILE_NAME, "w"); if (newMap == NULL) return; - oldMap = MapFileOpen(root_name, MAP_FILE_NAME, "r"); + oldMap = MapFileOpen(mem, root_name, MAP_FILE_NAME, "r"); if (oldMap != NULL && (!MapFileReadVersion(oldMap, &file_version) || file_version != MAP_FILE_VERSION)) { fclose(oldMap); @@ -864,7 +972,7 @@ } if (oldMap == NULL) { fclose(newMap); - MapFileUnlink(root_name, TEMP_FILE_NAME); + MapFileUnlink(mem, root_name, TEMP_FILE_NAME); return; } @@ -878,7 +986,8 @@ MapFileWrite(newMap, newname, d); fclose(newMap); fclose(oldMap); - MapFileUnlink(root_name, MAP_FILE_NAME); - MapFileRename(root_name, MAP_FILE_NAME, TEMP_FILE_NAME); + MapFileUnlink(mem, root_name, MAP_FILE_NAME); + MapFileRename(mem, root_name, MAP_FILE_NAME, TEMP_FILE_NAME); } + gs_free_object(mem, name ,"map_file_name_ren(name)"); } diff -Nru ghostscript-9.10~dfsg/base/gsio.h ghostscript-9.25~dfsg+1/base/gsio.h --- ghostscript-9.10~dfsg/base/gsio.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsio.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsiomacres.c ghostscript-9.25~dfsg+1/base/gsiomacres.c --- ghostscript-9.10~dfsg/base/gsiomacres.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiomacres.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,437 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* %macresource% IODevice implementation for loading MacOS fonts */ - -/* - * MacOS often stores fonts in 'resource forks' an extended attribute - * of the HFS filesystem that allows storing chunks of data indexed by - * a resource 'type' and 'id'. MacOS X introduced the '.dfont' format - * for compatibility with non-HFS filesystems; it consists of the - * resource data for a font stored on the data fork (normal file). - * - * We provide here a special %macresource% IODevice so that Ghostscript - * can open these native fonts on MacOS. It opens the requested file and - * returns a stream containing the indicated resource data, whether from - * the resource fork or, if that fails, from the datafork assuming a - * .dfont file. - * - * Since the only use at this point is font loading, we don't implement - * the usual complement of delete, rename and so on. - */ - -#include "std.h" -#include "stdio_.h" -#include "string_.h" -#include "malloc_.h" -#include "ierrors.h" -#include "gstypes.h" -#include "gsmemory.h" -#include "stream.h" -#include "gdebug.h" -#include "gxiodev.h" -#include "gp.h" - -/* dfont loading code */ - -/* 4-byte resource types as uint32s */ -#define TYPE_sfnt 0x73666e74 -#define TYPE_FOND 0x464f4e44 -#define TYPE_NFNT 0x4e464e54 -#define TYPE_ftag 0x66746167 -#define TYPE_vers 0x76657273 - -typedef struct { - unsigned int data_offset; - unsigned int map_offset; - unsigned int data_length; - unsigned int map_length; -} resource_header; - -typedef struct { - unsigned int type; - unsigned int offset; - unsigned int length; - byte *data; - char *name; - unsigned short id; - byte flags; -} resource; - -typedef struct { - resource *resources; - int n_resources; -} resource_list; - -static -int get_int32(byte *p) { - return (p[0]&0xFF)<<24 | (p[1]&0xFF)<<16 | (p[2]&0xFF)<<8 | (p[3]&0xFF); -} - -static -int get_int24(byte *p) { - return (p[0]&0xFF)<<16 | (p[1]&0xFF)<<8 | (p[2]&0xFF); -} - -static -int get_int16(byte *p) { - return (p[0]&0xFF)<<8 | (p[1]&0xFF); -} - -static -int read_int32(FILE *in, void *p) -{ - byte w[4], err; - - err = fread(w, 1, 4, in); - if (err != 4) return -1; - - *(unsigned int*)p = get_int32(w); - return 0; -} - -static -int read_int24(FILE *in, void *p) -{ - byte w[3], err; - - err = fread(w, 1, 3, in); - if (err != 3) return -1; - - *(unsigned int*)p = get_int24(w); - return 0; -} - -static -int read_int16(FILE *in, void *p) -{ - byte w[2], err; - - err = fread(w, 1, 2, in); - if (err != 2) return -1; - - *(unsigned short*)p = get_int16(w); - return 0; -} - -static -int read_int8(FILE *in, void *p) -{ - byte c = fgetc(in); - if (c < 0) return -1; - - *(byte*)p = (c&0xFF); - return 0; -} - -/* convert a 4-character typecode from C string to uint32 representation */ -static unsigned int res_string2type(const char *type_string) -{ - unsigned int type = type_string[0] << 24 | - type_string[1] << 16 | - type_string[2] << 8 | - type_string[3]; - return (type); -} -/* convert a 4-character typecode from unsigned int to C string representation */ -static char * res_type2string(const unsigned int type, char *type_string) -{ - if (type_string == NULL) return NULL; - - type_string[0] = (type >> 24) & 0xFF; - type_string[1] = (type >> 16) & 0xFF; - type_string[2] = (type >> 8) & 0xFF; - type_string[3] = (type) & 0xFF; - type_string[4] = '\0'; - - return (type_string); -} - -static -resource_header *read_resource_header(FILE *in, int offset) -{ - resource_header *header = malloc(sizeof(*header)); - - fseek(in, offset, SEEK_SET); - - read_int32(in, &(header->data_offset)); - read_int32(in, &(header->map_offset)); - read_int32(in, &(header->data_length)); - read_int32(in, &(header->map_length)); - - if (feof(in)) { - free (header); - header = NULL; - } - - return header; -} - -static -resource_list *read_resource_map(FILE *in, resource_header *header) -{ - resource_list *list; - int n_resources; - int type_offset, name_offset, this_name_offset; - unsigned int *types; - int *number, *ref_offsets; - int n_types; - char type_string[5]; - byte *buf, *p; - int i,j,k; - - buf = malloc(sizeof(*buf)*header->map_length); - if (buf == NULL) { - if_debug1('s', "error: could not allocate %d bytes for resource map\n", header->map_length); - return NULL; - } - - /* read in the whole resource map */ - fseek(in, header->map_offset, SEEK_SET); - fread(buf, 1, header->map_length, in); - - type_offset = get_int16(buf + 24); - name_offset = get_int16(buf + 26); - n_types = get_int16(buf + 28); n_types++; - - if (type_offset != 30) - if_debug1('s', "[s] warning! resource type list offset is %d, not 30!\n", type_offset); - - /* determine the total number of resources */ - types = malloc(sizeof(*types)*n_types); - number = malloc(sizeof(*number)*n_types); - ref_offsets = malloc(sizeof(*ref_offsets)*n_types); - n_resources = 0; - p = buf + type_offset; /* this seems to be off by two in files!? */ - p = buf + 30; - for (i = 0; i < n_types; i++) { - types[i] = get_int32(p); - number[i] = get_int16(p + 4) + 1; - ref_offsets[i] = get_int16(p + 6); - p += 8; - n_resources += number[i]; - } - - /* parse the individual resources */ - list = malloc(sizeof(resource_list)); - list->resources = malloc(sizeof(resource)*n_resources); - list->n_resources = n_resources; - k = 0; - for (i = 0; i < n_types; i++) { - res_type2string(types[i], type_string); - if_debug2('s', "[s] %d resources of type '%s':\n", number[i], type_string); - p = buf + type_offset + ref_offsets[i]; /* FIXME: also off? */ - /* p = buf + 32 + ref_offsets[i]; */ - for (j = 0; j < number[i]; j++) { - list->resources[k].type = types[i]; - list->resources[k].id = get_int16(p); - this_name_offset = get_int16(p + 2); - if (this_name_offset == 0xFFFF) { /* no name field */ - list->resources[k].name = NULL; - } else { /* read name field (a pascal string) */ - char *c = buf + name_offset + this_name_offset; - int len = *c; - list->resources[k].name = malloc(sizeof(char)*(len+1)); - memcpy(list->resources[k].name, c + 1, len); - list->resources[k].name[len] = '\0'; - } - list->resources[k].flags = *(p+4); - list->resources[k].offset = get_int24(p+5); - /* load the actual resource data separately */ - list->resources[k].length = 0; - list->resources[k].data = NULL; - - p += 12; - if_debug4('s', "\tid %d offset 0x%08x flags 0x%02x '%s'\n", - list->resources[k].id, list->resources[k].offset, - list->resources[k].flags, list->resources[k].name); - k++; - } - } - - free(buf); - free(types); - - return list; -} - -static -void load_resource(FILE *in, resource_header *header, resource *res) -{ - unsigned int len; - byte *buf; - - fseek(in, header->data_offset + res->offset, SEEK_SET); - read_int32(in, &len); - - buf = malloc(len); - fread(buf, 1, len, in); - res->data = buf; - res->length = len; - - return; -} - -static -int read_datafork_resource(byte *buf, const char *fname, const uint type, const ushort id) -{ - resource_header *header; - resource_list *list; - FILE *in; - int i; - - in = gp_fopen(fname, "rb"); - if (in == NULL) { - if_debug1('s', "[s] couldn't open '%s'\n", fname); - return 0; - } - - header = read_resource_header(in, 0); - if (header == NULL) { - if_debug0('s', "[s] could not read resource file header.\n"); - if_debug0('s', "[s] not a serialized data fork resource file?\n"); - return 0; - } - - if_debug0('s', "[s] loading resource map\n"); - list = read_resource_map(in, header); - if (list == NULL) { - if_debug0('s', "[s] couldn't read resource map.\n"); - return 0; - } - - /* load the resource data we're interested in */ - for (i = 0; i < list->n_resources; i++) { - if ((list->resources[i].type == type) && - (list->resources[i].id == id)) { - if_debug2('s', "[s] loading '%s' resource id %d", - list->resources[i].name, list->resources[i].id); - load_resource(in, header, &(list->resources[i])); - if_debug1('s', " (%d bytes)\n", list->resources[i].length); - fclose(in); - if (buf) memcpy (buf, list->resources[i].data, list->resources[i].length); - return (list->resources[i].length); - } - } - - fclose(in); - free(list); - free(header); - - return (0); -} - -/* end dfont loading code */ - -/* prototypes */ -static iodev_proc_init(iodev_macresource_init); -static iodev_proc_open_file(iodev_macresource_open_file); -/* there is no close_file()...stream closure takes care of it */ -/* ignore rest for now */ - -/* Define the %macresource% device */ -const gx_io_device gs_iodev_macresource = -{ - "%macresource%", "FileSystem", - { - iodev_macresource_init, iodev_no_open_device, - iodev_macresource_open_file, - iodev_no_fopen, iodev_no_fclose, - iodev_no_delete_file, iodev_no_rename_file, - iodev_no_file_status, - iodev_no_enumerate_files, NULL, NULL, - iodev_no_get_params, iodev_no_put_params - } -}; - -/* init state. don't know if we need state yet--probably not */ -static int -iodev_macresource_init(gx_io_device *iodev, gs_memory_t *mem) -{ - return 0; -} - -/* open the requested file return (in ps) a stream containing the resource data */ -static int -iodev_macresource_open_file(gx_io_device *iodev, const char *fname, uint namelen, - const char *access, stream **ps, gs_memory_t *mem) -{ - char filename[gp_file_name_sizeof]; - char *res_type_string, *res_id_string; - uint type; - ushort id; - bool datafork = 0; - int size; - byte *buf; - - /* return NULL if there's an error */ - *ps = NULL; - - strncpy(filename, fname, min(namelen, gp_file_name_sizeof)); - if (namelen < gp_file_name_sizeof) filename[namelen] = '\0'; - /* parse out the resource type and id. they're appended to the pathname - in the form '#+' */ - res_type_string = strrchr(filename, '#'); - if (res_type_string == NULL) { - if_debug0('s', "[s] couldn't find resource type separator\n"); - return_error(e_invalidfileaccess); - } - *res_type_string++ = '\0'; - res_id_string = strrchr(res_type_string, '+'); - if (res_id_string == NULL) { - if_debug0('s', "couldn't find resource id separator\n"); - return_error(e_invalidfileaccess); - } - *res_id_string++ = '\0'; - type = res_string2type(res_type_string); - id = (ushort)atoi(res_id_string); - if_debug3('s', "[s] opening resource fork of '%s' for type '%s' id '%d'\n", filename, res_type_string, id); - - /* we call with a NULL buffer to get the size */ - size = gp_read_macresource(NULL, filename, type, id); - if (size == 0) { - /* this means that opening the resource fork failed */ - /* try to open as a .dfont from here */ - if_debug0('s', "[s] trying to open as a datafork file instead...\n"); - size = read_datafork_resource(NULL, filename, type, id); - if (size != 0) { - datafork = true; - } else { - if_debug0('s', "could not get resource size\n"); - return_error(e_invalidfileaccess); - } - } - if_debug1('s', "[s] got resource size %d bytes\n", size); - /* allocate a buffer */ - buf = gs_alloc_string(mem, size, "macresource buffer"); - if (buf == NULL) { - if_debug0('s', "macresource: could not allocate buffer for resource data\n"); - return_error(e_VMerror); - } - /* call again to get the resource data */ - if (!datafork) { - size = gp_read_macresource(buf, filename, type, id); - } else { - size = read_datafork_resource(buf, filename, type, id); - } - - /* allocate stream *ps and set it up with the buffered data */ - *ps = s_alloc(mem, "macresource"); - sread_string(*ps, buf, size); - - /* return success */ - return 0; -} diff -Nru ghostscript-9.10~dfsg/base/gsioram.c ghostscript-9.25~dfsg+1/base/gsioram.c --- ghostscript-9.10~dfsg/base/gsioram.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsioram.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,574 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* %ram% file device implementation */ + +/* + * This file implements a simple ram-based file system. + * + * The fs has no subdirs, only a root directory. Files are stored as a + * resizable array of pointers to blocks. Timestamps are not implemented + * for performance reasons. + * + * The implementation is in two parts - a ramfs interface that works + * mostly like the unix file system calls, and a layer to hook this up + * to ghostscript. + * + * Macros define an upper limit on the number of blocks a ram device + * can take up, and (in ramfs.c) the size of each block. + * + * Routines for the gs stream interface were graciously stolen from + * sfxstdio.c et al. + */ + +#include "string_.h" +#include "unistd_.h" +#include "gx.h" +#include "gserrors.h" +#include "gp.h" +#include "gscdefs.h" +#include "gsparam.h" +#include "gsstruct.h" +#include "gxiodev.h" +#include "gsutil.h" +#include "stream.h" +#include "ramfs.h" + +/* Function prototypes */ +static iodev_proc_init(iodev_ram_init); +static iodev_proc_finit(iodev_ram_finit); +static iodev_proc_open_file(ram_open_file); +static iodev_proc_delete_file(ram_delete); +static iodev_proc_rename_file(ram_rename); +static iodev_proc_file_status(ram_status); +static iodev_proc_enumerate_files(ram_enumerate_init); +static iodev_proc_enumerate_next(ram_enumerate_next); +static iodev_proc_enumerate_close(ram_enumerate_close); +static iodev_proc_get_params(ram_get_params); +static void ram_finalize(const gs_memory_t *memory, void * vptr); + +const gx_io_device gs_iodev_ram = { + "%ram%", "FileSystem", { + iodev_ram_init, iodev_ram_finit, iodev_no_open_device, + ram_open_file, iodev_no_fopen, iodev_no_fclose, + ram_delete, ram_rename, ram_status, + ram_enumerate_init, ram_enumerate_next, ram_enumerate_close, + ram_get_params, iodev_no_put_params + } +}; + +typedef struct ramfs_state_s { + gs_memory_t *memory; + ramfs* fs; +} ramfs_state; + +#define GETRAMFS(state) (((ramfs_state*)(state))->fs) + +gs_private_st_simple_final(st_ramfs_state, struct ramfs_state_s, "ramfs_state", ram_finalize); + +typedef struct gsram_enum_s { + char *pattern; + ramfs_enum* e; + gs_memory_t *memory; +} gsram_enum; + +gs_private_st_ptrs3(st_gsram_enum, struct gsram_enum_s, "gsram_enum", + gsram_enum_enum_ptrs, gsram_enum_reloc_ptrs, pattern, e, memory); + +/* could make this runtime configurable later. It doesn't allocate + all the blocks in one go so it's not critical */ +#define MAXBLOCKS 2000000 + +#define DEFAULT_BUFFER_SIZE 2048 + +/* stream stuff */ + +static int +s_ram_available(stream *, gs_offset_t *), + s_ram_read_seek(stream *, gs_offset_t), + s_ram_read_close(stream *), + s_ram_read_process(stream_state *, stream_cursor_read *, + stream_cursor_write *, bool); +static int +s_ram_write_seek(stream *, gs_offset_t), + s_ram_write_flush(stream *), + s_ram_write_close(stream *), + s_ram_write_process(stream_state *, stream_cursor_read *, + stream_cursor_write *, bool); +static int +s_ram_switch(stream *, bool); + +static int +ramfs_errno_to_code(int errno) { + switch (errno) { + case RAMFS_NOTFOUND: + return_error(gs_error_undefinedfilename); + case RAMFS_NOACCESS: + return_error(gs_error_invalidfileaccess); + case RAMFS_NOMEM: + return_error(gs_error_VMerror); + /* just in case */ + default: + return_error(gs_error_ioerror); + } +} + +static void +sread_ram(register stream * s, ramhandle * file, byte * buf, uint len), + swrite_ram(register stream * s, ramhandle * file, byte * buf, uint len), + sappend_ram(register stream * s, ramhandle * file, byte * buf, uint len); + +static int +ram_open_file(gx_io_device * iodev, const char *fname, uint len, + const char *file_access, stream ** ps, gs_memory_t * mem) +{ + int code = 0; + ramhandle * file; + char fmode[4]; /* r/w/a, [+], [b], null */ + int openmode=RAMFS_READ; + ramfs * fs; + char * namestr = NULL; + + /* Is there a more efficient way to do this? */ + namestr = (char *)gs_alloc_bytes(mem, len + 1, "temporary filename string"); + if(!namestr) + return_error(gs_error_VMerror); + strncpy(namestr,fname,len); + namestr[len] = 0; + + if (!iodev) {/*iodev = iodev_default;*/ + gs_free_object(mem, namestr, "free temporary filename string"); + return gs_note_error(gs_error_invalidaccess); + } + fs = GETRAMFS(iodev->state); + code = file_prepare_stream(fname, len, file_access, DEFAULT_BUFFER_SIZE, + ps, fmode, mem + ); + if (code < 0) goto error; + if (fname == 0) { + gs_free_object(mem, namestr, "free temporary filename string"); + return 0; + } + + switch (fmode[0]) { + case 'a': + openmode = RAMFS_WRITE | RAMFS_APPEND; + break; + case 'r': + openmode = RAMFS_READ; + if (fmode[1] == '+') + openmode |= RAMFS_WRITE; + break; + case 'w': + openmode |= RAMFS_WRITE | RAMFS_TRUNC | RAMFS_CREATE; + if (fmode[1] == '+') + openmode |= RAMFS_READ; + } + + /* For now, we cheat here in the same way that sfxstdio.c et al cheat - + append mode is faked by opening in write mode and seeking to EOF just + once. This is different from unix semantics, which seeks atomically + before each write, and is actually useful as a distinct mode. */ + /* if (fmode[0] == 'a') openmode |= RAMFS_APPEND; */ + + file = ramfs_open(mem, fs,namestr,openmode); + if(!file) { code = ramfs_errno_to_code(ramfs_error(fs)); goto error; } + + switch (fmode[0]) { + case 'a': + sappend_ram(*ps, file, (*ps)->cbuf, (*ps)->bsize); + break; + case 'r': + sread_ram(*ps, file, (*ps)->cbuf, (*ps)->bsize); + break; + case 'w': + swrite_ram(*ps, file, (*ps)->cbuf, (*ps)->bsize); + } + if (fmode[1] == '+') { + (*ps)->modes = (*ps)->file_modes |= s_mode_read | s_mode_write; + } + (*ps)->save_close = (*ps)->procs.close; + (*ps)->procs.close = file_close_file; + error: + gs_free_object(mem, namestr, "free temporary filename string"); + /* XXX free stream stuff? */ + return code; +} + +/* Initialize a stream for reading an OS file. */ +static void +sread_ram(register stream * s, ramhandle * file, byte * buf, uint len) +{ + static const stream_procs p = { + s_ram_available, s_ram_read_seek, s_std_read_reset, + s_std_read_flush, s_ram_read_close, s_ram_read_process, + s_ram_switch + }; + + s_std_init(s, buf, len, &p,s_mode_read + s_mode_seek); + s->file = (FILE*)file; + s->file_modes = s->modes; + s->file_offset = 0; + ramfile_seek(file, 0, RAMFS_SEEK_END); + s->file_limit = ramfile_tell(file); + ramfile_seek(file, 0, RAMFS_SEEK_SET); +} + +/* Procedures for reading from a file */ +static int +s_ram_available(register stream * s, gs_offset_t *pl) +{ + long max_avail = s->file_limit - stell(s); + + *pl = max_avail; + if(*pl == 0 && ramfile_eof((ramhandle*)s->file)) + *pl = -1; /* EOF */ + return 0; +} + +static int +s_ram_read_seek(register stream * s, gs_offset_t pos) +{ + uint end = s->srlimit - s->cbuf + 1; + long offset = pos - s->position; + + if (offset >= 0 && offset <= end) { /* Staying within the same buffer */ + s->srptr = s->cbuf + offset - 1; + return 0; + } + if (pos < 0 || pos > s->file_limit || + ramfile_seek((ramhandle*)s->file, s->file_offset + pos, RAMFS_SEEK_SET) != 0 + ) + return ERRC; + s->srptr = s->srlimit = s->cbuf - 1; + s->end_status = 0; + s->position = pos; + return 0; +} +static int +s_ram_read_close(stream * s) +{ + ramhandle *file = (ramhandle*)s->file; + + if (file != 0) { + s->file = 0; + ramfile_close(file); + } + return 0; +} + +/* + * Process a buffer for a file reading stream. + * This is the first stream in the pipeline, so pr is irrelevant. + */ +static int +s_ram_read_process(stream_state * st, stream_cursor_read * ignore_pr, + stream_cursor_write * pw, bool last) +{ + stream *s = (stream *)st; /* no separate state */ + ramhandle *file = (ramhandle*)s->file; + uint max_count = pw->limit - pw->ptr; + int status = 1; + int count; + + if (s->file_limit < S_FILE_LIMIT_MAX) { + long limit_count = s->file_offset + s->file_limit - + ramfile_tell(file); + + if (max_count > limit_count) + max_count = limit_count, status = EOFC; + } + count = ramfile_read(file,pw->ptr + 1, max_count); + if (count < 0) return ERRC; + pw->ptr += count; + /* process_interrupts(s->memory); */ + return ramfile_eof(file) ? EOFC : status; +} + +/* ------ File writing ------ */ + +/* Initialize a stream for writing a file. */ +static void +swrite_ram(register stream * s, ramhandle * file, byte * buf, uint len) +{ + static const stream_procs p = { + s_std_noavailable, s_ram_write_seek, s_std_write_reset, + s_ram_write_flush, s_ram_write_close, s_ram_write_process, + s_ram_switch + }; + + s_std_init(s, buf, len, &p, s_mode_write + s_mode_seek); + s->file = (FILE*)file; + s->file_modes = s->modes; + s->file_offset = 0; /* in case we switch to reading later */ + s->file_limit = S_FILE_LIMIT_MAX; +} + +/* Initialize for appending to a file. */ +static void +sappend_ram(register stream * s, ramhandle * file, byte * buf, uint len) +{ + swrite_ram(s, file, buf, len); + s->modes = s_mode_write + s_mode_append; /* no seek */ + s->file_modes = s->modes; + ramfile_seek(file,0,RAMFS_SEEK_END); + s->position = ramfile_tell(file); +} + +/* Procedures for writing on a file */ +static int +s_ram_write_seek(stream * s, gs_offset_t pos) +{ + /* We must flush the buffer to reposition. */ + int code = sflush(s); + + if (code < 0) return code; + if (ramfile_seek((ramhandle*)s->file, pos, RAMFS_SEEK_SET) != 0) + return ERRC; + s->position = pos; + return 0; +} + +static int +s_ram_write_flush(register stream * s) +{ + int result = s_process_write_buf(s, false); + return result; +} + +static int +s_ram_write_close(register stream * s) +{ + s_process_write_buf(s, true); + return s_ram_read_close(s); +} + +/* + * Process a buffer for a file writing stream. + * This is the last stream in the pipeline, so pw is irrelevant. + */ +static int +s_ram_write_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * ignore_pw, bool last) +{ + uint count = pr->limit - pr->ptr; + + ramhandle *file = (ramhandle*)((stream *) st)->file; + int written = ramfile_write(file,pr->ptr + 1, count); + + if (written < 0) return ERRC; + pr->ptr += written; + return 0; +} + +static int +s_ram_switch(stream * s, bool writing) +{ + uint modes = s->file_modes; + ramhandle *file = (ramhandle*)s->file; + long pos; + + if (writing) { + if (!(s->file_modes & s_mode_write)) return ERRC; + pos = stell(s); + ramfile_seek(file, pos, RAMFS_SEEK_SET); + if (modes & s_mode_append) { + sappend_ram(s, file, s->cbuf, s->cbsize); /* sets position */ + } else { + swrite_ram(s, file, s->cbuf, s->cbsize); + s->position = pos; + } + s->modes = modes; + } else { + if (!(s->file_modes & s_mode_read)) return ERRC; + pos = stell(s); + if (sflush(s) < 0) return ERRC; + sread_ram(s, file, s->cbuf, s->cbsize); + s->modes |= modes & s_mode_append; /* don't lose append info */ + s->position = pos; + } + s->file_modes = modes; + return 0; +} + + +/* gx_io_device stuff */ + +static int +iodev_ram_init(gx_io_device * iodev, gs_memory_t * mem) +{ + ramfs* fs = ramfs_new(mem, MAXBLOCKS); + ramfs_state* state = gs_alloc_struct(mem, ramfs_state, &st_ramfs_state, + "ramfs_init(state)" + ); + if (fs && state) { + state->fs = fs; + state->memory = mem; + iodev->state = state; + return 0; + } + if(fs) ramfs_destroy(mem, fs); + if(state) gs_free_object(mem,state,"iodev_ram_init(state)"); + return_error(gs_error_VMerror); +} + +static void +iodev_ram_finit(gx_io_device * iodev, gs_memory_t * mem) +{ + ramfs_state *state = (ramfs_state *)iodev->state; + if (state != NULL) + { + iodev->state = NULL; + gs_free_object(state->memory, state, "iodev_ram_finit"); + } + return; +} + +static void +ram_finalize(const gs_memory_t *memory, void * vptr) +{ + ramfs* fs = GETRAMFS((ramfs_state*)vptr); + ramfs_destroy((gs_memory_t *)memory, fs); + GETRAMFS((ramfs_state*)vptr) = NULL; +} + +static int +ram_delete(gx_io_device * iodev, const char *fname) +{ + ramfs* fs = GETRAMFS(iodev->state); + + if(ramfs_unlink(fs,fname)!=0) { + return_error(ramfs_errno_to_code(ramfs_error(fs))); + } + return 0; +} + +static int +ram_rename(gx_io_device * iodev, const char *from, const char *to) +{ + ramfs* fs = GETRAMFS(iodev->state); + + if(ramfs_rename(fs,from,to)!=0) { + return_error(ramfs_errno_to_code(ramfs_error(fs))); + } + return 0; +} + +static int +ram_status(gx_io_device * iodev, const char *fname, struct stat *pstat) +{ + ramhandle * f; + ramfs* fs = GETRAMFS(iodev->state); + + f = ramfs_open(((ramfs_state *)iodev->state)->memory, fs,fname,RAMFS_READ); + if(!f) return_error(ramfs_errno_to_code(ramfs_error(fs))); + + memset(pstat, 0, sizeof(*pstat)); + pstat->st_size = ramfile_size(f); + /* The Windows definition of struct stat doesn't include a st_blocks member + pstat->st_blocks = (pstat->st_size+blocksize-1)/blocksize;*/ + /* XXX set mtime & ctime */ + ramfile_close(f); + return 0; +} + +static file_enum * +ram_enumerate_init(gx_io_device *iodev, const char *pat, uint patlen, + gs_memory_t *mem) +{ + gsram_enum * penum = gs_alloc_struct( + mem, gsram_enum, &st_gsram_enum, + "ram_enumerate_files_init(file_enum)" + ); + char *pattern = (char *)gs_alloc_bytes( + mem, patlen+1, "ram_enumerate_file_init(pattern)" + ); + ramfs_enum * e = ramfs_enum_new(GETRAMFS(iodev->state)); + if(penum && pattern && e) { + memcpy(pattern, pat, patlen); + pattern[patlen]=0; + + penum->memory = mem; + penum->pattern = pattern; + penum->e = e; + return (file_enum *)penum; + } + if (penum) gs_free_object(mem,penum,"ramfs_enum_init(ramfs_enum)"); + if (pattern) + gs_free_object(mem, pattern, "ramfs_enum_init(pattern)"); + if(e) ramfs_enum_end(e); + return NULL; +} + +static void +ram_enumerate_close(file_enum *pfen) +{ + gsram_enum *penum = (gsram_enum *)pfen; + gs_memory_t *mem = penum->memory; + + ramfs_enum_end(penum->e); + gs_free_object(mem, penum->pattern, "ramfs_enum_init(pattern)"); + gs_free_object(mem, penum, "ramfs_enum_init(ramfs_enum)"); +} + +static uint +ram_enumerate_next(file_enum *pfen, char *ptr, uint maxlen) +{ + gsram_enum *penum = (gsram_enum *)pfen; + + char * filename; + while ((filename = ramfs_enum_next(penum->e))) { + if (string_match((byte *)filename, strlen(filename), + (byte *)penum->pattern, + strlen(penum->pattern), 0)) { + if (strlen(filename) < maxlen) + memcpy(ptr, filename, strlen(filename)); + return strlen(filename); /* if > maxlen, caller will detect rangecheck */ + } + } + /* ran off end of list, close the enum */ + ram_enumerate_close(pfen); + return ~(uint)0; +} + +static int +ram_get_params(gx_io_device * iodev, gs_param_list * plist) +{ + int code; + int i0 = 0, so = 1; + bool btrue = true, bfalse = false; + ramfs* fs = GETRAMFS(iodev->state); + int BlockSize; + long Free, LogicalSize; + + BlockSize = ramfs_blocksize(fs); + LogicalSize = MAXBLOCKS; + Free = ramfs_blocksfree(fs); + + if ( + (code = param_write_bool(plist, "HasNames", &btrue)) < 0 || + (code = param_write_int (plist, "BlockSize", &BlockSize)) < 0 || + (code = param_write_long(plist, "Free", &Free)) < 0 || + (code = param_write_int (plist, "InitializeAction",&i0)) < 0 || + (code = param_write_bool(plist, "Mounted", &btrue)) < 0 || + (code = param_write_bool(plist, "Removable", &bfalse)) < 0 || + (code = param_write_bool(plist, "Searchable", &btrue)) < 0 || + (code = param_write_int (plist, "SearchOrder", &so)) < 0 || + (code = param_write_bool(plist, "Writeable", &btrue)) < 0 || + (code = param_write_long(plist, "LogicalSize", &LogicalSize)) < 0 + ) + return code; + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/gsiorom.c ghostscript-9.25~dfsg+1/base/gsiorom.c --- ghostscript-9.10~dfsg/base/gsiorom.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiorom.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -41,6 +41,7 @@ /* device method prototypes */ static iodev_proc_init(romfs_init); +static iodev_proc_finit(romfs_finit); static iodev_proc_open_file(romfs_open_file); static iodev_proc_file_status(romfs_file_status); static iodev_proc_enumerate_files(romfs_enumerate_files_init); @@ -52,7 +53,7 @@ const gx_io_device gs_iodev_rom = { "%rom%", "FileSystem", - {romfs_init, iodev_no_open_device, + {romfs_init, romfs_finit, iodev_no_open_device, romfs_open_file, iodev_no_fopen, iodev_no_fclose, iodev_no_delete_file, iodev_no_rename_file, @@ -114,7 +115,7 @@ s->file = (FILE *)node; /* convenient place to put it for %rom% files */ s->file_modes = s->modes; s->file_offset = 0; - s->file_limit = max_long; + s->file_limit = S_FILE_LIMIT_MAX; } /* Return the number of available bytes */ @@ -193,7 +194,7 @@ if (s->position + (s->cursor.r.limit - s->cbuf + 1) >= filelen || block_data == NULL) return EOFC; /* at EOF */ - if (s->file_limit < max_long) { + if (s->file_limit < S_FILE_LIMIT_MAX) { /* Adjust count for subfile limit */ uint32_t limit_count = s->file_offset + s->file_limit - s->position; @@ -224,7 +225,7 @@ } /* Decompress the data into this block */ code = uncompress (dest, &buflen, block_data, block_length); - if (count != buflen) + if (code != Z_OK || count != buflen) return ERRC; if (need_copy) { memcpy(pw->ptr+1, dest, max_count); @@ -250,11 +251,19 @@ romfs_state *state = gs_alloc_struct(mem, romfs_state, &st_romfs_state, "romfs_init(state)"); if (!state) - return gs_error_VMerror; + return_error(gs_error_VMerror); iodev->state = state; return 0; } +static void +romfs_finit(gx_io_device *iodev, gs_memory_t *mem) +{ + gs_free_object(mem, iodev->state, "romfs_finit"); + iodev->state = NULL; + return; +} + static int romfs_open_file(gx_io_device *iodev, const char *fname, uint namelen, const char *access, stream **ps, gs_memory_t *mem) @@ -308,6 +317,14 @@ char *filename; uint namelen = strlen(fname); + /* a build time of zero indicates we have the "dummy" romfs + * used when COMPILE_INITS==0 - returning a specific error here + * gives us a quick way to check for that. + */ + if (gs_romfs_buildtime == (time_t)0) { + return_error(gs_error_unregistered); + } + memset(pstat, 0, sizeof(struct stat)); /* scan the inodes to find the requested file */ for (i=0; node_scan != 0; i++, node_scan = gs_romfs[i]) { diff -Nru ghostscript-9.10~dfsg/base/gsiorom.h ghostscript-9.25~dfsg+1/base/gsiorom.h --- ghostscript-9.10~dfsg/base/gsiorom.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiorom.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsipar3x.h ghostscript-9.25~dfsg+1/base/gsipar3x.h --- ghostscript-9.10~dfsg/base/gsipar3x.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsipar3x.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsiparam.h ghostscript-9.25~dfsg+1/base/gsiparam.h --- ghostscript-9.10~dfsg/base/gsiparam.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiparam.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,6 +22,7 @@ #include "gsccolor.h" /* for GS_CLIENT_COLOR_MAX_COMPONENTS */ #include "gsmatrix.h" #include "gsstype.h" /* for extern_st */ +#include "gxbitmap.h" /* ---------------- Image parameters ---------------- */ @@ -299,8 +300,21 @@ * 16 though, due to increased time in image_render_mono_ht in the loop * that copies data from scanlines to scancolumns. It seems that writing to * the buffer in positions [0] [16] [32] [48] etc is faster than writing in - * positions [0] [32] [64] [96] etc. For now we leave LAND_BITS set to 16. */ -#define LAND_BITS 16 + * positions [0] [32] [64] [96] etc. We would therefore like to leave + * LAND_BITS set to 16. + * + * Unfortunately, we call through the device interface to copy_mono with the + * results of these buffers, and various copy_mono implementations assume + * that the raster given is a multiple of align_bitmap_mod bits. In order to + * ensure safely, we therefore set LAND_BITS to max(16, align_bitmap_mod). We + * are guaranteed that align_bitmap_mod is a multiple of 16. + */ +#define LAND_BITS_MIN 16 +#if LAND_BITS_MIN < (align_bitmap_mod*8) +#define LAND_BITS (align_bitmap_mod*8) +#else +#define LAND_BITS LAND_BITS_MIN +#endif /* Used for bookkeeping ht buffer information in landscape mode */ typedef struct ht_landscape_info_s { diff -Nru ghostscript-9.10~dfsg/base/gsiparm2.h ghostscript-9.25~dfsg+1/base/gsiparm2.h --- ghostscript-9.10~dfsg/base/gsiparm2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiparm2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -34,7 +34,7 @@ typedef struct gs_image2_s { gs_image_common; - gs_state *DataSource; + gs_gstate *DataSource; float XOrigin, YOrigin; float Width, Height; /* diff -Nru ghostscript-9.10~dfsg/base/gsiparm3.h ghostscript-9.25~dfsg+1/base/gsiparm3.h --- ghostscript-9.10~dfsg/base/gsiparm3.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiparm3.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsiparm4.h ghostscript-9.25~dfsg+1/base/gsiparm4.h --- ghostscript-9.10~dfsg/base/gsiparm4.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsiparm4.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsistate.c ghostscript-9.25~dfsg+1/base/gsistate.c --- ghostscript-9.10~dfsg/base/gsistate.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsistate.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Imager state housekeeping */ -#include "gx.h" -#include "gserrors.h" -#include "gscspace.h" -#include "gscie.h" -#include "gsstruct.h" -#include "gsutil.h" /* for gs_next_ids */ -#include "gxbitmap.h" -#include "gxcmap.h" -#include "gxdht.h" -#include "gxistate.h" -#include "gzht.h" -#include "gzline.h" -#include "gxfmap.h" -#include "gsicc_cache.h" -#include "gsicc_manage.h" -#include "gsicc_profilecache.h" - -/****************************************************************************** - * See gsstate.c for a discussion of graphics/imager state memory management. * - ******************************************************************************/ - -/* Imported values */ -/* The following should include a 'const', but for some reason */ -/* the Watcom compiler won't accept it, even though it happily accepts */ -/* the same construct everywhere else. */ -extern /*const*/ gx_color_map_procs *const cmap_procs_default; - -/* GC procedures for gx_line_params */ -static -ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0; - case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ? - NULL : plp->dash.pattern)); -ENUM_PTRS_END -static RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp) -{ - if (plp->dash.pattern_size) - RELOC_VAR(plp->dash.pattern); -} RELOC_PTRS_END -private_st_line_params(); - -/* - * GC procedures for gs_imager_state - * - * See comments in gixstate.h before the definition of gs_cr_state_do_rc and - * st_cr_state_num_ptrs for an explanation about why the effective_transfer - * pointers are handled in this manner. - */ -public_st_imager_state(); -static -ENUM_PTRS_BEGIN(imager_state_enum_ptrs) - ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs); - ENUM_PTR(0, gs_imager_state, client_data); - ENUM_PTR(1, gs_imager_state, trans_device); - ENUM_PTR(2, gs_imager_state, icc_manager); - ENUM_PTR(3, gs_imager_state, icc_link_cache); - ENUM_PTR(4, gs_imager_state, icc_profile_cache); -#define E1(i,elt) ENUM_PTR(i+5,gs_imager_state,elt); - gs_cr_state_do_ptrs(E1) -#undef E1 -ENUM_PTRS_END -static RELOC_PTRS_BEGIN(imager_state_reloc_ptrs) -{ - RELOC_SUPER(gs_imager_state, st_line_params, line_params); - RELOC_PTR(gs_imager_state, client_data); - RELOC_PTR(gs_imager_state, trans_device); - RELOC_PTR(gs_imager_state, icc_manager); - RELOC_PTR(gs_imager_state, icc_link_cache); - RELOC_PTR(gs_imager_state, icc_profile_cache); -#define R1(i,elt) RELOC_PTR(gs_imager_state,elt); - gs_cr_state_do_ptrs(R1) -#undef R1 - { - int i = GX_DEVICE_COLOR_MAX_COMPONENTS - 1; - - for (; i >= 0; i--) - RELOC_PTR(gs_imager_state, effective_transfer[i]); - } -} RELOC_PTRS_END - -/* Initialize an imager state, other than the parts covered by */ -/* gs_imager_state_initial. */ -int -gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem) -{ - int i; - pis->memory = mem; - pis->client_data = 0; - pis->trans_device = 0; - /* Color rendering state */ - pis->halftone = 0; - { - int i; - - for (i = 0; i < gs_color_select_count; ++i) - pis->screen_phase[i].x = pis->screen_phase[i].y = 0; - } - pis->dev_ht = 0; - pis->cie_render = 0; - pis->cie_to_xyz = false; - pis->black_generation = 0; - pis->undercolor_removal = 0; - /* Allocate an initial transfer map. */ - rc_alloc_struct_n(pis->set_transfer.gray, - gx_transfer_map, &st_transfer_map, - mem, return_error(gs_error_VMerror), - "gs_imager_state_init(transfer)", 1); - pis->set_transfer.gray->proc = gs_identity_transfer; - pis->set_transfer.gray->id = gs_next_ids(pis->memory, 1); - pis->set_transfer.gray->values[0] = frac_0; - pis->set_transfer.red = - pis->set_transfer.green = - pis->set_transfer.blue = NULL; - for (i = 0; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++) - pis->effective_transfer[i] = pis->set_transfer.gray; - pis->cie_joint_caches = NULL; - pis->cie_joint_caches_alt = NULL; - pis->cmap_procs = cmap_procs_default; - pis->pattern_cache = NULL; - pis->have_pattern_streams = false; - pis->devicergb_cs = gs_cspace_new_DeviceRGB(mem); - pis->devicecmyk_cs = gs_cspace_new_DeviceCMYK(mem); - pis->icc_link_cache = gsicc_cache_new(pis->memory); - pis->icc_manager = gsicc_manager_new(pis->memory); - pis->icc_profile_cache = gsicc_profilecache_new(pis->memory); - return 0; -} - -/* - * Make a temporary copy of a gs_imager_state. Note that this does not - * do all the necessary reference counting, etc. However, it does - * clear out the transparency stack in the destination. - */ -gs_imager_state * -gs_imager_state_copy(const gs_imager_state * pis, gs_memory_t * mem) -{ - gs_imager_state *pis_copy = - gs_alloc_struct(mem, gs_imager_state, &st_imager_state, - "gs_imager_state_copy"); - - if (pis_copy) { - *pis_copy = *pis; - } - return pis_copy; -} - -/* Increment reference counts to note that an imager state has been copied. */ -void -gs_imager_state_copied(gs_imager_state * pis) -{ - rc_increment(pis->halftone); - rc_increment(pis->dev_ht); - rc_increment(pis->cie_render); - rc_increment(pis->black_generation); - rc_increment(pis->undercolor_removal); - rc_increment(pis->set_transfer.gray); - rc_increment(pis->set_transfer.red); - rc_increment(pis->set_transfer.green); - rc_increment(pis->set_transfer.blue); - rc_increment(pis->cie_joint_caches); - rc_increment(pis->cie_joint_caches_alt); - rc_increment(pis->devicergb_cs); - rc_increment(pis->devicecmyk_cs); - rc_increment(pis->icc_link_cache); - rc_increment(pis->icc_profile_cache); - rc_increment(pis->icc_manager); -} - -/* Adjust reference counts before assigning one imager state to another. */ -void -gs_imager_state_pre_assign(gs_imager_state *pto, const gs_imager_state *pfrom) -{ - const char *const cname = "gs_imager_state_pre_assign"; - -#define RCCOPY(element)\ - rc_pre_assign(pto->element, pfrom->element, cname) - - RCCOPY(cie_joint_caches); - RCCOPY(cie_joint_caches_alt); - RCCOPY(set_transfer.blue); - RCCOPY(set_transfer.green); - RCCOPY(set_transfer.red); - RCCOPY(set_transfer.gray); - RCCOPY(undercolor_removal); - RCCOPY(black_generation); - RCCOPY(cie_render); - RCCOPY(dev_ht); - RCCOPY(halftone); - RCCOPY(devicergb_cs); - RCCOPY(devicecmyk_cs); - RCCOPY(icc_link_cache); - RCCOPY(icc_profile_cache); - RCCOPY(icc_manager); -#undef RCCOPY -} - -/* Release an imager state. */ -void -gs_imager_state_release(gs_imager_state * pis) -{ - const char *const cname = "gs_imager_state_release"; - gx_device_halftone *pdht = pis->dev_ht; - -#define RCDECR(element)\ - rc_decrement(pis->element, cname);\ - pis->element = NULL /* prevent subsequent decrements from this imager state */ - - RCDECR(cie_joint_caches); - RCDECR(set_transfer.gray); - RCDECR(set_transfer.blue); - RCDECR(set_transfer.green); - RCDECR(set_transfer.red); - RCDECR(undercolor_removal); - RCDECR(black_generation); - RCDECR(cie_render); - /* - * If we're going to free the device halftone, make sure we free the - * dependent structures as well. - */ - if (pdht != 0 && pdht->rc.ref_count == 1) { - gx_device_halftone_release(pdht, pdht->rc.memory); - } - RCDECR(dev_ht); - RCDECR(halftone); - RCDECR(devicergb_cs); - RCDECR(devicecmyk_cs); - RCDECR(icc_link_cache); - RCDECR(icc_profile_cache); - RCDECR(icc_manager); -#undef RCDECR -} diff -Nru ghostscript-9.10~dfsg/base/gsjconf.h ghostscript-9.25~dfsg+1/base/gsjconf.h --- ghostscript-9.10~dfsg/base/gsjconf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsjconf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,6 +31,166 @@ #include "arch.h" +#ifdef GS_HIDE_INTERNAL_JPEG +/* The first list is culled from NEED_SHORT_EXTERNAL_NAMES */ +#define jpeg_std_error gpeg_std_error +#define jpeg_CreateCompress gpeg_CreateCompress +#define jpeg_CreateDecompress gpeg_CreateDecompress +#define jpeg_destroy_compress gpeg_destroy_compress +#define jpeg_destroy_decompress gpeg_destroy_decompress +#define jpeg_stdio_dest gpeg_stdio_dest +#define jpeg_stdio_src gpeg_stdio_src +#define jpeg_mem_dest gpeg_mem_dest +#define jpeg_mem_src gpeg_mem_src +#define jpeg_set_defaults gpeg_set_defaults +#define jpeg_set_colorspace gpeg_set_colorspace +#define jpeg_default_colorspace gpeg_default_colorspace +#define jpeg_set_quality gpeg_set_quality +#define jpeg_set_linear_quality gpeg_set_linear_quality +#define jpeg_default_qtables gpeg_default_qtables +#define jpeg_add_quant_table gpeg_add_quant_table +#define jpeg_quality_scaling gpeg_quality_scaling +#define jpeg_simple_progression gpeg_simple_progression +#define jpeg_suppress_tables gpeg_suppress_tables +#define jpeg_alloc_quant_table gpeg_alloc_quant_table +#define jpeg_alloc_huff_table gpeg_alloc_huff_table +#define jpeg_start_compress gpeg_start_compress +#define jpeg_write_scanlines gpeg_write_scanlines +#define jpeg_finish_compress gpeg_finish_compress +#define jpeg_calc_jpeg_dimensions gpeg_calc_jpeg_dimensions +#define jpeg_write_raw_data gpeg_write_raw_data +#define jpeg_write_marker gpeg_write_marker +#define jpeg_write_m_header gpeg_write_m_header +#define jpeg_write_m_byte gpeg_write_m_byte +#define jpeg_write_tables gpeg_write_tables +#define jpeg_read_header gpeg_read_header +#define jpeg_start_decompress gpeg_start_decompress +#define jpeg_read_scanlines gpeg_read_scanlines +#define jpeg_finish_decompress gpeg_finish_decompress +#define jpeg_read_raw_data gpeg_read_raw_data +#define jpeg_has_multiple_scans gpeg_has_multiple_scans +#define jpeg_start_output gpeg_start_output +#define jpeg_finish_output gpeg_finish_output +#define jpeg_input_complete gpeg_input_complete +#define jpeg_new_colormap gpeg_new_colormap +#define jpeg_consume_input gpeg_consume_input +#define jpeg_core_output_dimensions gpeg_core_output_dimensions +#define jpeg_calc_output_dimensions gpeg_calc_output_dimensions +#define jpeg_save_markers gpeg_save_markers +#define jpeg_set_marker_processor gpeg_set_marker_processor +#define jpeg_read_coefficients gpeg_read_coefficients +#define jpeg_write_coefficients gpeg_write_coefficients +#define jpeg_copy_critical_parameters gpeg_copy_critical_parameters +#define jpeg_abort_compress gpeg_abort_compress +#define jpeg_abort_decompress gpeg_abort_decompress +#define jpeg_abort gpeg_abort +#define jpeg_destroy gpeg_destroy +#define jpeg_resync_to_restart gpeg_resync_to_restart + +/* This second list comes from examination of symbols in the lib */ +#define jpeg_free_small gpeg_free_small +#define jpeg_get_small gpeg_get_small +#define jpeg_get_large gpeg_get_large +#define jpeg_free_large gpeg_free_large +#define jpeg_mem_available gpeg_mem_available +#define jpeg_open_backing_store gpeg_open_backing_store +#define jpeg_mem_init gpeg_mem_init +#define jpeg_mem_term gpeg_mem_term +#define jpeg_natural_order gpeg_natural_order +#define jpeg_natural_order2 gpeg_natural_order2 +#define jpeg_natural_order3 gpeg_natural_order3 +#define jpeg_natural_order4 gpeg_natural_order4 +#define jpeg_natural_order5 gpeg_natural_order5 +#define jpeg_natural_order6 gpeg_natural_order6 +#define jpeg_natural_order7 gpeg_natural_order7 +#define jpeg_fdct_10x10 gpeg_fdct_10x10 +#define jpeg_fdct_10x5 gpeg_fdct_10x5 +#define jpeg_fdct_11x11 gpeg_fdct_11x11 +#define jpeg_fdct_12x12 gpeg_fdct_12x12 +#define jpeg_fdct_12x6 gpeg_fdct_12x6 +#define jpeg_fdct_13x13 gpeg_fdct_13x13 +#define jpeg_fdct_14x14 gpeg_fdct_14x14 +#define jpeg_fdct_14x7 gpeg_fdct_14x7 +#define jpeg_fdct_15x15 gpeg_fdct_15x15 +#define jpeg_fdct_16x16 gpeg_fdct_16x16 +#define jpeg_fdct_16x8 gpeg_fdct_16x8 +#define jpeg_fdct_1x1 gpeg_fdct_1x1 +#define jpeg_fdct_1x2 gpeg_fdct_1x2 +#define jpeg_fdct_2x1 gpeg_fdct_2x1 +#define jpeg_fdct_2x2 gpeg_fdct_2x2 +#define jpeg_fdct_2x4 gpeg_fdct_2x4 +#define jpeg_fdct_3x3 gpeg_fdct_3x3 +#define jpeg_fdct_3x6 gpeg_fdct_3x6 +#define jpeg_fdct_4x2 gpeg_fdct_4x2 +#define jpeg_fdct_4x4 gpeg_fdct_4x4 +#define jpeg_fdct_4x8 gpeg_fdct_4x8 +#define jpeg_fdct_5x10 gpeg_fdct_5x10 +#define jpeg_fdct_5x5 gpeg_fdct_5x5 +#define jpeg_fdct_6x12 gpeg_fdct_6x12 +#define jpeg_fdct_6x3 gpeg_fdct_6x3 +#define jpeg_fdct_6x6 gpeg_fdct_6x6 +#define jpeg_fdct_7x14 gpeg_fdct_7x14 +#define jpeg_fdct_7x7 gpeg_fdct_7x7 +#define jpeg_fdct_8x16 gpeg_fdct_8x16 +#define jpeg_fdct_8x4 gpeg_fdct_8x4 +#define jpeg_fdct_9x9 gpeg_fdct_9x9 +#define jpeg_cust_mem_init gpeg_cust_mem_init +#define jpeg_cust_mem_set_private gpeg_cust_mem_set_private +#define jpeg_fill_bit_buffer gpeg_fill_bit_buffer +#define jpeg_huff_decode gpeg_huff_decode +#define jpeg_make_c_derived_tbl gpeg_make_c_derived_tbl +#define jpeg_make_d_derived_tbl gpeg_make_d_derived_tbl +#define jpeg_zigzag_order gpeg_zigzag_order +#define jpeg_zigzag_order2 gpeg_zigzag_order2 +#define jpeg_zigzag_order3 gpeg_zigzag_order3 +#define jpeg_zigzag_order4 gpeg_zigzag_order4 +#define jpeg_zigzag_order5 gpeg_zigzag_order5 +#define jpeg_zigzag_order6 gpeg_zigzag_order6 +#define jpeg_zigzag_order7 gpeg_zigzag_order7 +#define jpeg_std_message_table gpeg_std_message_table +#define jpeg_aritab gpeg_aritab +#define jpeg_idct_islow gpeg_idct_islow +#define jpeg_fdct_islow gpeg_fdct_islow +#define jpeg_aritab gpeg_aritab +#define jpeg_gen_optimal_table gpeg_gen_optimal_table +#define jinit_marker_reader ginit_marker_reader +#define jdiv_round_up gdiv_round_up +#define jround_up ground_up +#define jcopy_block_row gcopy_block_row +#define jcopy_sample_rows gcopy_sample_rows +#define jinit_input_controller ginit_input_controller +#define jinit_memory_mgr ginit_memory_mgr +#define jinit_master_decompress ginit_master_decompress +#define jinit_huff_decoder ginit_huff_decoder +#define jinit_d_coef_controller ginit_d_coef_controller +#define jinit_color_deconverter ginit_color_deconverter +#define jinit_inverse_dct ginit_inverse_dct +#define jinit_d_main_controller ginit_d_main_controller +#define jinit_arith_decoder ginit_arith_decoder +#define jinit_color_deconverter ginit_color_deconverter +#define jinit_d_coef_controller ginit_d_coef_controller +#define jinit_d_main_controller ginit_d_main_controller +#define jinit_d_post_controller ginit_d_post_controller +#define jinit_huff_decoder ginit_huff_decoder +#define jinit_master_decompress ginit_master_decompress +#define jinit_upsampler ginit_upsampler +#define jinit_d_post_controller ginit_d_post_controller +#define jinit_downsampler ginit_downsampler +#define jinit_arith_decoder ginit_arith_decoder +#define jinit_marker_writer ginit_marker_writer +#define jinit_marker_mgr ginit_marker_mgr +#define jinit_compress_master ginit_compress_master +#define jinit_c_coef_controller ginit_c_coef_controller +#define jinit_color_converter ginit_color_converter +#define jinit_forward_dct ginit_forward_dct +#define jinit_arith_encoder ginit_arith_encoder +#define jinit_huff_encoder ginit_huff_encoder +#define jinit_c_main_controller ginit_c_main_controller +#define jinit_marker_writer ginit_marker_writer +#define jinit_c_master_control ginit_c_master_control +#define jinit_c_prep_controller ginit_c_prep_controller +#endif + /* See IJG's jconfig.doc for the contents of this file. */ #ifdef __PROTOTYPES__ @@ -42,8 +202,12 @@ #undef CHAR_IS_UNSIGNED #ifdef __STDC__ /* is this right? */ +# ifndef HAVE_STDDEF_H # define HAVE_STDDEF_H +# endif +# ifndef HAVE_STDLIB_H # define HAVE_STDLIB_H +# endif #endif #undef NEED_BSD_STRINGS /* WRONG */ diff -Nru ghostscript-9.10~dfsg/base/gsjmorec.h ghostscript-9.25~dfsg+1/base/gsjmorec.h --- ghostscript-9.10~dfsg/base/gsjmorec.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsjmorec.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gslib.c ghostscript-9.25~dfsg+1/base/gslib.c --- ghostscript-9.10~dfsg/base/gslib.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gslib.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,26 +47,27 @@ #include "gxht.h" /* for gs_halftone */ #include "gdevbbox.h" #include "gshtx.h" +#include "gxiodev.h" /* Define whether we are processing captured data. */ /*#define CAPTURE */ /* Test programs */ -static int test1(gs_state *, gs_memory_t *); /* kaleidoscope */ -static int test2(gs_state *, gs_memory_t *); /* pattern fill */ -static int test3(gs_state *, gs_memory_t *); /* RasterOp */ -static int test4(gs_state *, gs_memory_t *); /* set resolution */ -static int test5(gs_state *, gs_memory_t *); /* images */ -static int test6(gs_state *, gs_memory_t *); /* CIE API, snapping */ -static int test7(gs_state *, gs_memory_t *); /* non-monot HT */ -static int test8(gs_state *, gs_memory_t *); /* transp patterns */ +static int test1(gs_gstate *, gs_memory_t *); /* kaleidoscope */ +static int test2(gs_gstate *, gs_memory_t *); /* pattern fill */ +static int test3(gs_gstate *, gs_memory_t *); /* RasterOp */ +static int test4(gs_gstate *, gs_memory_t *); /* set resolution */ +static int test5(gs_gstate *, gs_memory_t *); /* images */ +static int test6(gs_gstate *, gs_memory_t *); /* CIE API, snapping */ +static int test7(gs_gstate *, gs_memory_t *); /* non-monot HT */ +static int test8(gs_gstate *, gs_memory_t *); /* transp patterns */ #ifdef CAPTURE #include "k/capture.c" -static int test10(gs_state *, gs_memory_t *); /* captured data */ +static int test10(gs_gstate *, gs_memory_t *); /* captured data */ #endif -static int (*tests[]) (gs_state *, gs_memory_t *) = +static int (*tests[]) (gs_gstate *, gs_memory_t *) = { test1, test2, test3, test4, test5, test6, test7, test8, 0 @@ -76,11 +77,10 @@ }; /* Include the extern for the device stuff. */ -extern init_proc(gs_iodev_init); extern_gs_lib_device_list(); /* Forward references */ -static float odsf(floatp, floatp); +static float odsf(double, double); static void gs_abort(const gs_memory_t *); int @@ -89,7 +89,7 @@ char achar = '0'; gs_memory_t *mem; - gs_state *pgs; + gs_gstate *pgs; const gx_device *const *list; gx_device *dev; gx_device_bbox *bbdev; @@ -172,7 +172,7 @@ } } dev = (gx_device *) bbdev; - pgs = gs_state_alloc(mem); + pgs = gs_gstate_alloc(mem); gs_setdevice_no_erase(pgs, dev); /* can't erase yet */ { gs_point dpi; @@ -209,7 +209,7 @@ } /* Ordered dither spot function */ static float -odsf(floatp x, floatp y) +odsf(double x, double y) { static const byte dither[256] = { @@ -238,7 +238,7 @@ /* Fill a rectangle. */ static int -fill_rect1(gs_state * pgs, floatp x, floatp y, floatp w, floatp h) +fill_rect1(gs_gstate * pgs, double x, double y, double w, double h) { gs_rect r; @@ -283,7 +283,7 @@ /* Return the number with the magnitude of x and the sign of y. */ /* This is a BSD addition to libm; not all compilers have it. */ static double -gs_copysign(floatp x, floatp y) +gs_copysign(double x, double y) { return ( y >= 0 ? fabs(x) : -fabs(x) ); } @@ -294,7 +294,7 @@ /* Random number generator */ static long rand_state = 1; static long -rand(void) +gs_rand(void) { #define A 16807 #define M 0x7fffffff @@ -311,7 +311,7 @@ return rand_state; } static int -test1(gs_state * pgs, gs_memory_t * mem) +test1(gs_gstate * pgs, gs_memory_t * mem) { int n; @@ -322,7 +322,7 @@ for (n = 200; --n >= 0;) { int j; -#define rf() (rand() / (1.0 * 0x10000 * 0x8000)) +#define rf() (gs_rand() / (1.0 * 0x10000 * 0x8000)) double r = rf(), g = rf(), b = rf(); double x0 = rf(), y0 = rf(), x1 = rf(), y1 = rf(), x2 = rf(), y2 = rf(); @@ -345,7 +345,7 @@ /* Fill an area with a pattern. */ static int -test2(gs_state * pgs, gs_memory_t * mem) +test2(gs_gstate * pgs, gs_memory_t * mem) { gs_client_color cc; gx_tile_bitmap tile; @@ -406,7 +406,7 @@ /* Currently, this only works with monobit devices. */ static int -test3(gs_state * pgs, gs_memory_t * mem) +test3(gs_gstate * pgs, gs_memory_t * mem) { gx_device *dev = gs_currentdevice(pgs); gx_color_index black = gx_device_black(dev); @@ -448,7 +448,7 @@ /* Set the resolution dynamically. */ static int -test4(gs_state * pgs, gs_memory_t * mem) +test4(gs_gstate * pgs, gs_memory_t * mem) { gs_c_param_list list; float resv[2]; @@ -495,7 +495,7 @@ /* Test masked (and non-masked) images. */ static int -test5(gs_state * pgs, gs_memory_t * mem) +test5(gs_gstate * pgs, gs_memory_t * mem) { gx_device *dev = gs_currentdevice(pgs); gx_image_enum_common_t *info; @@ -541,7 +541,7 @@ #define do_image(image, idata)\ BEGIN\ - code = gx_device_begin_typed_image(dev, (gs_imager_state *)pgs, NULL,\ + code = gx_device_begin_typed_image(dev, pgs, NULL,\ (gs_image_common_t *)&image, NULL, &dcolor, NULL, mem, &info);\ /****** TEST code >= 0 ******/\ planes[0].data = idata;\ @@ -575,7 +575,7 @@ image1.BitsPerComponent = 8; gs_translate(pgs, 0.5, 4.0); - code = gx_device_begin_image(dev, (gs_imager_state *) pgs, + code = gx_device_begin_image(dev, pgs, &image1, gs_image_format_chunky, NULL, &dcolor, NULL, mem, &info1); /****** TEST code >= 0 ******/ @@ -632,7 +632,7 @@ /* Display with 1-for-1 mask and image. */ gs_translate(pgs, 0.5, 2.0); - code = gx_device_begin_typed_image(dev, (gs_imager_state *) pgs, + code = gx_device_begin_typed_image(dev, pgs, NULL, (gs_image_common_t *) & image3, NULL, &dcolor, NULL, mem, &info); /****** TEST code >= 0 ******/ @@ -655,7 +655,7 @@ image3.MaskDict.Width *= 2; image3.MaskDict.Height *= 2; gs_translate(pgs, 1.5, 0.0); - code = gx_device_begin_typed_image(dev, (gs_imager_state *) pgs, + code = gx_device_begin_typed_image(dev, pgs, NULL, (gs_image_common_t *) & image3, NULL, &dcolor, NULL, mem, &info); /****** TEST code >= 0 ******/ @@ -722,7 +722,7 @@ /* Test the C API for CIE CRDs, and color snapping. */ static void -spectrum(gs_state * pgs, int n) +spectrum(gs_gstate * pgs, int n) { float den = n; float den1 = n - 1; @@ -745,12 +745,12 @@ } } static float -render_abc(floatp v, const gs_cie_render * ignore_crd) +render_abc(double v, const gs_cie_render * ignore_crd) { return v / 2; } static int -test6(gs_state * pgs, gs_memory_t * mem) +test6(gs_gstate * pgs, gs_memory_t * mem) { gs_color_space *pcs; gs_cie_abc *pabc; @@ -797,7 +797,7 @@ /* Test the C API for non-monotonic halftones. */ static int -test7(gs_state * pgs, gs_memory_t * mem) +test7(gs_gstate * pgs, gs_memory_t * mem) { /* Define a non-monotonic 4 x 4 halftone with 4 gray levels. */ static const byte masks[1 * 4 * 4] = @@ -834,7 +834,7 @@ /* Test partially transparent patterns */ static int -test8(gs_state * pgs, gs_memory_t * mem) +test8(gs_gstate * pgs, gs_memory_t * mem) { /* * Define a 16 x 16 pattern using a 4-entry palette @@ -918,7 +918,7 @@ static const float ymove_origin = 0.0; static int -test10(gs_state * pgs, gs_memory_t * mem) +test10(gs_gstate * pgs, gs_memory_t * mem) { gs_c_param_list list; gs_param_string nstr, OFstr; diff -Nru ghostscript-9.10~dfsg/base/gslibctx.c ghostscript-9.25~dfsg+1/base/gslibctx.c --- ghostscript-9.10~dfsg/base/gslibctx.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gslibctx.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,6 +24,12 @@ #include "string_.h" /* memset */ #include "gp.h" #include "gsicc_manage.h" +#include "gserrors.h" +#include "gscdefs.h" /* for gs_lib_device_list */ +#include "gsstruct.h" /* for gs_gc_root_t */ + +/* Include the extern for the device list. */ +extern_gs_lib_device_list(); static void gs_lib_ctx_get_real_stdio(FILE **in, FILE **out, FILE **err) @@ -42,48 +48,107 @@ gs_memory_t * gs_lib_ctx_get_non_gc_memory_t() { - return mem_err_print ? mem_err_print->non_gc_memory : NULL; + return mem_err_print ? mem_err_print : NULL; } #endif /* This sets the directory to prepend to the ICC profile names specified for defaultgray, defaultrgb, defaultcmyk, proofing, linking, named color and device */ -void +int gs_lib_ctx_set_icc_directory(const gs_memory_t *mem_gc, const char* pname, - int dir_namelen) + int dir_namelen) { char *result; gs_lib_ctx_t *p_ctx = mem_gc->gs_lib_ctx; + gs_memory_t *p_ctx_mem = p_ctx->memory; /* If it is already set and the incoming is the default then don't set as we are coming from a VMreclaim which is trying to reset the user parameter */ if (p_ctx->profiledir != NULL && strcmp(pname,DEFAULT_DIR_ICC) == 0) { - return; + return 0; } - if (p_ctx->profiledir_len > 0) { + if (p_ctx->profiledir != NULL && p_ctx->profiledir_len > 0) { if (strncmp(pname, p_ctx->profiledir, p_ctx->profiledir_len) == 0) { - return; + return 0; } - gs_free_object(mem_gc->non_gc_memory, p_ctx->profiledir, - "gsicc_set_icc_directory"); + gs_free_object(p_ctx_mem, p_ctx->profiledir, + "gs_lib_ctx_set_icc_directory"); } /* User param string. Must allocate in non-gc memory */ - result = (char*) gs_alloc_bytes(mem_gc->non_gc_memory, dir_namelen+1, - "gsicc_set_icc_directory"); - if (result != NULL) { - strcpy(result, pname); - p_ctx->profiledir = result; - p_ctx->profiledir_len = dir_namelen; + result = (char*) gs_alloc_bytes(p_ctx_mem, dir_namelen+1, + "gs_lib_ctx_set_icc_directory"); + if (result == NULL) + return -1; + strcpy(result, pname); + p_ctx->profiledir = result; + p_ctx->profiledir_len = dir_namelen; + return 0; +} + +/* Sets/Gets the string containing the list of default devices we should try */ +int +gs_lib_ctx_set_default_device_list(const gs_memory_t *mem, const char* dev_list_str, + int list_str_len) +{ + char *result; + gs_lib_ctx_t *p_ctx = mem->gs_lib_ctx; + gs_memory_t *ctx_mem = p_ctx->memory; + int code = 0; + + result = (char *)gs_alloc_bytes(ctx_mem, list_str_len + 1, + "gs_lib_ctx_set_default_device_list"); + + if (result) { + gs_free_object(ctx_mem, p_ctx->default_device_list, + "gs_lib_ctx_set_default_device_list"); + + memcpy(result, dev_list_str, list_str_len); + result[list_str_len] = '\0'; + p_ctx->default_device_list = result; + } + else { + code = gs_note_error(gs_error_VMerror); + } + return code; +} + +int +gs_lib_ctx_get_default_device_list(const gs_memory_t *mem, char** dev_list_str, + int *list_str_len) +{ + /* In the case the lib ctx hasn't been initialised */ + if (mem && mem->gs_lib_ctx && mem->gs_lib_ctx->default_device_list) { + *dev_list_str = mem->gs_lib_ctx->default_device_list; + } + else { + *dev_list_str = (char *)gs_dev_defaults; } + + *list_str_len = strlen(*dev_list_str); + + return 0; +} + +static int +gs_lib_ctx_alloc_root_structure(gs_memory_t *mem, gs_gc_root_ptr *rp) +{ + int code = 0; + + *rp = gs_raw_alloc_struct_immovable(mem, &st_gc_root_t, "gs_lib_ctx_alloc_root_structure"); + if (*rp == 0) + code = gs_note_error(gs_error_VMerror); + + return code; } int gs_lib_ctx_init( gs_memory_t *mem ) { gs_lib_ctx_t *pio = 0; - if ( mem == 0 ) - return -1; /* assert mem != 0 */ + /* Check the non gc allocator is being passed in */ + if (mem == 0 || mem != mem->non_gc_memory) + return_error(gs_error_Fatal); #ifndef GS_THREADSAFE mem_err_print = mem; @@ -113,25 +178,83 @@ /* Initialize our default ICCProfilesDir */ pio->profiledir = NULL; pio->profiledir_len = 0; - gs_lib_ctx_set_icc_directory(mem, DEFAULT_DIR_ICC, strlen(DEFAULT_DIR_ICC)); + pio->icc_color_accuracy = MAX_COLOR_ACCURACY; + if (gs_lib_ctx_set_icc_directory(mem, DEFAULT_DIR_ICC, strlen(DEFAULT_DIR_ICC)) < 0) + goto Failure; + + if (gs_lib_ctx_set_default_device_list(mem, gs_dev_defaults, + strlen(gs_dev_defaults)) < 0) + goto Failure; /* Initialise the underlying CMS. */ - if (gscms_create(mem)) { - gs_free_object(mem, pio, "gsicc_set_icc_directory"); - mem->gs_lib_ctx = NULL; - return -1; - } - + if (gscms_create(mem)) + goto Failure; + + /* Initialise any lock required for the jpx codec */ + if (sjpxd_create(mem)) + goto Failure; + + pio->client_check_file_permission = NULL; gp_get_realtime(pio->real_time_0); + /* Set scanconverter to 1 (default) */ + pio->scanconverter = GS_SCANCONVERTER_DEFAULT; + + if (gs_lib_ctx_alloc_root_structure(mem, &pio->name_table_root)) + goto Failure; + + if (gs_lib_ctx_alloc_root_structure(mem, &pio->io_device_table_root)) + goto Failure; + + if (gs_lib_ctx_alloc_root_structure(mem, &pio->font_dir_root)) + goto Failure; + return 0; + +Failure: + gs_lib_ctx_fin(mem); + return -1; +} + +static void remove_ctx_pointers(gs_memory_t *mem) +{ + mem->gs_lib_ctx = NULL; + if (mem->stable_memory && mem->stable_memory != mem) + remove_ctx_pointers(mem->stable_memory); + if (mem->non_gc_memory && mem->non_gc_memory != mem) + remove_ctx_pointers(mem->non_gc_memory); + if (mem->thread_safe_memory && mem->thread_safe_memory != mem) + remove_ctx_pointers(mem->thread_safe_memory); } -void gs_lib_ctx_fin( gs_memory_t *mem ) +void gs_lib_ctx_fin(gs_memory_t *mem) { + gs_lib_ctx_t *ctx; + gs_memory_t *ctx_mem; + if (!mem || !mem->gs_lib_ctx) return; - gscms_destroy(mem); + + ctx = mem->gs_lib_ctx; + ctx_mem = ctx->memory; + + sjpxd_destroy(mem); + gscms_destroy(ctx_mem); + gs_free_object(ctx_mem, ctx->profiledir, + "gs_lib_ctx_fin"); + + gs_free_object(ctx_mem, ctx->default_device_list, + "gs_lib_ctx_fin"); + + gs_free_object(ctx_mem, ctx->name_table_root, "gs_lib_ctx_fin"); + gs_free_object(ctx_mem, ctx->io_device_table_root, "gs_lib_ctx_fin"); + gs_free_object(ctx_mem, ctx->font_dir_root, "gs_lib_ctx_fin"); + +#ifndef GS_THREADSAFE + mem_err_print = NULL; +#endif + remove_ctx_pointers(ctx_mem); + gs_free_object(ctx_mem, ctx, "gs_lib_ctx_init"); } gs_lib_ctx_t *gs_lib_ctx_get_interp_instance(const gs_memory_t *mem) @@ -195,6 +318,15 @@ gs_lib_ctx_t *ctx; if (len == 0) return 0; + if (mem == NULL) { +#ifdef GS_THREADSAFE + return 0; +#else + mem = mem_err_print; + if (mem == NULL) + return 0; +#endif + } ctx = mem->gs_lib_ctx; if (ctx == NULL) return 0; @@ -233,3 +365,13 @@ fflush(mem->gs_lib_ctx->fstderr); /* else nothing to flush */ } + +int +gs_check_file_permission (gs_memory_t *mem, const char *fname, const int len, const char *permission) +{ + int code = 0; + if (mem->gs_lib_ctx->client_check_file_permission != NULL) { + code = mem->gs_lib_ctx->client_check_file_permission(mem, fname, len, permission); + } + return code; +} diff -Nru ghostscript-9.10~dfsg/base/gslibctx.h ghostscript-9.25~dfsg+1/base/gslibctx.h --- ghostscript-9.10~dfsg/base/gslibctx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gslibctx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,6 +23,10 @@ typedef struct name_table_s *name_table_ptr; +/* Opaque type for root pointer here, because including gsstruct.h for the + original gs_gc_root_t definition resulted in a circular header dependency. */ +typedef struct gs_gc_root_s *gs_gc_root_ptr; + #ifndef gs_fapi_server_DEFINED #define gs_fapi_server_DEFINED typedef struct gs_fapi_server_s gs_fapi_server; @@ -32,6 +36,9 @@ # define gs_font_dir_DEFINED typedef struct gs_font_dir_s gs_font_dir; #endif + +typedef int (*client_check_file_permission_t) (gs_memory_t *mem, const char *fname, const int len, const char *permission); + typedef struct gs_lib_ctx_s { gs_memory_t *memory; /* mem->gs_lib_ctx->memory == mem */ @@ -55,33 +62,54 @@ name_table_ptr gs_name_table; /* hack this is the ps interpreters name table * doesn't belong here */ + gs_gc_root_ptr name_table_root; /* Define whether dictionaries expand automatically when full. */ bool dict_auto_expand; /* ps dictionary: false level 1 true level 2 or 3 */ /* A table of local copies of the IODevices */ struct gx_io_device_s **io_device_table; + int io_device_table_count; + int io_device_table_size; + gs_gc_root_ptr io_device_table_root; + client_check_file_permission_t client_check_file_permission; /* Define the default value of AccurateScreens that affects setscreen and setcolorscreen. */ bool screen_accurate_screens; uint screen_min_screen_levels; + /* Accuracy vs. performance for ICC color */ + uint icc_color_accuracy; /* real time clock 'bias' value. Not strictly required, but some FTS * tests work better if realtime starts from 0 at boot time. */ long real_time_0[2]; /* font directory - see gsfont.h */ gs_font_dir *font_dir; + gs_gc_root_ptr font_dir_root; /* True if we are emulating CPSI. Ideally this would be in the imager * state, but this can't be done due to problems detecting changes in it * for the clist based devices. */ bool CPSI_mode; - /* Keep the path for the ICCProfiles here so devices and the icc_manager + /* Keep the path for the ICCProfiles here so devices and the icc_manager * can get to it. Prevents needing two copies, one in the icc_manager * and one in the device */ char *profiledir; /* Directory used in searching for ICC profiles */ int profiledir_len; /* length of directory name (allows for Unicode) */ void *cms_context; /* Opaque context pointer from underlying CMS in use */ gs_fapi_server **fapi_servers; + char *default_device_list; + int gcsignal; + int scanconverter; + void *sjpxd_private; /* optional for use of jpx codec */ } gs_lib_ctx_t; +enum { + GS_SCANCONVERTER_OLD = 0, + GS_SCANCONVERTER_DEFAULT = 1, + GS_SCANCONVERTER_EDGEBUFFER = 2, + + /* And finally a flag to let us know which is the default */ + GS_SCANCONVERTER_DEFAULT_IS_EDGEBUFFER = 1 +}; + /** initializes and stores itself in the given gs_memory_t pointer. * it is the responsibility of the gs_memory_t objects to copy * the pointer to subsequent memory objects. @@ -105,7 +133,31 @@ gs_memory_t * gs_lib_ctx_get_non_gc_memory_t(void); #endif -void gs_lib_ctx_set_icc_directory(const gs_memory_t *mem_gc, const char* pname, - int dir_namelen); +int gs_lib_ctx_set_icc_directory(const gs_memory_t *mem_gc, const char* pname, + int dir_namelen); + + +/* Sets/Gets the string containing the list of device names we should search + * to find a suitable default + */ +int +gs_lib_ctx_set_default_device_list(const gs_memory_t *mem, const char* dev_list_str, + int list_str_len); + +/* Returns a pointer to the string not a new string */ +int +gs_lib_ctx_get_default_device_list(const gs_memory_t *mem, char** dev_list_str, + int *list_str_len); + +int +gs_check_file_permission (gs_memory_t *mem, const char *fname, const int len, const char *permission); + +#define IS_LIBCTX_STDOUT(mem, f) (f == mem->gs_lib_ctx->fstdout) +#define IS_LIBCTX_STDERR(mem, f) (f == mem->gs_lib_ctx->fstderr) + +/* Functions to init/fin JPX decoder libctx entry */ +int sjpxd_create(gs_memory_t *mem); + +void sjpxd_destroy(gs_memory_t *mem); #endif /* GSLIBCTX_H */ diff -Nru ghostscript-9.10~dfsg/base/gslib.h ghostscript-9.25~dfsg+1/base/gslib.h --- ghostscript-9.10~dfsg/base/gslib.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gslib.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsline.c ghostscript-9.25~dfsg+1/base/gsline.c --- ghostscript-9.10~dfsg/base/gsline.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsline.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,7 +32,7 @@ /* setlinewidth */ int -gs_setlinewidth(gs_state * pgs, floatp width) +gs_setlinewidth(gs_gstate * pgs, double width) { gx_set_line_width(pgs_lp, width); return 0; @@ -40,14 +40,14 @@ /* currentlinewidth */ float -gs_currentlinewidth(const gs_state * pgs) +gs_currentlinewidth(const gs_gstate * pgs) { return gx_current_line_width(pgs_lp); } /* setlinecap (sets all 3 caps) */ int -gs_setlinecap(gs_state * pgs, gs_line_cap cap) +gs_setlinecap(gs_gstate * pgs, gs_line_cap cap) { if ((uint) cap > gs_line_cap_max) return_error(gs_error_rangecheck); @@ -59,7 +59,7 @@ /* setlinestartcap */ int -gs_setlinestartcap(gs_state * pgs, gs_line_cap cap) +gs_setlinestartcap(gs_gstate * pgs, gs_line_cap cap) { if ((uint) cap > gs_line_cap_max) return_error(gs_error_rangecheck); @@ -69,7 +69,7 @@ /* setlineendcap */ int -gs_setlineendcap(gs_state * pgs, gs_line_cap cap) +gs_setlineendcap(gs_gstate * pgs, gs_line_cap cap) { if ((uint) cap > gs_line_cap_max) return_error(gs_error_rangecheck); @@ -79,7 +79,7 @@ /* setlinedashcap */ int -gs_setlinedashcap(gs_state * pgs, gs_line_cap cap) +gs_setlinedashcap(gs_gstate * pgs, gs_line_cap cap) { if ((uint) cap > gs_line_cap_max) return_error(gs_error_rangecheck); @@ -89,7 +89,7 @@ /* currentlinecap */ gs_line_cap -gs_currentlinecap(const gs_state * pgs) +gs_currentlinecap(const gs_gstate * pgs) { /* This assumes that all caps are the same as start_cap - this will be * the case for postscript at least. */ @@ -98,7 +98,7 @@ /* setlinejoin */ int -gs_setlinejoin(gs_state * pgs, gs_line_join join) +gs_setlinejoin(gs_gstate * pgs, gs_line_join join) { if ((uint) join > gs_line_join_max) return_error(gs_error_rangecheck); @@ -108,14 +108,14 @@ /* currentlinejoin */ gs_line_join -gs_currentlinejoin(const gs_state * pgs) +gs_currentlinejoin(const gs_gstate * pgs) { return pgs_lp->join; } /* setmiterlimit */ int -gx_set_miter_limit(gx_line_params * plp, floatp limit) +gx_set_miter_limit(gx_line_params * plp, double limit) { if (limit < 1.0) return_error(gs_error_rangecheck); @@ -140,14 +140,14 @@ return 0; } int -gs_setmiterlimit(gs_state * pgs, floatp limit) +gs_setmiterlimit(gs_gstate * pgs, double limit) { return gx_set_miter_limit(pgs_lp, limit); } /* currentmiterlimit */ float -gs_currentmiterlimit(const gs_state * pgs) +gs_currentmiterlimit(const gs_gstate * pgs) { return pgs_lp->miter_limit; } @@ -155,7 +155,7 @@ /* setdash */ int gx_set_dash(gx_dash_params * dash, const float *pattern, uint length, - floatp offset, gs_memory_t * mem) + double offset, gs_memory_t * mem) { uint n = length; const float *dfrom = pattern; @@ -228,7 +228,7 @@ return 0; } int -gs_setdash(gs_state * pgs, const float *pattern, uint length, floatp offset) +gs_setdash(gs_gstate * pgs, const float *pattern, uint length, double offset) { return gx_set_dash(&pgs_lp->dash, pattern, length, offset, pgs->memory); @@ -236,57 +236,57 @@ /* currentdash */ uint -gs_currentdash_length(const gs_state * pgs) +gs_currentdash_length(const gs_gstate * pgs) { return pgs_lp->dash.pattern_size; } const float * -gs_currentdash_pattern(const gs_state * pgs) +gs_currentdash_pattern(const gs_gstate * pgs) { return pgs_lp->dash.pattern; } float -gs_currentdash_offset(const gs_state * pgs) +gs_currentdash_offset(const gs_gstate * pgs) { return pgs_lp->dash.offset; } /* Internal accessor for line parameters */ const gx_line_params * -gs_currentlineparams(const gs_imager_state * pis) +gs_currentlineparams(const gs_gstate * pgs) { - return gs_currentlineparams_inline(pis); + return gs_currentlineparams_inline(pgs); } /* ------ Device-dependent parameters ------ */ /* setflat */ int -gs_imager_setflat(gs_imager_state * pis, floatp flat) +gs_gstate_setflat(gs_gstate * pgs, double flat) { if (flat <= 0.2) flat = 0.2; else if (flat > 100) flat = 100; - pis->flatness = flat; + pgs->flatness = flat; return 0; } int -gs_setflat(gs_state * pgs, floatp flat) +gs_setflat(gs_gstate * pgs, double flat) { - return gs_imager_setflat((gs_imager_state *) pgs, flat); + return gs_gstate_setflat(pgs, flat); } /* currentflat */ float -gs_currentflat(const gs_state * pgs) +gs_currentflat(const gs_gstate * pgs) { return pgs->flatness; } /* setstrokeadjust */ int -gs_setstrokeadjust(gs_state * pgs, bool stroke_adjust) +gs_setstrokeadjust(gs_gstate * pgs, bool stroke_adjust) { pgs->stroke_adjust = stroke_adjust; return 0; @@ -294,7 +294,7 @@ /* currentstrokeadjust */ bool -gs_currentstrokeadjust(const gs_state * pgs) +gs_currentstrokeadjust(const gs_gstate * pgs) { return pgs->stroke_adjust; } @@ -305,26 +305,26 @@ /* setdashadapt */ void -gs_setdashadapt(gs_state * pgs, bool adapt) +gs_setdashadapt(gs_gstate * pgs, bool adapt) { pgs_lp->dash.adapt = adapt; } /* currentdashadapt */ bool -gs_imager_currentdashadapt(const gs_imager_state * pis) +gs_gstate_currentdashadapt(const gs_gstate * pgs) { - return gs_currentlineparams_inline(pis)->dash.adapt; + return gs_currentlineparams_inline(pgs)->dash.adapt; } bool -gs_currentdashadapt(const gs_state * pgs) +gs_currentdashadapt(const gs_gstate * pgs) { - return gs_imager_currentdashadapt((const gs_imager_state *)pgs); + return gs_gstate_currentdashadapt((const gs_gstate *)pgs); } /* setcurvejoin */ int -gs_setcurvejoin(gs_state * pgs, int join) +gs_setcurvejoin(gs_gstate * pgs, int join) { if (join < -1 || join > gs_line_join_max) return_error(gs_error_rangecheck); @@ -334,7 +334,7 @@ /* currentcurvejoin */ int -gs_currentcurvejoin(const gs_state * pgs) +gs_currentcurvejoin(const gs_gstate * pgs) { return pgs_lp->curve_join; } @@ -343,26 +343,26 @@ /* setaccuratecurves */ void -gs_setaccuratecurves(gs_state * pgs, bool accurate) +gs_setaccuratecurves(gs_gstate * pgs, bool accurate) { pgs->accurate_curves = accurate; } /* currentaccuratecurves */ bool -gs_imager_currentaccuratecurves(const gs_imager_state * pis) +gs_gstate_currentaccuratecurves(const gs_gstate * pgs) { - return pis->accurate_curves; + return pgs->accurate_curves; } bool -gs_currentaccuratecurves(const gs_state * pgs) +gs_currentaccuratecurves(const gs_gstate * pgs) { - return gs_imager_currentaccuratecurves((const gs_imager_state *)pgs); + return gs_gstate_currentaccuratecurves((const gs_gstate *)pgs); } /* setdotlength */ int -gx_set_dot_length(gx_line_params * plp, floatp length, bool absolute) +gx_set_dot_length(gx_line_params * plp, double length, bool absolute) { if (length < 0) return_error(gs_error_rangecheck); @@ -371,26 +371,26 @@ return 0; } int -gs_setdotlength(gs_state * pgs, floatp length, bool absolute) +gs_setdotlength(gs_gstate * pgs, double length, bool absolute) { return gx_set_dot_length(pgs_lp, length, absolute); } /* currentdotlength */ float -gs_currentdotlength(const gs_state * pgs) +gs_currentdotlength(const gs_gstate * pgs) { return pgs_lp->dot_length; } bool -gs_currentdotlength_absolute(const gs_state * pgs) +gs_currentdotlength_absolute(const gs_gstate * pgs) { return pgs_lp->dot_length_absolute; } /* setdotorientation */ int -gs_setdotorientation(gs_state *pgs) +gs_setdotorientation(gs_gstate *pgs) { if (is_xxyy(&pgs->ctm) || is_xyyx(&pgs->ctm)) return gs_currentmatrix(pgs, &pgs_lp->dot_orientation); @@ -399,7 +399,7 @@ /* dotorientation */ int -gs_dotorientation(gs_state *pgs) +gs_dotorientation(gs_gstate *pgs) { return gs_setmatrix(pgs, &pgs_lp->dot_orientation); } diff -Nru ghostscript-9.10~dfsg/base/gsline.h ghostscript-9.25~dfsg+1/base/gsline.h --- ghostscript-9.10~dfsg/base/gsline.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsline.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,48 +22,48 @@ #include "gslparam.h" /* Procedures */ -int gs_setlinewidth(gs_state *, floatp); -float gs_currentlinewidth(const gs_state *); -int gs_setlinecap(gs_state *, gs_line_cap); -gs_line_cap gs_currentlinecap(const gs_state *); -int gs_setlinestartcap(gs_state *, gs_line_cap); -int gs_setlineendcap(gs_state *, gs_line_cap); -int gs_setlinedashcap(gs_state *, gs_line_cap); -int gs_setlinejoin(gs_state *, gs_line_join); -gs_line_join gs_currentlinejoin(const gs_state *); -int gs_setmiterlimit(gs_state *, floatp); -float gs_currentmiterlimit(const gs_state *); -int gs_setdash(gs_state *, const float *, uint, floatp); -uint gs_currentdash_length(const gs_state *); -const float *gs_currentdash_pattern(const gs_state *); -float gs_currentdash_offset(const gs_state *); -int gs_setflat(gs_state *, floatp); -float gs_currentflat(const gs_state *); -int gs_setstrokeadjust(gs_state *, bool); -bool gs_currentstrokeadjust(const gs_state *); +int gs_setlinewidth(gs_gstate *, double); +float gs_currentlinewidth(const gs_gstate *); +int gs_setlinecap(gs_gstate *, gs_line_cap); +gs_line_cap gs_currentlinecap(const gs_gstate *); +int gs_setlinestartcap(gs_gstate *, gs_line_cap); +int gs_setlineendcap(gs_gstate *, gs_line_cap); +int gs_setlinedashcap(gs_gstate *, gs_line_cap); +int gs_setlinejoin(gs_gstate *, gs_line_join); +gs_line_join gs_currentlinejoin(const gs_gstate *); +int gs_setmiterlimit(gs_gstate *, double); +float gs_currentmiterlimit(const gs_gstate *); +int gs_setdash(gs_gstate *, const float *, uint, double); +uint gs_currentdash_length(const gs_gstate *); +const float *gs_currentdash_pattern(const gs_gstate *); +float gs_currentdash_offset(const gs_gstate *); +int gs_setflat(gs_gstate *, double); +float gs_currentflat(const gs_gstate *); +int gs_setstrokeadjust(gs_gstate *, bool); +bool gs_currentstrokeadjust(const gs_gstate *); /* Extensions - device-independent */ -void gs_setdashadapt(gs_state *, bool); -bool gs_currentdashadapt(const gs_state *); -int gs_setcurvejoin(gs_state *, int); -int gs_currentcurvejoin(const gs_state *); +void gs_setdashadapt(gs_gstate *, bool); +bool gs_currentdashadapt(const gs_gstate *); +int gs_setcurvejoin(gs_gstate *, int); +int gs_currentcurvejoin(const gs_gstate *); /* Extensions - device-dependent */ -void gs_setaccuratecurves(gs_state *, bool); -bool gs_currentaccuratecurves(const gs_state *); -int gs_setdotlength(gs_state *, floatp, bool); -float gs_currentdotlength(const gs_state *); -bool gs_currentdotlength_absolute(const gs_state *); -int gs_setdotorientation(gs_state *); -int gs_dotorientation(gs_state *); - -/* Imager-level procedures */ -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +void gs_setaccuratecurves(gs_gstate *, bool); +bool gs_currentaccuratecurves(const gs_gstate *); +int gs_setdotlength(gs_gstate *, double, bool); +float gs_currentdotlength(const gs_gstate *); +bool gs_currentdotlength_absolute(const gs_gstate *); +int gs_setdotorientation(gs_gstate *); +int gs_dotorientation(gs_gstate *); + +/* gs_gstate-level procedures */ +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif -int gs_imager_setflat(gs_imager_state *, floatp); -bool gs_imager_currentdashadapt(const gs_imager_state *); -bool gs_imager_currentaccuratecurves(const gs_imager_state *); +int gs_gstate_setflat(gs_gstate *, double); +bool gs_gstate_currentdashadapt(const gs_gstate *); +bool gs_gstate_currentaccuratecurves(const gs_gstate *); #endif /* gsline_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gslparam.h ghostscript-9.25~dfsg+1/base/gslparam.h --- ghostscript-9.10~dfsg/base/gslparam.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gslparam.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gs.mak ghostscript-9.25~dfsg+1/base/gs.mak --- ghostscript-9.10~dfsg/base/gs.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gs.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # Generic makefile, common to all platforms, products, and configurations. @@ -240,7 +240,6 @@ LCUPSIGENDIR=$(GLGENDIR) LCUPSIOBJDIR=$(GLOBJDIR) -TRIOOBJDIR=$(GLOBJDIR) #**************** END PATCHES GSGEN=$(GLGENDIR)$(D) @@ -249,10 +248,14 @@ #DD=$(GLGEN) # Define the name of this makefile. -GS_MAK=$(GLSRCDIR)$(D)gs.mak +GS_MAK=$(GLSRCDIR)$(D)gs.mak $(TOP_MAKEFILES) # Define the names of the executables. GS_XE=$(BINDIR)$(D)$(GS)$(XE) +GPCL_XE=$(BINDIR)$(D)$(PCL)$(XE) +GXPS_XE=$(BINDIR)$(D)$(XPS)$(XE) +GPDL_XE=$(BINDIR)$(D)$(GPDL)$(XE) + AUX=$(AUXDIR)$(D) ECHOGS_XE=$(AUX)echogs$(XEAUX) GENARCH_XE=$(AUX)genarch$(XEAUX) @@ -260,6 +263,7 @@ GENDEV_XE=$(AUX)gendev$(XEAUX) GENHT_XE=$(AUX)genht$(XEAUX) MKROMFS_XE=$(AUX)mkromfs$(XEAUX) +PACKPS_XE=$(AUX)packps$(XEAUX) # Define the names of the generated header files. # gconfig*.h and gconfx*.h are generated dynamically. @@ -268,7 +272,10 @@ gconfigf_h=$(GLGENDIR)$(D)gconfxc.h gconfigd_h=$(GLGENDIR)$(D)gconfigd.h -all default : $(GS_XE) $(GS_SHARED_OBJS) $(MAKEDIRSTOP) $(MAKEDIRS) +iconfxx_h=$(GLGENDIR)$(D)iconfxx.h +iconfig_h=$(GLGENDIR)$(D)iconfig.h + +all default : $(GS_XE) $(PCL_XPS_TARGETS) $(GS_SHARED_OBJS) $(MAKEDIRSTOP) $(GS_MAK) $(MAKEDIRS) $(NO_OP) # the distclean and maintainer-clean targets (if any) @@ -278,12 +285,14 @@ realclean : clean $(NO_OP) -clean : mostlyclean +cleansub : mostlyclean $(RM_) $(GSGEN)arch.h $(RM_) $(GS_XE) $(RM_) $(GS_SHARED_OBJS) $(RMN_) -r $(BINDIR) $(GLGENDIR) $(GLOBJDIR) $(PSGENDIR) $(PSOBJDIR) +clean : cleansub $(PCL_XPS_CLEAN) + $(NO_OP) #****** FOLLOWING IS WRONG, NEEDS TO BE PER-SUBSYSTEM ****** mostlyclean : config-clean $(RMN_) $(GSOBJ)*.$(OBJ) $(GSOBJ)*.a $(GSOBJ)core $(GSOBJ)gmon.out @@ -296,6 +305,7 @@ $(RMN_) $(MKROMFS_XE) $(RMN_) $(MKROMFS_XE)_0 $(RMN_) $(MKROMFS_XE)_1 + $(RMN_) $(PACKPS_XE) $(RMN_) $(GSGEN)gsromfs1.c $(GSGEN)gsromfs1_.c $(GSGEN)gsromfs1_1.c $(RMN_) $(AUX)*.$(OBJ) $(AUX)gscdefs*.c @@ -324,10 +334,11 @@ JI_=$(JSRCDIR) JF_= JCF_=$(D_)SHARE_JPEG=$(SHARE_JPEG)$(_D) -PI_=$(PNGSRCDIR) $(II)$(ZSRCDIR) +ZI_=$(ZSRCDIR) +PI_=$(PNGSRCDIR) $(II)$(ZI_) # PF_ should include PNG_USE_CONST, but this doesn't work. #PF_=-DPNG_USE_CONST -TI_=$(TIFFSRCDIR)$(D)libtiff $(II)$(TIFFCONFDIR)$(D)libtiff $(II)$(JGENDIR) $(II)$(ZSRCDIR) +TI_=$(TIFFSRCDIR)$(D)libtiff $(II)$(TIFFCONFDIR)$(D)libtiff $(II)$(JGENDIR) $(II)$(ZI_) PF_= PCF_=$(D_)SHARE_LIBPNG=$(SHARE_LIBPNG)$(_D) ZI_=$(ZSRCDIR) @@ -338,7 +349,7 @@ LDF_JB2I_=$(JBIG2SRCDIR)$(D)source$(D)libraries LWF_JPXI_=$(JPXSRCDIR)$(D)library$(D)source JPXCF_=$(JPX_CFLAGS) -JPX_OPENJPEG_I_=$(JPXSRCDIR)$(D)libopenjpeg +JPX_OPENJPEG_I_=$(JPXSRCDIR)$(D)src$(D)lib$(D)openjp2 ######################## How to define new 'features' ####################### # @@ -376,46 +387,81 @@ # FEATURE_DEVS_EXTRA and DEVICE_DEVS_EXTRA are explicitly reserved # to be set from the command line. +GSPLAT_DEVS_ALL=$(GLGENDIR)$(D)$(GSPLATFORM).dev + +DEVICE_DEVS_ALL=$(DEVICE_DEVS) $(DEVICE_DEVS1) \ + $(DEVICE_DEVS2) $(DEVICE_DEVS3) $(DEVICE_DEVS4) $(DEVICE_DEVS5) \ + $(DEVICE_DEVS6) $(DEVICE_DEVS7) $(DEVICE_DEVS8) $(DEVICE_DEVS9) \ + $(DEVICE_DEVS10) $(DEVICE_DEVS11) $(DEVICE_DEVS12) $(DEVICE_DEVS13) \ + $(DEVICE_DEVS14) $(DEVICE_DEVS15) $(DEVICE_DEVS16) $(DEVICE_DEVS17) \ + $(DEVICE_DEVS18) $(DEVICE_DEVS19) $(DEVICE_DEVS20) $(DEVICE_DEVS21) \ + $(DEVICE_DEVS_EXTRA) + +PSI_DEVS_ALL=$(GSPLAT_DEVS_ALL) \ + $(PSI_FEATURE_DEVS) \ + $(FEATURE_DEVS) \ + $(FEATURE_DEVS_EXTRA) \ + $(DEVICE_DEVS_ALL) + +PCL_DEVS_ALL=$(GSPLAT_DEVS_ALL) \ + $(FEATURE_DEVS) \ + $(FEATURE_DEVS_EXTRA) \ + $(DEVICE_DEVS_ALL) + +XPS_DEVS_ALL=$(GSPLAT_DEVS_ALL) \ + $(FEATURE_DEVS) \ + $(FEATURE_DEVS_EXTRA) \ + $(DEVICE_DEVS_ALL) + DEVS_ALL=$(GLGENDIR)$(D)$(GSPLATFORM).dev\ - $(FEATURE_DEVS) $(FEATURE_DEVS_EXTRA) \ + $(FEATURE_DEVS_EXTRA) \ $(DEVICE_DEVS) $(DEVICE_DEVS1) \ $(DEVICE_DEVS2) $(DEVICE_DEVS3) $(DEVICE_DEVS4) $(DEVICE_DEVS5) \ $(DEVICE_DEVS6) $(DEVICE_DEVS7) $(DEVICE_DEVS8) $(DEVICE_DEVS9) \ $(DEVICE_DEVS10) $(DEVICE_DEVS11) $(DEVICE_DEVS12) $(DEVICE_DEVS13) \ $(DEVICE_DEVS14) $(DEVICE_DEVS15) $(DEVICE_DEVS16) $(DEVICE_DEVS17) \ $(DEVICE_DEVS18) $(DEVICE_DEVS19) $(DEVICE_DEVS20) $(DEVICE_DEVS21) \ - $(DEVICE_DEVS_EXTRA) $(GLD)romfs$(COMPILE_INITS).dev + $(DEVICE_DEVS_EXTRA) + + +$(GLGENDIR)$(D)fdevs.tr: $(GS_MAK) $(ECHOGS_XE) $(GSPLAT_DEVS_ALL) $(FEATURE_DEVS) $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(GLGENDIR)$(D)fdevs.tr - -include $(GLGENDIR)$(D)$(GSPLATFORM) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)fdevs.tr -+ $(FEATURE_DEVS) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)fdevs.tr -+ $(FEATURE_DEVS_EXTRA) + +$(GLGENDIR)$(D)devdevs.tr: $(GS_MAK) $(ECHOGS_XE) $(DEVICE_DEVS_ALL) $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS1) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS2) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS3) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS4) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS5) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS6) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS7) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS8) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS9) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS10) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS11) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS12) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS13) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS14) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS15) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS16) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS17) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS18) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS19) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS20) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS21) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr -+ $(DEVICE_DEVS_EXTRA) + $(EXP)$(ECHOGS_XE) -a $(GLGENDIR)$(D)devdevs.tr - $(GLGENDIR)$(D)libcore devs_tr=$(GLGENDIR)$(D)devs.tr -$(devs_tr) : $(GS_MAK) $(TOP_MAKEFILES) $(ECHOGS_XE) - $(EXP)$(ECHOGS_XE) -w $(devs_tr) - -include $(GLGENDIR)$(D)$(GSPLATFORM) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(FEATURE_DEVS) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(FEATURE_DEVS_EXTRA) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS1) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS2) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS3) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS4) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS5) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS6) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS7) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS8) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS9) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS10) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS11) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS12) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS13) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS14) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS15) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS16) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS17) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS18) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS19) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS20) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS21) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(DEVICE_DEVS_EXTRA) - $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ $(GLD)romfs$(COMPILE_INITS).dev - $(EXP)$(ECHOGS_XE) -a $(devs_tr) - $(GLGENDIR)$(D)libcore +psdevs_tr=$(GLGENDIR)$(D)psdevs.tr + +$(devs_tr) : $(GS_MAK) $(ECHOGS_XE) $(GLGENDIR)$(D)fdevs.tr $(GLGENDIR)$(D)devdevs.tr $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(devs_tr) -n -R $(GLGENDIR)$(D)fdevs.tr + $(EXP)$(ECHOGS_XE) -a $(devs_tr) -+ "" + $(EXP)$(ECHOGS_XE) -a $(devs_tr) -n -R $(GLGENDIR)$(D)devdevs.tr # GCONFIG_EXTRAS can be set on the command line. # Note that it consists of arguments for echogs, i.e., @@ -424,10 +470,56 @@ ld_tr=$(GLGENDIR)$(D)ld.tr $(ld_tr) : \ - $(GS_MAK) $(TOP_MAKEFILES) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(devs_tr) $(DEVS_ALL) $(GLGENDIR)$(D)libcore.dev + $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(devs_tr)\ + $(GLGENDIR)$(D)libcore.dev $(MAKEDIRS) $(EXP)$(GENCONF_XE) $(devs_tr) -h $(gconfxx_h) $(CONFILES) $(CONFLDTR) $(ld_tr) $(EXP)$(ECHOGS_XE) -a $(gconfxx_h) $(GCONFIG_EXTRAS) +gs_tr=$(GLGENDIR)$(D)gs.tr +igs_tr=$(GLGENDIR)$(D)igs.tr +gsld_tr=$(GLGENDIR)$(D)gsld.tr +$(gs_tr): $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(ld_tr) $(devs_tr) $(PSI_DEVS_ALL) \ + $(GLGENDIR)$(D)libcore.dev $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(igs_tr) - -include $(PSI_FEATURE_DEVS) + $(EXP)$(GENCONF_XE) $(igs_tr) -h $(iconfxx_h) $(CONFILES) $(CONFLDTR) $(gsld_tr) + $(EXP)$(ECHOGS_XE) -w $(iconfig_h) -R $(iconfxx_h) + $(EXP)$(ECHOGS_XE) -w $(gs_tr) -R $(devs_tr) + $(EXP)$(ECHOGS_XE) -a $(gs_tr) -R $(igs_tr) + $(EXP)$(GENCONF_XE) $(gs_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) $(CONFLDTR) $(gsld_tr) + +pcl_tr=$(GLGENDIR)$(D)pcl.tr +ipcl_tr=$(GLGENDIR)$(D)ipcl.tr +pclld_tr=$(GLGENDIR)$(D)pclld.tr +$(pcl_tr): $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(ld_tr) $(devs_tr) $(PCL_DEVS_ALL) \ + $(devs_tr) $(PCL_FEATURE_DEVS) $(GLGENDIR)$(D)libcore.dev $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(ipcl_tr) - -include $(PCL_FEATURE_DEVS) + $(EXP)$(ECHOGS_XE) -w $(pcl_tr) -R $(devs_tr) + $(EXP)$(ECHOGS_XE) -a $(pcl_tr) -R $(ipcl_tr) + $(EXP)$(GENCONF_XE) $(pcl_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) $(CONFLDTR) $(pclld_tr) + +xps_tr=$(GLGENDIR)$(D)xps.tr +ixps_tr=$(GLGENDIR)$(D)ixps.tr +xpsld_tr=$(GLGENDIR)$(D)xpsld.tr +$(xps_tr): $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(ld_tr) $(devs_tr) $(XPS_DEVS_ALL) \ + $(devs_tr) $(XPS_FEATURE_DEVS) $(GLGENDIR)$(D)libcore.dev $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(ixps_tr) - -include $(XPS_FEATURE_DEVS) + $(EXP)$(ECHOGS_XE) -w $(xps_tr) -R $(devs_tr) + $(EXP)$(ECHOGS_XE) -a $(xps_tr) -R $(ixps_tr) + $(EXP)$(GENCONF_XE) $(xps_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) $(CONFLDTR) $(xpsld_tr) + +gpdl_tr=$(GLGENDIR)$(D)gpdl.tr +igpdl_tr=$(GLGENDIR)$(D)igpdl.tr +gpdlld_tr=$(GLGENDIR)$(D)gpdlld.tr +$(gpdl_tr): $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(GENCONF_XE) $(ECHOGS_XE) $(ld_tr) $(devs_tr) $(XPS_DEVS_ALL) \ + $(devs_tr) $(PSI_DEVS_ALL) $(PCL_FEATURE_DEVS) $(XPS_FEATURE_DEVS) $(GLGENDIR)$(D)libcore.dev $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(igpdl_tr) - -include $(PSI_FEATURE_DEVS) + $(EXP)$(GENCONF_XE) $(igpdl_tr) -h $(iconfxx_h) $(CONFILES) $(CONFLDTR) $(gpdlld_tr) + $(EXP)$(ECHOGS_XE) -w $(iconfig_h) -R $(iconfxx_h) + $(EXP)$(ECHOGS_XE) -w $(gpdl_tr) -R $(devs_tr) + $(EXP)$(ECHOGS_XE) -a $(gpdl_tr) -R $(igpdl_tr) + $(EXP)$(ECHOGS_XE) -a $(gpdl_tr) - -include $(PCL_FEATURE_DEVS) $(XPS_FEATURE_DEVS) + $(EXP)$(GENCONF_XE) $(gpdl_tr) -h $(GLGENDIR)$(D)unused2.h $(CONFILES) $(CONFLDTR) $(gpdlld_tr) + $(gconfxx_h) : $(ld_tr) $(NO_OP) @@ -438,7 +530,7 @@ # The line above is an empty command; don't delete. # save our set of makefile variables that are defined in every build (paths, etc.) -$(gconfigd_h) : $(ECHOGS_XE) $(GS_MAK) $(TOP_MAKEFILES) $(GLSRCDIR)$(D)version.mak +$(gconfigd_h) : $(ECHOGS_XE) $(GS_MAK) $(GLSRCDIR)$(D)version.mak $(MAKEDIRS) $(EXP)$(ECHOGS_XE) -w $(gconfigd_h) -x 23 define -s -u GS_LIB_DEFAULT -x 2022 $(GS_LIB_DEFAULT) -x 22 $(EXP)$(ECHOGS_XE) -a $(gconfigd_h) -x 23 define -s -u GS_DEV_DEFAULT -x 2022 $(GS_DEV_DEFAULT) -x 22 $(EXP)$(ECHOGS_XE) -a $(gconfigd_h) -x 23 define -s -u GS_CACHE_DIR -x 2022 $(GS_CACHE_DIR) -x 22 @@ -449,5 +541,22 @@ $(EXP)$(ECHOGS_XE) -a $(gconfigd_h) -x 23 define -s -u GS_REVISIONDATE -s $(GS_REVISIONDATE) obj_tr=$(GLGENDIR)$(D)obj.tr -$(obj_tr) : $(ld_tr) - $(EXP)$(GENCONF_XE) $(devs_tr) $(CONFILES) -o $(obj_tr) +$(obj_tr) : $(gs_tr) + $(EXP)$(GENCONF_XE) $(gs_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) -o $(obj_tr) + + +pclobj_tr=$(GLGENDIR)$(D)pclobj.tr +$(pclobj_tr) : $(pcl_tr) + $(EXP)$(GENCONF_XE) $(pcl_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) -o $(pclobj_tr) + + +xpsobj_tr=$(GLGENDIR)$(D)xpsobj.tr +$(xpsobj_tr) : $(xps_tr) + $(EXP)$(GENCONF_XE) $(xps_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) -o $(xpsobj_tr) + + +pdlobj_tr=$(GLGENDIR)$(D)pdlobj.tr +$(pdlobj_tr) : $(gpdl_tr) + $(EXP)$(GENCONF_XE) $(gpdl_tr) -h $(GLGENDIR)$(D)unused.h $(CONFILES) -o $(pdlobj_tr) + + diff -Nru ghostscript-9.10~dfsg/base/gsmalloc.c ghostscript-9.25~dfsg+1/base/gsmalloc.c --- ghostscript-9.10~dfsg/base/gsmalloc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmalloc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -52,6 +52,8 @@ static gs_memory_proc_register_root(gs_heap_register_root); static gs_memory_proc_unregister_root(gs_heap_unregister_root); static gs_memory_proc_enable_free(gs_heap_enable_free); +static gs_memory_proc_set_object_type(gs_heap_set_object_type); +static gs_memory_proc_defer_frees(gs_heap_defer_frees); static const gs_memory_procs_t gs_malloc_memory_procs = { /* Raw memory procedures */ @@ -78,7 +80,9 @@ gs_heap_free_string, gs_heap_register_root, gs_heap_unregister_root, - gs_heap_enable_free + gs_heap_enable_free, + gs_heap_set_object_type, + gs_heap_defer_frees }; /* We must make sure that malloc_blocks leave the block aligned. */ @@ -123,7 +127,13 @@ mem->thread_safe_memory = (gs_memory_t *)mem; /* this allocator is thread safe */ /* Allocate a monitor to serialize access to structures within */ mem->monitor = NULL; /* prevent use during initial allocation */ - mem->monitor = gx_monitor_alloc((gs_memory_t *)mem); +#ifndef MEMENTO_SQUEEZE_BUILD + mem->monitor = gx_monitor_label(gx_monitor_alloc((gs_memory_t *)mem), "heap"); + if (mem->monitor == NULL) { + free(mem); + return NULL; + } +#endif return mem; } @@ -178,7 +188,7 @@ } else { uint added = size + sizeof(gs_malloc_block_t); - if (mmem->limit - added < mmem->used) + if (added <= size || mmem->limit - added < mmem->used) set_msg("exceeded limit"); else if ((ptr = (byte *) Memento_label(malloc(added), cname)) == 0) set_msg("failed"); @@ -337,7 +347,8 @@ bp->next->prev = bp->prev; if (bp == mmem->allocated) { mmem->allocated = bp->next; - mmem->allocated->prev = NULL; + if (mmem->allocated) + mmem->allocated->prev = NULL; } mmem->used -= bp->size + sizeof(gs_malloc_block_t); if (mmem->monitor) @@ -441,6 +452,7 @@ pstat->allocated = mmem->used + heap_available(); pstat->used = mmem->used; + pstat->max_used = mmem->max_used; pstat->is_thread_safe = true; /* this allocator has a mutex (monitor) and IS thread safe */ } static void @@ -454,6 +466,19 @@ mem->procs.free_string = gs_ignore_free_string; } +static void gs_heap_set_object_type(gs_memory_t *mem, void *ptr, gs_memory_type_ptr_t type) +{ + gs_malloc_block_t *bp = (gs_malloc_block_t *) ptr; + + if (ptr == 0) + return; + bp[-1].type = type; +} + +static void gs_heap_defer_frees(gs_memory_t *mem, int defer) +{ +} + /* Release all memory acquired by this allocator. */ static void gs_heap_free_all(gs_memory_t * mem, uint free_mask, client_name_t cname) @@ -509,14 +534,12 @@ sizeof(gs_memory_retrying_t), "gs_malloc_wrap(retrying)"); if (rmem == 0) { - gs_memory_locked_release(lmem); gs_free_object(cmem, lmem, "gs_malloc_wrap(locked)"); return_error(gs_error_VMerror); } code = gs_memory_retrying_init(rmem, (gs_memory_t *)lmem); if (code < 0) { gs_free_object((gs_memory_t *)lmem, rmem, "gs_malloc_wrap(retrying)"); - gs_memory_locked_release(lmem); gs_free_object(cmem, lmem, "gs_malloc_wrap(locked)"); return code; } @@ -565,8 +588,10 @@ if (malloc_memory_default == NULL) return NULL; - if (gs_lib_ctx_init((gs_memory_t *)malloc_memory_default) != 0) + if (gs_lib_ctx_init((gs_memory_t *)malloc_memory_default) != 0) { + gs_malloc_release((gs_memory_t *)malloc_memory_default); return NULL; + } #if defined(USE_RETRY_MEMORY_WRAPPER) gs_malloc_wrap(&memory_t_default, malloc_memory_default); @@ -585,6 +610,7 @@ if (mem == NULL) return; + #ifdef USE_RETRY_MEMORY_WRAPPER malloc_memory_default = gs_malloc_unwrap(mem); #else diff -Nru ghostscript-9.10~dfsg/base/gsmalloc.h ghostscript-9.25~dfsg+1/base/gsmalloc.h --- ghostscript-9.10~dfsg/base/gsmalloc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmalloc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,9 +27,9 @@ typedef struct gs_malloc_memory_s { gs_memory_common; gs_malloc_block_t *allocated; - long limit; - long used; - long max_used; + ulong limit; + ulong used; + ulong max_used; gx_monitor_t *monitor; /* monitor to serialize access to functions */ } gs_malloc_memory_t; diff -Nru ghostscript-9.10~dfsg/base/gsmatrix.c ghostscript-9.25~dfsg+1/base/gsmatrix.c --- ghostscript-9.10~dfsg/base/gsmatrix.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmatrix.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -39,7 +39,7 @@ /* Create a translation matrix */ int -gs_make_translation(floatp dx, floatp dy, gs_matrix * pmat) +gs_make_translation(double dx, double dy, gs_matrix * pmat) { *pmat = gs_identity_matrix; pmat->tx = dx; @@ -49,7 +49,7 @@ /* Create a scaling matrix */ int -gs_make_scaling(floatp sx, floatp sy, gs_matrix * pmat) +gs_make_scaling(double sx, double sy, gs_matrix * pmat) { *pmat = gs_identity_matrix; pmat->xx = sx; @@ -60,7 +60,7 @@ /* Create a rotation matrix. */ /* The angle is in degrees. */ int -gs_make_rotation(floatp ang, gs_matrix * pmat) +gs_make_rotation(double ang, gs_matrix * pmat) { gs_sincos_t sincos; @@ -222,7 +222,7 @@ /* Translate a matrix, possibly in place. */ int -gs_matrix_translate(const gs_matrix * pm, floatp dx, floatp dy, gs_matrix * pmr) +gs_matrix_translate(const gs_matrix * pm, double dx, double dy, gs_matrix * pmr) { gs_point trans; int code = gs_distance_transform(dx, dy, pm, &trans); @@ -238,7 +238,7 @@ /* Scale a matrix, possibly in place. */ int -gs_matrix_scale(const gs_matrix * pm, floatp sx, floatp sy, gs_matrix * pmr) +gs_matrix_scale(const gs_matrix * pm, double sx, double sy, gs_matrix * pmr) { pmr->xx = pm->xx * sx; pmr->xy = pm->xy * sx; @@ -253,7 +253,7 @@ /* Rotate a matrix, possibly in place. The angle is in degrees. */ int -gs_matrix_rotate(const gs_matrix * pm, floatp ang, gs_matrix * pmr) +gs_matrix_rotate(const gs_matrix * pm, double ang, gs_matrix * pmr) { double mxx, mxy; gs_sincos_t sincos; @@ -278,7 +278,7 @@ /* Transform a point. */ int -gs_point_transform(floatp x, floatp y, const gs_matrix * pmat, +gs_point_transform(double x, double y, const gs_matrix * pmat, gs_point * ppt) { /* @@ -297,7 +297,7 @@ /* Inverse-transform a point. */ /* Return gs_error_undefinedresult if the matrix is not invertible. */ int -gs_point_transform_inverse(floatp x, floatp y, const gs_matrix * pmat, +gs_point_transform_inverse(double x, double y, const gs_matrix * pmat, gs_point * ppt) { if (is_xxyy(pmat)) { @@ -325,7 +325,7 @@ /* Transform a distance. */ int -gs_distance_transform(floatp dx, floatp dy, const gs_matrix * pmat, +gs_distance_transform(double dx, double dy, const gs_matrix * pmat, gs_point * pdpt) { pdpt->x = dx * pmat->xx; @@ -340,7 +340,7 @@ /* Inverse-transform a distance. */ /* Return gs_error_undefinedresult if the matrix is not invertible. */ int -gs_distance_transform_inverse(floatp dx, floatp dy, +gs_distance_transform_inverse(double dx, double dy, const gs_matrix * pmat, gs_point * pdpt) { if (is_xxyy(pmat)) { @@ -391,7 +391,7 @@ static int bbox_transform_either_only(const gs_rect * pbox_in, const gs_matrix * pmat, gs_point pts[4], - int (*point_xform) (floatp, floatp, const gs_matrix *, gs_point *)) + int (*point_xform) (double, double, const gs_matrix *, gs_point *)) { int code; @@ -407,7 +407,7 @@ static int bbox_transform_either(const gs_rect * pbox_in, const gs_matrix * pmat, gs_rect * pbox_out, - int (*point_xform) (floatp, floatp, const gs_matrix *, gs_point *)) + int (*point_xform) (double, double, const gs_matrix *, gs_point *)) { int code; @@ -468,7 +468,7 @@ /* Transform a point with a fixed-point result. */ int gs_point_transform2fixed(const gs_matrix_fixed * pmat, - floatp x, floatp y, gs_fixed_point * ppt) + double x, double y, gs_fixed_point * ppt) { fixed px, py, t; double xtemp, ytemp; @@ -534,7 +534,7 @@ see comment in clamp_point_aux. */ int gs_point_transform2fixed_rounding(const gs_matrix_fixed * pmat, - floatp x, floatp y, gs_fixed_point * ppt) + double x, double y, gs_fixed_point * ppt) { gs_point fpt; @@ -550,7 +550,7 @@ /* Transform a distance with a fixed-point result. */ int gs_distance_transform2fixed(const gs_matrix_fixed * pmat, - floatp dx, floatp dy, gs_fixed_point * ppt) + double dx, double dy, gs_fixed_point * ppt) { fixed px, py, t; double xtemp, ytemp; @@ -716,5 +716,3 @@ return(1); return(0); } - - diff -Nru ghostscript-9.10~dfsg/base/gsmatrix.h ghostscript-9.25~dfsg+1/base/gsmatrix.h --- ghostscript-9.10~dfsg/base/gsmatrix.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmatrix.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -60,27 +60,27 @@ /* Matrix creation */ void gs_make_identity(gs_matrix *); -int gs_make_translation(floatp, floatp, gs_matrix *), - gs_make_scaling(floatp, floatp, gs_matrix *), - gs_make_rotation(floatp, gs_matrix *); +int gs_make_translation(double, double, gs_matrix *), + gs_make_scaling(double, double, gs_matrix *), + gs_make_rotation(double, gs_matrix *); /* Matrix arithmetic */ int gs_matrix_multiply(const gs_matrix *, const gs_matrix *, gs_matrix *), gs_matrix_multiply_double(const gs_matrix_double *, const gs_matrix *, gs_matrix_double *), gs_matrix_invert(const gs_matrix *, gs_matrix *), gs_matrix_invert_to_double(const gs_matrix *, gs_matrix_double *), - gs_matrix_translate(const gs_matrix *, floatp, floatp, gs_matrix *), - gs_matrix_scale(const gs_matrix *, floatp, floatp, gs_matrix *), - gs_matrix_rotate(const gs_matrix *, floatp, gs_matrix *); + gs_matrix_translate(const gs_matrix *, double, double, gs_matrix *), + gs_matrix_scale(const gs_matrix *, double, double, gs_matrix *), + gs_matrix_rotate(const gs_matrix *, double, gs_matrix *); /* Matrix comparison */ int gs_matrix_compare(const gs_matrix *, const gs_matrix *); /* Coordinate transformation */ -int gs_point_transform(floatp, floatp, const gs_matrix *, gs_point *), - gs_point_transform_inverse(floatp, floatp, const gs_matrix *, gs_point *), - gs_distance_transform(floatp, floatp, const gs_matrix *, gs_point *), - gs_distance_transform_inverse(floatp, floatp, const gs_matrix *, gs_point *), +int gs_point_transform(double, double, const gs_matrix *, gs_point *), + gs_point_transform_inverse(double, double, const gs_matrix *, gs_point *), + gs_distance_transform(double, double, const gs_matrix *, gs_point *), + gs_distance_transform_inverse(double, double, const gs_matrix *, gs_point *), gs_points_bbox(const gs_point[4], gs_rect *), gs_bbox_transform_only(const gs_rect *, const gs_matrix *, gs_point[4]), gs_bbox_transform(const gs_rect *, const gs_matrix *, gs_rect *), diff -Nru ghostscript-9.10~dfsg/base/gsmchunk.c ghostscript-9.25~dfsg+1/base/gsmchunk.c --- ghostscript-9.10~dfsg/base/gsmchunk.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmchunk.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,20 +9,72 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* chunk consolidating wrapper on a base memory allocator */ +/* This uses dual binary trees to handle the free list. One tree + * holds the blocks in size order, one in location order. We use + * a top-down semi-splaying access scheme on lookups and + * insertions. */ + #include "memory_.h" #include "gx.h" +#include "gsstruct.h" +#include "gxobj.h" #include "gsstype.h" #include "gserrors.h" #include "gsmchunk.h" #include "gxsync.h" #include "malloc_.h" /* For MEMENTO */ +#include "assert_.h" +#include "gsmdebug.h" + +/* Enable DEBUG_CHUNK to check the validity of the heap at every turn */ +#undef DEBUG_CHUNK + +/* Enable DEBUG_SEQ to keep sequence numbers in every block */ +#undef DEBUG_SEQ + +/* Enable DEBUG_CHUNK_PRINT to print the heap at every turn */ +#undef DEBUG_CHUNK_PRINT + +/* Enable DEBUG_CHUNK_PRINT_SLABS to list the slabs in the heap */ +#undef DEBUG_CHUNK_PRINT_SLABS + +#if defined(DEBUG_CHUNK_PRINT_SLABS) && !defined(DEBUG_CHUNK_PRINT) +#define DEBUG_CHUNK_PRINT +#endif + +#if defined(DEBUG_CHUNK_PRINT) && !defined(DEBUG_CHUNK) +#define DEBUG_CHUNK +#endif + +#if defined(DEBUG_CHUNK) && !defined(DEBUG) +#define DEBUG +#define CHUNK_FAKE_ASSERT +#endif + +#ifdef DEBUG +#ifdef CHUNK_FAKE_ASSERT +#define CHUNK_ASSERT(M,A) gs_chunk_assert(M, A, #A) + +static void gs_chunk_assert(gs_memory_t *m, int v, const char *s) +{ + void (*crash)(void); + if (v) + return; + dmlprintf1(m, "Assert failed: %s\n", s); + crash = NULL; + crash(); +} +#else +#define CHUNK_ASSERT(M,A) assert(A) +#endif +#endif /* Raw memory procedures */ static gs_memory_proc_alloc_bytes(chunk_alloc_bytes_immovable); @@ -50,6 +102,8 @@ static gs_memory_proc_register_root(chunk_register_root); static gs_memory_proc_unregister_root(chunk_unregister_root); static gs_memory_proc_enable_free(chunk_enable_free); +static gs_memory_proc_set_object_type(chunk_set_object_type); +static gs_memory_proc_defer_frees(chunk_defer_frees); static const gs_memory_procs_t chunk_procs = { /* Raw memory procedures */ @@ -76,75 +130,96 @@ chunk_free_string, chunk_register_root, chunk_unregister_root, - chunk_enable_free + chunk_enable_free, + chunk_set_object_type, + chunk_defer_frees }; typedef struct chunk_obj_node_s { - struct chunk_obj_node_s *next; gs_memory_type_ptr_t type; - uint size; /* objlist: client size */ -#ifdef DEBUG - unsigned long sequence; +#ifdef DEBUG_SEQ + unsigned int sequence; #endif + struct chunk_obj_node_s *defer_next; + uint size; /* Actual size of block */ + uint padding; /* Actual size - requested size */ } chunk_obj_node_t; +typedef struct chunk_free_node_s { + struct chunk_free_node_s *left_loc; + struct chunk_free_node_s *right_loc; + struct chunk_free_node_s *left_size; + struct chunk_free_node_s *right_size; + uint size; /* size of entire freelist block */ +} chunk_free_node_t; + /* * Note: All objects within a chunk are 'aligned' since we round_up_to_align * the free list pointer when removing part of a free area. */ -typedef struct chunk_mem_node_s { - uint size; - uint largest_free; /* quick check when allocating */ - bool is_multiple_object_chunk; /* tells us which list this chunk is on */ - struct chunk_mem_node_s *next; - chunk_obj_node_t *objlist; /* head of objects in this chunk (no order) */ - chunk_obj_node_t *freelist; /* free list (ordered) */ - /* chunk data follows immediately */ -} chunk_mem_node_t; +typedef struct chunk_slab_s { + struct chunk_slab_s *next; +} chunk_slab_t; typedef struct gs_memory_chunk_s { - gs_memory_common; /* interface outside world sees */ - gs_memory_t *target; /* base allocator */ - chunk_mem_node_t *head_mo_chunk; /* head of multiple object chunks */ - chunk_mem_node_t *head_so_chunk; /* head of single object chunks */ + gs_memory_common; /* interface outside world sees */ + gs_memory_t *target; /* base allocator */ + chunk_slab_t *slabs; /* list of slabs for freeing */ + chunk_free_node_t *free_size;/* free tree */ + chunk_free_node_t *free_loc; /* free tree */ + chunk_obj_node_t *defer_finalize_list; + chunk_obj_node_t *defer_free_list; unsigned long used; -#ifdef DEBUG - unsigned long sequence_counter; unsigned long max_used; - int in_use; /* 0 for idle, 1 in alloc, -1 in free */ + unsigned long total_free; +#ifdef DEBUG_SEQ + unsigned int sequence; #endif + int deferring; } gs_memory_chunk_t; +#define SIZEOF_ROUND_ALIGN(a) ROUND_UP(sizeof(a), obj_align_mod) + /* ---------- Public constructors/destructors ---------- */ /* Initialize a gs_memory_chunk_t */ -int /* -ve error code or 0 */ -gs_memory_chunk_wrap( gs_memory_t **wrapped, /* chunk allocator init */ - gs_memory_t * target ) /* base allocator */ +int +gs_memory_chunk_wrap(gs_memory_t **wrapped, /* chunk allocator init */ + gs_memory_t *target) /* base allocator */ { /* Use the non-GC allocator of the target. */ - gs_memory_t *non_gc_target = target->non_gc_memory; + gs_memory_t *non_gc_target = target->non_gc_memory; gs_memory_chunk_t *cmem = NULL; - *wrapped = NULL; /* don't leave garbage in case we fail */ if (non_gc_target) - cmem = (gs_memory_chunk_t *) gs_alloc_bytes_immovable(non_gc_target, - sizeof(gs_memory_chunk_t), "gs_malloc_wrap(chunk)"); - if (cmem == 0) + cmem = (gs_memory_chunk_t *)gs_alloc_bytes_immovable(non_gc_target, + sizeof(gs_memory_chunk_t), + "gs_memory_chunk_wrap"); + if (cmem == NULL) { + *wrapped = NULL; return_error(gs_error_VMerror); + } cmem->stable_memory = (gs_memory_t *)cmem; /* we are stable */ cmem->procs = chunk_procs; cmem->gs_lib_ctx = non_gc_target->gs_lib_ctx; cmem->non_gc_memory = (gs_memory_t *)cmem; /* and are not subject to GC */ cmem->thread_safe_memory = non_gc_target->thread_safe_memory; cmem->target = non_gc_target; - cmem->head_mo_chunk = NULL; - cmem->head_so_chunk = NULL; + cmem->slabs = NULL; + cmem->free_size = NULL; + cmem->free_loc = NULL; cmem->used = 0; -#ifdef DEBUG - cmem->sequence_counter = 0; cmem->max_used = 0; - cmem->in_use = 0; /* idle */ + cmem->total_free = 0; +#ifdef DEBUG_SEQ + cmem->sequence = 0; +#endif + cmem->deferring = 0; + cmem->defer_finalize_list = NULL; + cmem->defer_free_list = NULL; + +#ifdef DEBUG_CHUNK_PRINT + dmlprintf1(non_gc_target, "New chunk %p\n", cmem); #endif /* Init the chunk management values */ @@ -161,6 +236,22 @@ "gs_memory_chunk_release"); } +/* Release chunk memory manager, and return the target */ +gs_memory_t * /* Always succeeds */ +gs_memory_chunk_unwrap(gs_memory_t *mem) +{ + gs_memory_t *tmem; + + /* If this isn't a chunk, nothing to unwrap */ + if (mem->procs.status != chunk_status) + return mem; + + tmem = ((gs_memory_chunk_t *)mem)->target; + gs_memory_chunk_release(mem); + + return tmem; +} + /* ---------- Accessors ------------- */ /* Retrieve this allocator's target */ @@ -171,38 +262,6 @@ return cmem->target; } -#ifdef DEBUG -void -gs_memory_chunk_dump_memory(const gs_memory_t *mem) -{ - gs_memory_chunk_t *cmem = (gs_memory_chunk_t *)mem; - chunk_mem_node_t *head = cmem->head_mo_chunk; /* dump multiple object chunks first */ - chunk_mem_node_t *current; - chunk_mem_node_t *next; - int i; - - dmprintf2(mem, "chunk_dump_memory: current used=%d, max_used=%d\n", cmem->used, cmem->max_used); - if (cmem->in_use != 0) - dmprintf1(mem, "*** this memory allocator is not idle, used for: %s\n", - cmem->in_use < 0 ? "free" : "alloc"); - for (i=0; i<2; i++) { - current = head; - while ( current != NULL ) { - if (current->objlist != NULL) { - chunk_obj_node_t *obj; - - for (obj= current->objlist; obj != NULL; obj=obj->next) - dmprintf4(mem, "chunk_mem leak, obj=0x%lx, size=%d, type=%s, sequence#=%ld\n", - (ulong)obj, obj->size, obj->type->sname, obj->sequence); - } - next = current->next; - current = next; - } - head = cmem->head_so_chunk; /* switch to single object chunk list */ - } -} -#endif - /* -------- Private members --------- */ /* Note that all of the data is 'immovable' and is opaque to the base allocator */ @@ -212,30 +271,21 @@ /* Procedures */ static void -chunk_mem_node_free_all_remaining(gs_memory_chunk_t *cmem) +chunk_mem_node_free_all_slabs(gs_memory_chunk_t *cmem) { - chunk_mem_node_t *head = cmem->head_mo_chunk; /* Free multiple object chunk nodes first */ - gs_memory_t * const target = cmem->target; - chunk_mem_node_t *current; - chunk_mem_node_t *next; - int i; + chunk_slab_t *slab, *next; + gs_memory_t *const target = cmem->target; -#ifdef DEBUG - if (cmem->in_use != 0) - dmprintf1(target, "*** chunk_mem_node_free_all_remaining: this memory allocator is not idle, used for: %s\n", - cmem->in_use < 0 ? "free" : "alloc"); -#endif - for (i=0; i<2; i++) { - current = head; - while ( current != NULL ) { - next = current->next; - gs_free_object(target, current, "chunk_mem_node_remove"); - current = next; - } - cmem->head_mo_chunk = NULL; - head = cmem->head_so_chunk; /* switch to single object chunk list */ + for (slab = cmem->slabs; slab != NULL; slab = next) { + next = slab->next; + gs_free_object(target, slab, "chunk_mem_node_free_all_slabs"); } - cmem->head_so_chunk = NULL; + + cmem->slabs = NULL; + cmem->free_size = NULL; + cmem->free_loc = NULL; + cmem->total_free = 0; + cmem->used = 0; } static void @@ -244,11 +294,8 @@ gs_memory_chunk_t * const cmem = (gs_memory_chunk_t *)mem; gs_memory_t * const target = cmem->target; -#ifdef DEBUG - if (cmem->in_use != 0) - dmprintf1(target, "*** chunk_free_all: this memory allocator is not idle, used for: %s\n", - cmem->in_use < 0 ? "free" : "alloc"); -#endif + if (free_mask & FREE_ALL_DATA) + chunk_mem_node_free_all_slabs(cmem); /* Only free the structures and the allocator itself. */ if (mem->stable_memory) { if (mem->stable_memory != mem) @@ -256,9 +303,6 @@ if (free_mask & FREE_ALL_ALLOCATOR) mem->stable_memory = 0; } - if (free_mask & FREE_ALL_DATA) { - chunk_mem_node_free_all_remaining(cmem); - } if (free_mask & FREE_ALL_STRUCTURES) { cmem->target = 0; } @@ -268,250 +312,657 @@ extern const gs_memory_struct_type_t st_bytes; -/* round up objects to make sure we have room for a header left */ -inline static uint -round_up_to_align(uint size) +#ifdef DEBUG +static int dump_free_loc(gs_memory_t *mem, chunk_free_node_t *node, int depth, void **limit, uint *total) { - uint num_node_headers = (size + sizeof(chunk_obj_node_t) - 1) / sizeof(chunk_obj_node_t); +#ifdef DEBUG_CHUNK_PRINT + int i; +#endif + int count; - return num_node_headers * sizeof(chunk_obj_node_t); -} + if (node == NULL) + return 0; -#ifdef MEMENTO -/* If we're using memento, make ALL objects single objects (i.e. put them all - * in their own chunk. */ -#define IS_SINGLE_OBJ_SIZE(chunk_size) (1) -#else -#define IS_SINGLE_OBJ_SIZE(chunk_size) \ - (chunk_size > (CHUNK_SIZE>>1)) + count = dump_free_loc(mem, node->left_loc, depth + 1 + (depth&1), limit, total); + *total += node->size; +#ifdef DEBUG_CHUNK_PRINT + if (depth != 0) { + for (i = (depth-1)>>1; i != 0; i--) + dmlprintf(mem, " "); + if (depth & 1) + dmlprintf(mem, "/"); + else + dmlprintf(mem, "\\"); + } + dmlprintf3(mem, "%p+%x->%p\n", node, node->size, ((byte *)node)+node->size); #endif -#define MULTIPLE_OBJ_CHUNK_SIZE \ - (sizeof(chunk_mem_node_t) + round_up_to_align(CHUNK_SIZE)) + CHUNK_ASSERT(mem, *limit < (void *)node); + *limit = ((byte *)node)+node->size; + return 1 + count + dump_free_loc(mem, node->right_loc, depth + 2 + (depth&1), limit, total); +} -/* return -1 on error, 0 on success */ -static int -chunk_mem_node_add(gs_memory_chunk_t *cmem, uint size_needed, bool is_multiple_object_chunk, - chunk_mem_node_t **newchunk -#ifdef MEMENTO - , client_name_t cname -#endif - ) -{ - chunk_mem_node_t *node; - gs_memory_t *target = cmem->target; - /* Allocate enough for the chunk header, and the size_needed */ - /* The size needed already includes the object header from caller */ - /* and is already rounded up to the obj_node_t sized elements */ - uint chunk_size = size_needed + sizeof(chunk_mem_node_t); - - /* caller tells us whether or not to use a single object chunk */ - if (is_multiple_object_chunk && (chunk_size < MULTIPLE_OBJ_CHUNK_SIZE)) { - chunk_size = MULTIPLE_OBJ_CHUNK_SIZE; /* the size for collections of objects */ - is_multiple_object_chunk = true; - } else - is_multiple_object_chunk = false; - - *newchunk = NULL; -#ifdef MEMENTO -#define LOCAL_CNAME cname -#else -#define LOCAL_CNAME "chunk_mem_node_add" +static int dump_free_size(gs_memory_t *mem, chunk_free_node_t *node, int depth, uint *size, void **addr) +{ +#ifdef DEBUG_CHUNK_PRINT + int i; #endif - node = (chunk_mem_node_t *)gs_alloc_bytes_immovable(target, chunk_size, - LOCAL_CNAME); -#undef LOCAL_CNAME + int count; + if (node == NULL) - return -1; - cmem->used += chunk_size; -#ifdef DEBUG - if (cmem->used > cmem->max_used) - cmem->max_used = cmem->used; + return 0; + + count = dump_free_size(mem, node->left_size, depth + 1 + (depth&1), size, addr); +#ifdef DEBUG_CHUNK_PRINT + if (depth != 0) { + for (i = (depth-1)>>1; i != 0; i--) + dmlprintf(mem, " "); + if (depth & 1) + dmlprintf(mem, "/"); + else + dmlprintf(mem, "\\"); + } + dmlprintf3(mem, "%p+%x->%p\n", node, node->size, ((byte *)node)+node->size); #endif - node->size = chunk_size; /* how much we allocated */ - node->largest_free = chunk_size - sizeof(chunk_mem_node_t); - node->is_multiple_object_chunk = is_multiple_object_chunk; - node->objlist = NULL; - node->freelist = (chunk_obj_node_t *)((byte *)(node) + sizeof(chunk_mem_node_t)); - node->freelist->next = NULL; - node->freelist->size = node->largest_free; - - /* Put the node at the head of the list (so=single object, mo=multiple object) */ - /* only multiple objects will be have any room in them */ - if (is_multiple_object_chunk) { - if (cmem->head_mo_chunk == NULL) { - cmem->head_mo_chunk = node; - node->next = NULL; - } else { - node->next = cmem->head_mo_chunk; - cmem->head_mo_chunk = node; - } - } else { - if (cmem->head_so_chunk == NULL) { - cmem->head_so_chunk = node; - node->next = NULL; - } else { - node->next = cmem->head_so_chunk; - cmem->head_so_chunk = node; - } + CHUNK_ASSERT(mem, *size < node->size || (*size == node->size && *addr < (void *)node)); + *size = node->size; + *addr = node; + return 1 + count + dump_free_size(mem, node->right_size, depth + 2 + (depth&1), size, addr); +} + +void +gs_memory_chunk_dump_memory(const gs_memory_t *mem) +{ + const gs_memory_chunk_t *cmem = (const gs_memory_chunk_t *)mem; + int count1, count2; + void *limit = NULL; + void *addr = NULL; + uint size = 1; + uint total = 0; + +#ifdef DEBUG_CHUNK_PRINT + dmlprintf1(cmem->target, "Chunk %p:\n", cmem); +#ifdef DEBUG_CHUNK_PRINT_SLABS + { + chunk_slab_t *slab; + dmlprintf(cmem->target, "Slabs\n"); + for (slab = cmem->slabs; slab != NULL; slab = slab->next) + dmlprintf1(cmem->target, " %p\n", slab); + } +#endif + dmlprintf(cmem->target, "Locs:\n"); +#endif + count1 = dump_free_loc(cmem->target, cmem->free_loc, 0, &limit, &total); +#ifdef DEBUG_CHUNK_PRINT + dmlprintf(cmem->target, "Sizes:\n"); +#endif + count2 = dump_free_size(cmem->target, cmem->free_size, 0, &size, &addr); + if (count1 != count2) { + void (*crash)(void) = NULL; + dmlprintf2(cmem->target, "Tree mismatch! %d vs %d\n", count1, count2); + crash(); } + if (total != cmem->total_free) { + void (*crash)(void) = NULL; + dmlprintf2(cmem->target, "Free size mismatch! %u vs %lu\n", total, cmem->total_free); + crash(); + } +} +#endif - *newchunk = node; /* return the chunk we just allocated */ - return 0; +/* round up objects to make sure we have room for a header left */ +inline static uint +round_up_to_align(uint size) +{ + uint num_node_headers = (size + SIZEOF_ROUND_ALIGN(chunk_obj_node_t) - 1) / SIZEOF_ROUND_ALIGN(chunk_obj_node_t); + + return num_node_headers * SIZEOF_ROUND_ALIGN(chunk_obj_node_t); } -static int -chunk_mem_node_remove(gs_memory_chunk_t *cmem, chunk_mem_node_t *addr) +static inline int CMP_SIZE(const chunk_free_node_t * a, const chunk_free_node_t * b) { - chunk_mem_node_t **p_head = addr->is_multiple_object_chunk ? - &(cmem->head_mo_chunk) : &(cmem->head_so_chunk); - chunk_mem_node_t *head = *p_head; - gs_memory_t * const target = cmem->target; + if (a->size > b->size) + return 1; + if (a->size < b->size) + return 0; + return (a > b); +} - cmem->used -= addr->size; -#ifdef DEBUG -#endif +static void insert_free_size(gs_memory_chunk_t *cmem, chunk_free_node_t *node) +{ + chunk_free_node_t **ap; + chunk_free_node_t *a, *b, *c; - /* check the head first */ - if (head == NULL) { - dmprintf(target, "FAIL - no nodes to be removed\n" ); - return -1; - } - if (head == addr) { - *p_head = head->next; - gs_free_object(target, head, "chunk_mem_node_remove"); - } else { - chunk_mem_node_t *current; - bool found = false; + node->left_size = NULL; + node->right_size = NULL; - /* scan the list, stopping in front of element */ - for (current = head; current != NULL; current = current->next) { - if ( current->next && (current->next == addr) ) { - current->next = current->next->next; /* de-link it */ - gs_free_object(target, addr, "chunk_mem_node_remove"); - found = true; + /* Insert into size */ + ap = &cmem->free_size; + while ((a = *ap) != NULL) { + if (CMP_SIZE(a, node)) { + b = a->left_size; + if (b == NULL) { + ap = &a->left_size; + break; /* Stop searching */ + } + if (CMP_SIZE(b, node)) { + c = b->left_size; + if (c == NULL) { + ap = &b->left_size; + break; + } + /* Splay: a c + * b Z => W b + * c Y X a + * W X Y Z + */ + *ap = c; + a->left_size = b->right_size; + b->left_size = c->right_size; + b->right_size = a; + c->right_size = b; + if (CMP_SIZE(c, node)) + ap = &c->left_size; + else + ap = &b->left_size; + } else { + c = b->right_size; + if (c == NULL) { + ap = &b->right_size; + break; + } + /* Splay: a c + * b Z => b a + * W c W X Y Z + * X Y + */ + *ap = c; + a->left_size = c->right_size; + b->right_size = c->left_size; + c->left_size = b; + c->right_size = a; + if (CMP_SIZE(c, node)) + ap = &b->right_size; + else + ap = &a->left_size; + } + } else { + b = a->right_size; + if (b == NULL) + { + ap = &a->right_size; break; } - } - if ( !found ) { - dmprintf1(target, "FAIL freeing wild pointer freed address 0x%lx not found\n", (ulong)addr ); - return -1; + if (CMP_SIZE(b, node)) { + c = b->left_size; + if (c == NULL) { + ap = &b->left_size; + break; + } + /* Splay: a c + * W b => a b + * c Z W X Y Z + * X Y + */ + *ap = c; + a->right_size = c->left_size; + b->left_size = c->right_size; + c->left_size = a; + c->right_size = b; + if (CMP_SIZE(c, node)) + ap = &a->right_size; + else + ap = &b->left_size; + } else { + c = b->right_size; + if (c == NULL) { + ap = &b->right_size; + break; + } + /* Splay: a c + * W b => b Z + * X c a Y + * Y Z W X + */ + *ap = c; + a->right_size = b->left_size; + b->right_size = c->left_size; + b->left_size = a; + c->left_size = b; + if (CMP_SIZE(c, node)) + ap = &b->right_size; + else + ap = &c->right_size; + } } } - return 0; + *ap = node; } -/* all of the allocation routines reduce to the this function */ -static byte * -chunk_obj_alloc(gs_memory_t *mem, uint size, gs_memory_type_ptr_t type, client_name_t cname) +static void insert_free_loc(gs_memory_chunk_t *cmem, chunk_free_node_t *node) { - gs_memory_chunk_t *cmem = (gs_memory_chunk_t *)mem; - chunk_mem_node_t *head = cmem->head_mo_chunk; /* we only scan chunks with space in them */ - uint newsize, free_size; - chunk_obj_node_t *newobj = NULL; - chunk_obj_node_t *free_obj, *prev_free, *new_free; - chunk_mem_node_t *current = NULL; - bool rescan_free_list = false; - bool is_multiple_object_size; + chunk_free_node_t **ap; + chunk_free_node_t *a, *b, *c; -#ifdef DEBUG - if (cmem->in_use != 0) - dmprintf1(mem, "*** chunk_obj_alloc: this memory allocator is not idle, used for: %s\n", - cmem->in_use < 0 ? "free" : "alloc"); - cmem->in_use = 1; /* alloc */ -#endif - newsize = round_up_to_align(size + sizeof(chunk_obj_node_t)); /* space we will need */ - is_multiple_object_size = ! IS_SINGLE_OBJ_SIZE(newsize); - - if ( is_multiple_object_size ) { - /* Search the multiple object chunks for one with a large enough free area */ - for (current = head; current != NULL; current = current->next) { - if ( current->largest_free >= newsize) + node->left_loc = NULL; + node->right_loc = NULL; + + /* Insert into loc */ + ap = &cmem->free_loc; + while ((a = *ap) != NULL) { + if (a > node) { + b = a->left_loc; + if (b == NULL) { + ap = &a->left_loc; + break; /* Stop searching */ + } + if (b > node) { + c = b->left_loc; + if (c == NULL) { + ap = &b->left_loc; + break; + } + /* Splay: a c + * b Z => W b + * c Y X a + * W X Y Z + */ + *ap = c; + a->left_loc = b->right_loc; + b->left_loc = c->right_loc; + b->right_loc = a; + c->right_loc = b; + if (c > node) + ap = &c->left_loc; + else + ap = &b->left_loc; + } else { + c = b->right_loc; + if (c == NULL) { + ap = &b->right_loc; + break; + } + /* Splay: a c + * b Z => b a + * W c W X Y Z + * X Y + */ + *ap = c; + a->left_loc = c->right_loc; + b->right_loc = c->left_loc; + c->left_loc = b; + c->right_loc = a; + if (c > node) + ap = &b->right_loc; + else + ap = &a->left_loc; + } + } else { + b = a->right_loc; + if (b == NULL) + { + ap = &a->right_loc; break; + } + if (b > node) { + c = b->left_loc; + if (c == NULL) { + ap = &b->left_loc; + break; + } + /* Splay: a c + * W b => a b + * c Z W X Y Z + * X Y + */ + *ap = c; + a->right_loc = c->left_loc; + b->left_loc = c->right_loc; + c->left_loc = a; + c->right_loc = b; + if (c > node) + ap = &a->right_loc; + else + ap = &b->left_loc; + } else { + c = b->right_loc; + if (c == NULL) { + ap = &b->right_loc; + break; + } + /* Splay: a c + * W b => b Z + * X c a Y + * Y Z W X + */ + *ap = c; + a->right_loc = b->left_loc; + b->right_loc = c->left_loc; + b->left_loc = a; + c->left_loc = b; + if (c > node) + ap = &b->right_loc; + else + ap = &c->right_loc; + } } } - if (current == NULL) { - /* No chunks with enough space or size makes this a single object, allocate one */ - if (chunk_mem_node_add(cmem, newsize, is_multiple_object_size, ¤t -#ifdef MEMENTO - , cname -#endif - ) < 0) { -#ifdef DEBUG - if (gs_debug_c('a')) - dmlprintf1(mem, "[a+]chunk_obj_alloc(chunk_mem_node_add)(%u) Failed.\n", size); - cmem->in_use = 0; /* idle */ -#endif - return NULL; - } - } - /* Find the first free area in the current chunk that is big enough */ - /* LATER: might be better to find the 'best fit' */ - prev_free = NULL; /* NULL means chunk */ - for (free_obj = current->freelist; free_obj != NULL; free_obj=free_obj->next) { - if (free_obj->size >= newsize) - break; - prev_free = free_obj; /* keep track so we can update link */ + *ap = node; +} + +static void insert_free(gs_memory_chunk_t *cmem, chunk_free_node_t *node, uint size) +{ + node->size = size; + insert_free_size(cmem, node); + insert_free_loc(cmem, node); +} + +static void remove_free_loc(gs_memory_chunk_t *cmem, chunk_free_node_t *node) +{ + chunk_free_node_t **ap = &cmem->free_loc; + + while (*ap != node) + { + if (*ap > node) + ap = &(*ap)->left_loc; + else + ap = &(*ap)->right_loc; } - if (free_obj == NULL) { - dmprintf2(mem, "largest_free value = %d is too large, cannot find room for size = %d\n", - current->largest_free, newsize); -#ifdef DEBUG - cmem->in_use = 0; /* idle */ -#endif - return NULL; + if (node->left_loc == NULL) + *ap = node->right_loc; + else if (node->right_loc == NULL) + *ap = node->left_loc; + else { + /* Find the in-order predecessor to node and use that to replace node */ + chunk_free_node_t **bp; + chunk_free_node_t *b; + bp = &node->left_loc; + while ((*bp)->right_loc) + bp = &(*bp)->right_loc; + b = (*bp); + *bp = b->left_loc; + b->left_loc = node->left_loc; + b->right_loc = node->right_loc; + *ap = b; } +} - /* If this free object's size == largest_free, we'll have to re-scan */ - rescan_free_list = current->is_multiple_object_chunk && free_obj->size == current->largest_free; +static void remove_free_size(gs_memory_chunk_t *cmem, chunk_free_node_t *node) +{ + chunk_free_node_t **ap = &cmem->free_size; - /* Make an object in the free_obj we found above, reducing it's size */ - /* and adjusting the free list preserving alignment */ - newobj = free_obj; - free_size = free_obj->size - newsize; /* amount remaining */ - new_free = (chunk_obj_node_t *)((byte *)(free_obj) + newsize); /* start of remaining free area */ - if (free_size >= sizeof(chunk_obj_node_t)) { - if (prev_free != NULL) - prev_free->next = new_free; - else - current->freelist = new_free; - new_free->next = free_obj->next; - new_free->size = free_size; - } else { - /* Not enough space remaining, just skip around it */ - if (prev_free != NULL) - prev_free->next = free_obj->next; + while (*ap != node) + { + if (CMP_SIZE(*ap, node)) + ap = &(*ap)->left_size; else - current->freelist = free_obj->next; + ap = &(*ap)->right_size; } -#ifdef DEBUG - memset((byte *)(newobj) + sizeof(chunk_obj_node_t), 0xa1, newsize - sizeof(chunk_obj_node_t)); - memset((byte *)(newobj) + sizeof(chunk_obj_node_t), 0xac, size); - newobj->sequence = cmem->sequence_counter++; + if (node->left_size == NULL) + *ap = node->right_size; + else if (node->right_size == NULL) + *ap = node->left_size; + else { + /* Find the in-order predecessor to node and use that to replace node */ + chunk_free_node_t **bp; + chunk_free_node_t *b; + bp = &node->left_size; + while ((*bp)->right_size) + bp = &(*bp)->right_size; + b = (*bp); + *bp = b->left_size; + b->left_size = node->left_size; + b->right_size = node->right_size; + *ap = b; + } +} + +static void remove_free_size_fast(gs_memory_chunk_t *cmem, chunk_free_node_t **ap) +{ + chunk_free_node_t *node = *ap; + + if (node->left_size == NULL) + *ap = node->right_size; + else if (node->right_size == NULL) + *ap = node->left_size; + else { + /* Find the in-order predecessor to node and use that to replace node */ + chunk_free_node_t **bp; + chunk_free_node_t *b; + bp = &node->left_size; + while ((*bp)->right_size) + bp = &(*bp)->right_size; + b = (*bp); + *bp = b->left_size; + b->left_size = node->left_size; + b->right_size = node->right_size; + *ap = b; + } +} + +static void remove_free(gs_memory_chunk_t *cmem, chunk_free_node_t *node) +{ + remove_free_loc(cmem, node); + remove_free_size(cmem, node); +} + +#if defined(MEMENTO) || defined(SINGLE_OBJECT_MEMORY_BLOCKS_ONLY) +#define SINGLE_OBJECT_CHUNK(size) (1) +#else +#define SINGLE_OBJECT_CHUNK(size) ((size) > (CHUNK_SIZE>>1)) +#endif + +/* All of the allocation routines reduce to this function */ +static byte * +chunk_obj_alloc(gs_memory_t *mem, uint size, gs_memory_type_ptr_t type, client_name_t cname) +{ + gs_memory_chunk_t *cmem = (gs_memory_chunk_t *)mem; + chunk_free_node_t **ap, **okp; + chunk_free_node_t *a, *b, *c; + uint newsize; + chunk_obj_node_t *obj = NULL; + + newsize = round_up_to_align(size + SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); /* space we will need */ + /* When we free this block it might have to go in free - so it had + * better be large enough to accommodate a complete free node! */ + if (newsize < SIZEOF_ROUND_ALIGN(chunk_free_node_t)) + newsize = SIZEOF_ROUND_ALIGN(chunk_free_node_t); + /* Protect against overflow */ + if (newsize < size) + return NULL; + +#ifdef DEBUG_SEQ + cmem->sequence++; #endif - newobj->next = current->objlist; /* link to start of list */ - current->objlist = newobj; - newobj->size = size; /* client requested size */ - newobj->type = type; /* and client desired type */ +#ifdef DEBUG_CHUNK_PRINT +#ifdef DEBUG_SEQ + dmlprintf4(cmem->target, "Event %x: malloc(chunk=%p, size=%x, cname=%s)\n", cmem->sequence, cmem, newsize, cname); +#else + dmlprintf3(cmem->target, "malloc(chunk=%p, size=%x, cname=%s)\n", cmem, newsize, cname); +#endif +#endif - /* If we flagged for re-scan to find the new largest_free, do it now */ - if (rescan_free_list) { - current->largest_free = 0; - for (free_obj = current->freelist; free_obj != NULL; free_obj=free_obj->next) - if (free_obj->size > current->largest_free) - current->largest_free = free_obj->size; + /* Large blocks are allocated directly */ + if (SINGLE_OBJECT_CHUNK(newsize)) { + obj = (chunk_obj_node_t *)gs_alloc_bytes_immovable(cmem->target, newsize, cname); + if (obj == NULL) + return NULL; + } else { + /* Find the smallest free block that's large enough */ + /* okp points to the parent pointer to the block we pick */ + ap = &cmem->free_size; + okp = NULL; + while ((a = *ap) != NULL) { + if (a->size >= newsize) { + b = a->left_size; + if (b == NULL) { + okp = ap; /* a will do */ + break; /* Stop searching */ + } + if (b->size >= newsize) { + c = b->left_size; + if (c == NULL) { + okp = &a->left_size; /* b is as good as we're going to get */ + break; + } + /* Splay: a c + * b Z => W b + * c Y X a + * W X Y Z + */ + *ap = c; + a->left_size = b->right_size; + b->left_size = c->right_size; + b->right_size = a; + c->right_size = b; + if (c->size >= newsize) { + okp = ap; /* c is the best so far */ + ap = &c->left_size; + } else { + okp = &c->right_size; /* b is the best so far */ + ap = &b->left_size; + } + } else { + c = b->right_size; + if (c == NULL) { + okp = ap; /* a is as good as we are going to get */ + break; + } + /* Splay: a c + * b Z => b a + * W c W X Y Z + * X Y + */ + *ap = c; + a->left_size = c->right_size; + b->right_size = c->left_size; + c->left_size = b; + c->right_size = a; + if (c->size >= newsize) { + okp = ap; /* c is the best so far */ + ap = &b->right_size; + } else { + okp = &c->right_size; /* a is the best so far */ + ap = &a->left_size; + } + } + } else { + b = a->right_size; + if (b == NULL) + break; /* No better match to be found */ + if (b->size >= newsize) { + c = b->left_size; + if (c == NULL) { + okp = &a->right_size; /* b is as good as we're going to get */ + break; + } + /* Splay: a c + * W b => a b + * c Z W X Y Z + * X Y + */ + *ap = c; + a->right_size = c->left_size; + b->left_size = c->right_size; + c->left_size = a; + c->right_size = b; + if (c->size >= newsize) { + okp = ap; /* c is the best so far */ + ap = &a->right_size; + } else { + okp = &c->right_size; /* b is the best so far */ + ap = &b->left_size; + } + } else { + c = b->right_size; + if (c == NULL) + break; /* No better match to be found */ + /* Splay: a c + * W b => b Z + * X c a Y + * Y Z W X + */ + *ap = c; + a->right_size = b->left_size; + b->right_size = c->left_size; + b->left_size = a; + c->left_size = b; + if (c->size >= newsize) { + okp = ap; /* c is the best so far */ + ap = &b->right_size; + } else + ap = &c->right_size; + } + } + } + + /* So *okp points to the most appropriate free tree entry. */ + + if (okp == NULL) { + /* No appropriate free space slot. We need to allocate a new slab. */ + chunk_slab_t *slab; + uint slab_size = newsize + SIZEOF_ROUND_ALIGN(chunk_slab_t); + if (slab_size <= (CHUNK_SIZE>>1)) + slab_size = CHUNK_SIZE; + slab = (chunk_slab_t *)gs_alloc_bytes_immovable(cmem->target, slab_size, cname); + if (slab == NULL) + return NULL; + slab->next = cmem->slabs; + cmem->slabs = slab; + + obj = (chunk_obj_node_t *)(((byte *)slab) + SIZEOF_ROUND_ALIGN(chunk_slab_t)); + if (slab_size != newsize + SIZEOF_ROUND_ALIGN(chunk_slab_t)) { + insert_free(cmem, (chunk_free_node_t *)(((byte *)obj)+newsize), slab_size - newsize - SIZEOF_ROUND_ALIGN(chunk_slab_t)); + cmem->total_free += slab_size - newsize - SIZEOF_ROUND_ALIGN(chunk_slab_t); + } + } else { + chunk_free_node_t *ok = *okp; + obj = (chunk_obj_node_t *)(void *)ok; + if (ok->size >= newsize + SIZEOF_ROUND_ALIGN(chunk_free_node_t)) { + chunk_free_node_t *tail = (chunk_free_node_t *)(((byte *)ok) + newsize); + uint tail_size = ok->size - newsize; + remove_free_size_fast(cmem, okp); + remove_free_loc(cmem, ok); + insert_free(cmem, tail, tail_size); + } else { + newsize = ok->size; + remove_free_size_fast(cmem, okp); + remove_free_loc(cmem, ok); + } + cmem->total_free -= newsize; + } } - /* return the client area of the object we allocated */ -#ifdef DEBUG + if (gs_alloc_debug) { + memset((byte *)(obj) + SIZEOF_ROUND_ALIGN(chunk_obj_node_t), 0xa1, newsize - SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); + memset((byte *)(obj) + SIZEOF_ROUND_ALIGN(chunk_obj_node_t), 0xac, size); + } + + obj->size = newsize; /* actual size */ + obj->padding = newsize - size; /* actual size - client requested size */ + obj->type = type; /* and client desired type */ + obj->defer_next = NULL; + +#ifdef DEBUG_SEQ + obj->sequence = cmem->sequence; +#endif if (gs_debug_c('A')) dmlprintf3(mem, "[a+]chunk_obj_alloc (%s)(%u) = 0x%lx: OK.\n", - client_name_string(cname), size, (ulong) newobj); - cmem->in_use = 0; /* idle */ + client_name_string(cname), size, (ulong) obj); +#ifdef DEBUG_CHUNK_PRINT +#ifdef DEBUG_SEQ + dmlprintf5(cmem->target, "Event %x: malloced(chunk=%p, addr=%p, size=%x, cname=%s)\n", obj->sequence, cmem, obj, obj->size, cname); +#else + dmlprintf4(cmem->target, "malloced(chunk=%p, addr=%p, size=%x, cname=%s)\n", cmem, obj, obj->size, cname); +#endif #endif - return (byte *)(newobj) + sizeof(chunk_obj_node_t); +#ifdef DEBUG_CHUNK + gs_memory_chunk_dump_memory(cmem); +#endif + + return (byte *)(obj) + SIZEOF_ROUND_ALIGN(chunk_obj_node_t); } static byte * @@ -572,16 +1023,14 @@ chunk_resize_object(gs_memory_t * mem, void *ptr, uint new_num_elements, client_name_t cname) { /* This isn't particularly efficient, but it is rarely used */ - chunk_obj_node_t *obj = ((chunk_obj_node_t *)ptr) - 1; + chunk_obj_node_t *obj = (chunk_obj_node_t *)(((byte *)ptr) - SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); ulong new_size = (obj->type->ssize * new_num_elements); - ulong old_size = obj->size; + ulong old_size = obj->size - obj->padding; /* get the type from the old object */ gs_memory_type_ptr_t type = obj->type; void *new_ptr; -#ifdef DEBUG gs_memory_chunk_t *cmem = (gs_memory_chunk_t *)mem; ulong save_max_used = cmem->max_used; -#endif if (new_size == old_size) return ptr; @@ -589,182 +1038,261 @@ return 0; memcpy(new_ptr, ptr, min(old_size, new_size)); chunk_free_object(mem, ptr, cname); -#ifdef DEBUG cmem->max_used = save_max_used; if (cmem->used > cmem->max_used) cmem->max_used = cmem->used; -#endif return new_ptr; } static void -chunk_free_object(gs_memory_t * mem, void *ptr, client_name_t cname) +chunk_free_object(gs_memory_t *mem, void *ptr, client_name_t cname) { gs_memory_chunk_t * const cmem = (gs_memory_chunk_t *)mem; + int obj_node_size; + chunk_obj_node_t *obj; + struct_proc_finalize((*finalize)); + chunk_free_node_t **ap, **gtp, **ltp; + chunk_free_node_t *a, *b, *c; - if (ptr == NULL ) + if (ptr == NULL) return; - { - /* back up to obj header */ - chunk_obj_node_t *obj = ((chunk_obj_node_t *)ptr) - 1; - struct_proc_finalize((*finalize)) = obj->type->finalize; - chunk_mem_node_t *current; - chunk_obj_node_t *free_obj, *prev_free; - chunk_obj_node_t *scan_obj, *prev_obj; - /* space we will free */ - uint freed_size = round_up_to_align(obj->size + sizeof(chunk_obj_node_t)); - if ( finalize != NULL ) + /* back up to obj header */ + obj_node_size = SIZEOF_ROUND_ALIGN(chunk_obj_node_t); + obj = (chunk_obj_node_t *)(((byte *)ptr) - obj_node_size); + + if (cmem->deferring) { + if (obj->defer_next == NULL) { + obj->defer_next = cmem->defer_finalize_list; + cmem->defer_finalize_list = obj; + } + return; + } + +#ifdef DEBUG_CHUNK_PRINT +#ifdef DEBUG_SEQ + cmem->sequence++; + dmlprintf6(cmem->target, "Event %x: free(chunk=%p, addr=%p, size=%x, num=%x, cname=%s)\n", cmem->sequence, cmem, obj, obj->size, obj->sequence, cname); +#else + dmlprintf4(cmem->target, "free(chunk=%p, addr=%p, size=%x, cname=%s)\n", cmem, obj, obj->size, cname); +#endif +#endif + + if (obj->type) { + finalize = obj->type->finalize; + if (finalize != NULL) finalize(mem, ptr); -#ifdef DEBUG - if (cmem->in_use != 0) - dmprintf1(cmem->target, - "*** chunk_free_object: this memory allocator is not idle, used for: %s\n", - cmem->in_use < 0 ? "free" : "alloc"); - cmem->in_use = -1; /* free */ -#endif - /* finalize may change the head_**_chunk doing free of stuff */ - current = IS_SINGLE_OBJ_SIZE(freed_size) ? - cmem->head_so_chunk : cmem->head_mo_chunk; - /* Find the chunk containing this object */ - for ( ; current != NULL; current = current->next) { - if (((byte *)obj > (byte *)current) && ((byte *)obj < (byte *)(current) + current->size)) + } + /* finalize may change the head_**_chunk doing free of stuff */ + + if_debug3m('A', cmem->target, "[a-]chunk_free_object(%s) 0x%lx(%u)\n", + client_name_string(cname), (ulong) ptr, obj->size); + + if (SINGLE_OBJECT_CHUNK(obj->size - obj->padding)) { + gs_free_object(cmem->target, obj, "chunk_free_object(single object)"); +#ifdef DEBUG_CHUNK + gs_memory_chunk_dump_memory(cmem); +#endif + return; + } + + /* We want to find where to insert this free entry into our free tree. We need to know + * both the point to the left of it, and the point to the right of it, in order to see + * if we can merge the free entries. Accordingly, we search from the top of the tree + * and keep pointers to the nodes that we pass that are greater than it, and less than + * it. */ + gtp = NULL; /* gtp is set to the address of the pointer to the node where we last stepped left */ + ltp = NULL; /* ltp is set to the address of the pointer to the node where we last stepped right */ + ap = &cmem->free_loc; + while ((a = *ap) != NULL) { + if ((void *)a > (void *)obj) { + b = a->left_loc; /* Try to step left from a */ + if (b == NULL) { + gtp = ap; /* a is greater than us */ break; - } - if (current == NULL) { - /* We _may_have searched the wrong list -- if so find out. */ - current = cmem->head_so_chunk; - /* Find the chunk containing this object */ - for ( ; current != NULL; current = current->next) { - if (((byte *)obj > (byte *)current) && ((byte *)obj < (byte *)(current) + current->size)) { - dmprintf1(cmem->target, - "chunk_free_obj: OOPS! found it on the single_object list, size=%d\n", - obj->size); + } + if ((void *)b > (void *)obj) { + c = b->left_loc; /* Try to step left from b */ + if (c == NULL) { + gtp = &a->left_loc; /* b is greater than us */ break; } - } - if (current == NULL) { - current = cmem->head_mo_chunk; - /* Find the chunk containing this object */ - for ( ; current != NULL; current = current->next) { - if (((byte *)obj > (byte *)current) && ((byte *)obj < (byte *)(current) + current->size)) { - dmprintf1(cmem->target, - "chunk_free_obj: OOPS! found it on the multiple_object list, size=%d\n", - obj->size); - break; - } + /* Splay: a c + * b Z => W b + * c Y X a + * W X Y Z + */ + *ap = c; + a->left_loc = b->right_loc; + b->left_loc = c->right_loc; + b->right_loc = a; + c->right_loc = b; + if ((void *)c > (void *)obj) { /* W */ + gtp = ap; /* c is greater than us */ + ap = &c->left_loc; + } else { /* X */ + gtp = &c->right_loc; /* b is greater than us */ + ltp = ap; /* c is less than us */ + ap = &b->left_loc; + } + } else { + c = b->right_loc; /* Try to step right from b */ + if (c == NULL) { + gtp = ap; /* a is greater than us */ + ltp = &a->left_loc; /* b is less than us */ + break; + } + /* Splay: a c + * b Z => b a + * W c W X Y Z + * X Y + */ + *ap = c; + a->left_loc = c->right_loc; + b->right_loc = c->left_loc; + c->left_loc = b; + c->right_loc = a; + if ((void *)c > (void *)obj) { /* X */ + gtp = ap; /* c is greater than us */ + ltp = &c->left_loc; /* b is less than us */ + ap = &b->right_loc; + } else { /* Y */ + gtp = &c->right_loc; /* a is greater than us */ + ltp = ap; /* c is less than us */ + ap = &a->left_loc; } } - if (current == NULL) { - /* Object not found in any chunk */ - dmprintf2(cmem->target, - "chunk_free_obj failed, object 0x%lx not in any chunk, size=%d\n", - ((ulong)obj), obj->size); -#ifdef DEBUG - cmem->in_use = 0; /* idle */ -#endif - return; + } else { + b = a->right_loc; /* Try to step right from a */ + if (b == NULL) { + ltp = ap; /* a is less than us */ + break; + } + if ((void *)b > (void *)obj) { + c = b->left_loc; + if (c == NULL) { + gtp = &a->right_loc; /* b is greater than us */ + ltp = ap; /* a is less than us */ + break; + } + /* Splay: a c + * W b => a b + * c Z W X Y Z + * X Y + */ + *ap = c; + a->right_loc = c->left_loc; + b->left_loc = c->right_loc; + c->left_loc = a; + c->right_loc = b; + if ((void *)c > (void *)obj) { /* X */ + gtp = ap; /* c is greater than us */ + ltp = &c->left_loc; /* a is less than us */ + ap = &a->right_loc; + } else { /* Y */ + gtp = &c->right_loc; /* b is greater than us */ + ltp = ap; /* c is less than than us */ + ap = &b->left_loc; + } + } else { + c = b->right_loc; + if (c == NULL) { + ltp = &a->right_loc; /* b is greater than us */ + break; + } + /* Splay: a c + * W b => b Z + * X c a Y + * Y Z W X + */ + *ap = c; + a->right_loc = b->left_loc; + b->right_loc = c->left_loc; + b->left_loc = a; + c->left_loc = b; + if ((void *)c > (void *)obj) { /* Y */ + gtp = ap; /* c is greater than us */ + ltp = &c->left_loc; /* b is less than us */ + ap = &b->right_loc; + } else { /* Z */ + ltp = ap; /* c is less than than us */ + ap = &c->right_loc; + } } } - /* For large objects, they were given their own chunk -- just remove the node */ - if (IS_SINGLE_OBJ_SIZE(freed_size)) { - chunk_mem_node_remove(cmem, current); -#ifdef DEBUG - cmem->in_use = 0; /* idle */ -#endif - return; - } + } - /* Scan obj list to find this element */ - prev_obj = NULL; /* object is head, linked to mem node */ - for (scan_obj = current->objlist; scan_obj != NULL; scan_obj = scan_obj->next) { - if (scan_obj == obj) - break; - prev_obj = scan_obj; + if (ltp) { + /* There is at least 1 node smaller than us - check for merging */ + chunk_free_node_t *ltfree = (chunk_free_node_t *)(*ltp); + if ((((byte *)ltfree) + ltfree->size) == (byte *)(void *)obj) { + /* Merge! */ + cmem->total_free += obj->size; + remove_free_size(cmem, ltfree); + ltfree->size += obj->size; + if (gtp) { + /* There is at least 1 node greater than us - check for merging */ + chunk_free_node_t *gtfree = (chunk_free_node_t *)(*gtp); + if ((((byte *)obj) + obj->size) == (byte *)(void *)gtfree) { + /* Double merge! */ + ltfree->size += gtfree->size; + remove_free(cmem, gtfree); + } + gtp = NULL; + } + insert_free_size(cmem, ltfree); + if (gs_alloc_debug) + memset(((byte *)ltfree) + SIZEOF_ROUND_ALIGN(chunk_free_node_t), 0x69, ltfree->size - SIZEOF_ROUND_ALIGN(chunk_free_node_t)); + obj = NULL; } - if (scan_obj == NULL) { - /* Object not found in expected chunk */ - dmprintf3(cmem->target, - "chunk_free_obj failed, object 0x%lx not in chunk at 0x%lx, size = %d\n", - ((ulong)obj), ((ulong)current), current->size); -#ifdef DEBUG - cmem->in_use = 0; /* idle */ -#endif - return; + } + if (gtp && obj) { + /* There is at least 1 node greater than us - check for merging */ + chunk_free_node_t *gtfree = (chunk_free_node_t *)(*gtp); + if ((((byte *)obj) + obj->size) == (byte *)(void *)gtfree) { + /* Merge! */ + chunk_free_node_t *objfree = (chunk_free_node_t *)(void *)obj; + uint obj_size = obj->size; + cmem->total_free += obj_size; + remove_free_size(cmem, gtfree); + *objfree = *gtfree; + objfree->size += obj_size; + *gtp = objfree; + insert_free_size(cmem, objfree); + if (gs_alloc_debug) + memset(((byte *)objfree) + SIZEOF_ROUND_ALIGN(chunk_free_node_t), 0x96, objfree->size - SIZEOF_ROUND_ALIGN(chunk_free_node_t)); + obj = NULL; } - /* link around the object being freed */ - if (prev_obj == NULL) - current->objlist = obj->next; - else - prev_obj->next = obj->next; - - if_debug3m('A', cmem->target, "[a-]chunk_free_object(%s) 0x%lx(%u)\n", - client_name_string(cname), (ulong) ptr, obj->size); - - /* Add this object's space (including the header) to the free list */ - - /* Scan free list to find where this element goes */ - obj->size = freed_size; /* adjust size to include chunk_obj_node and pad */ + } - prev_free = NULL; - for (free_obj = current->freelist; free_obj != NULL; free_obj = free_obj->next) { - if (obj < free_obj) - break; - prev_free = free_obj; - } - if (prev_free == NULL) { - /* this object is before any other free objects */ - obj->next = current->freelist; - current->freelist = obj; - } else { - obj->next = free_obj; - prev_free->next = obj; - } - /* If the end of this object is adjacent to the next free space, - * merge the two. Next we'll merge with predecessor (prev_free) - */ - if (free_obj != NULL) { - byte *after_obj = (byte*)(obj) + freed_size; - - if (free_obj <= (chunk_obj_node_t *)after_obj) { - /* Object is adjacent to following free space block -- merge it */ - obj->next = free_obj->next; /* link around the one being absorbed */ - obj->size = (byte *)(free_obj) - (byte *)(obj) + free_obj->size; + if (obj) { + /* Insert new one */ + chunk_free_node_t *objfree = (chunk_free_node_t *)(void *)obj; + cmem->total_free += obj->size; + objfree->size = obj->size; + objfree->left_loc = NULL; + objfree->right_loc = NULL; + if (gtp) { + ap = &(*gtp)->left_loc; + while (*ap) { + ap = &(*ap)->right_loc; } - } - /* the prev_free object precedes this object that is now free, - * it _may_ be adjacent - */ - if (prev_free != NULL) { - byte *after_free = (byte*)(prev_free) + prev_free->size; - - if (obj <= (chunk_obj_node_t *)after_free) { - /* Object is adjacent to prior free space block -- merge it */ - /* NB: this is the common case with LIFO alloc-free patterns */ - /* (LIFO: Last-allocated, first freed) */ - prev_free->size = (byte *)(obj) - (byte *)(prev_free) + obj->size; - prev_free->next = obj->next; /* link around 'obj' area */ - obj = prev_free; + } else if (ltp) { + ap = &(*ltp)->right_loc; + while (*ap) { + ap = &(*ap)->left_loc; } - } -#ifdef DEBUG -memset((byte *)(obj) + sizeof(chunk_obj_node_t), 0xf1, obj->size - sizeof(chunk_obj_node_t)); -#endif - if (current->largest_free < obj->size) - current->largest_free = obj->size; + } else + ap = &cmem->free_loc; + *ap = objfree; + insert_free_size(cmem, objfree); + if (gs_alloc_debug) + memset(((byte *)objfree) + SIZEOF_ROUND_ALIGN(chunk_free_node_t), 0x9b, objfree->size - SIZEOF_ROUND_ALIGN(chunk_free_node_t)); + } - /* If this chunk is now totally empty, free it */ - if (current->objlist == NULL) { - if (current->size != current->freelist->size + sizeof(chunk_mem_node_t)) - dmprintf2(cmem->target, - "chunk freelist size not correct, is: %d, should be: %d\n", - round_up_to_align(current->freelist->size + sizeof(chunk_mem_node_t)), current->size); - chunk_mem_node_remove(cmem, current); - } -#ifdef DEBUG - cmem->in_use = 0; /* idle */ +#ifdef DEBUG_CHUNK + gs_memory_chunk_dump_memory(cmem); #endif - } } static byte * @@ -800,18 +1328,10 @@ chunk_status(gs_memory_t * mem, gs_memory_status_t * pstat) { gs_memory_chunk_t *cmem = (gs_memory_chunk_t *)mem; - chunk_mem_node_t *current = cmem->head_mo_chunk; /* we only scan chunks with space in them */ - chunk_obj_node_t *free_obj; /* free list object node */ - int tot_free = 0; pstat->allocated = cmem->used; - /* Scan all chunks for free space to calculate the actual amount 'used' */ - for ( ; current != NULL; current = current->next) { - for (free_obj = current->freelist; free_obj != NULL; free_obj=free_obj->next) - tot_free += free_obj->size; - } - pstat->used = cmem->used - tot_free; - + pstat->used = cmem->used - cmem->total_free; + pstat->max_used = cmem->max_used; pstat->is_thread_safe = false; /* this allocator does not have an internal mutex */ } @@ -826,24 +1346,65 @@ { } +static void chunk_set_object_type(gs_memory_t *mem, void *ptr, gs_memory_type_ptr_t type) +{ + chunk_obj_node_t *obj = (chunk_obj_node_t *)(((byte *)ptr) - SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); + + if (ptr == 0) + return; + obj->type = type; +} + +static void chunk_defer_frees(gs_memory_t *mem, int defer) +{ + gs_memory_chunk_t *cmem = (gs_memory_chunk_t *)mem; + chunk_obj_node_t *n; + + if (defer == 0) { + /* Run through and finalise everything on the finalize list. This + * might cause other stuff to be put onto the finalize list. As we + * finalize stuff we move it to the free list. */ + while (cmem->defer_finalize_list) { + n = cmem->defer_finalize_list; + cmem->defer_finalize_list = n->defer_next; + if (n->type) { + if (n->type->finalize) + n->type->finalize(mem, ((byte *)n) + SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); + n->type = NULL; + } + n->defer_next = cmem->defer_free_list; + cmem->defer_free_list = n; + } + } + cmem->deferring = defer; + if (defer == 0) { + /* Now run through and free everything on the free list */ + while (cmem->defer_free_list) { + n = cmem->defer_free_list; + cmem->defer_free_list = n->defer_next; + chunk_free_object(mem, ((byte *)n) + SIZEOF_ROUND_ALIGN(chunk_obj_node_t), "deferred free"); + } + } +} + static void chunk_consolidate_free(gs_memory_t *mem) { } -/* aceesors to get size and type given the pointer returned to the client */ +/* accessors to get size and type given the pointer returned to the client */ static uint chunk_object_size(gs_memory_t * mem, const void *ptr) { - chunk_obj_node_t *obj = ((chunk_obj_node_t *)ptr) - 1; + chunk_obj_node_t *obj = (chunk_obj_node_t *)(((byte *)ptr) - SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); - return obj->size; + return obj->size - obj->padding; } static gs_memory_type_ptr_t chunk_object_type(const gs_memory_t * mem, const void *ptr) { - chunk_obj_node_t *obj = ((chunk_obj_node_t *)ptr) - 1; + chunk_obj_node_t *obj = (chunk_obj_node_t *)(((byte *)ptr) - SIZEOF_ROUND_ALIGN(chunk_obj_node_t)); return obj->type; } @@ -858,53 +1419,3 @@ chunk_unregister_root(gs_memory_t * mem, gs_gc_root_t * rp, client_name_t cname) { } - -#ifdef DEBUG - -#define A(obj, size) \ - if ((obj = gs_alloc_bytes(cmem, size, "chunk_alloc_unit_test")) == NULL) { \ - dmprintf(cmem, "chunk alloc failed\n"); \ - return_error(gs_error_VMerror); \ - } - -#define F(obj) \ - gs_free_object(cmem, obj, "chunk_alloc_unit_test"); - -int -chunk_allocator_unit_test(gs_memory_t *mem) -{ - int code; - gs_memory_t *cmem; - byte *obj1, *obj2, *obj3, *obj4, *obj5, *obj6, *obj7; - - if ((code = gs_memory_chunk_wrap(&cmem, mem )) < 0) { - dmprintf1(cmem, "chunk_wrap returned error code: %d\n", code); - return code; - } - - /* Allocate a large object */ - A(obj1, 80000); - F(obj1); - A(obj1, 80000); - - A(obj2, 3); - A(obj3, 7); - A(obj4, 15); - A(obj5, 16); - A(obj6, 16); - A(obj7, 16); - - F(obj2); - F(obj1); - F(obj5); - F(obj4); - F(obj6); - F(obj7); - F(obj3); - - /* cleanup */ - gs_memory_chunk_release(cmem); - return 0; -} - -#endif /* DEBUG */ diff -Nru ghostscript-9.10~dfsg/base/gsmchunk.h ghostscript-9.25~dfsg+1/base/gsmchunk.h --- ghostscript-9.10~dfsg/base/gsmchunk.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmchunk.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,6 +31,13 @@ /* Release a chunk memory manager and all of the memory it held */ void gs_memory_chunk_release(gs_memory_t *cmem); +/* Release chunk memory manager, and return the target */ +/* if "mem" is not a chunk memory manager instance, "mem" + * is return untouched + */ +gs_memory_t * /* Always succeeds */ +gs_memory_chunk_unwrap(gs_memory_t *mem); + /* ---------- Accessors ------------- */ /* Retrieve this allocator's target */ @@ -38,8 +45,6 @@ #ifdef DEBUG void gs_memory_chunk_dump_memory(const gs_memory_t *mem); - - int chunk_allocator_unit_test(gs_memory_t *mem); #endif /* DEBUG */ #endif /* gsmchunk_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsmd5.c ghostscript-9.25~dfsg+1/base/gsmd5.c --- ghostscript-9.10~dfsg/base/gsmd5.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmd5.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,382 @@ +/* + Copyright (C) 1999-2018 Artifex Software, Inc. + All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.c is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2007-06-08 RG Namespaced the api calls to avoid conflict with other + implementations when linking gs as a library. + 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order + either statically or dynamically; added missing #include + in library. + 2002-03-11 lpd Corrected argument list for main(), and added int return + type, in test program and T value program. + 2002-02-21 lpd Added missing #include in test program. + 2000-07-03 lpd Patched to eliminate warnings about "constant is + unsigned in ANSI C, signed in traditional"; made test program + self-checking. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). + 1999-05-03 lpd Original version. + */ + +#include "gsmd5.h" +#include + +#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#ifdef ARCH_IS_BIG_ENDIAN +# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +#else +# define BYTE_ORDER 0 +#endif + +#define T_MASK ((gs_md5_word_t)~0) +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) +#define T3 0x242070db +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) +#define T6 0x4787c62a +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) +#define T9 0x698098d8 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) +#define T13 0x6b901122 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) +#define T16 0x49b40821 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) +#define T19 0x265e5a51 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) +#define T22 0x02441453 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) +#define T25 0x21e1cde6 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) +#define T28 0x455a14ed +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) +#define T31 0x676f02d9 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) +#define T35 0x6d9d6122 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) +#define T38 0x4bdecfa9 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) +#define T41 0x289b7ec6 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) +#define T44 0x04881d05 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) +#define T47 0x1fa27cf8 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) +#define T50 0x432aff97 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) +#define T53 0x655b59c3 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) +#define T57 0x6fa87e4f +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) +#define T60 0x4e0811a1 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) +#define T63 0x2ad7d2bb +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) + +static void +gs_md5_process(gs_md5_state_t *pms, const gs_md5_byte_t *data /*[64]*/) +{ + gs_md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + gs_md5_word_t t; +#if BYTE_ORDER > 0 + /* Define storage only for big-endian CPUs. */ + gs_md5_word_t X[16] = {0}; +#else + /* Define storage for little-endian or both types of CPUs. */ + gs_md5_word_t xbuf[16]; + const gs_md5_word_t *X = xbuf; +#endif + + { +#if BYTE_ORDER == 0 + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; + + if (*((const gs_md5_byte_t *)&w)) /* dynamic little-endian */ +#endif +#if BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (const gs_md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const gs_md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } +#endif +#if BYTE_ORDER == 0 + else /* dynamic big-endian */ +#endif +#if BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const gs_md5_byte_t *xp = data; + int i; + +# if BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ +# else +# define xbuf X /* (static only) */ +# endif + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } +#endif + } + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); +#undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); +#undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); +#undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); +#undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +void +gs_md5_init(gs_md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; +} + +void +gs_md5_append(gs_md5_state_t *pms, const gs_md5_byte_t *data, int nbytes) +{ + const gs_md5_byte_t *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + gs_md5_word_t nbits = (gs_md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + gs_md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + gs_md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +void +gs_md5_finish(gs_md5_state_t *pms, gs_md5_byte_t digest[16]) +{ + static const gs_md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + gs_md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (gs_md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + gs_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + gs_md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (gs_md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff -Nru ghostscript-9.10~dfsg/base/gsmd5.h ghostscript-9.25~dfsg+1/base/gsmd5.h --- ghostscript-9.10~dfsg/base/gsmd5.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmd5.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,91 @@ +/* + Copyright (C) 1999-2018 Artifex Software, Inc. + All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Removed support for non-ANSI compilers; removed + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + +#ifndef md5_INCLUDED +# define md5_INCLUDED + +/* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +typedef unsigned char gs_md5_byte_t; /* 8-bit byte */ +typedef unsigned int gs_md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct gs_md5_state_s { + gs_md5_word_t count[2]; /* message length in bits, lsw first */ + gs_md5_word_t abcd[4]; /* digest buffer */ + gs_md5_byte_t buf[64]; /* accumulate block */ +} gs_md5_state_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Initialize the algorithm. */ +void gs_md5_init(gs_md5_state_t *pms); + +/* Append a string to the message. */ +void gs_md5_append(gs_md5_state_t *pms, const gs_md5_byte_t *data, int nbytes); + +/* Finish the message and return the digest. */ +void gs_md5_finish(gs_md5_state_t *pms, gs_md5_byte_t digest[16]); + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* md5_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsmdebug.h ghostscript-9.25~dfsg+1/base/gsmdebug.h --- ghostscript-9.10~dfsg/base/gsmdebug.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmdebug.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsmemlok.c ghostscript-9.25~dfsg+1/base/gsmemlok.c --- ghostscript-9.10~dfsg/base/gsmemlok.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmemlok.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,396 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Monitor-locked heap memory allocator */ - -/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */ -/* Revised 8/6/98 by L. Peter Deutsch (ghost@aladdin.com) for changes */ -/* in memory manager API */ -/* Edited 3/23/1999 by L. Peter Deutsch to remove compiler warnings. */ - -#include "gx.h" -#include "gsmemlok.h" -#include "gserrors.h" - -/* Raw memory procedures */ -static gs_memory_proc_alloc_bytes(gs_locked_alloc_bytes_immovable); -static gs_memory_proc_resize_object(gs_locked_resize_object); -static gs_memory_proc_free_object(gs_locked_free_object); -static gs_memory_proc_stable(gs_locked_stable); -static gs_memory_proc_status(gs_locked_status); -static gs_memory_proc_free_all(gs_locked_free_all); -static gs_memory_proc_consolidate_free(gs_locked_consolidate_free); - -/* Object memory procedures */ -static gs_memory_proc_alloc_bytes(gs_locked_alloc_bytes); -static gs_memory_proc_alloc_struct(gs_locked_alloc_struct); -static gs_memory_proc_alloc_struct(gs_locked_alloc_struct_immovable); -static gs_memory_proc_alloc_byte_array(gs_locked_alloc_byte_array); -static gs_memory_proc_alloc_byte_array(gs_locked_alloc_byte_array_immovable); -static gs_memory_proc_alloc_struct_array(gs_locked_alloc_struct_array); -static gs_memory_proc_alloc_struct_array(gs_locked_alloc_struct_array_immovable); -static gs_memory_proc_object_size(gs_locked_object_size); -static gs_memory_proc_object_type(gs_locked_object_type); -static gs_memory_proc_alloc_string(gs_locked_alloc_string); -static gs_memory_proc_alloc_string(gs_locked_alloc_string_immovable); -static gs_memory_proc_resize_string(gs_locked_resize_string); -static gs_memory_proc_free_string(gs_locked_free_string); -static gs_memory_proc_register_root(gs_locked_register_root); -static gs_memory_proc_unregister_root(gs_locked_unregister_root); -static gs_memory_proc_enable_free(gs_locked_enable_free); -static const gs_memory_procs_t locked_procs = -{ - /* Raw memory procedures */ - gs_locked_alloc_bytes_immovable, - gs_locked_resize_object, - gs_locked_free_object, - gs_locked_stable, - gs_locked_status, - gs_locked_free_all, - gs_locked_consolidate_free, - /* Object memory procedures */ - gs_locked_alloc_bytes, - gs_locked_alloc_struct, - gs_locked_alloc_struct_immovable, - gs_locked_alloc_byte_array, - gs_locked_alloc_byte_array_immovable, - gs_locked_alloc_struct_array, - gs_locked_alloc_struct_array_immovable, - gs_locked_object_size, - gs_locked_object_type, - gs_locked_alloc_string, - gs_locked_alloc_string_immovable, - gs_locked_resize_string, - gs_locked_free_string, - gs_locked_register_root, - gs_locked_unregister_root, - gs_locked_enable_free -}; - -/* ---------- Public constructors/destructors ---------- */ - -/* Initialize a gs_memory_locked_t */ -int /* -ve error code or 0 */ -gs_memory_locked_init( - gs_memory_locked_t * lmem, /* allocator to init */ - gs_memory_t * target /* allocator to monitor lock */ -) -{ - lmem->stable_memory = 0; - lmem->procs = locked_procs; - lmem->target = target; - lmem->gs_lib_ctx = target->gs_lib_ctx; - lmem->non_gc_memory = (gs_memory_t *)lmem; /* WRONG: THIS IS QUESTIONABLE since this will not */ - /* be non_gc_memory if the target was a GC memory */ - lmem->thread_safe_memory = (gs_memory_t *)lmem; /* this allocator is thread safe */ - - /* Allocate a monitor to serialize access to structures within */ - lmem->monitor = gx_monitor_alloc(target); - return (lmem->monitor ? 0 : gs_note_error(gs_error_VMerror)); -} - -/* Release a locked memory manager. */ -/* Note that this has no effect on the target. */ -void -gs_memory_locked_release(gs_memory_locked_t *lmem) -{ - gs_memory_free_all((gs_memory_t *)lmem, FREE_ALL_STRUCTURES, - "gs_memory_locked_release"); - gx_monitor_free(lmem->monitor); -} - -/* ---------- Accessors ------------- */ - -/* Retrieve this allocator's target */ -gs_memory_t * -gs_memory_locked_target(const gs_memory_locked_t *lmem) -{ - return lmem->target; -} - -/* -------- Private members just wrap a monitor around a gs_memory_heap --- */ - -/* - * Contrary to our usual practice, we don't use BEGIN/END here, because - * that causes some compilers to give bogus error messages. - */ - -#define DO_MONITORED(call_target)\ - gs_memory_locked_t * const lmem = (gs_memory_locked_t *)mem;\ -\ - gx_monitor_enter(lmem->monitor);\ - call_target;\ - gx_monitor_leave(lmem->monitor) - -#define RETURN_MONITORED(result_type, call_target)\ - gs_memory_locked_t * const lmem = (gs_memory_locked_t *)mem;\ - result_type temp;\ -\ - gx_monitor_enter(lmem->monitor);\ - temp = call_target;\ - gx_monitor_leave(lmem->monitor);\ - return temp - -/* Procedures */ -static void -gs_locked_free_all(gs_memory_t * mem, uint free_mask, client_name_t cname) -{ - gs_memory_locked_t * const lmem = (gs_memory_locked_t *)mem; - gs_memory_t * const target = lmem->target; - - /* Only free the structures and the allocator itself. */ - if (mem->stable_memory) { - if (mem->stable_memory != mem) - gs_memory_free_all(mem->stable_memory, free_mask, cname); - if (free_mask & FREE_ALL_ALLOCATOR) - mem->stable_memory = 0; - } - if (free_mask & FREE_ALL_STRUCTURES) { - /* - * Check for monitor == 0, in case this is called after a - * failure during initialization. - */ - if (lmem->monitor) - gx_monitor_free(lmem->monitor); - lmem->monitor = 0; - lmem->target = 0; - } - if (free_mask & FREE_ALL_ALLOCATOR) - gs_free_object(target, lmem, cname); -} -static void -gs_locked_consolidate_free(gs_memory_t * mem) -{ - DO_MONITORED( - (*lmem->target->procs.consolidate_free)(lmem->target) - ); -} -static byte * -gs_locked_alloc_bytes(gs_memory_t * mem, uint size, client_name_t cname) -{ - RETURN_MONITORED( - byte *, - (*lmem->target->procs.alloc_bytes) - (lmem->target, size, cname) - ); -} -static byte * -gs_locked_alloc_bytes_immovable(gs_memory_t * mem, uint size, - client_name_t cname) -{ - RETURN_MONITORED( - byte *, - (*lmem->target->procs.alloc_bytes_immovable) - (lmem->target, size, cname) - ); -} -static void * -gs_locked_alloc_struct(gs_memory_t * mem, gs_memory_type_ptr_t pstype, - client_name_t cname) -{ - RETURN_MONITORED( - void *, - (*lmem->target->procs.alloc_struct) - (lmem->target, pstype, cname) - ); -} -static void * -gs_locked_alloc_struct_immovable(gs_memory_t * mem, - gs_memory_type_ptr_t pstype, client_name_t cname) -{ - RETURN_MONITORED( - void *, - (*lmem->target->procs.alloc_struct_immovable) - (lmem->target, pstype, cname) - ); -} -static byte * -gs_locked_alloc_byte_array(gs_memory_t * mem, uint num_elements, uint elt_size, - client_name_t cname) -{ - RETURN_MONITORED( - byte *, - (*lmem->target->procs.alloc_byte_array) - (lmem->target, num_elements, elt_size, cname) - ); -} -static byte * -gs_locked_alloc_byte_array_immovable(gs_memory_t * mem, uint num_elements, - uint elt_size, client_name_t cname) -{ - RETURN_MONITORED( - byte *, - (*lmem->target->procs.alloc_byte_array_immovable) - (lmem->target, num_elements, elt_size, cname) - ); -} -static void * -gs_locked_alloc_struct_array(gs_memory_t * mem, uint num_elements, - gs_memory_type_ptr_t pstype, client_name_t cname) -{ - RETURN_MONITORED( - void *, - (*lmem->target->procs.alloc_struct_array) - (lmem->target, num_elements, pstype, cname) - ); -} -static void * -gs_locked_alloc_struct_array_immovable(gs_memory_t * mem, uint num_elements, - gs_memory_type_ptr_t pstype, client_name_t cname) -{ - RETURN_MONITORED( - void *, - (*lmem->target->procs.alloc_struct_array_immovable) - (lmem->target, num_elements, pstype, cname) - ); -} -static void * -gs_locked_resize_object(gs_memory_t * mem, void *obj, uint new_num_elements, - client_name_t cname) -{ - RETURN_MONITORED( - void *, - (*lmem->target->procs.resize_object) - (lmem->target, obj, new_num_elements, cname) - ); -} -static uint -gs_locked_object_size(gs_memory_t * mem, const void *ptr) -{ - RETURN_MONITORED( - uint, - (*lmem->target->procs.object_size) - (lmem->target, ptr) - ); -} -static gs_memory_type_ptr_t -gs_locked_object_type(const gs_memory_t * mem, const void *ptr) -{ - RETURN_MONITORED( - gs_memory_type_ptr_t, - (*lmem->target->procs.object_type) - (lmem->target, ptr) - ); -} -static void -gs_locked_free_object(gs_memory_t * mem, void *ptr, client_name_t cname) -{ - DO_MONITORED( - (*lmem->target->procs.free_object) - (lmem->target, ptr, cname) - ); -} -static byte * -gs_locked_alloc_string(gs_memory_t * mem, uint nbytes, client_name_t cname) -{ - RETURN_MONITORED( - byte *, - (*lmem->target->procs.alloc_string) - (lmem->target, nbytes, cname) - ); -} -static byte * -gs_locked_alloc_string_immovable(gs_memory_t * mem, uint nbytes, - client_name_t cname) -{ - RETURN_MONITORED( - byte *, - (*lmem->target->procs.alloc_string_immovable) - (lmem->target, nbytes, cname) - ); -} -static byte * -gs_locked_resize_string(gs_memory_t * mem, byte * data, uint old_num, - uint new_num, - client_name_t cname) -{ - RETURN_MONITORED( - byte *, - (*lmem->target->procs.resize_string) - (lmem->target, data, old_num, new_num, cname) - ); -} -static void -gs_locked_free_string(gs_memory_t * mem, byte * data, uint nbytes, - client_name_t cname) -{ - DO_MONITORED( - (*lmem->target->procs.free_string) - (lmem->target, data, nbytes, cname) - ); -} -static int -gs_locked_register_root(gs_memory_t * mem, gs_gc_root_t * rp, - gs_ptr_type_t ptype, void **up, client_name_t cname) -{ - RETURN_MONITORED( - int, - (*lmem->target->procs.register_root) - (lmem->target, rp, ptype, up, cname) - ); -} -static void -gs_locked_unregister_root(gs_memory_t * mem, gs_gc_root_t * rp, - client_name_t cname) -{ - DO_MONITORED( - (*lmem->target->procs.unregister_root) - (lmem->target, rp, cname) - ); -} -static gs_memory_t * -gs_locked_stable(gs_memory_t * mem) -{ - if (!mem->stable_memory) { - gs_memory_locked_t * const lmem = (gs_memory_locked_t *)mem; - gs_memory_t *stable; - - gx_monitor_enter(lmem->monitor); - stable = gs_memory_stable(lmem->target); - if (stable == lmem->target) - mem->stable_memory = mem; - else { - gs_memory_locked_t *locked_stable = (gs_memory_locked_t *) - gs_alloc_bytes(stable, sizeof(*lmem), "gs_locked_stable"); - - if (locked_stable) { - int code = gs_memory_locked_init(locked_stable, stable); - - if (code < 0) - gs_free_object(stable, locked_stable, "gs_locked_stable"); - else - mem->stable_memory = (gs_memory_t *)locked_stable; - } - } - gx_monitor_leave(lmem->monitor); - } - return mem->stable_memory; -} -static void -gs_locked_status(gs_memory_t * mem, gs_memory_status_t * pstat) -{ - DO_MONITORED( - (*lmem->target->procs.status)(lmem->target, pstat) - ); - pstat->is_thread_safe = true; /* the monitor (mutex) makes this thread safe */ -} -static void -gs_locked_enable_free(gs_memory_t * mem, bool enable) -{ - DO_MONITORED( - (*lmem->target->procs.enable_free)(lmem->target, enable) - ); -} diff -Nru ghostscript-9.10~dfsg/base/gsmemlok.h ghostscript-9.25~dfsg+1/base/gsmemlok.h --- ghostscript-9.10~dfsg/base/gsmemlok.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmemlok.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Interface to monitor-locked heap memory allocator */ - -/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */ - -#if !defined(gsmemlok_INCLUDED) -# define gsmemlok_INCLUDED - -#include "gsmemory.h" -#include "gxsync.h" - -/* - * This allocator encapsulates another allocator with a mutex. - * Note that it does not keep track of memory that it acquires: - * thus free_all with FREE_ALL_DATA is a no-op. - */ - -typedef struct gs_memory_locked_s { - gs_memory_common; /* interface outside world sees */ - gs_memory_t *target; /* allocator to front */ - gx_monitor_t *monitor; /* monitor to serialize access to functions */ -} gs_memory_locked_t; - -/* ---------- Public constructors/destructors ---------- */ - -/* Initialize a locked memory manager. */ -int gs_memory_locked_init( - gs_memory_locked_t * lmem, /* allocator to init */ - gs_memory_t * target /* allocator to monitor lock */ - ); - -/* Release a locked memory manager. */ -/* Note that this has no effect on the target. */ -void gs_memory_locked_release(gs_memory_locked_t *lmem); - -/* Get the target of a locked memory manager. */ -gs_memory_t * gs_memory_locked_target(const gs_memory_locked_t *lmem); - -#endif /*!defined(gsmemlok_INCLUDED) */ diff -Nru ghostscript-9.10~dfsg/base/gsmemory.c ghostscript-9.25~dfsg+1/base/gsmemory.c --- ghostscript-9.10~dfsg/base/gsmemory.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmemory.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -269,11 +269,11 @@ (ulong)vp, (long)prc->ref_count); } void -rc_trace_adjust(const void *vp, const rc_header *prc, int delta) +rc_trace_adjust(const void *vp, const rc_header *prc, int delta, const char *cname) { - dmprintf4(prc->memory, "[^]%s 0x%lx %+d => %ld\n", + dmprintf5(prc->memory, "[^]%s 0x%lx %+d => %ld (%s)\n", rc_object_type_name(vp, prc), - (ulong)vp, delta, (long)(prc->ref_count + delta)); + (ulong)vp, delta, (long)(prc->ref_count + delta), cname); } #endif /* DEBUG */ diff -Nru ghostscript-9.10~dfsg/base/gsmemory.h ghostscript-9.25~dfsg+1/base/gsmemory.h --- ghostscript-9.10~dfsg/base/gsmemory.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmemory.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -88,6 +88,7 @@ * plus overhead. */ ulong used; + ulong max_used; /* used when wrapping if underlying allocator must be thread safe */ bool is_thread_safe; } gs_memory_status_t; @@ -135,7 +136,7 @@ void proc(mem_t *mem, void *data, client_name_t cname) #define gs_free_object(mem, data, cname)\ - ((mem)->procs.free_object(mem, data, cname)) + do { if (mem != NULL) {((mem)->procs.free_object(mem, data, cname));} } while (0) /* * Report status (assigned, used). @@ -202,6 +203,7 @@ #define gs_consolidate_free(mem)\ ((mem)->procs.consolidate_free(mem)) + /* Define the members of the procedure structure. */ #define gs_raw_memory_procs(mem_t)\ gs_memory_t_proc_alloc_bytes((*alloc_bytes_immovable), mem_t);\ @@ -385,6 +387,19 @@ (*(mem)->procs.enable_free)(mem, enable) gs_memory_proc_enable_free((*enable_free)); +#define gs_memory_proc_set_object_type(proc)\ + void proc(gs_memory_t *mem, void *data, gs_memory_type_ptr_t type) +#define gs_set_object_type(mem, data, type)\ + (*(mem)->procs.set_object_type)(mem, data, type) + gs_memory_proc_set_object_type((*set_object_type)); + +#define gs_memory_proc_defer_frees(proc)\ + void proc(gs_memory_t *mem, int defer) +#define gs_defer_frees(mem, defer)\ + (*(mem)->procs.defer_frees)(mem, defer) + gs_memory_proc_defer_frees((*defer_frees)); +#define GS_MEMORY_CAN_DEFER_FREES + } gs_memory_procs_t; /* @@ -436,8 +451,6 @@ gs_memory_type_ptr_t pstype, client_name_t cname); -typedef struct pl_mem_node_s pl_mem_node_t; - /* * Define an abstract allocator instance. * Subclasses may have state as well diff -Nru ghostscript-9.10~dfsg/base/gsmemraw.h ghostscript-9.25~dfsg+1/base/gsmemraw.h --- ghostscript-9.10~dfsg/base/gsmemraw.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmemraw.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -55,6 +55,7 @@ * plus overhead. */ ulong used; + ulong max_used; /* used when wrapping if underlying allocator must be thread safe */ bool is_thread_safe; } gs_memory_status_t; diff -Nru ghostscript-9.10~dfsg/base/gsmemret.c ghostscript-9.25~dfsg+1/base/gsmemret.c --- ghostscript-9.10~dfsg/base/gsmemret.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmemret.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -46,6 +46,8 @@ static gs_memory_proc_register_root(gs_retrying_register_root); static gs_memory_proc_unregister_root(gs_forward_unregister_root); static gs_memory_proc_enable_free(gs_forward_enable_free); +static gs_memory_proc_set_object_type(gs_forward_set_object_type); +static gs_memory_proc_defer_frees(gs_forward_defer_frees); static const gs_memory_procs_t retrying_procs = { /* Raw memory procedures */ gs_retrying_alloc_bytes_immovable, @@ -71,7 +73,9 @@ gs_forward_free_string, gs_retrying_register_root, gs_forward_unregister_root, - gs_forward_enable_free + gs_forward_enable_free, + gs_forward_set_object_type, + gs_forward_defer_frees }; /* Define a vacuous recovery procedure. */ @@ -363,3 +367,13 @@ { DO_FORWARD(target->procs.enable_free(target, enable)); } + +static void gs_forward_set_object_type(gs_memory_t *mem, void *ptr, gs_memory_type_ptr_t type) +{ + DO_FORWARD(target->procs.set_object_type(target, ptr, type)); +} + +static void gs_forward_defer_frees(gs_memory_t *mem, int defer) +{ + DO_FORWARD(target->procs.defer_frees(target, defer)); +} diff -Nru ghostscript-9.10~dfsg/base/gsmemret.h ghostscript-9.25~dfsg+1/base/gsmemret.h --- ghostscript-9.10~dfsg/base/gsmemret.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmemret.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gs_mgl_e.h ghostscript-9.25~dfsg+1/base/gs_mgl_e.h --- ghostscript-9.10~dfsg/base/gs_mgl_e.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gs_mgl_e.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsmisc.c ghostscript-9.25~dfsg+1/base/gsmisc.c --- ghostscript-9.10~dfsg/base/gsmisc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsmisc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -297,9 +297,10 @@ { char msg[1024]; va_list ap; + int count; va_start(ap, fmt); - vsnprintf(msg, sizeof(msg), fmt, ap); + count = vsnprintf(msg, sizeof(msg), fmt, ap); msg[sizeof(msg) - 1] = 0; va_end(ap); @@ -327,6 +328,9 @@ if (op == 3) errprintf_nomem(" %s:%d: %s(): %s\n", file, line, func, msg); + if (count >= sizeof(msg) || count < 0) { /* C99 || MSVC */ + errwrite_nomem(msg_truncated, sizeof(msg_truncated) - 1); + } return code; } #endif diff -Nru ghostscript-9.10~dfsg/base/gs_mro_e.h ghostscript-9.25~dfsg+1/base/gs_mro_e.h --- ghostscript-9.10~dfsg/base/gs_mro_e.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gs_mro_e.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsnamecl.c ghostscript-9.25~dfsg+1/base/gsnamecl.c --- ghostscript-9.10~dfsg/base/gsnamecl.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsnamecl.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Callback mechanism for handling color spaces containing named colors. */ @@ -51,7 +51,7 @@ * Separation color space. */ bool -custom_color_callback_install_Separation(gs_color_space * pcs, gs_state * pgs) +custom_color_callback_install_Separation(gs_color_space * pcs, gs_gstate * pgs) { client_custom_color_params_t * pcb = (client_custom_color_params_t *) pgs->memory->gs_lib_ctx->custom_color_callback; @@ -65,7 +65,7 @@ * DeviceN color space. */ bool -custom_color_callback_install_DeviceN(gs_color_space * pcs, gs_state * pgs) +custom_color_callback_install_DeviceN(gs_color_space * pcs, gs_gstate * pgs) { client_custom_color_params_t * pcb = (client_custom_color_params_t *) pgs->memory->gs_lib_ctx->custom_color_callback; @@ -81,17 +81,17 @@ int gx_remap_concrete_custom_color_Separation(const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { client_custom_color_params_t * pcb = - (client_custom_color_params_t *) pis->memory->gs_lib_ctx->custom_color_callback; + (client_custom_color_params_t *) pgs->memory->gs_lib_ctx->custom_color_callback; if (pcb == NULL) { return_error(gs_error_rangecheck); } else return pcb->client_procs->remap_Separation(pcb, pconc, - pcs, pdc, pis, dev, select); + pcs, pdc, pgs, dev, select); } /* @@ -101,17 +101,17 @@ int gx_remap_concrete_custom_color_DeviceN(const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { client_custom_color_params_t * pcb = - (client_custom_color_params_t *) pis->memory->gs_lib_ctx->custom_color_callback; + (client_custom_color_params_t *) pgs->memory->gs_lib_ctx->custom_color_callback; if (pcb == NULL) { return_error(gs_error_rangecheck); } else return pcb->client_procs->remap_DeviceN(pcb, pconc, - pcs, pdc, pis, dev, select); + pcs, pdc, pgs, dev, select); } /* @@ -122,7 +122,7 @@ * would be a problem using integers to pass pointer values on 64 bit systems. */ int -custom_color_callback_get_params(gs_state * pgs, gs_param_list * plist) +custom_color_callback_get_params(gs_gstate * pgs, gs_param_list * plist) { /* Convert our pointer to a PostScript hex string */ char buf[64] = "16#"; @@ -156,7 +156,7 @@ * would be a problem using integers to pass pointer values on 64 bit systems. */ int -custom_color_callback_put_params(gs_state * pgs, gs_param_list * plist) +custom_color_callback_put_params(gs_gstate * pgs, gs_param_list * plist) { int code; size_t iptr = (size_t)(pgs->memory->gs_lib_ctx->custom_color_callback); diff -Nru ghostscript-9.10~dfsg/base/gsnamecl.h ghostscript-9.25~dfsg+1/base/gsnamecl.h --- ghostscript-9.10~dfsg/base/gsnamecl.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsnamecl.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Global definitions for the 'Named Color' callback handling. */ @@ -60,14 +60,14 @@ typedef struct gx_device_color_s gx_device_color; #endif -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_device_DEFINED @@ -96,7 +96,7 @@ * is not being used since PS integers are nominally 32 bits. Thus there * would be a problem using integers to pass pointer values on 64 bit systems. */ -int custom_color_callback_put_params(gs_state * pgs, gs_param_list * plist); +int custom_color_callback_put_params(gs_gstate * pgs, gs_param_list * plist); /* * Get the custom client client callback parameter block pointer. This value @@ -105,20 +105,20 @@ * is not being used since PS intergers are nominally 32 bits. Thus there * would be a problem using integers to pass pointer values on 64 bit systems. */ -int custom_color_callback_get_params(gs_state * pgs, gs_param_list * plist); +int custom_color_callback_get_params(gs_gstate * pgs, gs_param_list * plist); /* * Check if we want to use the callback color processing logic for the given * Separation color space. */ bool custom_color_callback_install_Separation(gs_color_space * pcs, - gs_state * pgs); + gs_gstate * pgs); /* * Check if we want to use the custom client callback processing logic for the * given DeviceN color space. */ -bool custom_color_callback_install_DeviceN(gs_color_space * pcs, gs_state * pgs); +bool custom_color_callback_install_DeviceN(gs_color_space * pcs, gs_gstate * pgs); /* * Convert a Separation color into device colorants using the custom client @@ -126,7 +126,7 @@ */ int gx_remap_concrete_custom_color_Separation(const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select); + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Convert a DeviceN color into device colorants using the custom client @@ -134,7 +134,7 @@ */ int gx_remap_concrete_custom_color_DeviceN(const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select); + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* "CLIENT COLOR CALLBACK APPLICATION INTERFACE" */ /* @@ -178,70 +178,70 @@ * Install a DeviceGray color space. */ bool (* install_DeviceGray)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a DeviceGray color into device color. */ int (* remap_DeviceGray)(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Install a DeviceRGB color space. */ bool (* install_DeviceRGB)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a DeviceRGB color into device color. */ int (* remap_DeviceRGB)(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Install a DeviceCMYK color space. */ bool (* install_DeviceCMYK)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a DeviceGray color into device color. */ int (* remap_DeviceCMYK)(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Check if we want to use the callback color processing logic for the * given Separation color space. */ bool (* install_Separation)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a Separation color into device color. */ int (* remap_Separation)(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Check if we want to use the callback color processing logic for the * given DeviceN color space. */ bool (* install_DeviceN)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a DeviceN color into device color. */ int (* remap_DeviceN)(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Check if we want to use the callback color processing logic for the * given CIEBasedA color space. */ bool (* install_CIEBasedA)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Please note that the 'complex' color spaces (CIEBasedA, CIEBasedABC, * CIEBasedDEF, CIEBasedDEFG, and ICCBased) have a different prototype, @@ -253,59 +253,59 @@ */ int (* remap_CIEBasedA)(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Check if we want to use the callback color processing logic for the * given CIEBasedABC color space. */ bool (* install_CIEBasedABC)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a CIEBasedABC color into device color. */ int (* remap_CIEBasedABC)(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Check if we want to use the callback color processing logic for the * given CIEBasedDEF color space. */ bool (* install_CIEBasedDEF)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a CIEBasedDEF color into device color. */ int (* remap_CIEBasedDEF)(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Check if we want to use the callback color processing logic for the * given CIEBasedDEFG color space. */ bool (* install_CIEBasedDEFG)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a CIEBasedDEFG color into device color. */ int (* remap_CIEBasedDEFG)(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); /* * Check if we want to use the callback color processing logic for the * given ICCBased color space. */ bool (* install_ICCBased)(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs); + gs_color_space * pcs, gs_gstate * pgs); /* * Convert a ICCBased color into device color. */ int (* remap_ICCBased)(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select); } client_custom_color_procs_t; diff -Nru ghostscript-9.10~dfsg/base/gsncdummy.c ghostscript-9.25~dfsg+1/base/gsncdummy.c --- ghostscript-9.10~dfsg/base/gsncdummy.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsncdummy.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Sample implementation for client custom processing of color spaces. */ @@ -136,20 +136,20 @@ * colorant in the color space. */ int color_index[GS_CLIENT_COLOR_MAX_COMPONENTS]; - gs_imager_state *CIEtoXYZ_pis; /* Used to map CIE spaces to XYZ */ + gs_gstate *CIEtoXYZ_pgs; /* Used to map CIE spaces to XYZ */ /* refer to gx_cie_to_xyz_alloc */ } demo_color_space_data_t; gs_private_st_ptrs1(st_demo_color_space_data, demo_color_space_data_t, "demo_color_space_data_t", demo_color_space_enum_ptrs, - demo_color_space_reloc_ptrs, CIEtoXYZ_pis); + demo_color_space_reloc_ptrs, CIEtoXYZ_pgs); /* * Dummy install routine for color spaces which are not handled by the client. */ static bool client_install_no_op(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { return false; /* Do nothing */ } @@ -166,9 +166,9 @@ pdata->ref_count += delta; if (pdata->ref_count <= 0) { - /* Free up the CIE to XYZ imager state if it was allocated */ - if (pdata->CIEtoXYZ_pis) { - gx_cie_to_xyz_free(pdata->CIEtoXYZ_pis); + /* Free up the CIE to XYZ gs_gstate if it was allocated */ + if (pdata->CIEtoXYZ_pgs) { + gx_cie_to_xyz_free(pdata->CIEtoXYZ_pgs); } gs_free_object(pdata->memory, pdata, "client_adjust_cspace_count(pdata)"); } @@ -186,7 +186,7 @@ { /* * We allocate this with normal GC structure declarations since - * we need this to be able to allocate the gs_imager_state for XYZ + * we need this to be able to allocate the gs_gstate for XYZ * conversion. * Since this is in stable memory, we use a simple reference count. * See client_adjust_cspace_count. @@ -211,7 +211,7 @@ static bool client_install_generic(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { demo_color_space_data_t * pclient_data; @@ -235,7 +235,7 @@ */ static bool client_pantone_install_Separation(client_custom_color_params_t * pparam, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { const gs_separation_name name = pcs->params.separation.sep_name; int pan_index; @@ -285,7 +285,7 @@ */ static bool client_pantone_install_DeviceN(client_custom_color_params_t * pparam, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { const gs_separation_name *names = pcs->params.device_n.names; int num_comp = pcs->params.device_n.num_components; @@ -406,7 +406,7 @@ static int client_pantone_remap_color(client_custom_color_params_t * pparam, const frac * pconc, const demo_color_space_data_t * pparams, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select, int num_comp) { int i, pantone_index, cvalue; @@ -463,7 +463,7 @@ cm = (magenta > frac_1) ? frac_1 : (magenta < frac_0) ? frac_0 : magenta; cy = (yellow > frac_1) ? frac_1 : (yellow < frac_0) ? frac_0 : yellow; ck = (black > frac_1) ? frac_1 : (black < frac_0) ? frac_0 : black; - gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pis, dev, select); + gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pgs, dev, select); return 0; } @@ -473,11 +473,11 @@ static int client_pantone_remap_Separation(client_custom_color_params_t * pparam, const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { return client_pantone_remap_color(pparam, pconc, (demo_color_space_data_t *)(pcs->pclient_color_space_data), - pdc, pis, dev, select, 1); + pdc, pgs, dev, select, 1); } /* @@ -486,11 +486,11 @@ static int client_pantone_remap_DeviceN(client_custom_color_params_t * pparam, const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { return client_pantone_remap_color(pparam, pconc, (demo_color_space_data_t *)(pcs->pclient_color_space_data), - pdc, pis, dev, select, gs_color_space_num_components(pcs)); + pdc, pgs, dev, select, gs_color_space_num_components(pcs)); } #if !PANTONE_ONLY @@ -500,7 +500,7 @@ */ static bool client_install_DeviceGray(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { /* Nothing to do in our demo */ return true; @@ -512,7 +512,7 @@ */ static int convert_intensity_into_device_color(const frac intensity, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { frac cc, cm, cy, ck; @@ -534,7 +534,7 @@ } /* Send CMYK colors to the device */ - gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pis, dev, select); + gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pgs, dev, select); return 0; } @@ -544,7 +544,7 @@ static int client_remap_DeviceGray(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { #if OBJECT_TYPE_EXAMPLE @@ -553,13 +553,13 @@ * intensity of the given colors and the object type. */ frac intensity = pconc[0]; - convert_intensity_into_device_color(intensity, pdc, pis, dev, select); + convert_intensity_into_device_color(intensity, pdc, pgs, dev, select); #else /* If desired, replace with your own color transformation */ - gx_remap_concrete_gray(pconc[0], pdc, pis, dev, select); + gx_remap_concrete_gray(pconc[0], pdc, pgs, dev, select); #endif @@ -571,7 +571,7 @@ */ static bool client_install_DeviceRGB(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { /* Nothing to do in our demo */ dlprintf1("client_install_DeviceRGB ri = %d\n", pgs->renderingintent); @@ -584,7 +584,7 @@ static int client_remap_DeviceRGB(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { #if OBJECT_TYPE_EXAMPLE @@ -593,13 +593,13 @@ * intensity of the given colors and the object type. */ frac intensity = (frac)(pconc[0] * 0.30 + pconc[1] * 0.59 + pconc[2] * 0.11); - convert_intensity_into_device_color(intensity, pdc, pis, dev, select); + convert_intensity_into_device_color(intensity, pdc, pgs, dev, select); #else /* If desired, replace with your own color transformation */ - gx_remap_concrete_rgb(pconc[0], pconc[1], pconc[2], pdc, pis, dev, select); + gx_remap_concrete_rgb(pconc[0], pconc[1], pconc[2], pdc, pgs, dev, select); #endif @@ -611,7 +611,7 @@ */ static bool client_install_DeviceCMYK(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { /* Nothing to do in our demo */ return true; @@ -623,7 +623,7 @@ static int client_remap_DeviceCMYK(client_custom_color_params_t * pparams, const frac * pconc, const gs_color_space * pcs, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { #if OBJECT_TYPE_EXAMPLE @@ -637,12 +637,12 @@ if (intensity < frac_0) intensity = frac_0; - convert_intensity_into_device_color(intensity, pdc, pis, dev, select); + convert_intensity_into_device_color(intensity, pdc, pgs, dev, select); #else /* If desired, replace with your own color transformation */ - gx_remap_concrete_cmyk(pconc[0], pconc[1], pconc[2], pconc[3],pdc, pis, dev, select); + gx_remap_concrete_cmyk(pconc[0], pconc[1], pconc[2], pconc[3],pdc, pgs, dev, select); #endif @@ -661,7 +661,7 @@ static bool client_install_CIEtoA(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { /* get ready for converting to XYZ */ demo_color_space_data_t * pdata; @@ -692,9 +692,9 @@ gx_cie_load_common_cache(&pcie->common, pgs); gs_cie_a_complete(pcie); if ((code=gs_cie_cs_complete(pgs, true)) >= 0) { - /* Now allocate the conversion imager state in stable_memory */ + /* Now allocate the conversion gs_gstate in stable_memory */ /* so that the garbage collector won't free it */ - code = gx_cie_to_xyz_alloc(&pdata->CIEtoXYZ_pis, pcs, + code = gx_cie_to_xyz_alloc(&pdata->CIEtoXYZ_pgs, pcs, pcs->rc.memory->stable_memory); } if (code < 0) { @@ -707,7 +707,7 @@ static bool client_install_CIEtoXYZ(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { /* get ready for converting to XYZ */ demo_color_space_data_t * pdata; @@ -753,9 +753,9 @@ } /* Fill the caches we need in the CIE color space */ if ((code=gx_install_cie_abc((gs_cie_abc *)pcie, pgs)) >= 0) { - /* Now allocate the conversion imager state in stable_memory */ + /* Now allocate the conversion gs_gstate in stable_memory */ /* so that the garbage collector won't free it */ - code = gx_cie_to_xyz_alloc(&pdata->CIEtoXYZ_pis, pcs, + code = gx_cie_to_xyz_alloc(&pdata->CIEtoXYZ_pgs, pcs, pcs->rc.memory->stable_memory); } if (code < 0) { @@ -768,7 +768,7 @@ static bool client_install_ICCtoXYZ(client_custom_color_params_t * pparams, - gs_color_space * pcs, gs_state * pgs) + gs_color_space * pcs, gs_gstate * pgs) { int code; const gs_icc_params * picc_params = (const gs_icc_params *)&pcs->params.icc; @@ -781,7 +781,7 @@ pdata = allocate_client_data_block(1, pcs->rc.memory->stable_memory); pcs->pclient_color_space_data = (client_color_space_data_t *) pdata; - /* Need to initialize the client data. The imager_state is what is needed in pdata->CIEtoXZY_ps */ + /* Need to initialize the client data. The gs_gstate is what is needed in pdata->CIEtoXZY_ps */ /* update the stub information used by the joint caches */ gx_cie_load_common_cache(&picc_info->common, pgs); @@ -792,9 +792,9 @@ return false; } - /* Now allocate the conversion imager state in stable_memory */ + /* Now allocate the conversion gs_gstate in stable_memory */ /* so that the garbage collector won't free it */ - code = gx_cie_to_xyz_alloc(&pdata->CIEtoXYZ_pis, pcs, + code = gx_cie_to_xyz_alloc(&pdata->CIEtoXYZ_pgs, pcs, pcs->rc.memory->stable_memory); if (code < 0) { @@ -811,7 +811,7 @@ static int client_remap_CIEBasedA(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { demo_color_space_data_t * pdata = @@ -819,10 +819,10 @@ frac gray = convert2frac(pc->paint.values[0], pcs->params.a->RangeA); /*** Demonstrate method to convert to XYZ ***/ - if (pdata->CIEtoXYZ_pis) { + if (pdata->CIEtoXYZ_pgs) { frac xyz[3]; - cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pis); + cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pgs); /* We don't really do anything with these values, but this */ /* is where a real client could convert to a device color */ if_debug4('|', "[c]client_remap CIEA [%g] -> XYZ [%g, %g, %g]\n", @@ -834,7 +834,7 @@ * For demo and debug purposes, make our colors a function of the * intensity of the given color value and the object type. */ - return client_remap_DeviceGray(pparams, &gray, pcs, pdc, pis, dev, select); + return client_remap_DeviceGray(pparams, &gray, pcs, pdc, pgs, dev, select); } /* @@ -843,7 +843,7 @@ static int client_remap_CIEBasedABC(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { demo_color_space_data_t * pdata = @@ -852,10 +852,10 @@ int i; /*** Demonstrate method to convert to XYZ ***/ - if (pdata->CIEtoXYZ_pis) { + if (pdata->CIEtoXYZ_pgs) { frac xyz[3]; - cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pis); + cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pgs); /* We don't really do anything with these values, but this */ /* is where a real client could convert to a device color */ if_debug6('|', "[c]client_remap CIEABC [%g, %g, %g] -> XYZ [%g, %g, %g]\n", @@ -871,7 +871,7 @@ for (i = 0; i < 3; i++) rgb[i] = convert2frac(pc->paint.values[i], pcs->params.abc->RangeABC.ranges[i]); - return client_remap_DeviceRGB(pparams, rgb, pcs, pdc, pis, dev, select); + return client_remap_DeviceRGB(pparams, rgb, pcs, pdc, pgs, dev, select); } /* @@ -880,7 +880,7 @@ static int client_remap_CIEBasedDEF(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { demo_color_space_data_t * pdata = @@ -889,10 +889,10 @@ int i; /*** Demonstrate method to convert to XYZ ***/ - if (pdata->CIEtoXYZ_pis) { + if (pdata->CIEtoXYZ_pgs) { frac xyz[3]; - cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pis); + cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pgs); /* We don't really do anything with these values, but this */ /* is where a real client could convert to a device color */ if_debug6('|', "[c]client_remap CIEDEF [%g, %g, %g] -> XYZ [%g, %g, %g]\n", @@ -908,7 +908,7 @@ for (i = 0; i < 3; i++) rgb[i] = convert2frac(pc->paint.values[i], pcs->params.def->RangeDEF.ranges[i]); - return client_remap_DeviceRGB(pparams, rgb, pcs, pdc, pis, dev, select); + return client_remap_DeviceRGB(pparams, rgb, pcs, pdc, pgs, dev, select); } /* @@ -917,7 +917,7 @@ static int client_remap_CIEBasedDEFG(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { demo_color_space_data_t * pdata = @@ -926,10 +926,10 @@ int i; /*** Demonstrate method to convert to XYZ ***/ - if (pdata->CIEtoXYZ_pis) { + if (pdata->CIEtoXYZ_pgs) { frac xyz[3]; - cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pis); + cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pgs); /* We don't really do anything with these values, but this */ /* is where a real client could convert to a device color */ if_debug7('|', "[c]client_remap CIEDEFG [%g, %g, %g] -> XYZ [%g, %g, %g]\n", @@ -946,7 +946,7 @@ for (i = 0; i < 4; i++) cmyk[i] = convert2frac(pc->paint.values[i], pcs->params.defg->RangeDEFG.ranges[i]); - return client_remap_DeviceRGB(pparams, cmyk, pcs, pdc, pis, dev, select); + return client_remap_DeviceRGB(pparams, cmyk, pcs, pdc, pgs, dev, select); } /* @@ -955,7 +955,7 @@ static int client_remap_ICCBased(client_custom_color_params_t * pparams, const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { demo_color_space_data_t * pdata = @@ -964,11 +964,11 @@ int i, num_values = pcs->params.icc.picc_info->num_components; /*** Demonstrate method to convert to XYZ ***/ - if (pdata->CIEtoXYZ_pis) { + if (pdata->CIEtoXYZ_pgs) { frac xyz[3]; - cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pis); + cs_concretize_color(pc, pcs, xyz, pdata->CIEtoXYZ_pgs); /* We don't really do anything with these values, but this */ /* is where a real client could convert to a device color */ if_debug6('|', "[c]client_remap ICCBased [%g, %g, %g] -> XYZ [%g, %g, %g]\n", @@ -992,14 +992,14 @@ return_error(gs_error_rangecheck); case 1: return client_remap_DeviceGray(pparams, frac_color, pcs, - pdc, pis, dev, select); + pdc, pgs, dev, select); case 3: return client_remap_DeviceRGB(pparams, frac_color, pcs, - pdc, pis, dev, select); + pdc, pgs, dev, select); case 4: default: return client_remap_DeviceCMYK(pparams, frac_color, pcs, - pdc, pis, dev, select); + pdc, pgs, dev, select); } } diff -Nru ghostscript-9.10~dfsg/base/gsncdummy.h ghostscript-9.25~dfsg+1/base/gsncdummy.h --- ghostscript-9.10~dfsg/base/gsncdummy.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsncdummy.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Global definitions for the example custom color callback handling. */ diff -Nru ghostscript-9.10~dfsg/base/gsnogc.c ghostscript-9.25~dfsg+1/base/gsnogc.c --- ghostscript-9.10~dfsg/base/gsnogc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsnogc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsnogc.h ghostscript-9.25~dfsg+1/base/gsnogc.h --- ghostscript-9.10~dfsg/base/gsnogc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsnogc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsnotify.c ghostscript-9.25~dfsg+1/base/gsnotify.c --- ghostscript-9.10~dfsg/base/gsnotify.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsnotify.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsnotify.h ghostscript-9.25~dfsg+1/base/gsnotify.h --- ghostscript-9.10~dfsg/base/gsnotify.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsnotify.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsovrc.c ghostscript-9.25~dfsg+1/base/gsovrc.c --- ghostscript-9.10~dfsg/base/gsovrc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsovrc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,7 +28,7 @@ #include "gxdcolor.h" #include "gxoprect.h" #include "gsbitops.h" -#include "gxistate.h" +#include "gxgstate.h" /* GC descriptor for gs_overprint_t */ private_st_gs_overprint_t(); @@ -63,7 +63,7 @@ ; if (num_bytes > *psize) { *psize = num_bytes; - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } ctmp = cindex; *psize = num_bytes; @@ -125,7 +125,6 @@ */ #define OVERPRINT_ANY_COMPS 1 #define OVERPRINT_SPOT_COMPS 2 -#define OVERPRINT_BLEND 4 /* * Convert an overprint compositor to string form for use by the command @@ -141,28 +140,13 @@ /* encoded the booleans in a single byte */ if (pparams->retain_any_comps) { flags |= OVERPRINT_ANY_COMPS; - if (pparams->blendspot) - flags |= OVERPRINT_BLEND; if (pparams->retain_spot_comps) flags |= OVERPRINT_SPOT_COMPS; /* write out the component bits only if necessary (and possible) */ - if (!pparams->retain_spot_comps || pparams->blendspot) { + if (!pparams->retain_spot_comps) { uint tmp_size = (avail > 0 ? avail - 1 : 0); - int code = write_color_index(pparams->drawn_comps, data + 1, + int code = write_color_index(pparams->drawn_comps, data + 1, &tmp_size); - /* It would be nice to do have an If RGB OP case, then write out - K value, but on the reader side, there is no way to find this - out so we will always write it out if we are writing the - drawn_comps */ - if (code == 0) { - /* Actually writing not getting size */ - int pos = tmp_size + 1; - memcpy(&(data[pos]), &(pparams->k_value), sizeof(pparams->k_value)); - pos = pos + sizeof(pparams->k_value); - memcpy(&(data[pos]), &(pparams->blendspot), sizeof(pparams->blendspot)); - } - used += sizeof(pparams->k_value); - used += sizeof(pparams->blendspot); if (code < 0 && code != gs_error_rangecheck) return code; used += tmp_size; @@ -200,19 +184,14 @@ params.retain_any_comps = (flags & OVERPRINT_ANY_COMPS) != 0; params.retain_spot_comps = (flags & OVERPRINT_SPOT_COMPS) != 0; params.idle = 0; - params.blendspot = (flags & OVERPRINT_BLEND) != 0; - params.k_value = 0; + params.drawn_comps = 0; /* check if the drawn_comps array is present */ - if (params.retain_any_comps && (!params.retain_spot_comps || params.blendspot)) { + if (params.retain_any_comps && (!params.retain_spot_comps)) { code = read_color_index(¶ms.drawn_comps, data + 1, size - 1); if (code < 0) return code; nbytes += code; - memcpy(&(params.k_value), &(data[nbytes]), sizeof(params.k_value)); - nbytes += sizeof(params.k_value); - memcpy(&(params.blendspot), &(data[nbytes]), sizeof(params.blendspot)); - nbytes += sizeof(params.blendspot); } code = gs_create_overprint(ppct, ¶ms, mem); return code < 0 ? code : nbytes; @@ -221,16 +200,15 @@ /* * Check for closing compositor. */ -static int +static gs_compositor_closing_state c_overprint_is_closing(const gs_composite_t *this, gs_composite_t **ppcte, gx_device *dev) { if (*ppcte != NULL && (*ppcte)->type->comp_id != GX_COMPOSITOR_OVERPRINT) - return 0; - return 3; + return COMP_ENQUEUE; + return COMP_REPLACE_PREV; } static composite_create_default_compositor_proc(c_overprint_create_default_compositor); -static composite_create_default_compositor_proc(c_overprint_create_default_compositor); static composite_equal_proc(c_overprint_equal); static composite_write_proc(c_overprint_write); static composite_is_closing_proc(c_overprint_is_closing); @@ -314,14 +292,6 @@ * for the devn color values since we may need more than 8 components */ gx_color_index drawn_comps; - - /* This is used to compensate for the use of black overprint for when - we are simulating CMYK overprinting with an RGB output device */ - ushort k_value; - - /* Used to indicate that the CMYK value should be blended to achieve - overprint simulation */ - bool blendspot; /* * The mask of gx_color_index bits to be retained during a drawing @@ -344,7 +314,7 @@ * is little-endian. */ gx_color_index retain_mask; - + bool copy_alpha_hl; /* We hold 3 sets of device procedures here. These are initialised from @@ -363,7 +333,7 @@ overprint_device_t_enum_ptrs, overprint_device_t_reloc_ptrs, gx_device_finalize, - st_device_forward ); + st_device_forward); /* * In the default (overprint false) case, the overprint device is almost @@ -452,7 +422,12 @@ 0, /* pop_transparency_state */ 0, /* put_image */ 0, /* dev_spec_op */ - gx_forward_copy_planes + gx_forward_copy_planes, + 0, /* get profile */ + 0, /* set graphics type tag */ + 0, /* strip_copy_rop2 */ + 0, /* strip_tile_rect_devn */ + gx_forward_copy_alpha_hl_color /* copy_alpha_hl_color */ }; /* @@ -556,7 +531,12 @@ 0, /* pop_transparency_state */ 0, /* put_image */ 0, /* dev_spec_op */ - gx_forward_copy_planes + gx_forward_copy_planes, + 0, /* get profile */ + 0, /* set graphics type tag */ + 0, /* strip_copy_rop2 */ + 0, /* strip_tile_rect_devn */ + gx_forward_copy_alpha_hl_color /* copy_alpha_hl_color */ }; static const gx_device_procs sep_overprint_procs = { @@ -660,7 +640,7 @@ * takes advantage of the fact that depths that are > 8 must be a multiple * of 8 and <= 64 */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN static gx_color_index swap_color_index(int depth, gx_color_index color) @@ -698,7 +678,7 @@ return color; } -#endif /* !arch_is_big_endian */ +#endif /* !ARCH_IS_BIG_ENDIAN */ /* * Update the retain_mask field to reflect the information in the @@ -708,17 +688,17 @@ static void set_retain_mask(overprint_device_t * opdev) { - int i, ncomps = opdev->color_info.num_components; + uchar i, ncomps = opdev->color_info.num_components; gx_color_index drawn_comps = opdev->drawn_comps, retain_mask = 0; -#if !arch_is_big_endian - int depth = opdev->color_info.depth; +#if !ARCH_IS_BIG_ENDIAN + int depth = opdev->color_info.depth; #endif for (i = 0; i < ncomps; i++, drawn_comps >>= 1) { if ((drawn_comps & 0x1) == 0) retain_mask |= opdev->color_info.comp_mask[i]; } -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN if (depth > 8) retain_mask = swap_color_index(depth, retain_mask); #endif @@ -727,10 +707,10 @@ /* enlarge mask of non-zero components */ static gx_color_index -check_drawn_comps(int ncomps, frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS]) +check_drawn_comps(uchar ncomps, frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS]) { - int i; - gx_color_index mask = 0x1, drawn_comps = 0; + uchar i; + gx_color_index mask = 0x1, drawn_comps = 0; for (i = 0; i < ncomps; i++, mask <<= 1) { if (cvals[i] != frac_0) @@ -751,8 +731,7 @@ overprint_device_t * opdev, const gs_overprint_params_t * pparams ) { - int ncomps = opdev->color_info.num_components; - bool degenerate_k = true; /* Used only for RGB simulation case */ + uchar ncomps = opdev->color_info.num_components; /* check if overprint is to be turned off */ if (!pparams->retain_any_comps || pparams->idle) { @@ -765,7 +744,7 @@ } /* set the procedures according to the color model */ - if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN) + if (colors_are_separable_and_linear(&opdev->color_info)) memcpy( &opdev->procs, &opdev->sep_overprint_procs, sizeof(opdev->sep_overprint_procs) ); @@ -775,59 +754,41 @@ sizeof(opdev->generic_overprint_procs) ); /* see if we need to determine the spot color components */ - opdev->blendspot = pparams->blendspot; if (!pparams->retain_spot_comps) { opdev->drawn_comps = pparams->drawn_comps; - opdev->k_value = pparams->k_value; } else { gx_device * dev = (gx_device *)opdev; - const gx_cm_color_map_procs * pprocs; + subclass_color_mappings scm; frac cvals[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index drawn_comps = 0; static const frac frac_13 = float2frac(1.0 / 3.0); - if ((pprocs = dev_proc(opdev, get_color_mapping_procs)(dev)) == 0 || - pprocs->map_gray == 0 || - pprocs->map_rgb == 0 || - pprocs->map_cmyk == 0 ) - return_error(gs_error_unknownerror); + scm = get_color_mapping_procs_subclass(dev); - pprocs->map_gray(dev, frac_13, cvals); + map_gray_subclass(scm, frac_13, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); - pprocs->map_rgb(dev, 0, frac_13, frac_0, frac_0, cvals); + map_rgb_subclass(scm, 0, frac_13, frac_0, frac_0, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); - pprocs->map_rgb(dev, 0, frac_0, frac_13, frac_0, cvals); + map_rgb_subclass(scm, 0, frac_0, frac_13, frac_0, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); - pprocs->map_rgb(dev, 0, frac_0, frac_0, frac_13, cvals); + map_rgb_subclass(scm, 0, frac_0, frac_0, frac_13, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); - pprocs->map_cmyk(dev, frac_13, frac_0, frac_0, frac_0, cvals); + map_cmyk_subclass(scm, frac_13, frac_0, frac_0, frac_0, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); - pprocs->map_cmyk(dev, frac_0, frac_13, frac_0, frac_0, cvals); + map_cmyk_subclass(scm, frac_0, frac_13, frac_0, frac_0, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); - pprocs->map_cmyk(dev, frac_0, frac_0, frac_13, frac_0, cvals); + map_cmyk_subclass(scm, frac_0, frac_0, frac_13, frac_0, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); - pprocs->map_cmyk(dev, frac_0, frac_0, frac_0, frac_13, cvals); + map_cmyk_subclass(scm, frac_0, frac_0, frac_0, frac_13, cvals); drawn_comps |= check_drawn_comps(ncomps, cvals); opdev->drawn_comps = drawn_comps; } - /* check for degenerate case */ - if (ncomps == 3 && pparams->k_value != 0) { - degenerate_k = false; - } - if (degenerate_k && !(opdev->blendspot) && - opdev->drawn_comps == ((gx_color_index)1 << ncomps) - 1) { - memcpy( &opdev->procs, - &opdev->no_overprint_procs, - sizeof(opdev->no_overprint_procs) ); - return 0; - } - /* if appropriate, update the retain_mask field */ - if (opdev->color_info.separable_and_linear == GX_CINFO_SEP_LIN) + if (colors_are_separable_and_linear(&opdev->color_info)) set_retain_mask(opdev); return 0; @@ -924,21 +885,19 @@ gx_device * dev, gx_device ** pcdev, const gs_composite_t * pct, - gs_imager_state * pis, + gs_gstate * pgs, gs_memory_t * memory, gx_device * cdev) { if (pct->type != &gs_composite_overprint_type) - return gx_default_create_compositor(dev, pcdev, pct, pis, memory, cdev); + return gx_default_create_compositor(dev, pcdev, pct, pgs, memory, cdev); else { gs_overprint_params_t params = ((const gs_overprint_t *)pct)->params; int code; params.idle = pct->idle; /* device must already exist, so just update the parameters */ - code = update_overprint_params( - (overprint_device_t *)dev, - ¶ms ); + code = update_overprint_params((overprint_device_t *)dev, ¶ms); if (code >= 0) *pcdev = dev; return code; @@ -967,12 +926,9 @@ if (tdev == 0) return 0; else - return gx_overprint_generic_fill_rectangle( tdev, opdev->blendspot, - opdev->drawn_comps, - opdev->k_value, - x, y, width, height, - color, - dev->memory ); + return gx_overprint_generic_fill_rectangle(tdev, opdev->drawn_comps, x, + y, width, height, color, + dev->memory); } static int @@ -981,9 +937,9 @@ const gx_drawing_color *pdcolor, int depth) { /* copy_alpha_hl_color will end up calling copy_planes which for the - copy alpha case we need to make sure we do in a proper overprint + copy alpha case we need to make sure we do in a proper overprint fashion. Other calls of copy_alpha for example from the pattern - tiling call are not done with overprint control. So we set an + tiling call are not done with overprint control. So we set an appopriate flag so that we know to handle this properly when we get to copy_alpha */ @@ -991,7 +947,7 @@ int code; opdev->copy_alpha_hl = true; - code = gx_default_copy_alpha_hl_color(dev, data, data_x, raster, id, x, y, + code = gx_default_copy_alpha_hl_color(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth); opdev->copy_alpha_hl = false; return code; @@ -999,10 +955,10 @@ /* Currently we really should only be here if the target device is planar AND it supports devn colors AND is 8 bit. This could use a rewrite to - make if more efficient but I had to get something in place that would + make if more efficient but I had to get something in place that would work */ static int -overprint_copy_planes(gx_device * dev, const byte * data, int data_x, int raster_in, +overprint_copy_planes(gx_device * dev, const byte * data, int data_x, int raster_in, gx_bitmap_id id, int x, int y, int w, int h, int plane_height) { overprint_device_t * opdev = (overprint_device_t *)dev; @@ -1012,12 +968,11 @@ gs_int_rect gb_rect; int code = 0, raster; int byte_depth; - int depth, num_comps; - int k,j; + int depth; + uchar num_comps; + uchar k,j; gs_memory_t * mem = dev->memory; gx_color_index comps = opdev->drawn_comps; - gx_color_index mask; - int shift; byte *curr_data = (byte *) data + data_x; int row, offset; @@ -1033,8 +988,6 @@ fit_fill(tdev, x, y, w, h); byte_depth = depth / num_comps; - mask = ((gx_color_index)1 << byte_depth) - 1; - shift = 16 - byte_depth; /* allocate a buffer for the returned data */ raster = bitmap_raster(w * byte_depth); @@ -1051,29 +1004,29 @@ | GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD - | GB_SELECT_PLANES; + | GB_SELECT_PLANES; - gb_params.x_offset = 0; + gb_params.x_offset = 0; gb_params.raster = raster; gb_rect.p.x = x; gb_rect.q.x = x + w; - + /* step through the height */ row = 0; while (h-- > 0 && code >= 0) { comps = opdev->drawn_comps; gb_rect.p.y = y++; gb_rect.q.y = y; - offset = row * raster_in + data_x; + offset = row * raster_in + data_x; row++; - curr_data = (byte *) data + offset; /* start us at the start of row */ + curr_data = (byte *) data + offset; /* start us at the start of row */ /* And now through each plane */ for (k = 0; k < tdev->color_info.num_components; k++) { /* First set the params to zero for all planes except the one we want */ - for (j = 0; j < tdev->color_info.num_components; j++) + for (j = 0; j < tdev->color_info.num_components; j++) gb_params.data[j] = 0; gb_params.data[k] = gb_buff + k * raster; - code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect, + code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect, &gb_params, 0); if (code < 0) { gs_free_object(mem, gb_buff, "overprint_copy_planes" ); @@ -1089,7 +1042,7 @@ curr_data += plane_height * raster_in; comps >>= 1; } - code = dev_proc(tdev, copy_planes)(tdev, gb_buff, 0, raster, + code = dev_proc(tdev, copy_planes)(tdev, gb_buff, 0, raster, gs_no_bitmap_id, x, y - 1, w, 1, 1); } gs_free_object(mem, gb_buff, "overprint_copy_planes" ); @@ -1098,16 +1051,16 @@ /* This is not a case where copy planes should be doing overprinting. For example, if we came here via the pattern tiling code, so just pass this along to the target */ - return (*dev_proc(tdev, copy_planes)) (tdev, data, data_x, raster_in, id, + return (*dev_proc(tdev, copy_planes)) (tdev, data, data_x, raster_in, id, x, y, w, h, plane_height); } } /* Currently we really should only be here if the target device is planar AND it supports devn colors AND is 8 bit. */ -static int +static int overprint_fill_rectangle_hl_color(gx_device *dev, - const gs_fixed_rect *rect, const gs_imager_state *pis, + const gs_fixed_rect *rect, const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { overprint_device_t * opdev = (overprint_device_t *)dev; @@ -1117,13 +1070,14 @@ gs_int_rect gb_rect; int code = 0, raster; int byte_depth; - int depth, num_comps; - int x,y,w,h,k,j; + int depth; + uchar num_comps; + int x, y, w, h; + uchar k, j; gs_memory_t * mem = dev->memory; gx_color_index comps = opdev->drawn_comps; gx_color_index mask; int shift; - bool blendspot = opdev->blendspot; if (tdev == 0) return 0; @@ -1156,7 +1110,7 @@ | GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD - | GB_SELECT_PLANES; + | GB_SELECT_PLANES; gb_params.x_offset = 0; /* for consistency */ gb_params.raster = raster; @@ -1171,45 +1125,28 @@ /* And now through each plane */ for (k = 0; k < tdev->color_info.num_components; k++) { /* First set the params to zero for all planes except the one we want */ - for (j = 0; j < tdev->color_info.num_components; j++) + for (j = 0; j < tdev->color_info.num_components; j++) gb_params.data[j] = 0; gb_params.data[k] = gb_buff + k * raster; - code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect, + code = dev_proc(tdev, get_bits_rectangle) (tdev, &gb_rect, &gb_params, 0); if (code < 0) { - gs_free_object(mem, gb_buff, + gs_free_object(mem, gb_buff, "overprint_fill_rectangle_hl_color" ); return code; } - if (blendspot) { - /* We need to blend the CMYK colorants as we are simulating - the overprint of a spot colorant with its equivalent CMYK - colorants */ - if ((comps & 0x01) == 1) { - int kk; - byte *cp = gb_params.data[k]; - byte new_val = ((pdcolor->colors.devn.values[k]) >> shift & mask); - for (kk = 0; kk < w; kk++, cp++) { - int temp = (255 - *cp) * (255 - new_val); - temp = temp >> 8; - *cp = (255-temp); - } - } - comps >>= 1; - } else { - /* Skip the plane if this component is not to be drawn. We have - to do a get bits for each plane due to the fact that we have - to do a copy_planes at the end. If we had a copy_plane - operation we would just get the ones needed and set those. */ - if ((comps & 0x01) == 1) { - /* Not sure if a loop or a memset is better here */ - memset(gb_params.data[k], - ((pdcolor->colors.devn.values[k]) >> shift & mask), w); - } - comps >>= 1; + /* Skip the plane if this component is not to be drawn. We have + to do a get bits for each plane due to the fact that we have + to do a copy_planes at the end. If we had a copy_plane + operation we would just get the ones needed and set those. */ + if ((comps & 0x01) == 1) { + /* Not sure if a loop or a memset is better here */ + memset(gb_params.data[k], + ((pdcolor->colors.devn.values[k]) >> shift & mask), w); } + comps >>= 1; } - code = dev_proc(tdev, copy_planes)(tdev, gb_buff, 0, raster, + code = dev_proc(tdev, copy_planes)(tdev, gb_buff, 0, raster, gs_no_bitmap_id, x, y - 1, w, 1, 1); } gs_free_object(mem, gb_buff, @@ -1239,7 +1176,7 @@ * bitmap. This is required only for littl-endian processors, and * then only if the depth > 8. */ -#if !arch_is_big_endian +#if !ARCH_IS_BIG_ENDIAN if (depth > 8) color = swap_color_index(depth, color); #endif @@ -1258,19 +1195,14 @@ * we need only check that depth is a power of 2 and * depth < 8 * sizeof(mono_fill_chunk). */ - if ( depth <= 8 * sizeof(mono_fill_chunk) && - (depth & (depth - 1)) == 0 && !(opdev->blendspot)) - return gx_overprint_sep_fill_rectangle_1( tdev, - opdev->retain_mask, + if ( depth <= 8 * sizeof(mono_fill_chunk) && (depth & (depth - 1)) == 0) + return gx_overprint_sep_fill_rectangle_1(tdev, opdev->retain_mask, x, y, width, height, - color, - dev->memory ); + color, dev->memory); else - return gx_overprint_sep_fill_rectangle_2( tdev, opdev->blendspot, - opdev->retain_mask, + return gx_overprint_sep_fill_rectangle_2(tdev,opdev->retain_mask, x, y, width, height, - color, - dev->memory ); + color, dev->memory); } } @@ -1320,7 +1252,7 @@ const gs_composite_t * pct, gx_device ** popdev, gx_device * tdev, - gs_imager_state * pis, + gs_gstate * pgs, gs_memory_t * mem ) { const gs_overprint_t * ovrpct = (const gs_overprint_t *)pct; @@ -1364,6 +1296,11 @@ gx_device_copy_params((gx_device *)opdev, tdev); gx_device_set_target((gx_device_forward *)opdev, tdev); + opdev->pad = tdev->pad; + opdev->log2_align_mod = tdev->log2_align_mod; + opdev->is_planar = tdev->is_planar; + if (opdev->is_planar) + opdev->generic_overprint_procs.copy_alpha_hl_color = overprint_copy_alpha_hl_color; params = ovrpct->params; params.idle = ovrpct->idle; diff -Nru ghostscript-9.10~dfsg/base/gsovrc.h ghostscript-9.25~dfsg+1/base/gsovrc.h --- ghostscript-9.10~dfsg/base/gsovrc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsovrc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -276,19 +276,6 @@ * it is to be left unaffected. */ gx_color_index drawn_comps; - - /* A representation of the K value that is used for simulating CMYK - overprinting out to an RGB device. While CMY map readily to RGB using - the simple 255-X color process, we have to know what the K value - was if we are overprinting with K so that we can properly reduce - the RGB values with the addition of K. We will use 8 bits for this. - */ - unsigned short k_value; - - /* This is used when we want to simulate the overprint of spot colors - by blending the equivalent CMYK colorant with with what was already - drawn */ - bool blendspot; }; /* diff -Nru ghostscript-9.10~dfsg/base/gspaint.c ghostscript-9.25~dfsg+1/base/gspaint.c --- ghostscript-9.10~dfsg/base/gspaint.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspaint.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,7 +21,7 @@ #include "gserrors.h" #include "gsropt.h" /* for gxpaint.h */ #include "gxfixed.h" -#include "gxmatrix.h" /* for gs_state */ +#include "gxmatrix.h" /* for gs_gstate */ #include "gspaint.h" #include "gspath.h" #include "gzpath.h" @@ -32,12 +32,15 @@ #include "gzcpath.h" #include "gxhldevc.h" #include "gsutil.h" +#include "gxscanc.h" #include "gxdevsop.h" +#include "gsicc_cms.h" +#include "gdevepo.h" /* Define the nominal size for alpha buffers. */ #define abuf_nominal_SMALL 500 #define abuf_nominal_LARGE 2000 -#if arch_small_memory +#if ARCH_SMALL_MEMORY # define abuf_nominal abuf_nominal_SMALL #else #ifdef DEBUG @@ -50,7 +53,7 @@ /* Erase the page */ int -gs_erasepage(gs_state * pgs) +gs_erasepage(gs_gstate * pgs) { /* * We can't just fill with device white; we must take the @@ -70,28 +73,39 @@ /* Fill the page with the current color. */ int -gs_fillpage(gs_state * pgs) +gs_fillpage(gs_gstate * pgs) { gx_device *dev = gs_currentdevice(pgs); int code; - /* If we get here without a valid get_color_mapping_procs, fail */ - if (dev_proc(dev, get_color_mapping_procs) == NULL || - dev_proc(dev, get_color_mapping_procs) == gx_error_get_color_mapping_procs) { + epo_check_and_install(dev); + + /* Deliberately use the terminal device here */ + if (dev_proc(dev, get_color_mapping_procs) == gx_error_get_color_mapping_procs) { emprintf1(dev->memory, "\n *** Error: No get_color_mapping_procs for device: %s\n", dev->dname); return_error(gs_error_Fatal); } - /* Processing a fill object operation */ - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_PATH_TAG); + /* Processing a fill object operation, but this counts as "UNTOUCHED" */ + gx_unset_dev_color(pgs); /* force update so we pick up the new tag */ + gx_unset_alt_dev_color(pgs); + dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_UNTOUCHED_TAG); code = gx_set_dev_color(pgs); if (code != 0) return code; - code = (*dev_proc(dev, fillpage))(dev, (gs_imager_state *)pgs, - gs_currentdevicecolor_inline(pgs)); + code = (*dev_proc(dev, fillpage))(dev, pgs, gs_currentdevicecolor_inline(pgs)); + if (code < 0) + return code; + + /* If GrayDetection is set, make sure monitoring is enabled. */ + if (dev->icc_struct != NULL && + dev->icc_struct->graydetection && !dev->icc_struct->pageneutralcolor) { + dev->icc_struct->pageneutralcolor = true; /* start detecting again */ + code = gsicc_mcm_begin_monitor(pgs->icc_link_cache, dev); + } if (code < 0) return code; return (*dev_proc(dev, sync_output)) (dev); @@ -108,7 +122,7 @@ * the former is less inconvenient. */ static int -scale_paths(gs_state * pgs, int log2_scale_x, int log2_scale_y, bool do_path) +scale_paths(gs_gstate * pgs, int log2_scale_x, int log2_scale_y, bool do_path) { /* * Because of clip and clippath, any of path, clip_path, and view_clip @@ -160,7 +174,7 @@ return 0; } static void -scale_dash_pattern(gs_state * pgs, floatp scale) +scale_dash_pattern(gs_gstate * pgs, double scale) { int i; @@ -172,8 +186,15 @@ if (pgs->line_params.dot_length_absolute) pgs->line_params.dot_length *= scale; } + +/* + Returns 0 for OK. + Returns 1 for "OK, buffer needs releasing" + Returns 2 for "Empty region" + Returns -ve for error + */ static int -alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits, +alpha_buffer_init(gs_gstate * pgs, fixed extra_x, fixed extra_y, int alpha_bits, bool devn) { gx_device *dev = gs_currentdevice_inline(pgs); @@ -181,7 +202,7 @@ gs_fixed_rect bbox; gs_int_rect ibox; uint width, raster, band_space; - uint height; + uint height, height2; gs_log2_scale_point log2_scale; gs_memory_t *mem; gx_device_memory *mdev; @@ -192,12 +213,19 @@ ibox.p.y = fixed2int(bbox.p.y - extra_y) - 1; ibox.q.x = fixed2int_ceiling(bbox.q.x + extra_x) + 1; ibox.q.y = fixed2int_ceiling(bbox.q.y + extra_y) + 1; + (void)dev_proc(dev, dev_spec_op)(dev, gxdso_restrict_bbox, &ibox, sizeof(ibox)); width = (ibox.q.x - ibox.p.x) << log2_scale.x; raster = bitmap_raster(width); band_space = raster << log2_scale.y; - height = (abuf_nominal / band_space) << log2_scale.y; + if (ibox.q.y <= ibox.p.y) + return 2; + height2 = (ibox.q.y - ibox.p.y); + height = (abuf_nominal / band_space); if (height == 0) - height = 1 << log2_scale.y; + height = 1; + if (height > height2) + height = height2; + height <<= log2_scale.y; mem = pgs->memory; mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory, "alpha_buffer_init"); @@ -205,7 +233,7 @@ return 0; /* if no room, don't buffer */ /* We may have to update the marking parameters if we have a pdf14 device as our target. Need to do while dev is still active in pgs */ - if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0)) { + if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, NULL, 0) > 0) { gs_update_trans_marking_params(pgs); } gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale, @@ -225,7 +253,7 @@ /* Release an alpha buffer. */ static int -alpha_buffer_release(gs_state * pgs, bool newpath) +alpha_buffer_release(gs_gstate * pgs, bool newpath) { gx_device_memory *mdev = (gx_device_memory *) gs_currentdevice_inline(pgs); @@ -239,49 +267,36 @@ return code; } -static int do_fill(gs_state *pgs, int rule) +static int do_fill(gs_gstate *pgs, int rule) { int code, abits, acode, rcode = 0; bool devn; - /* Here we need to distinguish text from vectors to compute the object tag. - Actually we need to know whether this function is called to rasterize a character, - or to rasterize a vector graphics to the output device. - Currently we assume it works for the bitrgbtags device only, - which is a low level device with a 4-component color model. - We use the fact that with printers a character is usually being rendered - to a 1bpp cache device rather than to the output device. - Therefore we hackly look whether the target device - "has a color" : either it's a multicomponent color model, - or it is not gray (such as a yellow separation). - - This check has several limitations : - 1. It doesn't work with -dNOCACHE. - 2. It doesn't work with large characters, - which cannot fit into a cache cell and thus they - render directly to the output device. - 3. It doesn't work for TextAlphaBits=2 or 4. - We don't care of this case because - text antialiasing usually usn't applied to printers. - 4. It doesn't work for things like with "(xyz) true charpath stroke". - That's unfortunate, we'd like to improve someday. - 5. It doesn't work for high level devices when a Type 3 character is being constructed. - This case is not important for low level devices - (which a printer is), because low level device doesn't accept - Type 3 charproc streams immediately. - 6. It doesn't work properly while an insiding testing, - which sets gs_hit_device, which is uncolored. + /* We need to distinguish text from vectors to set the object tag. + + To make that determination, we check for the show graphics state being stored + in the current graphics state. This works even in the case of a glyph from a + Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in + the BuildGlyph/BuildChar procedure. Also, it works in the case of operating + without a glyph cache or bypassing the cache because the glyph is too large or + the cache being already full. + + Note that it doesn't work for a construction like: + "(xyz) true charpath fill/stroke" + where the show machinations have completed before we get to the fill operation. + This has implications for how we handle PDF text rendering modes 1 and 2. To + handle that, we'll have to add a flag to the path structure, or to the path + segment structure (depending on how fine grained we require it to be). */ - if (gx_device_has_color(gs_currentdevice(pgs))) { - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_PATH_TAG); - } - else { - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_TEXT_TAG); - } + if (pgs->show_gstate == NULL) + ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + else + ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ + code = gx_set_dev_color(pgs); if (code != 0) return code; - code = gs_state_color_load(pgs); + code = gs_gstate_color_load(pgs); if (code < 0) return code; abits = 0; @@ -294,6 +309,8 @@ if (abits > 1) { acode = alpha_buffer_init(pgs, pgs->fill_adjust.x, pgs->fill_adjust.y, abits, devn); + if (acode == 2) /* Special case for no fill required */ + return 0; if (acode < 0) return acode; } else @@ -310,7 +327,7 @@ /* Fill the current path using a specified rule. */ static int -fill_with_rule(gs_state * pgs, int rule) +fill_with_rule(gs_gstate * pgs, int rule) { int code; @@ -328,73 +345,62 @@ else if (gs_is_null_device(pgs->device) || (pgs->show_gstate && pgs->text_rendering_mode == 3 && pgs->in_cachedevice == CACHE_DEVICE_NOT_CACHING)) { - /* Handle separately to prevent gs_state_color_load - bug 688308. */ + /* Handle separately to prevent gs_gstate_color_load - bug 688308. */ gs_newpath(pgs); code = 0; } else { code = do_fill(pgs, rule); if (code >= 0) - gs_newpath(pgs); + code = gs_newpath(pgs); } return code; } /* Fill using the winding number rule */ int -gs_fill(gs_state * pgs) +gs_fill(gs_gstate * pgs) { pgs->device->sgr.stroke_stored = false; return fill_with_rule(pgs, gx_rule_winding_number); } /* Fill using the even/odd rule */ int -gs_eofill(gs_state * pgs) +gs_eofill(gs_gstate * pgs) { pgs->device->sgr.stroke_stored = false; return fill_with_rule(pgs, gx_rule_even_odd); } static int -do_stroke(gs_state * pgs) +do_stroke(gs_gstate * pgs) { int code, abits, acode, rcode = 0; bool devn; - /* Here we need to distinguish text from vectors to compute the object tag. - Actually we need to know whether this function is called to rasterize a character, - or to rasterize a vector graphics to the output device. - Currently we assume it works for the bitrgbtags device only, - which is a low level device with a 4-component color model. - We use the fact that with printers a character is usually being rendered - to a 1bpp cache device rather than to the output device. - Therefore we hackly look whether the target device - "has a color" : either it's a multicomponent color model, - or it is not gray (such as a yellow separation). - - This check has several limitations : - 1. It doesn't work with -dNOCACHE. - 2. It doesn't work with large characters, - which cannot fit into a cache cell and thus they - render directly to the output device. - 3. It doesn't work for TextAlphaBits=2 or 4. - We don't care of this case because - text antialiasing usually usn't applied to printers. - 4. It doesn't work for things like with "(xyz) true charpath stroke". - That's unfortunate, we'd like to improve someday. - 5. It doesn't work for high level devices when a Type 3 character is being constructed. - This case is not important for low level devices - (which a printer is), because low level device doesn't accept - Type 3 charproc streams immediately. + /* We need to distinguish text from vectors to set the object tag. + + To make that determination, we check for the show graphics state being stored + in the current graphics state. This works even in the case of a glyph from a + Type 3 Postscript/PDF font which has multiple, nested gsave/grestore pairs in + the BuildGlyph/BuildChar procedure. Also, it works in the case of operating + without a glyph cache or bypassing the cache because the glyph is too large or + the cache being already full. + + Note that it doesn't work for a construction like: + "(xyz) true charpath fill/stroke" + where the show machinations have completed before we get to the fill operation. + This has implications for how we handle PDF text rendering modes 1 and 2. To + handle that, we'll have to add a flag to the path structure, or to the path + segment structure (depending on how fine grained we require it to be). */ - if (gx_device_has_color(gs_currentdevice(pgs))) { - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_PATH_TAG); - } - else { - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_TEXT_TAG); - } + if (pgs->show_gstate == NULL) + ensure_tag_is_set(pgs, pgs->device, GS_PATH_TAG); /* NB: may unset_dev_color */ + else + ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ + code = gx_set_dev_color(pgs); if (code != 0) return code; - code = gs_state_color_load(pgs); + code = gs_gstate_color_load(pgs); if (code < 0) return code; abits = 0; @@ -427,6 +433,8 @@ pgs->fill_adjust.x + extra_adjust, pgs->fill_adjust.y + extra_adjust, abits, devn); + if (acode == 2) /* Special code meaning no fill required */ + return 0; if (acode < 0) return acode; gs_setlinewidth(pgs, new_width); @@ -458,7 +466,7 @@ /* Stroke the current path */ int -gs_stroke(gs_state * pgs) +gs_stroke(gs_gstate * pgs) { int code; @@ -478,22 +486,20 @@ } code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path, pgs->in_charpath); + if (code < 0) + return code; } - if (gs_is_null_device(pgs->device)) { - /* Handle separately to prevent gs_state_color_load. */ - gs_newpath(pgs); - code = 0; - } else { + if (!gs_is_null_device(pgs->device)) { code = do_stroke(pgs); - if (code >= 0) - gs_newpath(pgs); + if (code < 0) + return code; } - return code; + return gs_newpath(pgs); } /* Compute the stroked outline of the current path */ static int -gs_strokepath_aux(gs_state * pgs, bool traditional) +gs_strokepath_aux(gs_gstate * pgs, bool traditional) { gx_path spath; int code; @@ -511,20 +517,21 @@ /* NB: needs testing with PCL */ if (gx_path_is_void(pgs->path)) pgs->current_point_valid = false; - else + else { gx_setcurrentpoint(pgs, fixed2float(spath.position.x), fixed2float(spath.position.y)); + } return 0; } int -gs_strokepath(gs_state * pgs) +gs_strokepath(gs_gstate * pgs) { return gs_strokepath_aux(pgs, true); } int -gs_strokepath2(gs_state * pgs) +gs_strokepath2(gs_gstate * pgs) { return gs_strokepath_aux(pgs, false); } diff -Nru ghostscript-9.10~dfsg/base/gspaint.h ghostscript-9.25~dfsg+1/base/gspaint.h --- ghostscript-9.10~dfsg/base/gspaint.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspaint.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,13 +21,13 @@ # define gspaint_INCLUDED /* Painting */ -int gs_erasepage(gs_state *), - gs_fillpage(gs_state *), - gs_fill(gs_state *), - gs_eofill(gs_state *), - gs_stroke(gs_state *); +int gs_erasepage(gs_gstate *), + gs_fillpage(gs_gstate *), + gs_fill(gs_gstate *), + gs_eofill(gs_gstate *), + gs_stroke(gs_gstate *); /* Image tracing */ -int gs_imagepath(gs_state *, int, int, const byte *); +int gs_imagepath(gs_gstate *, int, int, const byte *); #endif /* gspaint_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsparam2.c ghostscript-9.25~dfsg+1/base/gsparam2.c --- ghostscript-9.10~dfsg/base/gsparam2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsparam2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ #include "gserrors.h" #include "gsparams.h" -#define MAX_PARAM_KEY 255 +#define MAX_PARAM_KEY gp_file_name_sizeof /* ---------------- Serializer ---------------- */ @@ -42,6 +42,11 @@ int code = 0; gs_param_enumerator_t key_enum; gs_param_key_t key; + char *string_key = gs_alloc_bytes(dest->memory, MAX_PARAM_KEY + 1, "gs_param_list_puts(string_key)"); + + if (!string_key) { + return_error(gs_error_VMerror); + } param_init_enumerator(&key_enum); @@ -72,7 +77,6 @@ /* Get next datum & put its type & key to stream */ gs_param_typed_value value; - char string_key[MAX_PARAM_KEY + 1]; if (sizeof(string_key) < key.size + 1) { code = gs_note_error(gs_error_rangecheck); @@ -155,6 +159,8 @@ break; } + gs_free_object(dest->memory, string_key, "gs_param_list_puts(string_key)"); + /* Write end marker, which is an (illegal) 0 key length */ return (code < 0 ? code : sput_word(dest, 0)); } @@ -200,6 +206,11 @@ gs_param_list_gets(stream *src, gs_param_list *list, gs_memory_t *mem) { int code = 0; + char *string_key = gs_alloc_bytes(dest->memory, MAX_PARAM_KEY + 1, "gs_param_list_gets(string_key)"); + + if (!string_key) { + return_error(gs_error_VMerror); + } do { gs_param_typed_value typed; @@ -210,7 +221,6 @@ void *data; uint size; gs_param_type type; - char string_key[MAX_PARAM_KEY + 1]; /* key length 0 indicates end of data */ if ((code = sget_word(src, &key_sizeof)) < 0 || @@ -340,6 +350,8 @@ } while (code >= 0); + gs_free_object(dest->memory, string_key, "gs_param_list_gets(string_key)"); + return code; } diff -Nru ghostscript-9.10~dfsg/base/gsparam.c ghostscript-9.25~dfsg+1/base/gsparam.c --- ghostscript-9.10~dfsg/base/gsparam.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsparam.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -187,7 +187,7 @@ case gs_param_type_long: switch (req_type) { case gs_param_type_int: -#if arch_sizeof_int < arch_sizeof_long +#if ARCH_SIZEOF_INT < ARCH_SIZEOF_LONG if (pvalue->value.l != (int)pvalue->value.l) return_error(gs_error_rangecheck); #endif diff -Nru ghostscript-9.10~dfsg/base/gsparam.h ghostscript-9.25~dfsg+1/base/gsparam.h --- ghostscript-9.10~dfsg/base/gsparam.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsparam.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -387,6 +387,16 @@ param_read_requested_typed(plist, pkey, pvalue)) /* Transmit parameters of specific types. */ + +/*************** WARNING ******************** + * You CANNOT use heap allocated strings as + * KEYS in param lists. Keys MUST be string + * constants. + * String values can be heap allocated by + * using param_string_from_transient_string() + * rather than param_string_from_string() + * + ********************************************/ int param_read_null(gs_param_list *, gs_param_name); int param_write_null(gs_param_list *, gs_param_name); int param_read_bool(gs_param_list *, gs_param_name, bool *); diff -Nru ghostscript-9.10~dfsg/base/gsparams.c ghostscript-9.25~dfsg+1/base/gsparams.c --- ghostscript-9.10~dfsg/base/gsparams.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsparams.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsparams.h ghostscript-9.25~dfsg+1/base/gsparams.h --- ghostscript-9.10~dfsg/base/gsparams.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsparams.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsparamx.c ghostscript-9.25~dfsg+1/base/gsparamx.c --- ghostscript-9.10~dfsg/base/gsparamx.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsparamx.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -52,11 +52,12 @@ } } code = gs_error_rangecheck; + /* fall through */ default: ecode = code; param_signal_error(plist, param_name, code); } - return code; + return ecode; } /* Put a Boolean value. */ @@ -176,6 +177,7 @@ value.value.fa.persistent &= copy_persists; goto ca; case gs_param_type_string_array: value.value.sa.persistent &= copy_persists; + /* fall through */ ca: default: code = param_write_typed(plto, string_key, &value); diff -Nru ghostscript-9.10~dfsg/base/gsparamx.h ghostscript-9.25~dfsg+1/base/gsparamx.h --- ghostscript-9.10~dfsg/base/gsparamx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsparamx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gspath1.c ghostscript-9.25~dfsg+1/base/gspath1.c --- ghostscript-9.10~dfsg/base/gspath1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspath1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -41,7 +41,7 @@ typedef struct arc_curve_params_s { /* The following are set once. */ gx_path *ppath; - gs_imager_state *pis; + gs_gstate *pgs; gs_point center; /* (not used by arc_add) */ double radius; /* The following may be updated dynamically. */ @@ -59,34 +59,34 @@ /* Forward declarations */ static int arc_add(const arc_curve_params_t *arc, bool is_quadrant); -static int gs_imager_arc_add(gx_path * ppath, gs_imager_state * pis, bool clockwise, - floatp axc, floatp ayc, floatp arad, floatp aang1, floatp aang2, +static int gs_gstate_arc_add(gx_path * ppath, gs_gstate * pgs, bool clockwise, + double axc, double ayc, double arad, double aang1, double aang2, bool add_line, gs_point *p3); int -gx_setcurrentpoint_from_path(gs_imager_state *pis, gx_path *path) +gx_setcurrentpoint_from_path(gs_gstate *pgs, gx_path *path) { gs_point pt; pt.x = fixed2float(path->position.x); pt.y = fixed2float(path->position.y); - gx_setcurrentpoint(pis, pt.x, pt.y); - pis->current_point_valid = true; + gx_setcurrentpoint(pgs, pt.x, pt.y); + pgs->current_point_valid = true; return 0; } static inline int -gs_arc_add_inline(gs_state *pgs, bool cw, floatp xc, floatp yc, floatp rad, - floatp a1, floatp a2, bool add) +gs_arc_add_inline(gs_gstate *pgs, bool cw, double xc, double yc, double rad, + double a1, double a2, bool add) { gs_point p3; - int code = gs_imager_arc_add(pgs->path, (gs_imager_state *)pgs, cw, xc, yc, rad, a1, a2, add, &p3); + int code = gs_gstate_arc_add(pgs->path, pgs, cw, xc, yc, rad, a1, a2, add, &p3); if (code < 0) return code; #if !PRECISE_CURRENTPOINT - return gx_setcurrentpoint_from_path((gs_imager_state *)pgs, pgs->path); + return gx_setcurrentpoint_from_path(pgs, pgs->path); #else pgs->current_point_valid = true; return gs_point_transform(p3.x, p3.y, &ctm_only(pgs), &pgs->current_point); @@ -95,22 +95,22 @@ } int -gs_arc(gs_state * pgs, - floatp xc, floatp yc, floatp r, floatp ang1, floatp ang2) +gs_arc(gs_gstate * pgs, + double xc, double yc, double r, double ang1, double ang2) { return gs_arc_add_inline(pgs, false, xc, yc, r, ang1, ang2, true); } int -gs_arcn(gs_state * pgs, - floatp xc, floatp yc, floatp r, floatp ang1, floatp ang2) +gs_arcn(gs_gstate * pgs, + double xc, double yc, double r, double ang1, double ang2) { return gs_arc_add_inline(pgs, true, xc, yc, r, ang1, ang2, true); } int -gs_arc_add(gs_state * pgs, bool clockwise, floatp axc, floatp ayc, - floatp arad, floatp aang1, floatp aang2, bool add_line) +gs_arc_add(gs_gstate * pgs, bool clockwise, double axc, double ayc, + double arad, double aang1, double aang2, bool add_line) { return gs_arc_add_inline(pgs, clockwise, axc, ayc, arad, aang1, aang2, add_line); @@ -149,13 +149,13 @@ * If the CTM is well-behaved, we can pre-calculate the delta * from the arc points to the control points. */ - const gs_imager_state *pis = arc->pis; + const gs_gstate *pgs = arc->pgs; double scale = 0; /* Quiet gcc warning. */ - if (is_fzero2(pis->ctm.xy, pis->ctm.yx) ? - (scale = fabs(pis->ctm.xx)) == fabs(pis->ctm.yy) : - is_fzero2(pis->ctm.xx, pis->ctm.yy) ? - (scale = fabs(pis->ctm.xy)) == fabs(pis->ctm.yx) : + if (is_fzero2(pgs->ctm.xy, pgs->ctm.yx) ? + (scale = fabs(pgs->ctm.xx)) == fabs(pgs->ctm.yy) : + is_fzero2(pgs->ctm.xx, pgs->ctm.yy) ? + (scale = fabs(pgs->ctm.xy)) == fabs(pgs->ctm.yx) : 0 ) { double scaled_radius = arc->radius * scale; @@ -200,8 +200,8 @@ } static int -gs_imager_arc_add(gx_path * ppath, gs_imager_state * pis, bool clockwise, - floatp axc, floatp ayc, floatp arad, floatp aang1, floatp aang2, +gs_gstate_arc_add(gx_path * ppath, gs_gstate * pgs, bool clockwise, + double axc, double ayc, double arad, double aang1, double aang2, bool add_line, gs_point *p3) { double ar = arad; @@ -211,7 +211,7 @@ int code; arc.ppath = ppath; - arc.pis = pis; + arc.pgs = pgs; arc.center.x = axc; arc.center.y = ayc; if (ar < 0) { @@ -308,8 +308,8 @@ } int -gs_arcto(gs_state * pgs, -floatp ax1, floatp ay1, floatp ax2, floatp ay2, floatp arad, float retxy[4]) +gs_arcto(gs_gstate * pgs, +double ax1, double ay1, double ax2, double ay2, double arad, float retxy[4]) { double xt0, yt0, xt2, yt2; gs_point up0; @@ -354,7 +354,7 @@ arc_curve_params_t arc; arc.ppath = pgs->path; - arc.pis = (gs_imager_state *) pgs; + arc.pgs = pgs; arc.radius = arad; arc.action = arc_lineto; arc.notes = sn_none; @@ -368,7 +368,7 @@ arc.pt.y = ay1; code = arc_add(&arc, false); if (code == 0) - code = gx_setcurrentpoint_from_path((gs_imager_state *)pgs, pgs->path); + code = gx_setcurrentpoint_from_path(pgs, pgs->path); } } if (retxy != 0) { @@ -385,28 +385,28 @@ arc_add(const arc_curve_params_t * arc, bool is_quadrant) { gx_path *path = arc->ppath; - gs_imager_state *pis = arc->pis; + gs_gstate *pgs = arc->pgs; double x0 = arc->p0.x, y0 = arc->p0.y; double xt = arc->pt.x, yt = arc->pt.y; - floatp fraction; + double fraction; gs_fixed_point p0, p2, p3, pt; int code; if ((arc->action != arc_nothing && #if !PRECISE_CURRENTPOINT - (code = gs_point_transform2fixed(&pis->ctm, x0, y0, &p0)) < 0) || - (code = gs_point_transform2fixed(&pis->ctm, xt, yt, &pt)) < 0 || - (code = gs_point_transform2fixed(&pis->ctm, arc->p3.x, arc->p3.y, &p3)) < 0 + (code = gs_point_transform2fixed(&pgs->ctm, x0, y0, &p0)) < 0) || + (code = gs_point_transform2fixed(&pgs->ctm, xt, yt, &pt)) < 0 || + (code = gs_point_transform2fixed(&pgs->ctm, arc->p3.x, arc->p3.y, &p3)) < 0 #else - (code = gs_point_transform2fixed_rounding(&pis->ctm, x0, y0, &p0)) < 0) || - (code = gs_point_transform2fixed_rounding(&pis->ctm, xt, yt, &pt)) < 0 || - (code = gs_point_transform2fixed_rounding(&pis->ctm, arc->p3.x, arc->p3.y, &p3)) < 0 + (code = gs_point_transform2fixed_rounding(&pgs->ctm, x0, y0, &p0)) < 0) || + (code = gs_point_transform2fixed_rounding(&pgs->ctm, xt, yt, &pt)) < 0 || + (code = gs_point_transform2fixed_rounding(&pgs->ctm, arc->p3.x, arc->p3.y, &p3)) < 0 #endif ) return code; #if PRECISE_CURRENTPOINT if (!path_position_valid(path)) - gs_point_transform(arc->p0.x, arc->p0.y, &ctm_only(arc->pis), &pis->subpath_start); + gs_point_transform(arc->p0.x, arc->p0.y, &ctm_only(arc->pgs), &pgs->subpath_start); #endif code = (arc->action == arc_nothing ? (p0.x = path->position.x, p0.y = path->position.y, 0) : @@ -440,7 +440,7 @@ } } else { double r = arc->radius; - floatp dx = xt - x0, dy = yt - y0; + double dx = xt - x0, dy = yt - y0; double dist = dx * dx + dy * dy; double r2 = r * r; @@ -482,7 +482,7 @@ /* ------ Path transformers ------ */ int -gs_dashpath(gs_state * pgs) +gs_dashpath(gs_gstate * pgs) { gx_path *ppath; gx_path fpath; @@ -495,7 +495,7 @@ return code; ppath = pgs->path; gx_path_init_local(&fpath, ppath->memory); - code = gx_path_add_dash_expansion(ppath, &fpath, (gs_imager_state *)pgs); + code = gx_path_add_dash_expansion(ppath, &fpath, pgs); if (code < 0) { gx_path_free(&fpath, "gs_dashpath"); return code; @@ -505,7 +505,7 @@ } int -gs_flattenpath(gs_state * pgs) +gs_flattenpath(gs_gstate * pgs) { gx_path *ppath = pgs->path; gx_path fpath; @@ -525,7 +525,7 @@ } int -gs_reversepath(gs_state * pgs) +gs_reversepath(gs_gstate * pgs) { gx_path *ppath = pgs->path; gx_path rpath; @@ -553,7 +553,7 @@ /* ------ Accessors ------ */ int -gs_upathbbox(gs_state * pgs, gs_rect * pbox, bool include_moveto) +gs_upathbbox(gs_gstate * pgs, gs_rect * pbox, bool include_moveto) { gs_fixed_rect fbox; /* box in device coordinates */ gs_rect dbox; @@ -590,7 +590,7 @@ /* Start enumerating a path */ int -gs_path_enum_copy_init(gs_memory_t *mem, gs_path_enum * penum, const gs_state * pgs, bool copy) +gs_path_enum_copy_init(gs_memory_t *mem, gs_path_enum * penum, const gs_gstate * pgs, bool copy) { if (copy) { gx_path *copied_path = diff -Nru ghostscript-9.10~dfsg/base/gspath2.h ghostscript-9.25~dfsg+1/base/gspath2.h --- ghostscript-9.10~dfsg/base/gspath2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspath2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,12 +21,12 @@ # define gspath2_INCLUDED /* Miscellaneous */ -int gs_setbbox(gs_state *, floatp, floatp, floatp, floatp); +int gs_setbbox(gs_gstate *, double, double, double, double); /* Rectangles */ -int gs_rectappend(gs_state *, const gs_rect *, uint); -int gs_rectclip(gs_state *, const gs_rect *, uint); -int gs_rectfill(gs_state *, const gs_rect *, uint); -int gs_rectstroke(gs_state *, const gs_rect *, uint, const gs_matrix *); +int gs_rectappend(gs_gstate *, const gs_rect *, uint); +int gs_rectclip(gs_gstate *, const gs_rect *, uint); +int gs_rectfill(gs_gstate *, const gs_rect *, uint); +int gs_rectstroke(gs_gstate *, const gs_rect *, uint, const gs_matrix *); #endif /* gspath2_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gspath.c ghostscript-9.25~dfsg+1/base/gspath.c --- ghostscript-9.10~dfsg/base/gspath.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspath.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,14 +32,14 @@ /* ------ Miscellaneous ------ */ int -gs_newpath(gs_state * pgs) +gs_newpath(gs_gstate * pgs) { pgs->current_point_valid = false; return gx_path_new(pgs->path); } int -gs_closepath(gs_state * pgs) +gs_closepath(gs_gstate * pgs) { gx_path *ppath = pgs->path; int code = gx_path_close_subpath(ppath); @@ -51,15 +51,15 @@ } int -gs_upmergepath(gs_state * pgs) +gs_upmergepath(gs_gstate * pgs) { /* * We really should be able to implement this as simply * return gx_path_add_path(pgs->saved->path, pgs->path); - * But because of the current_point members in the imager state, + * But because of the current_point members in the gs_gstate, * we can't. */ - gs_state *saved = pgs->saved; + gs_gstate *saved = pgs->saved; int code; code = gx_path_add_path(saved->path, pgs->path); @@ -75,7 +75,7 @@ /* Get the current path (for internal use only). */ gx_path * -gx_current_path(const gs_state * pgs) +gx_current_path(const gs_gstate * pgs) { return pgs->path; } @@ -83,14 +83,14 @@ /* ------ Points and lines ------ */ static inline void -clamp_point(gs_fixed_point * ppt, floatp x, floatp y) +clamp_point(gs_fixed_point * ppt, double x, double y) { ppt->x = clamp_coord(x); ppt->y = clamp_coord(y); } int -gs_currentpoint(gs_state * pgs, gs_point * ppt) +gs_currentpoint(gs_gstate * pgs, gs_point * ppt) { if (!pgs->current_point_valid) return_error(gs_error_nocurrentpoint); @@ -99,7 +99,7 @@ } static inline int -gs_point_transform_compat(floatp x, floatp y, const gs_matrix_fixed *m, gs_point *pt) +gs_point_transform_compat(double x, double y, const gs_matrix_fixed *m, gs_point *pt) { #if !PRECISE_CURRENTPOINT gs_fixed_point p; @@ -116,7 +116,7 @@ } static inline int -gs_distance_transform_compat(floatp x, floatp y, const gs_matrix_fixed *m, gs_point *pt) +gs_distance_transform_compat(double x, double y, const gs_matrix_fixed *m, gs_point *pt) { #if !PRECISE_CURRENTPOINT gs_fixed_point p; @@ -133,7 +133,7 @@ } static inline int -clamp_point_aux(bool clamp_coordinates, gs_fixed_point *ppt, floatp x, floatp y) +clamp_point_aux(bool clamp_coordinates, gs_fixed_point *ppt, double x, double y) { if (!f_fits_in_bits(x, fixed_int_bits) || !f_fits_in_bits(y, fixed_int_bits)) { if (!clamp_coordinates) @@ -149,20 +149,20 @@ } int -gs_moveto_aux(gs_imager_state *pis, gx_path *ppath, floatp x, floatp y) +gs_moveto_aux(gs_gstate *pgs, gx_path *ppath, double x, double y) { gs_fixed_point pt; int code; - code = clamp_point_aux(pis->clamp_coordinates, &pt, x, y); + code = clamp_point_aux(pgs->clamp_coordinates, &pt, x, y); if (code < 0) return code; - if (pis->hpgl_path_mode && path_subpath_open(ppath)) + if (pgs->hpgl_path_mode && path_subpath_open(ppath)) { code = gx_path_add_gap_notes(ppath, pt.x, pt.y, 0); if (code < 0) return code; - gx_setcurrentpoint(pis, x, y); + gx_setcurrentpoint(pgs, x, y); } else { @@ -170,26 +170,26 @@ if (code < 0) return code; ppath->start_flags = ppath->state_flags; - gx_setcurrentpoint(pis, x, y); - pis->subpath_start = pis->current_point; + gx_setcurrentpoint(pgs, x, y); + pgs->subpath_start = pgs->current_point; } - pis->current_point_valid = true; + pgs->current_point_valid = true; return 0; } int -gs_moveto(gs_state * pgs, floatp x, floatp y) +gs_moveto(gs_gstate * pgs, double x, double y) { gs_point pt; int code = gs_point_transform_compat(x, y, &pgs->ctm, &pt); if (code < 0) return code; - return gs_moveto_aux((gs_imager_state *)pgs, pgs->path, pt.x, pt.y); + return gs_moveto_aux(pgs, pgs->path, pt.x, pt.y); } int -gs_rmoveto(gs_state * pgs, floatp x, floatp y) +gs_rmoveto(gs_gstate * pgs, double x, double y) { gs_point dd; int code; @@ -200,12 +200,12 @@ if (code < 0) return code; /* fixme : check in range. */ - return gs_moveto_aux((gs_imager_state *)pgs, pgs->path, + return gs_moveto_aux(pgs, pgs->path, dd.x + pgs->current_point.x, dd.y + pgs->current_point.y); } static inline int -gs_lineto_aux(gs_state * pgs, floatp x, floatp y) +gs_lineto_aux(gs_gstate * pgs, double x, double y) { gx_path *ppath = pgs->path; gs_fixed_point pt; @@ -222,7 +222,7 @@ } int -gs_lineto(gs_state * pgs, floatp x, floatp y) +gs_lineto(gs_gstate * pgs, double x, double y) { gs_point pt; int code = gs_point_transform_compat(x, y, &pgs->ctm, &pt); @@ -233,7 +233,7 @@ } int -gs_rlineto(gs_state * pgs, floatp x, floatp y) +gs_rlineto(gs_gstate * pgs, double x, double y) { gs_point dd; int code; @@ -251,8 +251,8 @@ /* ------ Curves ------ */ static inline int -gs_curveto_aux(gs_state * pgs, - floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3) +gs_curveto_aux(gs_gstate * pgs, + double x1, double y1, double x2, double y2, double x3, double y3) { gs_fixed_point p1, p2, p3; int code; @@ -275,8 +275,8 @@ } int -gs_curveto(gs_state * pgs, - floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3) +gs_curveto(gs_gstate * pgs, + double x1, double y1, double x2, double y2, double x3, double y3) { gs_point pt1, pt2, pt3; int code; @@ -294,8 +294,8 @@ } int -gs_rcurveto(gs_state * pgs, - floatp dx1, floatp dy1, floatp dx2, floatp dy2, floatp dx3, floatp dy3) +gs_rcurveto(gs_gstate * pgs, + double dx1, double dy1, double dx2, double dy2, double dx3, double dy3) { gs_point dd1, dd2, dd3; int code; @@ -320,7 +320,7 @@ /* ------ Clipping ------ */ /* Forward references */ -static int common_clip(gs_state *, int); +static int common_clip(gs_gstate *, int); /* Figure out the bbox for a path and a clip path with adjustment if we are also doing a stroke. This is used by the xps interpeter to deteremine @@ -329,7 +329,7 @@ The transparency group will be the intersection of the path and clipping path */ int -gx_curr_bbox(gs_state * pgs, gs_rect *bbox, gs_bbox_comp_t comp_type) +gx_curr_bbox(gs_gstate * pgs, gs_rect *bbox, gs_bbox_comp_t comp_type) { gx_clip_path *clip_path; int code; @@ -351,8 +351,7 @@ if (code < 0) return code; if (comp_type == PATH_STROKE) { /* Handle any stroke expansion of our bounding box */ - expansion_code = gx_stroke_path_expansion((const gs_imager_state *) pgs, - pgs->path, &expansion); + expansion_code = gx_stroke_path_expansion(pgs, pgs->path, &expansion); if (expansion_code >= 0) { path_bbox.p.x -= expansion.x; path_bbox.p.y -= expansion.y; @@ -390,7 +389,7 @@ * device is a cache device. */ int -gx_effective_clip_path(gs_state * pgs, gx_clip_path ** ppcpath) +gx_effective_clip_path(gs_gstate * pgs, gx_clip_path ** ppcpath) { gs_id view_clip_id = (pgs->view_clip == 0 || pgs->view_clip->rule == 0 ? gs_no_id : @@ -464,7 +463,7 @@ #ifdef DEBUG /* Note that we just set the clipping path (internal). */ static void -note_set_clip_path(const gs_state * pgs) +note_set_clip_path(const gs_gstate * pgs) { if (gs_debug_c('P')) { dmlprintf(pgs->memory, "[P]Clipping path:\n"); @@ -476,7 +475,7 @@ #endif int -gs_clippath(gs_state * pgs) +gs_clippath(gs_gstate * pgs) { gx_path cpath; int code; @@ -495,7 +494,7 @@ } int -gs_initclip(gs_state * pgs) +gs_initclip(gs_gstate * pgs) { gs_fixed_rect box; int code = gx_default_clip_box(pgs, &box); @@ -506,19 +505,19 @@ } int -gs_clip(gs_state * pgs) +gs_clip(gs_gstate * pgs) { return common_clip(pgs, gx_rule_winding_number); } int -gs_eoclip(gs_state * pgs) +gs_eoclip(gs_gstate * pgs) { return common_clip(pgs, gx_rule_even_odd); } static int -common_clip(gs_state * pgs, int rule) +common_clip(gs_gstate * pgs, int rule) { int code = gx_cpath_clip(pgs, pgs->clip_path, pgs->path, rule); if (code < 0) @@ -531,13 +530,18 @@ /* Establish a rectangle as the clipping path. */ /* Used by initclip and by the character and Pattern cache logic. */ int -gx_clip_to_rectangle(gs_state * pgs, gs_fixed_rect * pbox) +gx_clip_to_rectangle(gs_gstate * pgs, gs_fixed_rect * pbox) { int code = gx_cpath_from_rectangle(pgs->clip_path, pbox); if (code < 0) return code; pgs->clip_path->rule = gx_rule_winding_number; + /* We are explicitly setting the clip to a specific rectangle, the path list + * must therefore be reset (it bears no relation to the actual clip now). + */ + rc_decrement(pgs->clip_path->path_list, "gx_clip_to_rectangle"); + pgs->clip_path->path_list = 0; note_set_clip_path(pgs); return 0; } @@ -545,7 +549,7 @@ /* Set the clipping path to the current path, without intersecting. */ /* This is very inefficient right now. */ int -gx_clip_to_path(gs_state * pgs) +gx_clip_to_path(gs_gstate * pgs) { gs_fixed_rect bbox; int code; @@ -561,7 +565,7 @@ /* Get the default clipping box. */ int -gx_default_clip_box(const gs_state * pgs, gs_fixed_rect * pbox) +gx_default_clip_box(const gs_gstate * pgs, gs_fixed_rect * pbox) { register gx_device *dev = gs_currentdevice(pgs); gs_rect bbox; @@ -581,10 +585,8 @@ /* we don't think we can do any better.) */ (*dev_proc(dev, get_initial_matrix)) (dev, &imat); /* Adjust for the Margins. */ - imat.tx += dev->Margins[0] * dev->HWResolution[0] / - dev->MarginsHWResolution[0]; - imat.ty += dev->Margins[1] * dev->HWResolution[1] / - dev->MarginsHWResolution[1]; + imat.tx += dev->Margins[0]; + imat.ty += dev->Margins[1]; bbox.p.x = dev->HWMargins[0]; bbox.p.y = dev->HWMargins[1]; bbox.q.x = dev->MediaSize[0] - dev->HWMargins[2]; diff -Nru ghostscript-9.10~dfsg/base/gspath.h ghostscript-9.25~dfsg+1/base/gspath.h --- ghostscript-9.10~dfsg/base/gspath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -35,27 +35,27 @@ float2fixed(xy)) /* Path constructors */ -int gs_newpath(gs_state *), - gs_moveto(gs_state *, floatp, floatp), - gs_rmoveto(gs_state *, floatp, floatp), - gs_lineto(gs_state *, floatp, floatp), - gs_rlineto(gs_state *, floatp, floatp), - gs_arc(gs_state *, floatp, floatp, floatp, floatp, floatp), - gs_arcn(gs_state *, floatp, floatp, floatp, floatp, floatp), +int gs_newpath(gs_gstate *), + gs_moveto(gs_gstate *, double, double), + gs_rmoveto(gs_gstate *, double, double), + gs_lineto(gs_gstate *, double, double), + gs_rlineto(gs_gstate *, double, double), + gs_arc(gs_gstate *, double, double, double, double, double), + gs_arcn(gs_gstate *, double, double, double, double, double), /* * Because of an obscure bug in the IBM RS/6000 compiler, one (but not - * both) bool argument(s) for gs_arc_add must come before the floatp + * both) bool argument(s) for gs_arc_add must come before the double * arguments. */ - gs_arc_add(gs_state *, bool, floatp, floatp, floatp, floatp, floatp, bool), - gs_arcto(gs_state *, floatp, floatp, floatp, floatp, floatp, float[4]), - gs_curveto(gs_state *, floatp, floatp, floatp, floatp, floatp, floatp), - gs_rcurveto(gs_state *, floatp, floatp, floatp, floatp, floatp, floatp), - gs_closepath(gs_state *); - -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; + gs_arc_add(gs_gstate *, bool, double, double, double, double, double, bool), + gs_arcto(gs_gstate *, double, double, double, double, double, float[4]), + gs_curveto(gs_gstate *, double, double, double, double, double, double), + gs_rcurveto(gs_gstate *, double, double, double, double, double, double), + gs_closepath(gs_gstate *); + +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_path_DEFINED # define gx_path_DEFINED @@ -66,21 +66,21 @@ typedef struct gs_matrix_fixed_s gs_matrix_fixed; #endif -/* Imager-level procedures */ +/* gs_gstate-level procedures */ void make_quadrant_arc(gs_point *p, const gs_point *c, const gs_point *p0, const gs_point *p1, double r); /* Add the current path to the path in the previous graphics state. */ -int gs_upmergepath(gs_state *); +int gs_upmergepath(gs_gstate *); /* Path accessors and transformers */ -int gs_currentpoint(gs_state *, gs_point *), - gs_upathbbox(gs_state *, gs_rect *, bool), - gs_dashpath(gs_state *), - gs_flattenpath(gs_state *), - gs_reversepath(gs_state *), - gs_strokepath(gs_state *), - gs_strokepath2(gs_state *); +int gs_currentpoint(gs_gstate *, gs_point *), + gs_upathbbox(gs_gstate *, gs_rect *, bool), + gs_dashpath(gs_gstate *), + gs_flattenpath(gs_gstate *), + gs_reversepath(gs_gstate *), + gs_strokepath(gs_gstate *), + gs_strokepath2(gs_gstate *); /* The extra argument for gs_upathbbox controls whether to include */ /* a trailing moveto in the bounding box. */ @@ -91,7 +91,7 @@ /* This interface conditionally makes a copy of the path. */ gs_path_enum *gs_path_enum_alloc(gs_memory_t *, client_name_t); -int gs_path_enum_copy_init(gs_memory_t *mem, gs_path_enum *, const gs_state *, bool); +int gs_path_enum_copy_init(gs_memory_t *mem, gs_path_enum *, const gs_gstate *, bool); #define gs_path_enum_init(mem, penum, pgs)\ gs_path_enum_copy_init(mem, penum, pgs, true) @@ -99,9 +99,9 @@ void gs_path_enum_cleanup(gs_path_enum *); /* Clipping */ -int gs_clippath(gs_state *), - gs_initclip(gs_state *), - gs_clip(gs_state *), - gs_eoclip(gs_state *); +int gs_clippath(gs_gstate *), + gs_initclip(gs_gstate *), + gs_clip(gs_gstate *), + gs_eoclip(gs_gstate *); #endif /* gspath_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gspcolor.c ghostscript-9.25~dfsg+1/base/gspcolor.c --- ghostscript-9.10~dfsg/base/gspcolor.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspcolor.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -38,6 +38,7 @@ #include "gsimage.h" #include "gsiparm4.h" #include "stream.h" +#include "gsovrc.h" /* GC descriptors */ public_st_pattern_template(); @@ -65,7 +66,7 @@ gx_set_overprint_Pattern, gx_final_Pattern, gx_adjust_color_Pattern, gx_serialize_Pattern, - gx_cspace_no_linear + gx_cspace_no_linear, gx_polarity_unknown }; /* Initialize a generic pattern template. */ @@ -82,7 +83,7 @@ /* Generic makepattern */ int gs_make_pattern(gs_client_color * pcc, const gs_pattern_template_t * pcp, - const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem) + const gs_matrix * pmat, gs_gstate * pgs, gs_memory_t * mem) { return pcp->type->procs.make_pattern(pcc, pcp, pmat, pgs, mem); } @@ -94,30 +95,31 @@ int gs_make_pattern_common(gs_client_color *pcc, const gs_pattern_template_t *ptemp, - const gs_matrix *pmat, gs_state *pgs, gs_memory_t *mem, + const gs_matrix *pmat, gs_gstate *pgs, gs_memory_t *mem, gs_memory_type_ptr_t pstype) { gs_pattern_instance_t *pinst; - gs_state *saved; + gs_gstate *saved; + int code = 0; if (mem == 0) - mem = gs_state_memory(pgs); + mem = gs_gstate_memory(pgs); rc_alloc_struct_1(pinst, gs_pattern_instance_t, pstype, mem, return_error(gs_error_VMerror), "gs_make_pattern_common"); pinst->rc.free = rc_free_pattern_instance; pinst->type = ptemp->type; - saved = gs_state_copy(pgs, mem); + saved = gs_gstate_copy(pgs, mem); if (saved == 0) { gs_free_object(mem, pinst, "gs_make_pattern_common"); return_error(gs_error_VMerror); } gs_concat(saved, pmat); - gs_newpath(saved); + code = gs_newpath(saved); pinst->saved = saved; pcc->pattern = pinst; pcc->pattern->pattern_id = gs_next_ids(mem, 1); - return 0; + return code; } /* Free the saved gstate when freeing a Pattern instance. */ @@ -127,13 +129,13 @@ { gs_pattern_instance_t *pinst = pinst_void; - gs_state_free(pinst->saved); + gs_gstate_free(pinst->saved); rc_free_struct_only(mem, pinst_void, cname); } /* setpattern */ int -gs_setpattern(gs_state * pgs, const gs_client_color * pcc) +gs_setpattern(gs_gstate * pgs, const gs_client_color * pcc) { int code = gs_setpatternspace(pgs); @@ -145,7 +147,7 @@ /* setpatternspace */ /* This does all the work of setpattern except for the final setcolor. */ int -gs_setpatternspace(gs_state * pgs) +gs_setpatternspace(gs_gstate * pgs) { int code = 0; gs_color_space *ccs_old; @@ -210,7 +212,7 @@ /* Remap a Pattern color. */ static int gx_remap_Pattern(const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { if (pc->pattern == 0) { @@ -220,7 +222,7 @@ return 0; } return - pc->pattern->type->procs.remap_color(pc, pcs, pdc, pis, dev, select); + pc->pattern->type->procs.remap_color(pc, pcs, pdc, pgs, dev, select); } /* Initialize a Pattern color. */ @@ -256,7 +258,7 @@ /* Install a Pattern color space. */ static int -gx_install_Pattern(gs_color_space * pcs, gs_state * pgs) +gx_install_Pattern(gs_color_space * pcs, gs_gstate * pgs) { if (!pcs->params.pattern.has_base_space) return 0; @@ -266,10 +268,22 @@ /* * Set the overprint compositor for a Pattern color space. This does nothing; * for patterns the overprint compositor is set at set_device_color time. + * However, it is possible that this pattern color has nothing to do with what + * is about to happen (e.g. an image enumeration and fill). Hence, we should + * at least disable the overprint compositor if overprint is off. If overprint + * is not off, it is not clear how we should proceed, as the color space is + * a factor in that set up and here the color space is a pattern. */ static int -gx_set_overprint_Pattern(const gs_color_space * pcs, gs_state * pgs) +gx_set_overprint_Pattern(const gs_color_space * pcs, gs_gstate * pgs) { + gs_overprint_params_t params; + + if (!pgs->overprint) { + params.retain_any_comps = false; + pgs->effective_overprint_mode = 0; + return gs_gstate_update_overprint(pgs, ¶ms); + } return 0; } diff -Nru ghostscript-9.10~dfsg/base/gspcolor.h ghostscript-9.25~dfsg+1/base/gspcolor.h --- ghostscript-9.10~dfsg/base/gspcolor.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspcolor.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -83,7 +83,7 @@ rc_header rc;\ /* Following are set by makepattern */\ const gs_pattern_type_t *type; /* from template */\ - gs_state *saved;\ + gs_gstate *saved;\ gs_id pattern_id struct gs_pattern_instance_s { gs_pattern_instance_common; @@ -100,17 +100,17 @@ /* ---------------- Procedures ---------------- */ /* Set a Pattern color or a Pattern color space. */ -int gs_setpattern(gs_state *, const gs_client_color *); -int gs_setpatternspace(gs_state *); +int gs_setpattern(gs_gstate *, const gs_client_color *); +int gs_setpatternspace(gs_gstate *); /* * Construct a Pattern color of any PatternType. * The gs_memory_t argument for gs_make_pattern may be NULL, meaning use the - * same allocator as for the gs_state argument. Note that gs_make_pattern + * same allocator as for the gs_gstate argument. Note that gs_make_pattern * uses rc_alloc_struct_1 to allocate pattern instances. */ int gs_make_pattern(gs_client_color *, const gs_pattern_template_t *, - const gs_matrix *, gs_state *, gs_memory_t *); + const gs_matrix *, gs_gstate *, gs_memory_t *); const gs_pattern_template_t *gs_get_pattern(const gs_client_color *); /* diff -Nru ghostscript-9.10~dfsg/base/gspenum.h ghostscript-9.25~dfsg+1/base/gspenum.h --- ghostscript-9.10~dfsg/base/gspenum.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspenum.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gspmdrv.c ghostscript-9.25~dfsg+1/base/gspmdrv.c --- ghostscript-9.10~dfsg/base/gspmdrv.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspmdrv.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -155,7 +155,7 @@ BOOL flag; ULONG count; - unused = unused; /* to shut up warning */ + (void)unused; /* to shut up warning */ while (!DosQueryEventSem(update_event_sem, &count)) { /* loop while semaphore exists */ DosWaitEventSem(update_event_sem, SEM_INDEFINITE_WAIT); @@ -172,7 +172,7 @@ DosCloseMutexSem(bmp_mutex_sem); DosFreeMem((PVOID) bitmap.pbmi); DosExitList(EXLST_EXIT, 0); - code = code; /* to shut up warning */ + (void)code; /* to shut up warning */ } void diff -Nru ghostscript-9.10~dfsg/base/gspmdrv.h ghostscript-9.25~dfsg+1/base/gspmdrv.h --- ghostscript-9.10~dfsg/base/gspmdrv.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspmdrv.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gspmdrv.rc ghostscript-9.25~dfsg+1/base/gspmdrv.rc --- ghostscript-9.10~dfsg/base/gspmdrv.rc 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gspmdrv.rc 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Resources for gspmdrv.exe, the PM display driver for Ghostscript */ @@ -27,7 +27,7 @@ ICON ID_GSPMDRV, ID_GSPMDRV, 8, 56, 20, 16, WS_GROUP LTEXT "Ghostscript Presentation Manager Driver", -1, 34, 64, 210, 8 LTEXT GSPMDRV_VERSION, -1, 34, 56, 210, 8 - LTEXT "Copyright (C) 1992, 1993, 2001-2012 Artifex Software Inc.", -1, 34, 48, 210, 8 + LTEXT "Copyright (C) 1992, 1993, 2001-2018 Artifex Software Inc.", -1, 34, 48, 210, 8 LTEXT "All rights reserved", -1, 34, 40, 210, 8 PUSHBUTTON "OK", DID_OK, 105, 8, 40, 14 END diff -Nru ghostscript-9.10~dfsg/base/gsptype1.c ghostscript-9.25~dfsg+1/base/gsptype1.c --- ghostscript-9.10~dfsg/base/gsptype1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsptype1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -119,10 +119,10 @@ /* Make an instance of a PatternType 1 pattern. */ static int compute_inst_matrix(gs_pattern1_instance_t * pinst, - gs_state * saved, gs_rect * pbbox, int width, int height); + gs_gstate * saved, gs_rect * pbbox, int width, int height); int gs_makepattern(gs_client_color * pcc, const gs_pattern1_template_t * pcp, - const gs_matrix * pmat, gs_state * pgs, gs_memory_t * mem) + const gs_matrix * pmat, gs_gstate * pgs, gs_memory_t * mem) { return gs_pattern1_make_pattern(pcc, (const gs_pattern_template_t *)pcp, pmat, pgs, mem); @@ -130,13 +130,13 @@ static int gs_pattern1_make_pattern(gs_client_color * pcc, const gs_pattern_template_t * ptemp, - const gs_matrix * pmat, gs_state * pgs, + const gs_matrix * pmat, gs_gstate * pgs, gs_memory_t * mem) { const gs_pattern1_template_t *pcp = (const gs_pattern1_template_t *)ptemp; gs_pattern1_instance_t inst; gs_pattern1_instance_t *pinst; - gs_state *saved; + gs_gstate *saved; gs_rect bbox; gs_fixed_rect cbox; gx_device * pdev = pgs->device; @@ -149,8 +149,22 @@ if (code < 0) return code; if (mem == 0) - mem = gs_state_memory(pgs); + mem = gs_gstate_memory(pgs); pinst = (gs_pattern1_instance_t *)pcc->pattern; +#ifdef PACIFY_VALGRIND + /* The following memset is required to avoid a valgrind warning + * in: + * gs -I./gs/lib -sOutputFile=out.pgm -dMaxBitmap=10000 + * -sDEVICE=pgmraw -r300 -Z: -sDEFAULTPAPERSIZE=letter + * -dNOPAUSE -dBATCH -K2000000 -dClusterJob -dJOBSERVER + * tests_private/ps/ps3cet/11-14.PS + * Setting the individual elements of the structure directly is + * not enough, which leads me to believe that we are writing the + * entire struct out, padding and all. + */ + memset(((char *)&inst) + sizeof(gs_pattern_instance_t), 0, + sizeof(inst) - sizeof(gs_pattern_instance_t)); +#endif *(gs_pattern_instance_t *)&inst = *(gs_pattern_instance_t *)pinst; saved = inst.saved; switch (pcp->PaintType) { @@ -377,7 +391,7 @@ inst.id = gs_next_ids(mem, 1); *pinst = inst; return 0; - fsaved:gs_state_free(saved); + fsaved:gs_gstate_free(saved); gs_free_object(mem, pinst, "gs_makepattern"); return code; } @@ -407,6 +421,9 @@ gs_point dev_pat_origin, dev_step; int code; + double xepsilon = FLT_EPSILON * width; + double yepsilon = FLT_EPSILON * height; + /* * Scan across the page. We determine the region to be scanned * by working in the pattern coordinate space. This is logically @@ -460,7 +477,21 @@ xupper = (xdev + pbbox->q.x < width) ? pbbox->q.x : -xdev + width; ylower = (ydev + pbbox->p.y > 0) ? pbbox->p.y : -ydev; yupper = (ydev + pbbox->q.y < height) ? pbbox->q.y : -ydev + height; - if (xlower < xupper && ylower < yupper) { + + /* The use of floating point in these calculations causes us + * problems. Values which go through the calculation without ever + * being 'large' retain more accuracy in the lower bits than ones + * which momentarily become large. This is seen in bug 694528 + * where a y value of 0.00017... becomes either 0 when 8000 is + * first added to it, then subtracted. This can lead to yupper + * and ylower being different. + * + * The "fix" implemented here is to amend the following test to + * ensure that the region found is larger that 'epsilon'. The + * epsilon values are calculated to reflect the floating point + * innacuracies at the appropriate range. + */ + if (xlower + xepsilon < xupper && ylower + yepsilon < yupper) { /* * The pattern intersects the page. Expand required area if * needed. @@ -497,7 +528,7 @@ /* Compute the stepping matrix and device space instance bounding box */ /* from the step values and the saved matrix. */ static int -compute_inst_matrix(gs_pattern1_instance_t * pinst, gs_state * saved, +compute_inst_matrix(gs_pattern1_instance_t * pinst, gs_gstate * saved, gs_rect * pbbox, int width, int height) { float xx, xy, yx, yy, dx, dy, temp; @@ -581,14 +612,18 @@ void * gx_pattern1_get_transptr(const gx_device_color *pdevc) { - return pdevc->colors.pattern.p_tile->ttrans; + if (pdevc->colors.pattern.p_tile != NULL) + return pdevc->colors.pattern.p_tile->ttrans; + else + return NULL; } /* Check for if the clist in the pattern has transparency */ int gx_pattern1_clist_has_trans(const gx_device_color *pdevc) { - if (pdevc->colors.pattern.p_tile->cdev != NULL) { + if (pdevc->colors.pattern.p_tile != NULL && + pdevc->colors.pattern.p_tile->cdev != NULL) { return pdevc->colors.pattern.p_tile->cdev->common.page_uses_transparency; } else { return 0; @@ -655,7 +690,7 @@ * reset the overprint information as required. */ static int -gs_pattern1_set_color(const gs_client_color * pcc, gs_state * pgs) +gs_pattern1_set_color(const gs_client_color * pcc, gs_gstate * pgs) { gs_pattern1_instance_t * pinst = (gs_pattern1_instance_t *)pcc->pattern; gs_pattern1_template_t * ptmplt = &pinst->templat; @@ -670,7 +705,7 @@ params.retain_any_comps = false; pgs->effective_overprint_mode = 0; - return gs_state_update_overprint(pgs, ¶ms); + return gs_gstate_update_overprint(pgs, ¶ms); } } @@ -752,14 +787,14 @@ * PaintProcs for bitmap and pixmap patterns. */ static int bitmap_paint(gs_image_enum * pen, gs_data_image_t * pim, - const gs_depth_bitmap * pbitmap, gs_state * pgs); + const gs_depth_bitmap * pbitmap, gs_gstate * pgs); static int -mask_PaintProc(const gs_client_color * pcolor, gs_state * pgs) +mask_PaintProc(const gs_client_color * pcolor, gs_gstate * pgs) { const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data; const gs_depth_bitmap *pbitmap = &(ppmap->bitmap); gs_image_enum *pen = - gs_image_enum_alloc(gs_state_memory(pgs), "mask_PaintProc"); + gs_image_enum_alloc(gs_gstate_memory(pgs), "mask_PaintProc"); gs_image1_t mask; if (pen == 0) @@ -767,16 +802,16 @@ gs_image_t_init_mask(&mask, true); mask.Width = pbitmap->size.x; mask.Height = pbitmap->size.y; - gs_image_init(pen, &mask, false, pgs); + gs_image_init(pen, &mask, false, false, pgs); return bitmap_paint(pen, (gs_data_image_t *) & mask, pbitmap, pgs); } static int -image_PaintProc(const gs_client_color * pcolor, gs_state * pgs) +image_PaintProc(const gs_client_color * pcolor, gs_gstate * pgs) { const pixmap_info *ppmap = gs_getpattern(pcolor)->client_data; const gs_depth_bitmap *pbitmap = &(ppmap->bitmap); gs_image_enum *pen = - gs_image_enum_alloc(gs_state_memory(pgs), "image_PaintProc"); + gs_image_enum_alloc(gs_gstate_memory(pgs), "image_PaintProc"); gs_color_space *pcspace; gx_image_enum_common_t *pie; /* @@ -803,11 +838,13 @@ if (ppmap->pcspace == 0) { pcspace = gs_cspace_new_DeviceGray(pgs->memory); + if (pcspace == NULL) + return_error(gs_error_VMerror); } else pcspace = ppmap->pcspace; code = gs_gsave(pgs); if (code < 0) - return code; + goto fail; code = gs_setcolorspace(pgs, pcspace); if (code < 0) return code; @@ -833,19 +870,24 @@ if ( (code = gs_image_begin_typed( (const gs_image_common_t *)&image, pgs, false, + false, &pie )) >= 0 && (code = gs_image_enum_init( pen, pie, (gs_data_image_t *)&image, - pgs )) >= 0 ) - code = bitmap_paint(pen, (gs_data_image_t *) & image, pbitmap, pgs); - gs_grestore(pgs); + pgs )) >= 0 && + (code = bitmap_paint(pen, (gs_data_image_t *) & image, pbitmap, pgs)) >= 0) { + return gs_grestore(pgs); + } + +fail: + gs_free_object(gs_gstate_memory(pgs), pen, "image_PaintProc"); return code; } /* Finish painting any kind of bitmap pattern. */ static int bitmap_paint(gs_image_enum * pen, gs_data_image_t * pim, - const gs_depth_bitmap * pbitmap, gs_state * pgs) + const gs_depth_bitmap * pbitmap, gs_gstate * pgs) { uint raster = pbitmap->raster; uint nbytes = (pim->Width * pbitmap->pix_depth + 7) >> 3; @@ -865,7 +907,7 @@ return code; } -int pixmap_high_level_pattern(gs_state * pgs) +int pixmap_high_level_pattern(gs_gstate * pgs) { gs_matrix m; gs_rect bbox; @@ -878,8 +920,7 @@ (gs_pattern1_instance_t *)gs_currentcolor(pgs)->pattern; const pixmap_info *ppmap = ppat->client_data; - code = gx_pattern_cache_add_dummy_entry((gs_imager_state *)pgs, - pinst, pgs->device->color_info.depth); + code = gx_pattern_cache_add_dummy_entry(pgs, pinst, pgs->device->color_info.depth); if (code < 0) return code; @@ -903,8 +944,17 @@ gs_grestore(pgs); return code; } - code = dev_proc(pgs->device, dev_spec_op)(pgs->device, - gxdso_pattern_start_accum, pinst, pinst->id); + + { + pattern_accum_param_s param; + param.pinst = (void *)pinst; + param.graphics_state = (void *)pgs; + param.pinst_id = pinst->id; + + code = dev_proc(pgs->device, dev_spec_op)(pgs->device, + gxdso_pattern_start_accum, ¶m, sizeof(pattern_accum_param_s)); + } + if (code < 0) { gs_grestore(pgs); return code; @@ -914,6 +964,8 @@ code = image_PaintProc(&pdc->ccolor, pgs); else { pcs = gs_cspace_new_DeviceGray(pgs->memory); + if (pcs == NULL) + return_error(gs_error_VMerror); gs_setcolorspace(pgs, pcs); code = mask_PaintProc(&pdc->ccolor, pgs); } @@ -924,13 +976,20 @@ if (code < 0) return code; - code = dev_proc(pgs->device, dev_spec_op)(pgs->device, - gxdso_pattern_finish_accum, NULL, gx_no_bitmap_id); + { + pattern_accum_param_s param; + param.pinst = (void *)pinst; + param.graphics_state = (void *)pgs; + param.pinst_id = pinst->id; + + code = dev_proc(pgs->device, dev_spec_op)(pgs->device, + gxdso_pattern_finish_accum, ¶m, sizeof(pattern_accum_param_s)); + } return code; } -static int pixmap_remap_mask_pattern(const gs_client_color *pcc, gs_state *pgs) +static int pixmap_remap_mask_pattern(const gs_client_color *pcc, gs_gstate *pgs) { const gs_client_pattern *ppat = gs_getpattern(pcc); int code = 0; @@ -958,7 +1017,7 @@ } } -static int pixmap_remap_image_pattern(const gs_client_color *pcc, gs_state *pgs) +static int pixmap_remap_image_pattern(const gs_client_color *pcc, gs_gstate *pgs) { const gs_client_pattern *ppat = gs_getpattern(pcc); int code = 0; @@ -981,8 +1040,7 @@ */ return_error(gs_error_Remap_Color); } else { - image_PaintProc(pcc, pgs); - return 0; + return image_PaintProc(pcc, pgs); } } @@ -1003,7 +1061,7 @@ long id, gs_color_space * pcspace, uint white_index, - gs_state * pgs, + gs_gstate * pgs, gs_memory_t * mem ) { @@ -1025,7 +1083,7 @@ /* allocate and initialize a pixmap_info structure for the paint proc */ if (mem == 0) - mem = gs_state_memory(pgs); + mem = gs_gstate_memory(pgs); ppmap = gs_alloc_struct(mem, pixmap_info, &st_pixmap_info, @@ -1084,7 +1142,7 @@ * color, clear these so that there isn't an extra retained * reference to the Pattern object. */ - gs_setgray(pinst->saved, 0.0); + code = gs_setgray(pinst->saved, 0.0); } gs_setmatrix(pgs, &smat); @@ -1101,7 +1159,7 @@ bool mask, const gs_matrix * pmat, long id, - gs_state * pgs, + gs_gstate * pgs, gs_memory_t * mem ) { @@ -1291,10 +1349,12 @@ RELOC_PTRS_END static ENUM_PTRS_WITH(dc_devn_masked_enum_ptrs, gx_device_color *cptr) ENUM_SUPER(gx_device_color, st_client_color, ccolor, 0); +(void)cptr; /* Avoid unused warning */ ENUM_PTRS_END static RELOC_PTRS_WITH(dc_devn_masked_reloc_ptrs, gx_device_color *cptr) { RELOC_SUPER(gx_device_color, st_client_color, ccolor); + (void)cptr; /* Avoid unused warning */ } RELOC_PTRS_END static ENUM_PTRS_BEGIN(dc_binary_masked_enum_ptrs) @@ -1374,15 +1434,15 @@ /* Macros for pattern loading */ #define FINISH_PATTERN_LOAD\ - while ( !gx_pattern_cache_lookup(pdevc, pis, dev, select) )\ - { code = gx_pattern_load(pdevc, pis, dev, select);\ + while ( !gx_pattern_cache_lookup(pdevc, pgs, dev, select) )\ + { code = gx_pattern_load(pdevc, pgs, dev, select);\ if ( code < 0 ) break;\ }\ return code; /* Ensure that a colored Pattern is loaded in the cache. */ static int -gx_dc_pattern_load(gx_device_color * pdevc, const gs_imager_state * pis, +gx_dc_pattern_load(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { int code = 0; @@ -1391,40 +1451,40 @@ } /* Ensure that an uncolored Pattern is loaded in the cache. */ static int -gx_dc_pure_masked_load(gx_device_color * pdevc, const gs_imager_state * pis, +gx_dc_pure_masked_load(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int code = (*gx_dc_type_data_pure.load) (pdevc, pis, dev, select); + int code = (*gx_dc_type_data_pure.load) (pdevc, pgs, dev, select); if (code < 0) return code; FINISH_PATTERN_LOAD } static int -gx_dc_devn_masked_load(gx_device_color * pdevc, const gs_imager_state * pis, +gx_dc_devn_masked_load(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int code = (*gx_dc_type_data_devn.load) (pdevc, pis, dev, select); + int code = (*gx_dc_type_data_devn.load) (pdevc, pgs, dev, select); if (code < 0) return code; FINISH_PATTERN_LOAD } static int -gx_dc_binary_masked_load(gx_device_color * pdevc, const gs_imager_state * pis, +gx_dc_binary_masked_load(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int code = (*gx_dc_type_data_ht_binary.load) (pdevc, pis, dev, select); + int code = (*gx_dc_type_data_ht_binary.load) (pdevc, pgs, dev, select); if (code < 0) return code; FINISH_PATTERN_LOAD } static int -gx_dc_colored_masked_load(gx_device_color * pdevc, const gs_imager_state * pis, +gx_dc_colored_masked_load(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int code = (*gx_dc_type_data_ht_colored.load) (pdevc, pis, dev, select); + int code = (*gx_dc_type_data_ht_colored.load) (pdevc, pgs, dev, select); if (code < 0) return code; @@ -1433,10 +1493,10 @@ /* Look up a pattern color in the cache. */ bool -gx_pattern_cache_lookup(gx_device_color * pdevc, const gs_imager_state * pis, +gx_pattern_cache_lookup(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - gx_pattern_cache *pcache = pis->pattern_cache; + gx_pattern_cache *pcache = pgs->pattern_cache; gx_bitmap_id id = pdevc->mask.id; if (id == gx_no_bitmap_id) { @@ -1446,7 +1506,7 @@ if (pcache != 0) { gx_color_tile *ctile = &pcache->tiles[id % pcache->num_tiles]; bool internal_accum = true; - if (pis->have_pattern_streams) { + if (pgs->have_pattern_streams) { int code = dev_proc(dev, dev_spec_op)(dev, gxdso_pattern_load, NULL, id); internal_accum = (code == 0); if (code < 0) @@ -1455,8 +1515,8 @@ if (ctile->id == id && ctile->is_dummy == !internal_accum ) { - int px = pis->screen_phase[select].x; - int py = pis->screen_phase[select].y; + int px = pgs->screen_phase[select].x; + int py = pgs->screen_phase[select].y; if (gx_dc_is_pattern1_color(pdevc)) { /* colored */ pdevc->colors.pattern.p_tile = ctile; @@ -1544,9 +1604,9 @@ int rowstride; int planestride; int n_chan; /* number of pixel planes including alpha */ + bool has_tags; /* extra plane for tags */ int width; int height; - gs_blend_mode_t blend_mode; } tile_trans_clist_info_t; typedef struct gx_dc_serialized_tile_s { @@ -1556,6 +1616,7 @@ gs_matrix step_matrix; gs_rect bbox; int flags; + gs_blend_mode_t blending_mode; /* in case tile has transparency */ } gx_dc_serialized_tile_t; enum { @@ -1569,7 +1630,7 @@ }; static int -gx_dc_pattern_write_raster(gx_color_tile *ptile, int64_t offset, byte *data, +gx_dc_pattern_write_raster(gx_color_tile *ptile, int64_t offset, byte *data, uint *psize, const gx_device *dev) { int size_b, size_c; @@ -1577,7 +1638,7 @@ int left = *psize; int64_t offset1 = offset; - size_b = sizeof(gx_strip_bitmap) + + size_b = sizeof(gx_strip_bitmap) + ptile->tbits.size.y * ptile->tbits.raster * ptile->tbits.num_planes; size_c = ptile->tmask.data ? sizeof(gx_strip_bitmap) + ptile->tmask.size.y * ptile->tmask.raster : 0; if (data == NULL) { @@ -1674,6 +1735,8 @@ /* Everything that we need to handle the transparent tile */ size = size_h + ptile->ttrans->n_chan * ptile->ttrans->planestride; + if (ptile->ttrans->has_tags) + size += ptile->ttrans->planestride; /* data is sent with NULL if the clist writer just wanted the size */ if (data == NULL) { @@ -1696,6 +1759,7 @@ | (ptile->has_overlap ? TILE_HAS_OVERLAP : 0); buf.step_matrix = ptile->step_matrix; buf.bbox = ptile->bbox; + buf.blending_mode = ptile->blending_mode; if (sizeof(buf) > left) { /* For a while we require the client to provide enough buffer size. */ return_error(gs_error_unregistered); /* Must not happen. */ @@ -1706,9 +1770,9 @@ offset1 += sizeof(buf); /* Do the transparency information now */ - trans_info.blend_mode = ptile->ttrans->blending_mode; trans_info.height = ptile->ttrans->height; trans_info.n_chan = ptile->ttrans->n_chan; + trans_info.has_tags = ptile->ttrans->has_tags; trans_info.planestride = ptile->ttrans->planestride; trans_info.rect.p.x = ptile->ttrans->rect.p.x; trans_info.rect.p.y = ptile->ttrans->rect.p.y; @@ -1726,11 +1790,11 @@ offset1 += sizeof(trans_info); } - /* Now do the transparency tile data itself. Note that it may - be split up in the writing stage if it is large */ + /* Now do the transparency tile data itself. Note that it may be split up + * in the writing stage if it is large. The size include n_chan + the tag + * plane if this buffer has_tags. */ /* check if we have written it all */ - if (offset1 <= size) { /* Get the most that we can write */ int u = min(size, left); @@ -1738,9 +1802,6 @@ /* copy that amount */ ptr = ptile->ttrans->transbytes; memcpy(dp, ptr + (offset1 - size_h), u); - left -= u; - dp += u; - offset1 += u; } return 0; } @@ -1774,7 +1835,9 @@ /* A special case for writing a known pattern : Just write the tile id. */ gs_id id = ptile->id; /* Ensure sizeof(gs_id). */ - + if_debug2m('v', dev->memory, + "[v*] Writing trans tile ID into clist, uid = %ld id = %ld \n", + ptile->uid.id, ptile->id); memcpy(dp, &ptile->id, sizeof(id)); *psize = sizeof(gs_id); return 0; @@ -1783,9 +1846,12 @@ /* Check if pattern has transparency object If so then that is what we will stuff in the clist */ - - if (ptile->ttrans != NULL) - return gx_dc_pattern_trans_write_raster(ptile, offset, data, psize); + if (ptile->ttrans != NULL) { + if_debug2m('v', dev->memory, + "[v*] Writing trans tile into clist, uid = %ld id = %ld \n", + ptile->uid.id, ptile->id); + return gx_dc_pattern_trans_write_raster(ptile, offset, data, psize); + } if (ptile->cdev == NULL) return gx_dc_pattern_write_raster(ptile, offset, data, psize, dev); @@ -1816,6 +1882,7 @@ | (ptile->is_simple ? TILE_IS_SIMPLE : 0) | (ptile->has_overlap ? TILE_HAS_OVERLAP : 0) | (ptile->cdev->common.page_uses_transparency ? TILE_USES_TRANSP : 0); + buf.blending_mode = ptile->blending_mode; /* in case tile has transparency */ if (sizeof(buf) > left) { /* For a while we require the client to provide enough buffer size. */ return_error(gs_error_unregistered); /* Must not happen. */ @@ -1912,8 +1979,6 @@ memcpy(ptile->tmask.data + (offset1 - sizeof(gx_dc_serialized_tile_t) - size_b - sizeof(gx_strip_bitmap)), dp, l); left -= l; - offset1 += l; - dp += l; } return size - left; } @@ -1930,6 +1995,9 @@ int data_size; data_size = trans_pat->planestride * trans_pat->n_chan; + if (trans_pat->has_tags) + data_size += trans_pat->planestride; + /* Allocate the bytes */ if (trans_pat->transbytes == NULL){ trans_pat->transbytes = gs_alloc_bytes(mem, data_size, "gx_dc_pattern_read_raster"); @@ -1947,8 +2015,6 @@ sizeof(tile_trans_clist_info_t), dp, u); trans_pat->transbytes = save; left -= u; - offset1 += u; - dp += u; } return size - left; } @@ -1956,7 +2022,7 @@ int gx_dc_pattern_read( gx_device_color * pdevc, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_device_color * prior_devc, const gx_device * dev, int64_t offset, @@ -1971,7 +2037,7 @@ int64_t offset1 = offset; gx_color_tile *ptile; int code, l; - tile_trans_clist_info_t trans_info; + tile_trans_clist_info_t trans_info = { { { 0 } } }; int cache_space_needed; if (offset == 0) { @@ -2021,13 +2087,13 @@ /* the following works for raster or clist patterns */ cache_space_needed = buf.size_b + buf.size_c; } - gx_pattern_cache_ensure_space((gs_imager_state *)pis, cache_space_needed); + gx_pattern_cache_ensure_space((gs_gstate *)pgs, cache_space_needed); - code = gx_pattern_cache_get_entry((gs_imager_state *)pis, /* Break 'const'. */ + code = gx_pattern_cache_get_entry((gs_gstate *)pgs, /* Break 'const'. */ buf.id, &ptile); if (code < 0) return code; - gx_pattern_cache_update_used((gs_imager_state *)pis, cache_space_needed); + gx_pattern_cache_update_used((gs_gstate *)pgs, cache_space_needed); ptile->bits_used = cache_space_needed; pdevc->type = &gx_dc_pattern; pdevc->colors.pattern.p_tile = ptile; @@ -2039,6 +2105,7 @@ ptile->tiling_type = (buf.flags & TILE_TYPE_MASK)>>TILE_TYPE_SHIFT; ptile->is_simple = !!(buf.flags & TILE_IS_SIMPLE); ptile->has_overlap = !!(buf.flags & TILE_HAS_OVERLAP); + ptile->blending_mode = buf.blending_mode; ptile->is_dummy = 0; if (!(buf.flags & TILE_IS_CLIST)) { @@ -2050,9 +2117,9 @@ ptile->ttrans = new_pattern_trans_buff(mem); /* trans_info was loaded above */ - ptile->ttrans->blending_mode = trans_info.blend_mode; ptile->ttrans->height = trans_info.height; ptile->ttrans->n_chan = trans_info.n_chan; + ptile->ttrans->has_tags = trans_info.has_tags; ptile->ttrans->pdev14 = NULL; ptile->ttrans->planestride = trans_info.planestride; ptile->ttrans->rect.p.x = trans_info.rect.p.x; @@ -2062,6 +2129,9 @@ ptile->ttrans->rowstride = trans_info.rowstride; ptile->ttrans->width = trans_info.width; pdevc->type = &gx_dc_pattern_trans; + if_debug2m('v', pgs->memory, + "[v*] Reading trans tile from clist into cache, uid = %ld id = %ld \n", + ptile->uid.id, ptile->id); code = gx_dc_pattern_read_trans_buff(ptile, offset1, dp, left, mem); if (code < 0) @@ -2083,7 +2153,7 @@ ptile->tbits.size.x = size_b; /* HACK: Use unrelated field for saving size_b between calls. */ ptile->tbits.size.y = size_c; /* HACK: Use unrelated field for saving size_c between calls. */ { - gs_state state; + gs_gstate state; gs_pattern1_instance_t inst; memset(&state, 0, sizeof(state)); @@ -2099,8 +2169,6 @@ &inst, "gx_dc_pattern_read"); if (ptile->cdev == NULL) return_error(gs_error_VMerror); - ptile->cdev->common.band_params.page_uses_transparency = - !!(buf.flags & TILE_USES_TRANSP); ptile->cdev->common.page_uses_transparency = !!(buf.flags & TILE_USES_TRANSP); code = dev_proc(&ptile->cdev->writer, open_device)((gx_device *)&ptile->cdev->writer); if (code < 0) @@ -2116,7 +2184,6 @@ return gx_dc_pattern_read_raster(ptile, NULL, offset1, dp, left, mem); size_b = ptile->tbits.size.x; - size_c = ptile->tbits.size.y; } if (offset1 <= sizeof(buf) + size_b) { l = min(left, size_b - (offset1 - sizeof(buf))); @@ -2136,7 +2203,6 @@ return code; l = code; left -= l; - offset1 += l; } return size - left; } diff -Nru ghostscript-9.10~dfsg/base/gsptype1.h ghostscript-9.25~dfsg+1/base/gsptype1.h --- ghostscript-9.10~dfsg/base/gsptype1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsptype1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,7 +47,7 @@ gs_rect BBox; float XStep; float YStep; - int (*PaintProc) (const gs_client_color *, gs_state *); + int (*PaintProc) (const gs_client_color *, gs_gstate *); } gs_pattern1_template_t; #define private_st_pattern1_template() /* in gspcolor.c */\ @@ -83,11 +83,11 @@ * PatternType 1 patterns. * * The gs_memory_t argument for gs_makepattern may be NULL, meaning use the - * same allocator as for the gs_state argument. Note that gs_makepattern + * same allocator as for the gs_gstate argument. Note that gs_makepattern * uses rc_alloc_struct_1 to allocate pattern instances. */ int gs_makepattern(gs_client_color *, const gs_client_pattern *, - const gs_matrix *, gs_state *, gs_memory_t *); + const gs_matrix *, gs_gstate *, gs_memory_t *); const gs_client_pattern *gs_getpattern(const gs_client_color *); /* Check device color for Pattern Type 1. */ @@ -153,7 +153,7 @@ long id, gs_color_space * pcspace, uint white_index, - gs_state * pgs, + gs_gstate * pgs, gs_memory_t * mem ); @@ -167,14 +167,14 @@ bool mask, const gs_matrix * pmat, long id, - gs_state * pgs, + gs_gstate * pgs, gs_memory_t * mem ); /* * High level pattern support for pixmap patterns, if the interpreter supports them. */ -extern int pixmap_high_level_pattern(gs_state * pgs); +extern int pixmap_high_level_pattern(gs_gstate * pgs); #define gs_makebitmappattern(pcc, tile, mask, pgs, mem) \ gs_makebitmappattern_xform(pcc, tile, mask, 0, no_UniqueID, pgs, mem) diff -Nru ghostscript-9.10~dfsg/base/gsptype2.c ghostscript-9.25~dfsg+1/base/gsptype2.c --- ghostscript-9.10~dfsg/base/gsptype2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsptype2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,7 @@ #include "gxdcolor.h" #include "gsptype2.h" #include "gxpcolor.h" -#include "gxstate.h" /* for gs_state_memory */ +#include "gxstate.h" /* for gs_gstate_memory */ #include "gzpath.h" #include "gzcpath.h" #include "gzstate.h" @@ -86,7 +86,7 @@ static int gs_pattern2_make_pattern(gs_client_color * pcc, const gs_pattern_template_t * pcp, - const gs_matrix * pmat, gs_state * pgs, + const gs_matrix * pmat, gs_gstate * pgs, gs_memory_t * mem) { const gs_pattern2_template_t *ptemp = @@ -169,7 +169,7 @@ /* Load a PatternType 2 color into the cache. (No effect.) */ static int -gx_dc_pattern2_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis, +gx_dc_pattern2_load(gx_device_color *pdevc, const gs_gstate *ignore_pgs, gx_device *ignore_dev, gs_color_select_t ignore_select) { return 0; @@ -178,7 +178,7 @@ /* Remap a PatternType 2 color. */ static int gs_pattern2_remap_color(const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { /* We don't do any actual color mapping now. */ @@ -197,11 +197,12 @@ * information. */ static int -gs_pattern2_set_color(const gs_client_color * pcc, gs_state * pgs) +gs_pattern2_set_color(const gs_client_color * pcc, gs_gstate * pgs) { gs_pattern2_instance_t * pinst = (gs_pattern2_instance_t *)pcc->pattern; gs_color_space * pcs = pinst->templat.Shading->params.ColorSpace; - int code, k, num_comps; + int code; + uchar k, num_comps; pinst->saved->overprint_mode = pgs->overprint_mode; pinst->saved->overprint = pgs->overprint; @@ -240,7 +241,7 @@ rect.q.x = int2fixed(x + w); rect.q.y = int2fixed(y + h); return gs_shading_do_fill_rectangle(pinst->templat.Shading, &rect, dev, - (gs_imager_state *)pinst->saved, !pinst->shfill); + (gs_gstate *)pinst->saved, !pinst->shfill); } } @@ -276,11 +277,11 @@ /* Transform a shading bounding box into device space. */ /* This is just a bridge to an old code. */ int -gx_dc_pattern2_shade_bbox_transform2fixed(const gs_rect * rect, const gs_imager_state * pis, +gx_dc_pattern2_shade_bbox_transform2fixed(const gs_rect * rect, const gs_gstate * pgs, gs_fixed_rect * rfixed) { gs_rect dev_rect; - int code = gs_bbox_transform(rect, &ctm_only(pis), &dev_rect); + int code = gs_bbox_transform(rect, &ctm_only(pgs), &dev_rect); if (code >= 0) { rfixed->p.x = float2fixed(dev_rect.p.x); @@ -302,7 +303,7 @@ if (!pinst->templat.Shading->params.have_BBox) return 0; code = gx_dc_pattern2_shade_bbox_transform2fixed( - &pinst->templat.Shading->params.BBox, (gs_imager_state *)pinst->saved, bbox); + &pinst->templat.Shading->params.BBox, (gs_gstate *)pinst->saved, bbox); if (code < 0) return code; return 1; @@ -327,9 +328,9 @@ if (!psh->params.have_BBox) return_error(gs_error_unregistered); /* Do not call in this case. */ else { - gs_state *pis = pinst->saved; + gs_gstate *pgs = pinst->saved; - return gs_shading_path_add_box(ppath, &psh->params.BBox, &pis->ctm); + return gs_shading_path_add_box(ppath, &psh->params.BBox, &pgs->ctm); } } @@ -347,13 +348,15 @@ gx_path_init_local(&box_path, mem); code = gx_dc_shading_path_add_box(&box_path, pdevc); - if (code == gs_error_limitcheck) { - /* Ignore huge BBox - bug 689027. */ - code = 0; - } else { + if (code != gs_error_limitcheck) { + /* Ignore huge BBox causing limitcheck - bug 689027. */ if (code >= 0) { gx_cpath_init_local_shared(cpath_local, *ppcpath1, mem); - code = gx_cpath_intersect(cpath_local, &box_path, gx_rule_winding_number, (gs_imager_state *)pinst->saved); + code = gx_cpath_intersect(cpath_local, &box_path, gx_rule_winding_number, (gs_gstate *)pinst->saved); + if (code < 0) { + gx_path_free(&box_path, "gx_default_fill_path(path_bbox)"); + return code; + } *ppcpath1 = cpath_local; } } @@ -381,7 +384,7 @@ /* Ignore huge BBox - bug 689027. */ code = 0; } else if (code >= 0) { - code = gx_cpath_intersect(cpath_local, &box_path, gx_rule_winding_number, (gs_imager_state *)pinst->saved); + code = gx_cpath_intersect(cpath_local, &box_path, gx_rule_winding_number, (gs_gstate *)pinst->saved); } gx_path_free(&box_path, "gx_default_fill_path(path_bbox)"); } diff -Nru ghostscript-9.10~dfsg/base/gsptype2.h ghostscript-9.25~dfsg+1/base/gsptype2.h --- ghostscript-9.10~dfsg/base/gsptype2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsptype2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -104,7 +104,7 @@ /* Transform a shading bounding box into device space. */ int gx_dc_pattern2_shade_bbox_transform2fixed(const gs_rect * rect, - const gs_imager_state * pis, gs_fixed_rect * rfixed); + const gs_gstate * pgs, gs_fixed_rect * rfixed); /* Get a shading bbox. Returns 1 on success. */ int gx_dc_pattern2_get_bbox(const gx_device_color * pdevc, gs_fixed_rect *bbox); diff -Nru ghostscript-9.10~dfsg/base/gsrect.h ghostscript-9.25~dfsg+1/base/gsrect.h --- ghostscript-9.10~dfsg/base/gsrect.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsrect.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsrefct.h ghostscript-9.25~dfsg+1/base/gsrefct.h --- ghostscript-9.10~dfsg/base/gsrefct.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsrefct.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,6 +19,14 @@ #ifndef gsrefct_INCLUDED # define gsrefct_INCLUDED +#include "memento.h" + +/* Remove this, hopefully */ +#ifndef gs_memory_DEFINED +# define gs_memory_DEFINED +typedef struct gs_memory_s gs_memory_t; +#endif + /* * A reference-counted object must include the following header: * rc_header rc; @@ -61,7 +69,7 @@ void rc_trace_free_struct(const void *vp, const rc_header *prc, client_name_t cname); void rc_trace_increment(const void *vp, const rc_header *prc); -void rc_trace_adjust(const void *vp, const rc_header *prc, int delta); +void rc_trace_adjust(const void *vp, const rc_header *prc, int delta, const char *cname); #define IF_RC_DEBUG(call) BEGIN if (gs_debug_c('^')) { dlputs(""); call; } END #else #define IF_RC_DEBUG(call) DO_NOTHING @@ -128,17 +136,17 @@ END /* Guarantee that a structure is allocated and is not shared. */ -#define RC_DO_ADJUST(vp, delta)\ +#define RC_DO_ADJUST(vp, delta, cname)\ BEGIN\ - IF_RC_DEBUG(rc_trace_adjust(vp, &(vp)->rc, delta));\ + IF_RC_DEBUG(rc_trace_adjust(vp, &(vp)->rc, delta, cname));\ (vp)->rc.ref_count += (delta);\ END #define rc_unshare_struct(vp, typ, pstype, mem, errstat, cname)\ BEGIN\ if ( (vp) == 0 || (vp)->rc.ref_count > 1 || (vp)->rc.memory != (mem) ) {\ typ *new;\ + if ( vp ) RC_DO_ADJUST(vp, -1, cname);\ rc_alloc_struct_1(new, typ, pstype, mem, errstat, cname);\ - if ( vp ) RC_DO_ADJUST(vp, -1);\ (vp) = new;\ }\ END @@ -157,7 +165,7 @@ #define rc_adjust_(vp, delta, cname, body)\ BEGIN\ if (vp) {\ - RC_DO_ADJUST(vp, delta);\ + RC_DO_ADJUST(vp, delta, cname);\ if (!(vp)->rc.ref_count) {\ rc_free_struct(vp, cname);\ body;\ diff -Nru ghostscript-9.10~dfsg/base/gsromfs0.c ghostscript-9.25~dfsg+1/base/gsromfs0.c --- ghostscript-9.10~dfsg/base/gsromfs0.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsromfs0.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -18,5 +18,9 @@ #include "stdint_.h" +#include "time_.h" + + time_t gs_romfs_buildtime = 0; + uint32_t *gs_romfs[] = { 0 }; diff -Nru ghostscript-9.10~dfsg/base/gsrop.c ghostscript-9.25~dfsg+1/base/gsrop.c --- ghostscript-9.10~dfsg/base/gsrop.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsrop.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,7 +22,7 @@ /* setrasterop */ int -gs_setrasterop(gs_state * pgs, gs_rop3_t rop) +gs_setrasterop(gs_gstate * pgs, gs_rop3_t rop) { if (pgs->in_cachedevice) return_error(gs_error_undefined); @@ -32,14 +32,14 @@ /* currentrasterop */ gs_rop3_t -gs_currentrasterop(const gs_state * pgs) +gs_currentrasterop(const gs_gstate * pgs) { return lop_rop(pgs->log_op); } /* setsourcetransparent */ int -gs_setsourcetransparent(gs_state * pgs, bool transparent) +gs_setsourcetransparent(gs_gstate * pgs, bool transparent) { if (pgs->in_cachedevice) return_error(gs_error_undefined); @@ -51,14 +51,14 @@ /* currentsourcetransparent */ bool -gs_currentsourcetransparent(const gs_state * pgs) +gs_currentsourcetransparent(const gs_gstate * pgs) { return (pgs->log_op & lop_S_transparent) != 0; } /* settexturetransparent */ int -gs_settexturetransparent(gs_state * pgs, bool transparent) +gs_settexturetransparent(gs_gstate * pgs, bool transparent) { if (pgs->in_cachedevice) return_error(gs_error_undefined); @@ -70,20 +70,20 @@ /* currenttexturetransparent */ bool -gs_currenttexturetransparent(const gs_state * pgs) +gs_currenttexturetransparent(const gs_gstate * pgs) { return (pgs->log_op & lop_T_transparent) != 0; } /* Save/restore logical operation. (For internal use only.) */ int -gs_set_logical_op(gs_state * pgs, gs_logical_operation_t lop) +gs_set_logical_op(gs_gstate * pgs, gs_logical_operation_t lop) { pgs->log_op = lop; return 0; } gs_logical_operation_t -gs_current_logical_op(const gs_state * pgs) +gs_current_logical_op(const gs_gstate * pgs) { return pgs->log_op; } diff -Nru ghostscript-9.10~dfsg/base/gsrop.h ghostscript-9.25~dfsg+1/base/gsrop.h --- ghostscript-9.10~dfsg/base/gsrop.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsrop.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,15 +23,15 @@ /* Procedural interface */ -int gs_setrasterop(gs_state *, gs_rop3_t); -gs_rop3_t gs_currentrasterop(const gs_state *); -int gs_setsourcetransparent(gs_state *, bool); -bool gs_currentsourcetransparent(const gs_state *); -int gs_settexturetransparent(gs_state *, bool); -bool gs_currenttexturetransparent(const gs_state *); +int gs_setrasterop(gs_gstate *, gs_rop3_t); +gs_rop3_t gs_currentrasterop(const gs_gstate *); +int gs_setsourcetransparent(gs_gstate *, bool); +bool gs_currentsourcetransparent(const gs_gstate *); +int gs_settexturetransparent(gs_gstate *, bool); +bool gs_currenttexturetransparent(const gs_gstate *); /* Save/restore the combined logical operation. */ -gs_logical_operation_t gs_current_logical_op(const gs_state *); -int gs_set_logical_op(gs_state *, gs_logical_operation_t); +gs_logical_operation_t gs_current_logical_op(const gs_gstate *); +int gs_set_logical_op(gs_gstate *, gs_logical_operation_t); #endif /* gsrop_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsroprun1.h ghostscript-9.25~dfsg+1/base/gsroprun1.h --- ghostscript-9.10~dfsg/base/gsroprun1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsroprun1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsroprun24.h ghostscript-9.25~dfsg+1/base/gsroprun24.h --- ghostscript-9.10~dfsg/base/gsroprun24.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsroprun24.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -145,30 +145,30 @@ #endif #ifdef S_1BIT -#if S_1BIT +#if S_1BIT == MAYBE if (op->flags & rop_s_1bit) { -#endif /* S_1BIT */ - s = op->s.b.ptr + (op->s.b.pos>>3); +#endif /* S_1BIT == MAYBE */ + s += op->s.b.pos>>3; sroll = 8-(op->s.b.pos & 7); - sc[0] = GET24(&op->scolors[0]); - sc[1] = GET24(&op->scolors[3]); -#if S_1BIT + sc[0] = ((const gx_color_index *)op->scolors)[0]; + sc[1] = ((const gx_color_index *)op->scolors)[1]; +#if S_1BIT == MAYBE } else sroll = 0; -#endif /* S_1BIT */ +#endif /* S_1BIT == MAYBE */ #endif /* defined(S_1BIT) */ #ifdef T_1BIT -#if T_1BIT +#if T_1BIT == MAYBE if (op->flags & rop_t_1bit) { -#endif /* T_1BIT */ - t = op->t.b.ptr + (op->t.b.pos>>3); +#endif /* T_1BIT == MAYBE */ + t += op->t.b.pos>>3; troll = 8-(op->t.b.pos & 7); - tc[0] = GET24(&op->tcolors[0]); - tc[1] = GET24(&op->tcolors[3]); -#if T_1BIT + tc[0] = ((const gx_color_index *)op->tcolors)[0]; + tc[1] = ((const gx_color_index *)op->tcolors)[1]; +#if T_1BIT == MAYBE } else troll = 0; -#endif /* T_1BIT */ +#endif /* T_1BIT == MAYBE */ #endif /* defined(T_1BIT) */ do { #if defined(S_USED) && !defined(S_CONST) @@ -177,15 +177,15 @@ #if defined(T_USED) && !defined(T_CONST) rop_operand T; #endif /* defined(T_USED) && !defined(T_CONST) */ -#if defined(S_1BIT) && !S_1BIT +#if defined(S_1BIT) && S_1BIT == MAYBE if (sroll == 0) { -#endif /* defined(S_1BIT) && !S_1BIT */ -#if !defined(S_1BIT) || !S_1BIT +#endif /* defined(S_1BIT) && S_1BIT == MAYBE */ +#if !defined(S_1BIT) || S_1BIT == MAYBE FETCH_S; -#endif /* !defined(S_1BIT) || !S_1BIT */ -#if defined(S_1BIT) && !S_1BIT +#endif /* !defined(S_1BIT) || S_1BIT == MAYBE */ +#if defined(S_1BIT) && S_1BIT == MAYBE } else -#endif /* defined(S_1BIT) && !S_1BIT */ +#endif /* defined(S_1BIT) && S_1BIT == MAYBE */ { #ifdef S_1BIT --sroll; @@ -196,15 +196,15 @@ } #endif /* S_1BIT */ } -#if defined(T_1BIT) && !T_1BIT +#if defined(T_1BIT) && T_1BIT == MAYBE if (troll == 0) { -#endif /* defined(T_1BIT) && !T_1BIT */ -#if !defined(T_1BIT) || !T_1BIT +#endif /* defined(T_1BIT) && T_1BIT == MAYBE */ +#if !defined(T_1BIT) || T_1BIT == MAYBE FETCH_T; -#endif /* defined(T_1BIT) && !T_1BIT */ -#if defined(T_1BIT) && !T_1BIT +#endif /* defined(T_1BIT) && T_1BIT == MAYBE */ +#if defined(T_1BIT) && T_1BIT == MAYBE } else -#endif /* defined(T_1BIT) && !T_1BIT */ +#endif /* defined(T_1BIT) && T_1BIT == MAYBE */ { #ifdef T_1BIT --troll; diff -Nru ghostscript-9.10~dfsg/base/gsroprun8.h ghostscript-9.25~dfsg+1/base/gsroprun8.h --- ghostscript-9.10~dfsg/base/gsroprun8.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsroprun8.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -99,7 +99,7 @@ #endif /* defined(S_TRANS) */ #ifdef S_1BIT int sroll; - const byte *scolors = op->scolors; + const gx_color_index *scolors = op->scolors; #endif /* S_1BIT */ #else /* !defined(S_USED) */ #define S 0 @@ -120,7 +120,7 @@ #endif /* defined(T_TRANS) */ #ifdef T_1BIT int troll; - const byte *tcolors = op->tcolors; + const gx_color_index *tcolors = op->tcolors; #endif /* T_TRANS */ #else /* !defined(T_USED) */ #define T 0 @@ -138,26 +138,26 @@ #endif #ifdef S_1BIT -#if S_1BIT +#if S_1BIT == MAYBE if (op->flags & rop_s_1bit) { -#endif /* S_1BIT */ - s = op->s.b.ptr + (op->s.b.pos>>3); +#endif /* S_1BIT == MAYBE */ + s += op->s.b.pos>>3; sroll = 8-(op->s.b.pos & 7); -#if S_1BIT +#if S_1BIT == MAYBE } else sroll = 0; -#endif /* S_1BIT */ +#endif /* S_1BIT == MAYBE */ #endif /* defined(S_1BIT) */ #ifdef T_1BIT -#if T_1BIT +#if T_1BIT == MAYBE if (op->flags & rop_t_1bit) { -#endif /* T_1BIT */ - t = op->t.b.ptr + (op->t.b.pos>>3); +#endif /* T_1BIT == MAYBE */ + t += op->t.b.pos>>3; troll = 8-(op->t.b.pos & 7); -#if T_1BIT +#if T_1BIT == MAYBE } else troll = 0; -#endif /* T_1BIT */ +#endif /* T_1BIT == MAYBE */ #endif /* defined(T_1BIT) */ do { #if defined(S_USED) && !defined(S_CONST) @@ -166,15 +166,15 @@ #if defined(T_USED) && !defined(T_CONST) rop_operand T; #endif /* defined(T_USED) && !defined(T_CONST) */ -#if defined(S_1BIT) && !S_1BIT +#if defined(S_1BIT) && S_1BIT == MAYBE if (sroll == 0) { -#endif /* defined(S_1BIT) && !S_1BIT */ -#if !defined(S_1BIT) || !S_1BIT +#endif /* defined(S_1BIT) && S_1BIT == MAYBE */ +#if !defined(S_1BIT) || S_1BIT == MAYBE FETCH_S; -#endif /* !defined(S_1BIT) || !S_1BIT */ -#if defined(S_1BIT) && !S_1BIT +#endif /* !defined(S_1BIT) || S_1BIT == MAYBE */ +#if defined(S_1BIT) && S_1BIT == MAYBE } else -#endif /* defined(S_1BIT) && !S_1BIT */ +#endif /* defined(S_1BIT) && S_1BIT == MAYBE */ { #ifdef S_1BIT --sroll; @@ -185,15 +185,15 @@ } #endif /* S_1BIT */ } -#if defined(T_1BIT) && !T_1BIT +#if defined(T_1BIT) && T_1BIT == MAYBE if (troll == 0) { -#endif /* defined(T_1BIT) && !T_1BIT */ -#if !defined(T_1BIT) || !T_1BIT +#endif /* defined(T_1BIT) && T_1BIT == MAYBE */ +#if !defined(T_1BIT) || T_1BIT == MAYBE FETCH_T; -#endif /* defined(T_1BIT) && !T_1BIT */ -#if defined(T_1BIT) && !T_1BIT +#endif /* defined(T_1BIT) && T_1BIT == MAYBE */ +#if defined(T_1BIT) && T_1BIT == MAYBE } else -#endif /* defined(T_1BIT) && !T_1BIT */ +#endif /* defined(T_1BIT) && T_1BIT == MAYBE */ { #ifdef T_1BIT --troll; diff -Nru ghostscript-9.10~dfsg/base/gsroprun.c ghostscript-9.25~dfsg+1/base/gsroprun.c --- ghostscript-9.10~dfsg/base/gsroprun.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsroprun.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -18,8 +18,8 @@ #include "std.h" #include "stdpre.h" #include "gsropt.h" -#include "arch.h" #include "gp.h" +#include "gxcindex.h" /* Enable the following define to use 'template'd code (code formed by * repeated #inclusion of a header file to generate differen versions). @@ -87,11 +87,6 @@ usage[3*rop]++; } - -static void unrecord(int rop) -{ - usage[3*rop]--; -} #endif #define get24(ptr)\ @@ -192,22 +187,22 @@ } #endif -/* Rop 0x0f = ~t */ +/* Rop 0x33 = ~s */ -/* 0x0F = ~t dep=1 s_constant */ +/* 0x33 = ~s dep=1 t_constant */ #ifdef USE_TEMPLATES -#define TEMPLATE_NAME notT_rop_run1_const_s -#define SPECIFIC_ROP 0x0F -#define SPECIFIC_CODE(O,D,S,T) do { O = ~T; } while (0) -#define S_CONST +#define TEMPLATE_NAME notS_rop_run1_const_t +#define SPECIFIC_ROP 0x33 +#define SPECIFIC_CODE(O,D,S,T) do { O = ~S; } while (0) +#define T_CONST #include "gsroprun1.h" #else -static void notT_rop_run1_const_s(rop_run_op *op, byte *d, int len) +static void notS_rop_run1_const_s(rop_run_op *op, byte *d, int len) { byte lmask, rmask; - const byte *t = op->t.b.ptr; - byte T; - int t_skew; + const byte *s = op->s.b.ptr; + byte S; + int s_skew; len = len * op->depth + op->dpos; /* lmask = the set of bits to alter in the output bitmap on the left @@ -222,48 +217,48 @@ * of them due to the allocator. If we ever get valgrind properly marking * allocated blocks as readable etc, then this may throw some spurious * errors. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; + s_skew = op->t.b.pos - op->dpos; + if (s_skew < 0) { + s_skew += 8; + s--; } len -= 8; if (len < 0) { /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<>(8-t_skew)); - *d = (*d & ~lmask) | (~T & lmask); + S = (s[0]<>(8-s_skew)); + *d = (*d & ~lmask) | (~S & lmask); return; } if (lmask != 0xFF) { /* Unaligned left hand case */ - T = (t[0]<>(8-t_skew)); - t++; - *d = (*d & ~lmask) | (~T & lmask); + S = (s[0]<>(8-s_skew)); + s++; + *d = (*d & ~lmask) | (~S & lmask); d++; len -= 8; } if (len >= 0) { /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { + if (s_skew == 0) { do { - *d++ = ~*t++; + *d++ = ~*s++; len -= 8; } while (len >= 0); } else { do { - T = (t[0]<>(8-t_skew)); - t++; - *d++ = ~T; + S = (s[0]<>(8-s_skew)); + s++; + *d++ = ~S; len -= 8; } while (len >= 0); } } if (rmask != 0xFF) { /* Unaligned right hand case */ - T = (t[0]<>(8-t_skew)); - *d = (~T & ~rmask) | (*d & rmask); + S = (s[0]<>(8-s_skew)); + *d = (~S & ~rmask) | (*d & rmask); } } #endif @@ -348,102 +343,22 @@ } #endif -/* Rop 0xfa = d|t */ - -/* 0xFA = d|t dep=1 s_constant */ -#ifdef USE_TEMPLATES -#define TEMPLATE_NAME dort_rop_run1_const_s -#define SPECIFIC_ROP 0xFA -#define SPECIFIC_CODE(O,D,S,T) do { O = D|T; } while (0) -#define S_CONST -#include "gsroprun1.h" -#else -static void dort_rop_run1_const_s(rop_run_op *op, byte *d, int len) -{ - byte lmask, rmask; - const byte *t = op->t.b.ptr; - byte T, D; - int t_skew; - - len = len * op->depth + op->dpos; - /* lmask = the set of bits to alter in the output bitmap on the left - * hand edge of the run. rmask = the set of bits NOT to alter in the - * output bitmap on the right hand edge of the run. */ - lmask = 255>>(7 & op->dpos); - rmask = 255>>(7 & len); - - /* Note #1: This mirrors what the original code did, but I think it has - * the risk of moving s and t back beyond officially allocated space. We - * may be saved by the fact that all blocks have a word or two in front - * of them due to the allocator. If we ever get valgrind properly marking - * allocated blocks as readable etc, then this may throw some spurious - * errors. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; - } - - len -= 8; - if (len < 0) { - /* Short case - starts and ends in the same byte */ - lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<>(8-t_skew)); - D = *d | T; - *d = (*d & ~lmask) | (D & lmask); - return; - } - if (lmask != 0xFF) { - /* Unaligned left hand case */ - T = (t[0]<>(8-t_skew)); - t++; - D = *d | T; - *d = (*d & ~lmask) | (D & lmask); - d++; - len -= 8; - } - if (len >= 0) { - /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { - do { - *d++ |= *t++; - len -= 8; - } while (len >= 0); - } else { - do { - T = (t[0]<>(8-t_skew)); - t++; - *d |= T; - d++; - len -= 8; - } while (len >= 0); - } - } - if (rmask != 0xFF) { - /* Unaligned right hand case */ - T = (t[0]<>(8-t_skew)); - D = *d | T; - *d = (D & ~rmask) | (*d & rmask); - } -} -#endif - /* Rop 0x66 = d^s (and 0x5A = d^t) */ -/* 0x5A = d^t dep=1 s_constant */ +/* 0x66 = d^s dep=1 t_constant */ #ifdef USE_TEMPLATES -#define TEMPLATE_NAME xor_rop_run1_const_s -#define SPECIFIC_ROP 0x5A -#define SPECIFIC_CODE(O,D,S,T) do { O = D^T; } while (0) -#define S_CONST +#define TEMPLATE_NAME xor_rop_run1_const_t +#define SPECIFIC_ROP 0x66 +#define SPECIFIC_CODE(O,D,S,T) do { O = D^S; } while (0) +#define T_CONST #include "gsroprun1.h" #else -static void xor_rop_run1_const_s(rop_run_op *op, byte *d, int len) +static void xor_rop_run1_const_t(rop_run_op *op, byte *d, int len) { byte lmask, rmask; - const byte *t = op->t.b.ptr; - byte T, D; - int t_skew; + const byte *s = op->s.b.ptr; + byte S, D; + int s_skew; len = len * op->depth + op->dpos; /* lmask = the set of bits to alter in the output bitmap on the left @@ -458,42 +373,42 @@ * of them due to the allocator. If we ever get valgrind properly marking * allocated blocks as readable etc, then this may throw some spurious * errors. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; + s_skew = op->s.b.pos - op->dpos; + if (s_skew < 0) { + s_skew += 8; + s--; } len -= 8; if (len < 0) { /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<>(8-t_skew)); - D = *d ^ T; + S = (s[0]<>(8-s_skew)); + D = *d ^ S; *d = (*d & ~lmask) | (D & lmask); return; } if (lmask != 0xFF) { /* Unaligned left hand case */ - T = (t[0]<>(8-t_skew)); - t++; - D = *d ^ T; + S = (s[0]<>(8-s_skew)); + s++; + D = *d ^ S; *d = (*d & ~lmask) | (D & lmask); d++; len -= 8; } if (len >= 0) { /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { + if (s_skew == 0) { do { - *d++ ^= *t++; + *d++ ^= *s++; len -= 8; } while (len >= 0); } else { do { - T = (t[0]<>(8-t_skew)); - t++; - *d = *d ^ T; + S = (s[0]<>(8-s_skew)); + s++; + *d = *d ^ S; d++; len -= 8; } while (len >= 0); @@ -501,8 +416,8 @@ } if (rmask != 0xFF) { /* Unaligned right hand case */ - T = (t[0]<>(8-t_skew)); - D = *d ^ T; + S = (s[0]<>(8-s_skew)); + D = *d ^ S; *d = (D & ~rmask) | (*d & rmask); } } @@ -554,117 +469,20 @@ } #endif -/* rop = 0xFC = s | t dep=24 s_constant t_constant */ -#ifdef USE_TEMPLATES -/* FIXME: Not optimal; introduce 'PRE' code to combine S and T. */ -#define TEMPLATE_NAME sort_rop_run24_const_st -#define SPECIFIC_ROP 0x66 -#define SPECIFIC_CODE(O,D,S,T) do { O = S|T; } while (0) -#define S_CONST -#define T_CONST -#include "gsroprun24.h" -#else -static void sort_rop_run24_const_st(rop_run_op *op, byte *d, int len) -{ - rop_operand SorT = op->s.c | op->t.c; - do - { - put24(d, SorT); - d += 3; - } - while (--len); -} -#endif - /* rop = 0xAA = d dep=? s_constant t_constant */ static void nop_rop_const_st(rop_run_op *op, byte *d, int len) { } -/* rop = 0xF0 = t dep=1 s_constant */ -#ifdef USE_TEMPLATES -#define TEMPLATE_NAME sett_rop_run1_const_s -#define SPECIFIC_ROP 0xF0 -#define SPECIFIC_CODE(O,D,S,T) do { O = T; } while (0) -#define S_CONST -#include "gsroprun1.h" -#else -static void sett_rop_run1_const_s(rop_run_op *op, byte *d, int len) -{ - rop_proc proc = rop_proc_table[op->rop]; - byte lmask, rmask; - byte T, D; - const byte *t = op->t.b.ptr; - int t_skew; - - len = len*op->depth + op->dpos; - /* lmask = the set of bits to alter in the output bitmap on the left - * hand edge of the run. rmask = the set of bits NOT to alter in the - * output bitmap on the right hand edge of the run. */ - lmask = 255>>(7 & op->dpos); - rmask = 255>>(7 & len); - - /* See note #1 above. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; - } - - len -= 8; - if (len < 0) { - /* Short case - starts and ends in the same byte */ - lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<>(8-t_skew)); - D = proc(*d, 0, T); - *d = (*d & ~lmask) | (D & lmask); - return; - } - if (lmask != 0xFF) { - /* Unaligned left hand case */ - T = (t[0]<>(8-t_skew)); - t++; - D = proc(*d, 0, T); - *d = (*d & ~lmask) | (D & lmask); - d++; - len -= 8; - } - if (len >= 0) { - /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { - do { - *d = proc(*d, 0, *t++); - d++; - len -= 8; - } while (len >= 0); - } else { - do { - T = (t[0]<>(8-t_skew)); - t++; - *d = proc(*d, 0, T); - d++; - len -= 8; - } while (len >= 0); - } - } - if (rmask != 0xFF) { - /* Unaligned right hand case */ - T = (t[0]<>(8-t_skew)); - D = proc(*d, 0, T); - *d = (D & ~rmask) | (*d & rmask); - } -} -#endif - /* rop = 0xCC = s dep=1 t_constant */ #ifdef USE_TEMPLATES -#define TEMPLATE_NAME sets_rop_run1_const_t +#define TEMPLATE_NAME sets_rop_run1 #define SPECIFIC_ROP 0xCC #define SPECIFIC_CODE(O,D,S,T) do { O = S; } while (0) #define T_CONST #include "gsroprun1.h" #else -static void sets_rop_run1_const_s(rop_run_op *op, byte *d, int len) +static void sets_rop_run1(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[op->rop]; byte lmask, rmask; @@ -691,7 +509,7 @@ /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ S = (s[0]<>(8-s_skew)); - D = proc(*d, 0, S); + D = proc(*d, S, 0); *d = (*d & ~lmask) | (D & lmask); return; } @@ -699,7 +517,7 @@ /* Unaligned left hand case */ S = (s[0]<>(8-s_skew)); s++; - D = proc(*d, 0, S); + D = proc(*d, S, 0); *d = (*d & ~lmask) | (D & lmask); d++; len -= 8; @@ -708,7 +526,7 @@ /* Simple middle case (complete destination bytes). */ if (s_skew == 0) { do { - *d = proc(*d, 0, *s++); + *d = proc(*d, *s++, 0); d++; len -= 8; } while (len >= 0); @@ -716,7 +534,7 @@ do { S = (s[0]<>(8-s_skew)); s++; - *d = proc(*d, 0, S); + *d = proc(*d, S, 0); d++; len -= 8; } while (len >= 0); @@ -725,12 +543,51 @@ if (rmask != 0xFF) { /* Unaligned right hand case */ S = (s[0]<>(8-s_skew)); - D = proc(*d, 0, S); + D = proc(*d, S, 0); *d = (D & ~rmask) | (*d & rmask); } } #endif +/* rop = 0xCC = s dep=8 s_constant | t_constant */ +#ifdef USE_TEMPLATES +#define TEMPLATE_NAME sets_rop_run8 +#define SPECIFIC_ROP 0xCC +#define SPECIFIC_CODE(O,D,S,T) do { O = S; } while (0) +#define S_CONST +#define T_CONST +#include "gsroprun8.h" +#else +static void sets_rop_run8(rop_run_op *op, byte *d, int len) +{ + const byte S = op->s.c; + do { + *d++ = S; + } + while (--len); +} +#endif + +/* rop = 0xCC = s dep=24 s_constant | t_constant */ +#ifdef USE_TEMPLATES +#define TEMPLATE_NAME sets_rop_run24 +#define SPECIFIC_ROP 0xCC +#define SPECIFIC_CODE(O,D,S,T) do { O = S; } while (0) +#define S_CONST +#define T_CONST +#include "gsroprun24.h" +#else +static void copys_rop_run24(rop_run_op *op, byte *d, int len) +{ + rop_operand S = op->s.c; + { + put24(d, S); + d += 3; + } + while (--len); +} +#endif + /* Generic ROP run code */ #ifdef USE_TEMPLATES #define TEMPLATE_NAME generic_rop_run1 @@ -937,8 +794,8 @@ rop_operand strans = (op->rop & lop_S_transparent ? 255 : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 255 : -1); int sroll, troll; - const byte *scolors = op->scolors; - const byte *tcolors = op->tcolors; + const gx_color_index *scolors = op->scolors; + const gx_color_index *tcolors = op->tcolors; if (op->flags & rop_s_1bit) { s = op->s.b.ptr + (op->s.b.pos>>3); sroll = 8-(op->s.b.pos & 7); @@ -1045,21 +902,16 @@ rop_operand strans = (op->rop & lop_S_transparent ? 0xFFFFFF : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 0xFFFFFF : -1); int sroll, troll; - const byte *scolors = op->scolors; - const byte *tcolors = op->tcolors; - rop_operand sc[2], tc[2]; + const gx_color_index *scolors = op->scolors; + const gx_color_index *tcolors = op->tcolors; if (op->flags & rop_s_1bit) { s = op->s.b.ptr + (op->s.b.pos>>3); sroll = 8-(op->s.b.pos & 7); - sc[0] = get24(&op->scolors[0]); - sc[1] = get24(&op->scolors[3]); } else sroll = 0; if (op->flags & rop_t_1bit) { t = op->t.b.ptr + (op->t.b.pos>>3); troll = 8-(op->t.b.pos & 7); - tc[0] = get24(&op->tcolors[0]); - tc[1] = get24(&op->tcolors[3]); } else troll = 0; do { @@ -1069,7 +921,7 @@ s += 3; } else { --sroll; - S = sc[(*s >> sroll) & 1]; + S = scolors[(*s >> sroll) & 1]; if (sroll == 0) { sroll = 8; s++; @@ -1080,7 +932,7 @@ t += 3; } else { --troll; - T = tc[(*t >> troll) & 1]; + T = tcolors[(*t >> troll) & 1]; if (troll == 0) { troll = 8; t++; @@ -1097,27 +949,27 @@ #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run1_const_s -#define S_CONST +#define TEMPLATE_NAME generic_rop_run1_const_t +#define T_CONST #include "gsroprun1.h" #else -static void generic_rop_run1_const_s(rop_run_op *op, byte *d, int len) +static void generic_rop_run1_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[op->rop]; byte lmask, rmask; - byte S = (byte)op->s.c; - byte T, D; - const byte *t = op->t.b.ptr; - int t_skew; + byte T = (byte)op->t.c; + byte S, D; + const byte *s = op->s.b.ptr; + int s_skew; - /* S should be supplied as 'depth' bits. Duplicate that up to be byte + /* T should be supplied as 'depth' bits. Duplicate that up to be byte * size (if it's supplied byte sized, that's fine too). */ if (op->depth & 1) - S |= S<<1; + T |= T<<1; if (op->depth & 3) - S |= S<<2; + T |= T<<2; if (op->depth & 7) - S |= S<<4; + T |= T<<4; len = len*op->depth + op->dpos; /* lmask = the set of bits to alter in the output bitmap on the left @@ -1127,25 +979,25 @@ rmask = 255>>(7 & len); /* See note #1 above. RJW. */ - t_skew = op->t.b.pos - op->dpos; - if (t_skew < 0) { - t_skew += 8; - t--; + s_skew = op->s.b.pos - op->dpos; + if (s_skew < 0) { + s_skew += 8; + s--; } len -= 8; if (len < 0) { /* Short case - starts and ends in the same byte */ lmask &= ~rmask; /* Combined mask = bits to alter */ - T = (t[0]<>(8-t_skew)); + S = (s[0]<>(8-s_skew)); D = proc(*d, S, T); *d = (*d & ~lmask) | (D & lmask); return; } if (lmask != 0xFF) { /* Unaligned left hand case */ - T = (t[0]<>(8-t_skew)); - t++; + S = (s[0]<>(8-s_skew)); + s++; D = proc(*d, S, T); *d = (*d & ~lmask) | (D & lmask); d++; @@ -1153,16 +1005,16 @@ } if (len >= 0) { /* Simple middle case (complete destination bytes). */ - if (t_skew == 0) { + if (s_skew == 0) { do { - *d = proc(*d, S, *t++); + *d = proc(*d, *s++, T); d++; len -= 8; } while (len >= 0); } else { do { - T = (t[0]<>(8-t_skew)); - t++; + S = (s[0]<>(8-s_skew)); + s++; *d = proc(*d, S, T); d++; len -= 8; @@ -1171,7 +1023,7 @@ } if (rmask != 0xFF) { /* Unaligned right hand case */ - T = (t[0]<>(8-t_skew)); + S = (s[0]<>(8-s_skew)); D = proc(*d, S, T); *d = (D & ~rmask) | (*d & rmask); } @@ -1179,15 +1031,15 @@ #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run8_const_s -#define S_CONST +#define TEMPLATE_NAME generic_rop_run8_const_t +#define T_CONST #include "gsroprun8.h" #else -static void generic_rop_run8_const_s(rop_run_op *op, byte *d, int len) +static void generic_rop_run8_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[op->rop]; - byte s = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + byte t = op->t.c; do { *d = proc(*d, s, *t++); @@ -1198,26 +1050,26 @@ #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run8_const_s_trans -#define S_CONST +#define TEMPLATE_NAME generic_rop_run8_const_t_trans #define S_TRANS MAYBE +#define T_CONST #define T_TRANS MAYBE #include "gsroprun8.h" #else -static void generic_rop_run8_const_s_trans(rop_run_op *op, byte *d, int len) +static void generic_rop_run8_const_t_trans(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - byte S = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + byte T = op->t.c; rop_operand strans = (op->rop & lop_S_transparent ? 255 : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 255 : -1); - if (S == strans) + if (T == ttrans) return; do { - rop_operand T = *t++; - if (T != ttrans) + rop_operand S = *s++; + if (S != strans) *d = proc(*d, S, T); d++; } @@ -1226,42 +1078,34 @@ #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run8_const_s_1bit -#define S_CONST +#define TEMPLATE_NAME generic_rop_run8_1bit_const_t #define S_TRANS MAYBE -#define T_TRANS MAYBE -#define T_1BIT MAYBE +#define S_1BIT YES +#define T_CONST #include "gsroprun8.h" #else -static void generic_rop_run8_const_s_1bit(rop_run_op *op, byte *d, int len) +static void generic_rop_run8_1bit_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - byte S = op->s.c; - const byte *t = op->t.b.ptr; + byte T = op->t.c; + const byte *s = op->s.b.ptr; rop_operand strans = (op->rop & lop_S_transparent ? 255 : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 255 : -1); - int troll; - const byte *tcolors = op->tcolors; - if (S == strans) + int sroll; + const byte *scolors = op->scolors; + if (T == ttrans) return; - if (op->flags & rop_t_1bit) { - t = op->t.b.ptr + (op->t.b.pos>>3); - troll = 8-(op->t.b.pos & 7); - } else - troll = 0; + s = op->s.b.ptr + (op->s.b.pos>>3); + sroll = 8-(op->s.b.pos & 7); do { - rop_operand T; - if (troll == 0) - T = *t++; - else { - --troll; - T = tcolors[(*t >> troll) & 1]; - if (troll == 0) { - troll = 8; - t++; - } + rop_operand S; + --sroll; + S = scolors[(*s >> sroll) & 1]; + if (sroll == 0) { + sroll = 8; + s++; } - if ((T != ttrans)) + if ((S != strans)) *d = proc(*d, S, T); d++; } @@ -1270,20 +1114,20 @@ #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run24_const_s -#define S_CONST +#define TEMPLATE_NAME generic_rop_run24_const_t +#define T_CONST #include "gsroprun24.h" #else -static void generic_rop_run24_const_s(rop_run_op *op, byte *d, int len) +static void generic_rop_run24_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[op->rop]; - rop_operand s = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + rop_operand T = op->t.c; do { - rop_operand D = proc(get24(d), s, get24(t)); + rop_operand D = proc(get24(d), get24(s), T); put24(d, D); - t += 3; + s += 3; d += 3; } while (--len); @@ -1291,30 +1135,30 @@ #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run24_const_s_trans -#define S_CONST +#define TEMPLATE_NAME generic_rop_run24_const_t_trans #define S_TRANS MAYBE +#define T_CONST #define T_TRANS MAYBE #include "gsroprun24.h" #else -static void generic_rop_run24_const_s_trans(rop_run_op *op, byte *d, int len) +static void generic_rop_run24_const_t_trans(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - rop_operand s = op->s.c; - const byte *t = op->t.b.ptr; + const byte *s = op->s.b.ptr; + rop_operand T = op->t.c; rop_operand strans = (op->rop & lop_S_transparent ? 0xFFFFFF : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 0xFFFFFF : -1); - if (s == strans) + if (T == ttrans) return; do { - rop_operand T = get24(t); + rop_operand S = get24(s); rop_operand D; - if (T != ttrans) { - D = proc(get24(d), s, get24(t)); + if (S != strans) { + D = proc(get24(d), get24(s), T); put24(d, D); } - t += 3; + s += 3; d += 3; } while (--len); @@ -1322,45 +1166,38 @@ #endif #ifdef USE_TEMPLATES -#define TEMPLATE_NAME generic_rop_run24_const_s_1bit -#define S_CONST +#define TEMPLATE_NAME generic_rop_run24_1bit_const_t +#define S_1BIT YES #define S_TRANS MAYBE +#define T_CONST #define T_TRANS MAYBE -#define T_1BIT MAYBE #include "gsroprun24.h" #else -static void generic_rop_run24_const_s_1bit(rop_run_op *op, byte *d, int len) +static void generic_rop_run24_1bit_const_t(rop_run_op *op, byte *d, int len) { rop_proc proc = rop_proc_table[lop_rop(op->rop)]; - rop_operand S = op->s.c; - const byte *t = op->t.b.ptr; + rop_operand T = op->t.c; + const byte *s = op->s.b.ptr; rop_operand strans = (op->rop & lop_S_transparent ? 0xFFFFFF : -1); rop_operand ttrans = (op->rop & lop_T_transparent ? 0xFFFFFF : -1); - int troll; - const byte *tcolors = op->tcolors; - rop_operand tc[2]; - if (S == strans) + int sroll; + const byte *scolors = op->scolors; + rop_operand sc[2]; + if (T == ttrans) return; - if (op->flags & rop_t_1bit) { - t = op->t.b.ptr + (op->t.b.pos>>3); - troll = 8-(op->t.b.pos & 7); - tc[0] = get24(&op->tcolors[0]); - tc[1] = get24(&op->tcolors[3]); - } else - troll = 0; + s = op->s.b.ptr + (op->s.b.pos>>3); + sroll = 8-(op->s.b.pos & 7); + sc[0] = ((const gx_color_index *)op->scolors)[0]; + sc[1] = ((const gx_color_index *)op->scolors)[3]; do { - rop_operand T; - if (troll == 0) - T = *t++; - else { - --troll; - T = tc[(*t >> troll) & 1]; - if (troll == 0) { - troll = 8; - t++; - } + rop_operand S; + --sroll; + S = sc[(*s >> sroll) & 1]; + if (sroll == 0) { + sroll = 8; + s++; } - if ((T != ttrans)) { + if ((S != strans)) { rop_operand D = proc(get24(d), S, T); put24(d, D); } @@ -1577,60 +1414,159 @@ op->runswap(&local, d, len); } -void rop_get_run_op(rop_run_op *op, int rop, int depth, int flags) +int rop_get_run_op(rop_run_op *op, int lop, int depth, int flags) { int key; int swap = 0; - int could_swap = 0; #ifdef DISABLE_ROPS - rop = 0xAA; + lop = 0xAA; #endif - /* If the rop ignores either S or T, then we might as well set them to - * be constants; will save us slaving through memory. Also, they can't - * count towards transparency. */ - if (!rop3_uses_S(rop)) { + lop = lop_sanitize(lop); + + /* This is a simple initialisation to quiet a Coverity warning. It complains that + * the 'if (swap)' at the end of the function uses 'run' uninitialised. While its + * true that some ROPs do not instantly set the run member, they go through code + * which, I believe, swaps the lop source and texture, then executes the switch + * statement once more and the second execution sets run. So in summary I don't + * think this is a real problem, and this fixes the Coverity warning. + */ + op->run = 0; + + /* If the lop ignores either S or T, then we might as well set them to + * be constants; will save us slaving through memory. */ + if (!rop3_uses_S(lop) && (lop & lop_S_transparent) == 0) { flags |= rop_s_constant; flags &= ~rop_s_1bit; - rop &= ~lop_S_transparent; } - if (!rop3_uses_T(rop)) { + if (!rop3_uses_T(lop) && (lop & lop_T_transparent) == 0) { flags |= rop_t_constant; flags &= ~rop_t_1bit; - rop &= ~lop_T_transparent; } - /* Cut down the number of cases by mapping 'S bitmap,T constant' onto - * 'S constant,Tbitmap'. */ - could_swap = ((flags & (rop_s_constant | rop_t_constant)) == rop_t_constant); - if (0 == 1) { -force_swap: -#ifdef RECORD_ROP_USAGE - unrecord((int)op->opaque); -#endif - could_swap = 0; + /* Cull transparency if we can */ + if (depth != 1) { + if (lop & lop_S_transparent) { + gx_color_index v = (depth == 8 ? 0xff : 0xffffff); + if (flags & rop_s_constant) { + if (op->s.c == v) { + op->run = nop_rop_const_st; + return 0; + } else + lop &= ~lop_S_transparent; + } else if ((flags & rop_s_1bit) && + ((const gx_color_index *)op->scolors)[0] != v && + ((const gx_color_index *)op->scolors)[1] != v) { + lop &= ~lop_S_transparent; + } + } + if (lop & lop_T_transparent) { + gx_color_index v = (depth == 8 ? 0xff : 0xffffff); + if (flags & rop_t_constant) { + if (op->t.c == v) { + op->run = nop_rop_const_st; + return 0; + } else + lop &= ~lop_T_transparent; + } else if ((flags & rop_t_1bit) && + ((const gx_color_index *)op->tcolors)[0] != v && + ((const gx_color_index *)op->tcolors)[1] != v) { + lop &= ~lop_T_transparent; + } + } + } + + /* Cut down the number of cases. */ + /* S or T can either be constant, bitmaps, or '1-bitmaps' + * (arrays of single bits to choose between 2 preset colors). + * If S or T is unused, then it will appear as constant. + */ + switch (flags) + { + case rop_s_constant: /* Map 'S constant,T bitmap' -> 'S bitmap,T constant' */ + case rop_s_constant | rop_t_1bit: /* Map 'S constant,T 1-bitmap' -> 'S 1-bitmap,T constant' */ + case rop_t_1bit: /* Map 'S bitmap,T 1-bitmap' -> 'S 1-bitmap,T bitmap' */ swap = 1; + break; + case rop_s_constant | rop_t_constant: /* Map 'S unused, T used' -> 'S used, T unused' */ + swap = ((rop_usage_table[lop & 0xff] & (rop_usage_S | rop_usage_T)) == rop_usage_T); + break; } if (swap) { flags = ((flags & rop_t_constant ? rop_s_constant : 0) | (flags & rop_s_constant ? rop_t_constant : 0) | (flags & rop_t_1bit ? rop_s_1bit : 0) | (flags & rop_s_1bit ? rop_t_1bit : 0)); - rop = lop_swap_S_T(rop); + lop = lop_swap_S_T(lop); } + /* At this point, we know that in the ordering: + * 'unused' < 'constant' < 'bitmap' < '1-bitmap', + * that S >= T. + */ op->flags = (flags & (rop_s_constant | rop_t_constant | rop_s_1bit | rop_t_1bit)); op->depth = (byte)depth; - op->rop = rop & (0xFF | lop_S_transparent | lop_T_transparent); op->release = NULL; -#define ROP_SPECIFIC_KEY(rop, depth, flags) (((rop)<<7)+(1<<6)+((depth>>3)<<4)+(flags)) + /* If no transparency, and S and T are constant, and the lop uses both of them, we can combine them. + * Currently this only works for cases where D is unused. + */ + if (!(lop & (lop_T_transparent | lop_S_transparent)) && + op->flags == (rop_s_constant | rop_t_constant) && + rop_usage_table[lop] == rop_usage_ST) { + switch (lop & (rop3_D>>rop3_D_shift)) /* Ignore the D bits */ + { + /* Skip 0000 as doesn't use S or T */ + case ((0<<6) | (0<<4) | (0<<2) | 1): + op->s.c = ~(op->s.c | op->t.c); + break; + case ((0<<6) | (0<<4) | (1<<2) | 0): + op->s.c = op->s.c & ~op->t.c; + break; + /* Skip 0011 as doesn't use S */ + case ((0<<6) | (1<<4) | (0<<2) | 0): + op->s.c = ~op->s.c & op->t.c; + break; + /* Skip 0101 as doesn't use T */ + case ((0<<6) | (1<<4) | (1<<2) | 0): + op->s.c = op->s.c ^ op->t.c; + break; + case ((0<<6) | (1<<4) | (1<<2) | 1): + op->s.c = ~(op->s.c & op->t.c); + break; + case ((1<<6) | (0<<4) | (0<<2) | 0): + op->s.c = op->s.c & op->t.c; + break; + case ((1<<6) | (0<<4) | (0<<2) | 1): + op->s.c = ~(op->s.c ^ op->t.c); + break; + /* Skip 1010 as doesn't use T */ + case ((1<<6) | (0<<4) | (1<<2) | 1): + op->s.c = op->s.c | ~op->t.c; + break; + /* Skip 1100 as doesn't use S */ + case ((1<<6) | (1<<4) | (0<<2) | 1): + op->s.c = ~op->s.c | op->t.c; + break; + case ((1<<6) | (1<<4) | (1<<2) | 0): + op->s.c = op->s.c | op->t.c; + break; + /* Skip 1111 as doesn't use S or T */ + default: + /* Never happens */ + break; + } + lop = (lop & ~0xff) | rop3_S; + } + op->rop = lop & (0xFF | lop_S_transparent | lop_T_transparent); + +#define ROP_SPECIFIC_KEY(lop, depth, flags) (((lop)<<7)+(1<<6)+((depth>>3)<<4)+(flags)) #define KEY_IS_ROP_SPECIFIC(key) (key & (1<<6)) #define STRIP_ROP_SPECIFICITY(key) (key &= ((1<<6)-1)) #define KEY(depth, flags) (((depth>>3)<<4)+(flags)) - key = ROP_SPECIFIC_KEY(rop, depth, flags); + key = ROP_SPECIFIC_KEY(lop, depth, flags); #ifdef RECORD_ROP_USAGE op->opaque = (void*)(key & (MAX-1)); record((int)op->opaque); @@ -1639,9 +1575,9 @@ switch (key) { /* First, the rop specific ones */ - /* 0x0F = T */ - case ROP_SPECIFIC_KEY(0x0F, 1, rop_s_constant): - op->run = notT_rop_run1_const_s; + /* 0x33 = ~S */ + case ROP_SPECIFIC_KEY(0x33, 1, rop_t_constant): + op->run = notS_rop_run1_const_t; break; /* 0x55 = Invert */ case ROP_SPECIFIC_KEY(0x55, 1, rop_s_constant | rop_t_constant): @@ -1657,43 +1593,34 @@ op->run = invert_rop_run24; break; /* 0x66 = D xor S */ - case ROP_SPECIFIC_KEY(0x5a, 1, rop_s_constant): - op->run = xor_rop_run1_const_s; + case ROP_SPECIFIC_KEY(0x66, 1, rop_t_constant): + op->run = xor_rop_run1_const_t; break; - case ROP_SPECIFIC_KEY(0x5a, 8, rop_s_constant | rop_t_constant): - goto force_swap; - case ROP_SPECIFIC_KEY(0x66, 8, rop_s_constant | rop_t_constant): + case ROP_SPECIFIC_KEY(0x66, 8, rop_s_constant | rop_t_constant): /* T_UNUSED */ op->run = xor_rop_run8_const_st; break; - case ROP_SPECIFIC_KEY(0x5a, 24, rop_s_constant | rop_t_constant): - goto force_swap; - case ROP_SPECIFIC_KEY(0x66, 24, rop_s_constant | rop_t_constant): + case ROP_SPECIFIC_KEY(0x66, 24, rop_s_constant | rop_t_constant): /* T_UNUSED */ op->run = xor_rop_run24_const_st; break; - case ROP_SPECIFIC_KEY(0xFC, 24, rop_s_constant | rop_t_constant): - op->run = sort_rop_run24_const_st; - break; - case ROP_SPECIFIC_KEY(0xAA, 1, rop_s_constant | rop_t_constant): - case ROP_SPECIFIC_KEY(0xAA, 8, rop_s_constant | rop_t_constant): - case ROP_SPECIFIC_KEY(0xAA, 24, rop_s_constant | rop_t_constant): + case ROP_SPECIFIC_KEY(0xAA, 1, rop_s_constant | rop_t_constant): /* S & T UNUSED */ + case ROP_SPECIFIC_KEY(0xAA, 8, rop_s_constant | rop_t_constant): /* S & T UNUSED */ + case ROP_SPECIFIC_KEY(0xAA, 24, rop_s_constant | rop_t_constant):/* S & T UNUSED */ op->run = nop_rop_const_st; - break; + return 0; /* 0xCC = S */ - case ROP_SPECIFIC_KEY(0xCC, 1, rop_t_constant): - op->run = sets_rop_run1_const_t; + case ROP_SPECIFIC_KEY(0xCC, 1, rop_t_constant): /* T_UNUSED */ + op->run = sets_rop_run1; + break; + case ROP_SPECIFIC_KEY(0xCC, 8, rop_s_constant | rop_t_constant): /* T_UNUSED */ + op->run = sets_rop_run8; + break; + case ROP_SPECIFIC_KEY(0xCC, 24, rop_s_constant | rop_t_constant): /* T_UNUSED */ + op->run = sets_rop_run24; break; /* 0xEE = D or S */ case ROP_SPECIFIC_KEY(0xEE, 1, rop_t_constant): op->run = dors_rop_run1_const_t; break; - /* 0xF0 = T */ - case ROP_SPECIFIC_KEY(0xF0, 1, rop_s_constant): - op->run = sett_rop_run1_const_s; - break; - /* 0xFA = D or T */ - case ROP_SPECIFIC_KEY(0xFA, 1, rop_s_constant): - op->run = dort_rop_run1_const_s; - break; /* Then the generic ones */ case KEY(1, 0): op->run = generic_rop_run1; @@ -1702,60 +1629,54 @@ op->dpos = 0; break; case KEY(8, 0): - if (rop & lop_S_transparent) - if (rop & lop_T_transparent) + if (lop & lop_S_transparent) + if (lop & lop_T_transparent) op->run = generic_rop_run8_trans_ST; else op->run = generic_rop_run8_trans_S; else - if (rop & lop_T_transparent) + if (lop & lop_T_transparent) op->run = generic_rop_run8_trans_T; else op->run = generic_rop_run8; break; case KEY(8, rop_s_1bit): - case KEY(8, rop_t_1bit): case KEY(8, rop_s_1bit | rop_t_1bit ): op->run = generic_rop_run8_1bit; break; case KEY(24, 0): - if (rop & (lop_S_transparent | lop_T_transparent)) + if (lop & (lop_S_transparent | lop_T_transparent)) op->run = generic_rop_run24_trans; else op->run = generic_rop_run24; break; case KEY(24, rop_s_1bit): - case KEY(24, rop_t_1bit): case KEY(24, rop_s_1bit | rop_t_1bit ): op->run = generic_rop_run24_1bit; break; - case KEY(1, rop_s_constant): - op->run = generic_rop_run1_const_s; + case KEY(1, rop_t_constant): + op->run = generic_rop_run1_const_t; op->s.b.pos = 0; op->t.b.pos = 0; op->dpos = 0; break; - case KEY(8, rop_s_constant): - if (rop & (lop_S_transparent | lop_T_transparent)) - op->run = generic_rop_run8_const_s_trans; + case KEY(8, rop_t_constant): + if (lop & (lop_S_transparent | lop_T_transparent)) + op->run = generic_rop_run8_const_t_trans; else - op->run = generic_rop_run8_const_s; + op->run = generic_rop_run8_const_t; + break; + case KEY(8, rop_s_1bit | rop_t_constant): + op->run = generic_rop_run8_1bit_const_t; break; - case KEY(8, rop_s_constant | rop_s_1bit): - case KEY(8, rop_s_constant | rop_t_1bit): - case KEY(8, rop_s_constant | rop_s_1bit | rop_t_1bit ): - op->run = generic_rop_run8_const_s_1bit; - break; - case KEY(24, rop_s_constant): - if (rop & (lop_S_transparent | lop_T_transparent)) - op->run = generic_rop_run24_const_s_trans; + case KEY(24, rop_t_constant): + if (lop & (lop_S_transparent | lop_T_transparent)) + op->run = generic_rop_run24_const_t_trans; else - op->run = generic_rop_run24_const_s; + op->run = generic_rop_run24_const_t; break; - case KEY(24, rop_s_constant | rop_s_1bit): - case KEY(24, rop_s_constant | rop_t_1bit): - case KEY(24, rop_s_constant | rop_s_1bit | rop_t_1bit ): - op->run = generic_rop_run24_const_s_1bit; + case KEY(24, rop_s_1bit | rop_t_constant): + op->run = generic_rop_run24_1bit_const_t; break; case KEY(1, rop_s_constant | rop_t_constant): op->run = generic_rop_run1_const_st; @@ -1764,40 +1685,18 @@ op->dpos = 0; break; case KEY(8, rop_s_constant | rop_t_constant): - if (rop & (lop_S_transparent | lop_T_transparent)) + if (lop & (lop_S_transparent | lop_T_transparent)) op->run = generic_rop_run8_const_st_trans; else op->run = generic_rop_run8_const_st; break; - case KEY(8, rop_s_constant | rop_t_constant | rop_s_1bit): - case KEY(8, rop_s_constant | rop_t_constant | rop_t_1bit): - case KEY(8, rop_s_constant | rop_t_constant | rop_s_1bit | rop_t_1bit ): - /* Nothing in the code calls constant and 1 bit together. Which - * means that we can only get here if we spotted that the rop ignores - * S and/or T earlier. We know we aren't using transparency, so - * the 1 bit becomes moot. */ - op->run = generic_rop_run8_const_st; - break; case KEY(24, rop_s_constant | rop_t_constant): - if (rop & (lop_S_transparent | lop_T_transparent)) + if (lop & (lop_S_transparent | lop_T_transparent)) op->run = generic_rop_run24_const_st_trans; else op->run = generic_rop_run24_const_st; break; - case KEY(24, rop_s_constant | rop_t_constant | rop_s_1bit): - case KEY(24, rop_s_constant | rop_t_constant | rop_t_1bit): - case KEY(24, rop_s_constant | rop_t_constant | rop_s_1bit | rop_t_1bit ): - /* Nothing in the code calls constant and 1 bit together. Which - * means that we can only get here if we spotted that the rop ignores - * S and/or T earlier. We know we aren't using transparency, so - * the 1 bit becomes moot. */ - op->run = generic_rop_run24_const_st; - break; default: - /* If we failed to find a specific one, and swapping is an option, - * then try swapping. */ - if (could_swap) - goto force_swap; /* If we failed to find a specific one for this rop value, try again * for a generic one. */ if (KEY_IS_ROP_SPECIFIC(key)) @@ -1821,6 +1720,7 @@ op->run = record_run; } #endif + return 1; } void (rop_set_s_constant)(rop_run_op *op, int s) diff -Nru ghostscript-9.10~dfsg/base/gsroptab.c ghostscript-9.25~dfsg+1/base/gsroptab.c --- ghostscript-9.10~dfsg/base/gsroptab.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsroptab.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsropt.h ghostscript-9.25~dfsg+1/base/gsropt.h --- ghostscript-9.10~dfsg/base/gsropt.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsropt.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -94,14 +94,21 @@ * RasterOp operand is called texture, not pattern. */ +/* We have to define rop3_{T,S,D} as enum values to shut compilers + * up that do switch checking. We also have to #define them to allow + * the preprocessor templating to work. */ + /* 3-input RasterOp */ typedef enum { rop3_0 = 0, -#define rop3_T 0xf0 /* texture */ + rop3_T = 0xf0, /* texture */ +#define rop3_T 0xf0 #define rop3_T_shift 4 -#define rop3_S 0xcc /* source */ + rop3_S = 0xcc, /* source */ +#define rop3_S 0xcc #define rop3_S_shift 2 rop3_D = 0xaa, /* destination */ +#define rop3_D 0xaa #define rop3_D_shift 1 rop3_1 = 0xff, rop3_default = rop3_T | rop3_S @@ -214,6 +221,35 @@ #define lop_T_transparent 0x200 #define lop_pdf14 0x400 +/* RJW: A comment from 1998 in gdevrop.c indicates that + * if we are given a LOP that says "S is transparent", and + * S isn't used, then we should ignore that flag. (Similarly + * for T). Tests seem to indicate that this is indeed true + * (See page 12 of C425.bin for an example). + * + * Unfortunately, when we start 'folding' LOPs down onto simpler + * ones, we can start with a LOP where S (or T) matters, and + * end up with one where it looks like it doesn't. As such we + * introduce another flag so we can avoid trying to remove + * the S/T transparency flags after we have started to fold the + * rop down. + */ +#define lop_transparency_checked 0x800 + +static inline int +lop_sanitize(int lop) +{ + if (lop & lop_transparency_checked) + return lop; + lop |= lop_transparency_checked; + if (!rop3_uses_S(lop)) + lop &= ~lop_S_transparent; + if (!rop3_uses_T(lop)) + lop &= ~lop_T_transparent; + + return lop; +} + typedef uint gs_logical_operation_t; #define lop_default\ @@ -293,6 +329,14 @@ rop_operand c; } rop_source; +/* +scolors and tcolors in the following structure should really be +gx_color_index *, but to do that would require gxcindex.h being +included everywhere this header is, and it's not. Including it +at the top of this header runs other things into problems, so +living with void *'s until we can get the header inclusion +sorted. +*/ struct rop_run_op_s { void (*run)(rop_run_op *, byte *dest, int len); void (*runswap)(rop_run_op *, byte *dest, int len); @@ -302,8 +346,8 @@ byte depth; byte flags; byte dpos; - const byte *scolors; - const byte *tcolors; + const void *scolors; + const void *tcolors; void (*release)(rop_run_op *); void *opaque; }; @@ -316,21 +360,29 @@ rop_t_1bit = 8 }; -/* To use a rop_run_op, allocate it on the stack, then call - * rop_get_run_op with a pointer to it to fill it in with details of an - * implementer. If you're lucky (doing a popular rop) you'll get an optimised - * implementation. If you're not, you'll get a general purpose slow rop. You - * will always get an implementation of some kind though. +/* To use a rop_run_op, allocate it on the stack, then (if T or S are constant) + * call one of: + */ +void rop_set_s_constant(rop_run_op *op, int s); +void rop_set_t_constant(rop_run_op *op, int t); + +/* Then call rop_get_run_op with a pointer to it to fill it in with details + * of an implementer. If you're lucky (doing a popular rop) you'll get an + * optimised implementation. If you're not, you'll get a general purpose + * slow rop. You will always get an implementation of some kind though. * * You should logical or together the flags - this tells the routine whether * s and t are constant, or will be varying across the run. + * + * If this function returns non zero, the ROP has been optimised out. */ -void rop_get_run_op(rop_run_op *op, int rop, int depth, int flags); +int rop_get_run_op(rop_run_op *op, int rop, int depth, int flags); -/* Next, you should set the values of S and T. Each of these can either be - * a constant value, or a pointer to a run of bytes. It is the callers - * responsibility to set these in the correct way (corresponding to the flags - * passed into the call to rop_get_run_op. +/* Next, (for non-constant S or T) you should set the values of S and T. + * (Constant values were handled earlier, remember?) Each of these can + * either be a constant value, or a pointer to a run of bytes. It is the + * callers responsibility to set these in the correct way (corresponding + * to the flags passed into the call to rop_get_run_op. * * For cases where depth < 8, and a bitmap is used, we have to specify the * start bit position within the byte. (All data in rop bitmaps is considered @@ -339,7 +391,6 @@ void rop_set_s_bitmap(rop_run_op *op, const byte *s); void rop_set_s_bitmap_subbyte(rop_run_op *op, const byte *s, int startbitpos); void rop_set_s_colors(rop_run_op *op, const byte *scolors); -void rop_set_t_constant(rop_run_op *op, int t); void rop_set_t_bitmap(rop_run_op *op, const byte *t); void rop_set_t_bitmap_subbyte(rop_run_op *op, const byte *s, int startbitpos); void rop_set_t_colors(rop_run_op *op, const byte *scolors); diff -Nru ghostscript-9.10~dfsg/base/gsserial.c ghostscript-9.25~dfsg+1/base/gsserial.c --- ghostscript-9.10~dfsg/base/gsserial.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsserial.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* some utilities useful for converting objects to serial form */ diff -Nru ghostscript-9.10~dfsg/base/gsserial.h ghostscript-9.25~dfsg+1/base/gsserial.h --- ghostscript-9.10~dfsg/base/gsserial.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsserial.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* some general structures useful for converting objects to serial form */ diff -Nru ghostscript-9.10~dfsg/base/gsshade.c ghostscript-9.25~dfsg+1/base/gsshade.c --- ghostscript-9.10~dfsg/base/gsshade.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsshade.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ #include "gxcpath.h" #include "gxcspace.h" #include "gxdcolor.h" /* for filling background rectangle */ -#include "gxistate.h" +#include "gxgstate.h" #include "gxpaint.h" #include "gxpath.h" #include "gxshade.h" @@ -38,7 +38,6 @@ /* GC descriptors */ private_st_shading(); -private_st_shading_mesh(); static ENUM_PTRS_WITH(shading_mesh_enum_ptrs, gs_shading_mesh_t *psm) @@ -156,8 +155,7 @@ } /* Allocate and initialize a shading. */ -/* Free variables: mem, params, ppsh, psh. */ -#define ALLOC_SHADING(sttype, stype, sprocs, cname)\ +#define ALLOC_SHADING(ppsh, psh, mem, sttype, stype, sprocs, cname, params)\ BEGIN\ psh = gs_alloc_struct(mem, void, sttype, cname);\ if ( psh == 0 )\ @@ -200,8 +198,8 @@ (code = gs_matrix_invert(¶ms->Matrix, &imat)) < 0 ) return code; - ALLOC_SHADING(&st_shading_Fb, shading_type_Function_based, - shading_Fb_procs, "gs_shading_Fb_init"); + ALLOC_SHADING(ppsh, psh, mem, &st_shading_Fb, shading_type_Function_based, + shading_Fb_procs, "gs_shading_Fb_init", params); return 0; } @@ -235,8 +233,8 @@ if (code < 0) return code; - ALLOC_SHADING(&st_shading_A, shading_type_Axial, - shading_A_procs, "gs_shading_A_init"); + ALLOC_SHADING(ppsh, psh, mem, &st_shading_A, shading_type_Axial, + shading_A_procs, "gs_shading_A_init", params); return 0; } @@ -265,17 +263,18 @@ const gs_shading_R_params_t * params, gs_memory_t * mem) { gs_shading_R_t *psh; - int code = check_CBFD((const gs_shading_params_t *)params, + int code; + + if (params == NULL || params->Domain[0] == params->Domain[1] || + params->Coords[2] < 0 || params->Coords[5] < 0) + return_error(gs_error_rangecheck); + code = check_CBFD((const gs_shading_params_t *)params, params->Function, params->Domain, 1); if (code < 0) return code; - if ((params->Domain != 0 && params->Domain[0] == params->Domain[1]) || - params->Coords[2] < 0 || params->Coords[5] < 0 - ) - return_error(gs_error_rangecheck); - ALLOC_SHADING(&st_shading_R, shading_type_Radial, - shading_R_procs, "gs_shading_R_init"); + ALLOC_SHADING(ppsh, psh, mem, &st_shading_R, shading_type_Radial, + shading_R_procs, "gs_shading_R_init", params); return 0; } @@ -308,8 +307,8 @@ return code; if (bpf < 0) return bpf; - ALLOC_SHADING(&st_shading_FfGt, shading_type_Free_form_Gouraud_triangle, - shading_FfGt_procs, "gs_shading_FfGt_init"); + ALLOC_SHADING(ppsh, psh, mem, &st_shading_FfGt, shading_type_Free_form_Gouraud_triangle, + shading_FfGt_procs, "gs_shading_FfGt_init", params); psh->params.BitsPerFlag = bpf; return 0; } @@ -341,8 +340,8 @@ return code; if (params->VerticesPerRow < 2) return_error(gs_error_rangecheck); - ALLOC_SHADING(&st_shading_LfGt, shading_type_Lattice_form_Gouraud_triangle, - shading_LfGt_procs, "gs_shading_LfGt_init"); + ALLOC_SHADING(ppsh, psh, mem, &st_shading_LfGt, shading_type_Lattice_form_Gouraud_triangle, + shading_LfGt_procs, "gs_shading_LfGt_init", params); return 0; } @@ -374,8 +373,8 @@ return code; if (bpf < 0) return bpf; - ALLOC_SHADING(&st_shading_Cp, shading_type_Coons_patch, - shading_Cp_procs, "gs_shading_Cp_init"); + ALLOC_SHADING(ppsh, psh, mem, &st_shading_Cp, shading_type_Coons_patch, + shading_Cp_procs, "gs_shading_Cp_init", params); psh->params.BitsPerFlag = bpf; return 0; } @@ -408,8 +407,8 @@ return code; if (bpf < 0) return bpf; - ALLOC_SHADING(&st_shading_Tpp, shading_type_Tensor_product_patch, - shading_Tpp_procs, "gs_shading_Tpp_init"); + ALLOC_SHADING(ppsh, psh, mem, &st_shading_Tpp, shading_type_Tensor_product_patch, + shading_Tpp_procs, "gs_shading_Tpp_init", params); psh->params.BitsPerFlag = bpf; return 0; } @@ -444,9 +443,9 @@ int gs_shading_do_fill_rectangle(const gs_shading_t *psh, const gs_fixed_rect *prect, gx_device *dev, - gs_imager_state *pis, bool fill_background) + gs_gstate *pgs, bool fill_background) { /* If you need to fill a path, clip the output device before calling this function. */ - const gs_matrix_fixed *pmat = &pis->ctm; + const gs_matrix_fixed *pmat = &pgs->ctm; gs_fixed_rect path_box; gs_rect path_rect; gs_rect rect; @@ -462,11 +461,12 @@ cc = *psh->params.Background; (*pcs->type->restrict_color)(&cc, pcs); - (*pcs->type->remap_color)(&cc, pcs, &dev_color, pis, - dev, gs_color_select_texture); + code = (*pcs->type->remap_color)(&cc, pcs, &dev_color, pgs, + dev, gs_color_select_texture); /****** WRONG IF NON-IDEMPOTENT RasterOp ******/ - code = gx_shade_background(dev, &path_box, &dev_color, pis->log_op); + if (code >= 0) + code = gx_shade_background(dev, &path_box, &dev_color, pgs->log_op); } if (code >= 0) { path_rect.p.x = fixed2float(path_box.p.x); @@ -474,7 +474,7 @@ path_rect.q.x = fixed2float(path_box.q.x); path_rect.q.y = fixed2float(path_box.q.y); gs_bbox_transform_inverse(&path_rect, (const gs_matrix *)pmat, &rect); - code = gs_shading_fill_rectangle(psh, &rect, &path_box, dev, pis); + code = gs_shading_fill_rectangle(psh, &rect, &path_box, dev, pgs); } return code; } diff -Nru ghostscript-9.10~dfsg/base/gsshade.h ghostscript-9.25~dfsg+1/base/gsshade.h --- ghostscript-9.10~dfsg/base/gsshade.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsshade.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -81,10 +81,10 @@ #define SHADING_FILL_RECTANGLE_PROC(proc)\ int proc(const gs_shading_t *psh, const gs_rect *prect,\ const gs_fixed_rect *prect_clip, gx_device *dev,\ - gs_imager_state *pis) + gs_gstate *pgs) typedef SHADING_FILL_RECTANGLE_PROC((*shading_fill_rectangle_proc_t)); -#define gs_shading_fill_rectangle(psh, prect, prect_clip, dev, pis)\ - ((psh)->head.procs.fill_rectangle(psh, prect, prect_clip, dev, pis)) +#define gs_shading_fill_rectangle(psh, prect, prect_clip, dev, pgs)\ + ((psh)->head.procs.fill_rectangle(psh, prect, prect_clip, dev, pgs)) /* Define the generic shading structures. */ typedef struct gs_shading_procs_s { @@ -164,10 +164,6 @@ gs_shading_mesh_params_t params; } gs_shading_mesh_t; -#define private_st_shading_mesh() /* in gsshade.c */\ - gs_private_st_composite(st_shading_mesh, gs_shading_mesh_t,\ - "gs_shading_mesh_t", shading_mesh_enum_ptrs, shading_mesh_reloc_ptrs) - /* Define Free-form Gouraud triangle mesh shading. */ typedef struct gs_shading_FfGt_params_s { gs_shading_mesh_params_common; @@ -262,7 +258,7 @@ /* Fill a rectangle with a shading. */ int gs_shading_do_fill_rectangle(const gs_shading_t *psh, const gs_fixed_rect *prect, gx_device *dev, - gs_imager_state *pis, bool fill_background); + gs_gstate *pgs, bool fill_background); /* Add a shading bbox to a path. */ int gs_shading_path_add_box(gx_path *ppath, const gs_rect *pbox, diff -Nru ghostscript-9.10~dfsg/base/gssprintf.c ghostscript-9.25~dfsg+1/base/gssprintf.c --- ghostscript-9.10~dfsg/base/gssprintf.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gssprintf.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,73 +1,1529 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* From: https://svn.apache.org/repos/asf/apr/apr/trunk/strings/apr_snprintf.c */ +/* Additional modifications to work outside Apache for use with Ghostscript */ - This software is provided AS-IS with no warranty, either express or - implied. +#include "stdio_.h" +#include "stdint_.h" +#include "string_.h" +#include +#include "math_.h" +#include - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. +#define APR_HAVE_IPV6 0 +#define APR_HAS_THREADS 0 - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ +#define FOR_GS 1 +#define apr_isalpha(c) isalpha(c) +#define apr_islower(c) islower(c) +#define apr_isdigit(c) isdigit(c) -/* Simple interface to a sprintf/sscanf without locale */ -#include "gssprintf.h" -#include "trio.h" -#include "triop.h" -#include "triodef.h" -#include "trionan.h" -#include "triostr.h" -int -gs_vsnprintf(char *buf, int n, const char *format, va_list ap) +typedef uint32_t apr_uint32_t; +typedef int32_t apr_int32_t; +typedef uint64_t apr_uint64_t; +typedef int64_t apr_int64_t; +typedef size_t apr_size_t; +typedef int64_t apr_off_t; + + +typedef struct apr_vformatter_buff_t apr_vformatter_buff_t; + +/** + * Structure used by the variable-formatter routines. + */ +struct apr_vformatter_buff_t { + /** The current position */ + char *curpos; + /** The end position of the format string */ + char *endpos; +}; + +typedef enum { + NO = 0, YES = 1 +} boolean_e; + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#define NUL '\0' + +#define APR_INT64_C(x) ((int64_t)x) +#define APR_UINT64_C(x) ((uint64_t)x) + +#define APR_INT16_MIN (-0x7fff - 1) +#define APR_INT16_MAX (0x7fff) +#define APR_UINT16_MAX (0xffff) +#define APR_INT32_MIN (-0x7fffffff - 1) +#define APR_INT32_MAX 0x7fffffff +#define APR_UINT32_MAX (0xffffffffU) +#define APR_INT64_MIN (APR_INT64_C(-0x7fffffffffffffff) - 1) +#define APR_INT64_MAX APR_INT64_C(0x7fffffffffffffff) +#define APR_UINT64_MAX APR_UINT64_C(0xffffffffffffffff) +#define APR_SIZE_MAX (~((apr_size_t)0)) + +#define APR_SIZEOF_VOIDP ARCH_SIZEOF_PTR + +#define APR_INT64_T_FMT PRId64 +#define APR_UINT64_T_FMT PRIu64 +#define APR_UINT64_T_HEX_FMT PRIx64 +#define APR_OFF_T_FMT PRId64 + +static const char null_string[] = "(null)"; +#define S_NULL ((char *)null_string) +#define S_NULL_LEN 6 + +#define FLOAT_DIGITS 6 +#define EXPONENT_LENGTH 10 + +/* + * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions + * + * NOTICE: this is a magic number; do not decrease it + */ +#define NUM_BUF_SIZE 512 + +/* + * cvt - IEEE floating point formatting routines. + * Derived from UNIX V7, Copyright(C) Caldera International Inc. + */ + +/* + * apr_ecvt converts to decimal + * the number of digits is specified by ndigit + * decpt is set to the position of the decimal point + * sign is set to 0 for positive, 1 for negative + */ + +#define NDIG 80 + +/* buf must have at least NDIG bytes */ +static char *apr_cvt(double arg, int ndigits, int *decpt, int *sign, + int eflag, char *buf) { - return(trio_vsnprintf(buf, n, format, ap)); + register int r2; + double fi, fj; + register char *p, *p1; + + if (ndigits >= NDIG - 1) + ndigits = NDIG - 2; + r2 = 0; + *sign = 0; + p = &buf[0]; + if (arg < 0) { + *sign = 1; + arg = -arg; + } + arg = modf(arg, &fi); + /* + * Do integer part + */ + if (fi != 0) { + p1 = &buf[NDIG]; + while (p1 > &buf[0] && fi != 0) { + fj = modf(fi / 10, &fi); + *--p1 = (int) ((fj + .03) * 10) + '0'; + r2++; + } + while (p1 < &buf[NDIG]) + *p++ = *p1++; + } + else if (arg > 0) { + while ((fj = arg * 10) < 1) { + arg = fj; + r2--; + } + } + p1 = &buf[ndigits]; + if (eflag == 0) + p1 += r2; + if (p1 < &buf[0]) { + *decpt = -ndigits; + buf[0] = '\0'; + return (buf); + } + *decpt = r2; + while (p <= p1 && p < &buf[NDIG]) { + arg *= 10; + arg = modf(arg, &fj); + *p++ = (int) fj + '0'; + } + if (p1 >= &buf[NDIG]) { + buf[NDIG - 1] = '\0'; + return (buf); + } + p = p1; + *p1 += 5; + while (*p1 > '9') { + *p1 = '0'; + if (p1 > buf) + ++ * --p1; + else { + *p1 = '1'; + (*decpt)++; + if (eflag == 0) { + if (p > buf) + *p = '0'; + p++; + } + } + } + *p = '\0'; + return (buf); } -int -gs_snprintf(char *buf, int n, const char *format, ...) +static char *apr_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf) { - int len; - va_list ap; + return (apr_cvt(arg, ndigits, decpt, sign, 1, buf)); +} - va_start(ap, format); - len = trio_vsnprintf(buf, n, format, ap); - va_end(ap); - return len; +static char *apr_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf) +{ + return (apr_cvt(arg, ndigits, decpt, sign, 0, buf)); +} + +/* + * apr_gcvt - Floating output conversion to + * minimal length string + */ + +static char *apr_gcvt(double number, int ndigit, char *buf, boolean_e altform) +{ + int sign, decpt; + register char *p1, *p2; + register int i; + char buf1[NDIG]; + int nd = ndigit; + double magn = number < 0 ? -number : number; + + p1 = apr_ecvt(number, ndigit, &decpt, &sign, buf1); + p2 = buf; + if (sign) + *p2++ = '-'; + for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--) + ndigit--; +#if !FOR_GS + if ((decpt >= 0 && decpt - ndigit > 4) + || (decpt < 0 && decpt < -3)) { /* use E-style */ +#else + if (magn != 0 && ((magn < (double)9.9999989999999991e-05) + || (magn >= pow(10, nd)))) { /* use E-style */ +#endif + decpt--; + *p2++ = *p1++; + + if (ndigit >= 2) + *p2++ = '.'; + for (i = 1; i < ndigit; i++) + *p2++ = *p1++; + *p2++ = 'e'; + if (decpt < 0) { + decpt = -decpt; + *p2++ = '-'; + } + else + *p2++ = '+'; + if (decpt / 100 > 0) + *p2++ = decpt / 100 + '0'; + +#if !FOR_GS /* We want the extra zero here so we get, for example, 2e+08 instead of 2e+8 */ + if (decpt / 10 > 0) +#endif + *p2++ = (decpt % 100) / 10 + '0'; + *p2++ = decpt % 10 + '0'; + } + else { + if (decpt <= 0) { + if (*p1 != '0') { + *p2++ = '0'; + *p2++ = '.'; + } + while (decpt < 0) { + decpt++; + *p2++ = '0'; + } + } + for (i = 1; i <= ndigit; i++) { + *p2++ = *p1++; + if (i == decpt) + *p2++ = '.'; + } + if (ndigit < decpt) { + while (ndigit++ < decpt) + *p2++ = '0'; + *p2++ = '.'; + } + } + if (p2[-1] == '.' && !altform) + p2--; + *p2 = '\0'; + return (buf); +} + +/* + * The INS_CHAR macro inserts a character in the buffer and writes + * the buffer back to disk if necessary + * It uses the char pointers sp and bep: + * sp points to the next available character in the buffer + * bep points to the end-of-buffer+1 + * While using this macro, note that the nextb pointer is NOT updated. + * + * NOTE: Evaluation of the c argument should not have any side-effects + */ +#define INS_CHAR(c, sp, bep, cc) \ +{ \ + if (sp) { \ + if (sp >= bep) { \ + vbuff->curpos = sp; \ + if (flush_func(vbuff)) \ + return -1; \ + sp = vbuff->curpos; \ + bep = vbuff->endpos; \ + } \ + *sp++ = (c); \ + } \ + cc++; \ +} + +#define NUM(c) (c - '0') + +#define STR_TO_DEC(str, num) \ + num = NUM(*str++); \ + while (apr_isdigit(*str)) \ + { \ + num *= 10 ; \ + num += NUM(*str++); \ + } + +/* + * This macro does zero padding so that the precision + * requirement is satisfied. The padding is done by + * adding '0's to the left of the string that is going + * to be printed. We don't allow precision to be large + * enough that we continue past the start of s. + * + * NOTE: this makes use of the magic info that s is + * always based on num_buf with a size of NUM_BUF_SIZE. + */ +#define FIX_PRECISION(adjust, precision, s, s_len) \ + if (adjust) { \ + apr_size_t p = (precision + 1 < NUM_BUF_SIZE) \ + ? precision : NUM_BUF_SIZE - 1; \ + while (s_len < p) \ + { \ + *--s = '0'; \ + s_len++; \ + } \ + } + +/* + * Macro that does padding. The padding is done by printing + * the character ch. + */ +#define PAD(width, len, ch) \ +do \ +{ \ + INS_CHAR(ch, sp, bep, cc); \ + width--; \ +} \ +while (width > len) + +/* + * Prefix the character ch to the string str + * Increase length + * Set the has_prefix flag + */ +#define PREFIX(str, length, ch) \ + *--str = ch; \ + length++; \ + has_prefix=YES; + + +/* + * Convert num to its decimal format. + * Return value: + * - a pointer to a string containing the number (no sign) + * - len contains the length of the string + * - is_negative is set to TRUE or FALSE depending on the sign + * of the number (always set to FALSE if is_unsigned is TRUE) + * + * The caller provides a buffer for the string: that is the buf_end argument + * which is a pointer to the END of the buffer + 1 (i.e. if the buffer + * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * Note: we have 2 versions. One is used when we need to use quads + * (conv_10_quad), the other when we don't (conv_10). We're assuming the + * latter is faster. + */ +static char *conv_10(register apr_int32_t num, register int is_unsigned, + register int *is_negative, char *buf_end, + register apr_size_t *len) +{ + register char *p = buf_end; + register apr_uint32_t magnitude = num; + + if (is_unsigned) { + *is_negative = FALSE; + } + else { + *is_negative = (num < 0); + + /* + * On a 2's complement machine, negating the most negative integer + * results in a number that cannot be represented as a signed integer. + * Here is what we do to obtain the number's magnitude: + * a. add 1 to the number + * b. negate it (becomes positive) + * c. convert it to unsigned + * d. add 1 + */ + if (*is_negative) { + apr_int32_t t = num + 1; + magnitude = ((apr_uint32_t) -t) + 1; + } + } + + /* + * We use a do-while loop so that we write at least 1 digit + */ + do { + register apr_uint32_t new_magnitude = magnitude / 10; + + *--p = (char) (magnitude - new_magnitude * 10 + '0'); + magnitude = new_magnitude; + } + while (magnitude); + + *len = buf_end - p; + return (p); } -int -gs_vsprintf(char *buf, const char *format, va_list ap) +static char *conv_10_quad(apr_int64_t num, register int is_unsigned, + register int *is_negative, char *buf_end, + register apr_size_t *len) { - return(trio_vsprintf(buf, format, ap)); + register char *p = buf_end; + apr_uint64_t magnitude = num; + + /* + * We see if we can use the faster non-quad version by checking the + * number against the largest long value it can be. If <=, we + * punt to the quicker version. + */ + if ((magnitude <= APR_UINT32_MAX && is_unsigned) + || (num <= APR_INT32_MAX && num >= APR_INT32_MIN && !is_unsigned)) + return(conv_10((apr_int32_t)num, is_unsigned, is_negative, buf_end, len)); + + if (is_unsigned) { + *is_negative = FALSE; + } + else { + *is_negative = (num < 0); + + /* + * On a 2's complement machine, negating the most negative integer + * results in a number that cannot be represented as a signed integer. + * Here is what we do to obtain the number's magnitude: + * a. add 1 to the number + * b. negate it (becomes positive) + * c. convert it to unsigned + * d. add 1 + */ + if (*is_negative) { + apr_int64_t t = num + 1; + magnitude = ((apr_uint64_t) -t) + 1; + } + } + + /* + * We use a do-while loop so that we write at least 1 digit + */ + do { + apr_uint64_t new_magnitude = magnitude / 10; + + *--p = (char) (magnitude - new_magnitude * 10 + '0'); + magnitude = new_magnitude; + } + while (magnitude); + + *len = buf_end - p; + return (p); +} + +#if !FOR_GS +static char *conv_in_addr(struct in_addr *ia, char *buf_end, apr_size_t *len) +{ + unsigned addr = ntohl(ia->s_addr); + char *p = buf_end; + int is_negative; + apr_size_t sub_len; + + p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len); + *--p = '.'; + p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len); + *--p = '.'; + p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len); + *--p = '.'; + p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len); + + *len = buf_end - p; + return (p); +} + +/* Must be passed a buffer of size NUM_BUF_SIZE where buf_end points + * to 1 byte past the end of the buffer. */ +static char *conv_apr_sockaddr(apr_sockaddr_t *sa, char *buf_end, apr_size_t *len) +{ + char *p = buf_end; + int is_negative; + apr_size_t sub_len; + char *ipaddr_str; + + p = conv_10(sa->port, TRUE, &is_negative, p, &sub_len); + *--p = ':'; + ipaddr_str = buf_end - NUM_BUF_SIZE; + if (apr_sockaddr_ip_getbuf(ipaddr_str, sa->addr_str_len, sa)) { + /* Should only fail if the buffer is too small, which it + * should not be; but fail safe anyway: */ + *--p = '?'; + *len = buf_end - p; + return p; + } + sub_len = strlen(ipaddr_str); +#if APR_HAVE_IPV6 + if (sa->family == APR_INET6 && + !IN6_IS_ADDR_V4MAPPED(&sa->sa.sin6.sin6_addr)) { + *(p - 1) = ']'; + p -= sub_len + 2; + *p = '['; + memcpy(p + 1, ipaddr_str, sub_len); + } + else +#endif + { + p -= sub_len; + memcpy(p, ipaddr_str, sub_len); + } + + *len = buf_end - p; + return (p); +} +#endif + + + +#if APR_HAS_THREADS +static char *conv_os_thread_t(apr_os_thread_t *tid, char *buf_end, apr_size_t *len) +{ + union { + apr_os_thread_t tid; + apr_uint64_t u64; + apr_uint32_t u32; + } u; + int is_negative; + + u.tid = *tid; + switch(sizeof(u.tid)) { + case sizeof(apr_int32_t): + return conv_10(u.u32, TRUE, &is_negative, buf_end, len); + case sizeof(apr_int64_t): + return conv_10_quad(u.u64, TRUE, &is_negative, buf_end, len); + default: + /* not implemented; stick 0 in the buffer */ + return conv_10(0, TRUE, &is_negative, buf_end, len); + } } +#endif -int -gs_sprintf(char *buf, const char *format, ...) + + +/* + * Convert a floating point number to a string formats 'f', 'e' or 'E'. + * The result is placed in buf, and len denotes the length of the string + * The sign is returned in the is_negative argument (and is not placed + * in buf). + */ +static char *conv_fp(register char format, register double num, + boolean_e add_dp, int precision, int *is_negative, + char *buf, apr_size_t *len) +{ + register char *s = buf; + register char *p; + int decimal_point; + char buf1[NDIG]; + + if (format == 'f') + p = apr_fcvt(num, precision, &decimal_point, is_negative, buf1); + else /* either e or E format */ + p = apr_ecvt(num, precision + 1, &decimal_point, is_negative, buf1); + + /* + * Check for Infinity and NaN + */ + if (apr_isalpha(*p)) { + *len = strlen(p); + memcpy(buf, p, *len + 1); + *is_negative = FALSE; + return (buf); + } + + if (format == 'f') { + if (decimal_point <= 0) { + *s++ = '0'; + if (precision > 0) { + *s++ = '.'; + while (decimal_point++ < 0) + *s++ = '0'; + } + else if (add_dp) + *s++ = '.'; + } + else { + while (decimal_point-- > 0) + *s++ = *p++; + if (precision > 0 || add_dp) + *s++ = '.'; + } + } + else { + *s++ = *p++; + if (precision > 0 || add_dp) + *s++ = '.'; + } + + /* + * copy the rest of p, the NUL is NOT copied + */ + while (*p) + *s++ = *p++; + + if (format != 'f') { + char temp[EXPONENT_LENGTH]; /* for exponent conversion */ + apr_size_t t_len; + int exponent_is_negative; + + *s++ = format; /* either e or E */ + decimal_point--; + if (decimal_point != 0) { + p = conv_10((apr_int32_t) decimal_point, FALSE, &exponent_is_negative, + &temp[EXPONENT_LENGTH], &t_len); + *s++ = exponent_is_negative ? '-' : '+'; + + /* + * Make sure the exponent has at least 2 digits + */ + if (t_len == 1) + *s++ = '0'; + while (t_len--) + *s++ = *p++; + } + else { + *s++ = '+'; + *s++ = '0'; + *s++ = '0'; + } + } + + *len = s - buf; + return (buf); +} + + +/* + * Convert num to a base X number where X is a power of 2. nbits determines X. + * For example, if nbits is 3, we do base 8 conversion + * Return value: + * a pointer to a string containing the number + * + * The caller provides a buffer for the string: that is the buf_end argument + * which is a pointer to the END of the buffer + 1 (i.e. if the buffer + * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * As with conv_10, we have a faster version which is used when + * the number isn't quad size. + */ +static char *conv_p2(register apr_uint32_t num, register int nbits, + char format, char *buf_end, register apr_size_t *len) { - int len; + register int mask = (1 << nbits) - 1; + register char *p = buf_end; + static const char low_digits[] = "0123456789abcdef"; + static const char upper_digits[] = "0123456789ABCDEF"; + register const char *digits = (format == 'X') ? upper_digits : low_digits; + + do { + *--p = digits[num & mask]; + num >>= nbits; + } + while (num); + + *len = buf_end - p; + return (p); +} + +static char *conv_p2_quad(apr_uint64_t num, register int nbits, + char format, char *buf_end, register apr_size_t *len) +{ + register int mask = (1 << nbits) - 1; + register char *p = buf_end; + static const char low_digits[] = "0123456789abcdef"; + static const char upper_digits[] = "0123456789ABCDEF"; + register const char *digits = (format == 'X') ? upper_digits : low_digits; + + if (num <= APR_UINT32_MAX) + return(conv_p2((apr_uint32_t)num, nbits, format, buf_end, len)); + + do { + *--p = digits[num & mask]; + num >>= nbits; + } + while (num); + + *len = buf_end - p; + return (p); +} + +#if APR_HAS_THREADS +static char *conv_os_thread_t_hex(apr_os_thread_t *tid, char *buf_end, apr_size_t *len) +{ + union { + apr_os_thread_t tid; + apr_uint64_t u64; + apr_uint32_t u32; + } u; + int is_negative; + + u.tid = *tid; + switch(sizeof(u.tid)) { + case sizeof(apr_int32_t): + return conv_p2(u.u32, 4, 'x', buf_end, len); + case sizeof(apr_int64_t): + return conv_p2_quad(u.u64, 4, 'x', buf_end, len); + default: + /* not implemented; stick 0 in the buffer */ + return conv_10(0, TRUE, &is_negative, buf_end, len); + } +} +#endif + +/* + * Do format conversion placing the output in buffer + */ +static int apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *), + apr_vformatter_buff_t *vbuff, const char *fmt, va_list ap) +{ + register char *sp; + register char *bep; + register int cc = 0; + register apr_size_t i; + + register char *s = NULL; + char *q; + apr_size_t s_len = 0; + + register apr_size_t min_width = 0; + apr_size_t precision = 0; + enum { + LEFT, RIGHT + } adjust; + char pad_char; + char prefix_char; + + double fp_num; + apr_int64_t i_quad = 0; + apr_uint64_t ui_quad; + apr_int32_t i_num = 0; + apr_uint32_t ui_num = 0; + + char num_buf[NUM_BUF_SIZE]; + char char_buf[2]; /* for printing %% and % */ + char inf[] = "#INF"; + char nan[] = "#NAN"; + + enum var_type_enum { + IS_QUAD, IS_LONG, IS_SHORT, IS_INT + }; + enum var_type_enum var_type = IS_INT; + + /* + * Flag variables + */ + boolean_e alternate_form; + boolean_e print_sign; + boolean_e print_blank; + boolean_e adjust_precision; + boolean_e adjust_width; + int is_negative; + + sp = vbuff->curpos; + bep = vbuff->endpos; + + while (*fmt) { + if (*fmt != '%') { + INS_CHAR(*fmt, sp, bep, cc); + } + else { + /* + * Default variable settings + */ + boolean_e print_something = YES; + adjust = RIGHT; + alternate_form = print_sign = print_blank = NO; + pad_char = ' '; + prefix_char = NUL; + + fmt++; + + /* + * Try to avoid checking for flags, width or precision + */ + if (!apr_islower(*fmt)) { + /* + * Recognize flags: -, #, BLANK, + + */ + for (;; fmt++) { + if (*fmt == '-') + adjust = LEFT; + else if (*fmt == '+') + print_sign = YES; + else if (*fmt == '#') + alternate_form = YES; + else if (*fmt == ' ') + print_blank = YES; + else if (*fmt == '0') + pad_char = '0'; + else + break; + } + + /* + * Check if a width was specified + */ + if (apr_isdigit(*fmt)) { + STR_TO_DEC(fmt, min_width); + adjust_width = YES; + } + else if (*fmt == '*') { + int v = va_arg(ap, int); + fmt++; + adjust_width = YES; + if (v < 0) { + adjust = LEFT; + min_width = (apr_size_t)(-v); + } + else + min_width = (apr_size_t)v; + } + else + adjust_width = NO; + + /* + * Check if a precision was specified + */ + if (*fmt == '.') { + adjust_precision = YES; + fmt++; + if (apr_isdigit(*fmt)) { + STR_TO_DEC(fmt, precision); + } + else if (*fmt == '*') { + int v = va_arg(ap, int); + fmt++; + precision = (v < 0) ? 0 : (apr_size_t)v; + } + else + precision = 0; + } + else + adjust_precision = NO; + } + else + adjust_precision = adjust_width = NO; + + /* + * Modifier check. In same cases, APR_OFF_T_FMT can be + * "lld" and APR_INT64_T_FMT can be "ld" (that is, off_t is + * "larger" than int64). Check that case 1st. + * Note that if APR_OFF_T_FMT is "d", + * the first if condition is never true. If APR_INT64_T_FMT + * is "d' then the second if condition is never true. + */ + if ((sizeof(APR_OFF_T_FMT) > sizeof(APR_INT64_T_FMT)) && + ((sizeof(APR_OFF_T_FMT) == 4 && + fmt[0] == APR_OFF_T_FMT[0] && + fmt[1] == APR_OFF_T_FMT[1]) || + (sizeof(APR_OFF_T_FMT) == 3 && + fmt[0] == APR_OFF_T_FMT[0]) || + (sizeof(APR_OFF_T_FMT) > 4 && + strncmp(fmt, APR_OFF_T_FMT, + sizeof(APR_OFF_T_FMT) - 2) == 0))) { + /* Need to account for trailing 'd' and null in sizeof() */ + var_type = IS_QUAD; + fmt += (sizeof(APR_OFF_T_FMT) - 2); + } + else if ((sizeof(APR_INT64_T_FMT) == 4 && + fmt[0] == APR_INT64_T_FMT[0] && + fmt[1] == APR_INT64_T_FMT[1]) || + (sizeof(APR_INT64_T_FMT) == 3 && + fmt[0] == APR_INT64_T_FMT[0]) || + (sizeof(APR_INT64_T_FMT) > 4 && + strncmp(fmt, APR_INT64_T_FMT, + sizeof(APR_INT64_T_FMT) - 2) == 0)) { + /* Need to account for trailing 'd' and null in sizeof() */ + var_type = IS_QUAD; + fmt += (sizeof(APR_INT64_T_FMT) - 2); + } + else if (*fmt == 'q') { + var_type = IS_QUAD; + fmt++; + } + else if (*fmt == 'l') { + var_type = IS_LONG; + fmt++; + } + else if (*fmt == 'h') { + var_type = IS_SHORT; + fmt++; + } + else { + var_type = IS_INT; + } + + /* + * Argument extraction and printing. + * First we determine the argument type. + * Then, we convert the argument to a string. + * On exit from the switch, s points to the string that + * must be printed, s_len has the length of the string + * The precision requirements, if any, are reflected in s_len. + * + * NOTE: pad_char may be set to '0' because of the 0 flag. + * It is reset to ' ' by non-numeric formats + */ + switch (*fmt) { + case 'u': + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, apr_uint64_t); + s = conv_10_quad(i_quad, 1, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = (apr_int32_t) va_arg(ap, apr_uint32_t); + else if (var_type == IS_SHORT) + i_num = (apr_int32_t) (unsigned short) va_arg(ap, unsigned int); + else + i_num = (apr_int32_t) va_arg(ap, unsigned int); + s = conv_10(i_num, 1, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + break; + + case 'd': + case 'i': + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, apr_int64_t); + s = conv_10_quad(i_quad, 0, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = va_arg(ap, apr_int32_t); + else if (var_type == IS_SHORT) + i_num = (short) va_arg(ap, int); + else + i_num = va_arg(ap, int); + s = conv_10(i_num, 0, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + + if (is_negative) + prefix_char = '-'; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + break; + + + case 'o': + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, apr_uint64_t); + s = conv_p2_quad(ui_quad, 3, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = va_arg(ap, apr_uint32_t); + else if (var_type == IS_SHORT) + ui_num = (unsigned short) va_arg(ap, unsigned int); + else + ui_num = va_arg(ap, unsigned int); + s = conv_p2(ui_num, 3, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && *s != '0') { + *--s = '0'; + s_len++; + } + break; + + + case 'x': + case 'X': + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, apr_uint64_t); + s = conv_p2_quad(ui_quad, 4, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = va_arg(ap, apr_uint32_t); + else if (var_type == IS_SHORT) + ui_num = (unsigned short) va_arg(ap, unsigned int); + else + ui_num = va_arg(ap, unsigned int); + s = conv_p2(ui_num, 4, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + FIX_PRECISION(adjust_precision, precision, s, s_len); + if (alternate_form && ui_num != 0) { + *--s = *fmt; /* 'x' or 'X' */ + *--s = '0'; + s_len += 2; + } + break; + + + case 's': + s = va_arg(ap, char *); + if (s != NULL) { + if (!adjust_precision) { + s_len = strlen(s); + } + else { + /* From the C library standard in section 7.9.6.1: + * ...if the precision is specified, no more then + * that many characters are written. If the + * precision is not specified or is greater + * than the size of the array, the array shall + * contain a null character. + * + * My reading is is precision is specified and + * is less then or equal to the size of the + * array, no null character is required. So + * we can't do a strlen. + * + * This figures out the length of the string + * up to the precision. Once it's long enough + * for the specified precision, we don't care + * anymore. + * + * NOTE: you must do the length comparison + * before the check for the null character. + * Otherwise, you'll check one beyond the + * last valid character. + */ + const char *walk; + + for (walk = s, s_len = 0; + (s_len < precision) && (*walk != '\0'); + ++walk, ++s_len); + } + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + break; + + + case 'f': + case 'e': + case 'E': + fp_num = va_arg(ap, double); + /* + * We use &num_buf[ 1 ], so that we have room for the sign + */ + s = NULL; +#ifdef HAVE_ISNAN + if (isnan(fp_num)) { + s = nan; + s_len = strlen(nan); + } +#endif +#ifdef HAVE_ISINF + if (!s && isinf(fp_num)) { + s = inf; + s_len = strlen(inf); + } +#endif + if (!s) { + s = conv_fp(*fmt, fp_num, alternate_form, + (int)((adjust_precision == NO) ? FLOAT_DIGITS : precision), + &is_negative, &num_buf[1], &s_len); + if (is_negative) + prefix_char = '-'; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + } + break; + + + case 'g': + case 'G': + fp_num = va_arg(ap, double); + s = NULL; +#ifdef HAVE_ISNAN + if (isnan(fp_num)) { + s = nan; + s_len = strlen(nan); + } +#endif +#ifdef HAVE_ISINF + if (!s && isinf(fp_num)) { + s = inf; + s_len = strlen(inf); + } +#endif + if (!s) { + if (adjust_precision == NO) + precision = FLOAT_DIGITS; + else if (precision == 0) + precision = 1; + /* + * * We use &num_buf[ 1 ], so that we have room for the sign + */ + s = apr_gcvt(fp_num, (int) precision, &num_buf[1], + alternate_form); + if (*s == '-') + prefix_char = *s++; + else if (print_sign) + prefix_char = '+'; + else if (print_blank) + prefix_char = ' '; + + s_len = strlen(s); + + if (alternate_form && (q = strchr(s, '.')) == NULL) { + s[s_len++] = '.'; + s[s_len] = '\0'; /* delimit for following strchr() */ + } + if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL) + *q = 'E'; + } + break; + + + case 'c': + char_buf[0] = (char) (va_arg(ap, int)); + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case '%': + char_buf[0] = '%'; + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; + break; + + + case 'n': + if (var_type == IS_QUAD) + *(va_arg(ap, apr_int64_t *)) = cc; + else if (var_type == IS_LONG) + *(va_arg(ap, long *)) = cc; + else if (var_type == IS_SHORT) + *(va_arg(ap, short *)) = cc; + else + *(va_arg(ap, int *)) = cc; + print_something = NO; + break; + + /* + * This is where we extend the printf format, with a second + * type specifier + */ + case 'p': + switch(*++fmt) { + /* + * If the pointer size is equal to or smaller than the size + * of the largest unsigned int, we convert the pointer to a + * hex number, otherwise we print "%p" to indicate that we + * don't handle "%p". + */ + case 'p': +#if APR_SIZEOF_VOIDP == 8 + if (sizeof(void *) <= sizeof(apr_uint64_t)) { + ui_quad = (apr_uint64_t) va_arg(ap, void *); + s = conv_p2_quad(ui_quad, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#else + if (sizeof(void *) <= sizeof(apr_uint32_t)) { + ui_num = (apr_uint32_t) va_arg(ap, void *); + s = conv_p2(ui_num, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#endif + else { + s = (char *)"%p"; + s_len = 2; + prefix_char = NUL; + } + pad_char = ' '; + break; + +#if !FOR_GS + /* print an apr_sockaddr_t as a.b.c.d:port */ + case 'I': + { + apr_sockaddr_t *sa; + + sa = va_arg(ap, apr_sockaddr_t *); + if (sa != NULL) { + s = conv_apr_sockaddr(sa, &num_buf[NUM_BUF_SIZE], &s_len); + if (adjust_precision && precision < s_len) + s_len = precision; + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } + break; + + /* print a struct in_addr as a.b.c.d */ + case 'A': + { + struct in_addr *ia; + + ia = va_arg(ap, struct in_addr *); + if (ia != NULL) { + s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len); + if (adjust_precision && precision < s_len) + s_len = precision; + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } + break; + + /* print the error for an apr_status_t */ + case 'm': + { + apr_status_t *mrv; + + mrv = va_arg(ap, apr_status_t *); + if (mrv != NULL) { + s = apr_strerror(*mrv, num_buf, NUM_BUF_SIZE-1); + s_len = strlen(s); + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } + break; +#endif + + case 'T': +#if APR_HAS_THREADS + { + apr_os_thread_t *tid; + + tid = va_arg(ap, apr_os_thread_t *); + if (tid != NULL) { + s = conv_os_thread_t(tid, &num_buf[NUM_BUF_SIZE], &s_len); + if (adjust_precision && precision < s_len) + s_len = precision; + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } +#else + char_buf[0] = '0'; + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; +#endif + break; + + case 't': +#if APR_HAS_THREADS + { + apr_os_thread_t *tid; + + tid = va_arg(ap, apr_os_thread_t *); + if (tid != NULL) { + s = conv_os_thread_t_hex(tid, &num_buf[NUM_BUF_SIZE], &s_len); + if (adjust_precision && precision < s_len) + s_len = precision; + } + else { + s = S_NULL; + s_len = S_NULL_LEN; + } + pad_char = ' '; + } +#else + char_buf[0] = '0'; + s = &char_buf[0]; + s_len = 1; + pad_char = ' '; +#endif + break; + +#if !FOR_GS + case 'B': + case 'F': + case 'S': + { + char buf[5]; + apr_off_t size = 0; + + if (*fmt == 'B') { + apr_uint32_t *arg = va_arg(ap, apr_uint32_t *); + size = (arg) ? *arg : 0; + } + else if (*fmt == 'F') { + apr_off_t *arg = va_arg(ap, apr_off_t *); + size = (arg) ? *arg : 0; + } + else { + apr_size_t *arg = va_arg(ap, apr_size_t *); + size = (arg) ? *arg : 0; + } + + s = apr_strfsize(size, buf); + s_len = strlen(s); + pad_char = ' '; + } + break; +#endif + + case NUL: + /* if %p ends the string, treat it as pointer */ +#if APR_SIZEOF_VOIDP == 8 + if (sizeof(void *) <= sizeof(apr_uint64_t)) { + ui_quad = (apr_uint64_t) va_arg(ap, void *); + s = conv_p2_quad(ui_quad, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#else + if (sizeof(void *) <= sizeof(apr_uint32_t)) { + ui_num = (apr_uint32_t) va_arg(ap, void *); + s = conv_p2(ui_num, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#endif + else { + s = (char *)"%p"; + s_len = 2; + prefix_char = NUL; + } + pad_char = ' '; + fmt--; + break; + + default: + s = (char *)"bogus %p"; + s_len = 8; + prefix_char = NUL; + (void)va_arg(ap, void *); /* skip the bogus argument on the stack */ + break; + } + break; + + case NUL: + /* + * The last character of the format string was %. + * We ignore it. + */ + continue; + + + /* + * The default case is for unrecognized %'s. + * We print % to help the user identify what + * option is not understood. + * This is also useful in case the user wants to pass + * the output of format_converter to another function + * that understands some other % (like syslog). + * Note that we can't point s inside fmt because the + * unknown could be preceded by width etc. + */ + default: + char_buf[0] = '%'; + char_buf[1] = *fmt; + s = char_buf; + s_len = 2; + pad_char = ' '; + break; + } + + if (prefix_char != NUL && s != S_NULL && s != char_buf) { + *--s = prefix_char; + s_len++; + } + + if (adjust_width && adjust == RIGHT && min_width > s_len) { + if (pad_char == '0' && prefix_char != NUL) { + INS_CHAR(*s, sp, bep, cc); + s++; + s_len--; + min_width--; + } + PAD(min_width, s_len, pad_char); + } + + /* + * Print the string s. + */ + if (print_something == YES) { + for (i = s_len; i != 0; i--) { + INS_CHAR(*s, sp, bep, cc); + s++; + } + } + + if (adjust_width && adjust == LEFT && min_width > s_len) + PAD(min_width, s_len, pad_char); + } + fmt++; + } + vbuff->curpos = sp; + + return cc; +} + + +static int snprintf_flush(apr_vformatter_buff_t *vbuff) +{ + /* if the buffer fills we have to abort immediately, there is no way + * to "flush" an apr_snprintf... there's nowhere to flush it to. + */ + return -1; +} + +int gs_snprintf(char *buf, int len, + const char *format, ...) +{ + int cc; va_list ap; + apr_vformatter_buff_t vbuff; + if (len == 0) { + /* NOTE: This is a special case; we just want to return the number + * of chars that would be written (minus \0) if the buffer + * size was infinite. We leverage the fact that INS_CHAR + * just does actual inserts iff the buffer pointer is non-NULL. + * In this case, we don't care what buf is; it can be NULL, since + * we don't touch it at all. + */ + vbuff.curpos = NULL; + vbuff.endpos = NULL; + } else { + /* save one byte for nul terminator */ + vbuff.curpos = buf; + vbuff.endpos = buf + len - 1; + } va_start(ap, format); - len = trio_vsprintf(buf, format, ap); + cc = apr_vformatter(snprintf_flush, &vbuff, format, ap); va_end(ap); - - return(len); + if (len != 0) { + *vbuff.curpos = '\0'; + } + return (cc == -1) ? (int)len - 1 : cc; } -int -gs_sscanf(char *buf, const char *format, ...) +int gs_sprintf(char *buf, const char *format, ...) { - int len; + int cc; va_list ap; + apr_vformatter_buff_t vbuff; + + /* save one byte for nul terminator */ + vbuff.curpos = buf; + vbuff.endpos = buf + NUM_BUF_SIZE - 1; va_start(ap, format); - len = trio_vsscanf(buf, format, ap); + cc = apr_vformatter(snprintf_flush, &vbuff, format, ap); va_end(ap); + *vbuff.curpos = '\0'; + + return cc; +} + + +int gs_vsnprintf(char *buf, int len, const char *format, + va_list ap) +{ + int cc; + apr_vformatter_buff_t vbuff; + + if (len == 0) { + /* See above note */ + vbuff.curpos = NULL; + vbuff.endpos = NULL; + } else { + /* save one byte for nul terminator */ + vbuff.curpos = buf; + vbuff.endpos = buf + len - 1; + } + cc = apr_vformatter(snprintf_flush, &vbuff, format, ap); + if (len != 0) { + *vbuff.curpos = '\0'; + } + + return (cc == -1) ? (int)len - 1 : cc; +} + +int gs_vsprintf(char *buf, const char *format, va_list ap) +{ + int cc; + apr_vformatter_buff_t vbuff; + + /* save one byte for nul terminator */ + vbuff.curpos = buf; + vbuff.endpos = buf + NUM_BUF_SIZE - 1; + + cc = apr_vformatter(snprintf_flush, &vbuff, format, ap); + *vbuff.curpos = '\0'; - return(len); + return cc; } diff -Nru ghostscript-9.10~dfsg/base/gssprintf.h ghostscript-9.25~dfsg+1/base/gssprintf.h --- ghostscript-9.10~dfsg/base/gssprintf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gssprintf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ #ifndef gssprintf_INCLUDED diff -Nru ghostscript-9.10~dfsg/base/gsstate.c ghostscript-9.25~dfsg+1/base/gsstate.c --- ghostscript-9.10~dfsg/base/gsstate.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstate.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -41,13 +41,13 @@ #include "gsicc_manage.h" /* Forward references */ -static gs_state *gstate_alloc(gs_memory_t *, client_name_t, - const gs_state *); -static gs_state *gstate_clone(gs_state *, gs_memory_t *, client_name_t, - gs_state_copy_reason_t); -static void gstate_free_contents(gs_state *); -static int gstate_copy(gs_state *, const gs_state *, - gs_state_copy_reason_t, client_name_t); +static gs_gstate *gstate_alloc(gs_memory_t *, client_name_t, + const gs_gstate *); +static gs_gstate *gstate_clone(gs_gstate *, gs_memory_t *, client_name_t, + gs_gstate_copy_reason_t); +static void gstate_free_contents(gs_gstate *); +static int gstate_copy(gs_gstate *, const gs_gstate *, + gs_gstate_copy_reason_t, client_name_t); static void clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t cname); /* @@ -137,7 +137,7 @@ * individually for each state, except for line_params.dash.pattern. * Note that effective_clip_shared is not on the list. */ -typedef struct gs_state_parts_s { +typedef struct gs_gstate_parts_s { gx_path *path; gx_clip_path *clip_path; gx_clip_path *effective_clip_path; @@ -145,7 +145,7 @@ gs_client_color *ccolor; gx_device_color *dev_color; } color[2]; -} gs_state_parts; +} gs_gstate_parts; #define GSTATE_ASSIGN_PARTS(pto, pfrom)\ ((pto)->path = (pfrom)->path, (pto)->clip_path = (pfrom)->clip_path,\ @@ -155,39 +155,13 @@ (pto)->color[1].ccolor = (pfrom)->color[1].ccolor,\ (pto)->color[1].dev_color = (pfrom)->color[1].dev_color) -/* GC descriptors */ -extern_st(st_imager_state); -public_st_gs_state(); - -/* GC procedures for gs_state */ -static ENUM_PTRS_WITH(gs_state_enum_ptrs, gs_state *gsvptr) -ENUM_PREFIX(st_imager_state, gs_state_num_ptrs + 2); -#define e1(i,elt) ENUM_PTR(i,gs_state,elt); -gs_state_do_ptrs(e1) -case gs_state_num_ptrs: /* handle device specially */ -ENUM_RETURN(gx_device_enum_ptr(gsvptr->device)); -case gs_state_num_ptrs + 1: /* handle device filter stack specially */ -ENUM_RETURN(gsvptr->dfilter_stack); -#undef e1 -ENUM_PTRS_END -static RELOC_PTRS_WITH(gs_state_reloc_ptrs, gs_state *gsvptr) -{ - RELOC_PREFIX(st_imager_state); - { -#define r1(i,elt) RELOC_PTR(gs_state,elt); - gs_state_do_ptrs(r1) -#undef r1 - gsvptr->device = gx_device_reloc_ptr(gsvptr->device, gcst); - RELOC_PTR(gs_state, dfilter_stack); - } -} -RELOC_PTRS_END +extern_st(st_gs_gstate); /* for gstate_alloc() */ /* Copy client data, using the copy_for procedure if available, */ /* the copy procedure otherwise. */ static int -gstate_copy_client_data(gs_state * pgs, void *dto, void *dfrom, - gs_state_copy_reason_t reason) +gstate_copy_client_data(gs_gstate * pgs, void *dto, void *dfrom, + gs_gstate_copy_reason_t reason) { return (pgs->client_procs.copy_for != 0 ? (*pgs->client_procs.copy_for) (dto, dfrom, reason) : @@ -196,11 +170,6 @@ /* ------ Operations on the entire graphics state ------ */ -/* Define the initial value of the graphics state. */ -static const gs_imager_state gstate_initial = { - gs_imager_state_initial(1.0, true) /* is_gstate == true */ -}; - /* * Allocate a path for the graphics state. We use stable memory because * some PostScript files have Type 3 fonts whose BuildChar procedure @@ -215,72 +184,50 @@ } /* Allocate and initialize a graphics state. */ -gs_state * -gs_state_alloc(gs_memory_t * mem) +gs_gstate * +gs_gstate_alloc(gs_memory_t * mem) { - gs_state *pgs = gstate_alloc(mem, "gs_state_alloc", NULL); + gs_gstate *pgs = gstate_alloc(mem, "gs_gstate_alloc", NULL); + gs_memory_t *path_mem = gstate_path_memory(mem); int code; if (pgs == 0) return 0; - *(gs_imager_state *)pgs = gstate_initial; /* this sets is_gstate == true */ - /* Need to set up at least enough to make gs_state_free happy */ + GS_STATE_INIT_VALUES(pgs, 1.0); + /* Need to set up at least enough to make gs_gstate_free happy */ pgs->saved = 0; - pgs->path = NULL; - pgs->clip_path = NULL; pgs->clip_stack = NULL; pgs->view_clip = NULL; - pgs->effective_clip_path = NULL; pgs->font = NULL; pgs->root_font = NULL; pgs->show_gstate = NULL; pgs->device = NULL; - pgs->dfilter_stack = NULL; /* * Just enough of the state is initialized at this point - * that it's OK to call gs_state_free if an allocation fails. + * that it's OK to call gs_gstate_free if an allocation fails. */ - code = gs_imager_state_initialize((gs_imager_state *) pgs, mem); + code = gs_gstate_initialize(pgs, mem); if (code < 0) goto fail; /* Finish initializing the color rendering state. */ rc_alloc_struct_1(pgs->halftone, gs_halftone, &st_halftone, mem, - goto fail, "gs_state_alloc(halftone)"); + goto fail, "gs_gstate_alloc(halftone)"); pgs->halftone->type = ht_type_none; /* Initialize other things not covered by initgraphics */ - pgs->path = gx_path_alloc(gstate_path_memory(mem), "gs_state_alloc(path)"); - pgs->clip_path = gx_cpath_alloc(mem, "gs_state_alloc(clip_path)"); pgs->clip_stack = 0; - pgs->view_clip = gx_cpath_alloc(mem, "gs_state_alloc(view_clip)"); + pgs->view_clip = gx_cpath_alloc(path_mem, "gs_gstate_alloc(view_clip)"); if (pgs->view_clip == NULL) goto fail; pgs->view_clip->rule = 0; /* no clipping */ pgs->effective_clip_id = pgs->clip_path->id; pgs->effective_view_clip_id = gs_no_id; - pgs->effective_clip_path = pgs->clip_path; - pgs->effective_clip_shared = true; - /* Initialize things so that gx_remap_color won't crash. */ - pgs->color[0].color_space = gs_cspace_new_DeviceGray(pgs->memory); - if (pgs->color[0].color_space == NULL) - goto fail; - pgs->color[1].color_space = gs_cspace_new_DeviceGray(pgs->memory); - if (pgs->color[1].color_space == NULL) - goto fail; pgs->in_cachedevice = 0; - gs_swapcolors_quick(pgs); /* To color 1 */ - code = gx_set_device_color_1(pgs); /* sets colorspace and client color */ - if (code < 0) - goto fail; - gs_swapcolors_quick(pgs); /* To color 0 */ - code = gx_set_device_color_1(pgs); /* sets colorspace and client color */ - if (code < 0) - goto fail; pgs->device = 0; /* setting device adjusts refcts */ code = gs_nulldevice(pgs); if (code < 0) @@ -297,20 +244,19 @@ pgs->in_charpath = (gs_char_path_mode) 0; pgs->show_gstate = 0; pgs->level = 0; - pgs->dfilter_stack = 0; if (gs_initgraphics(pgs) >= 0) return pgs; /* Something went very wrong. */ fail: - gs_state_free(pgs); + gs_gstate_free(pgs); return 0; } /* Set the client data in a graphics state. */ /* This should only be done to a newly created state. */ void -gs_state_set_client(gs_state * pgs, void *pdata, - const gs_state_client_procs * pprocs, bool client_has_pattern_streams) +gs_gstate_set_client(gs_gstate * pgs, void *pdata, + const gs_gstate_client_procs * pprocs, bool client_has_pattern_streams) { pgs->client_data = pdata; pgs->client_procs = *pprocs; @@ -318,22 +264,22 @@ } /* Get the client data from a graphics state. */ -#undef gs_state_client_data /* gzstate.h makes this a macro */ +#undef gs_gstate_client_data /* gzstate.h makes this a macro */ void * -gs_state_client_data(const gs_state * pgs) +gs_gstate_client_data(const gs_gstate * pgs) { return pgs->client_data; } /* Free the chain of gstates.*/ int -gs_state_free_chain(gs_state * pgs) +gs_gstate_free_chain(gs_gstate * pgs) { - gs_state *saved = pgs, *tmp; + gs_gstate *saved = pgs, *tmp; while(saved != 0) { tmp = saved->saved; - gs_state_free(saved); + gs_gstate_free(saved); saved = tmp; } return 0; @@ -341,18 +287,18 @@ /* Free a graphics state. */ int -gs_state_free(gs_state * pgs) +gs_gstate_free(gs_gstate * pgs) { gstate_free_contents(pgs); - gs_free_object(pgs->memory, pgs, "gs_state_free"); + gs_free_object(pgs->memory, pgs, "gs_gstate_free"); return 0; } /* Save the graphics state. */ int -gs_gsave(gs_state * pgs) +gs_gsave(gs_gstate * pgs) { - gs_state *pnew = gstate_clone(pgs, pgs->memory, "gs_gsave", + gs_gstate *pnew = gstate_clone(pgs, pgs->memory, "gs_gsave", copy_for_gsave); if (pnew == 0) @@ -363,10 +309,9 @@ * * Ordinarily, reference count rules would indicate an rc_decrement() * on pgs->clip_stack, but gstate_clone() has an exception for - * the clip_stack and dfilter_stack fields. + * the clip_stack field. */ pgs->clip_stack = 0; - rc_increment(pnew->dfilter_stack); pgs->saved = pnew; if (pgs->show_gstate == pgs) pgs->show_gstate = pnew->show_gstate = pnew; @@ -382,7 +327,7 @@ * In addition to an ordinary gsave, we create a new view clip path. */ int -gs_gsave_for_save(gs_state * pgs, gs_state ** psaved) +gs_gsave_for_save(gs_gstate * pgs, gs_gstate ** psaved) { int code; gx_clip_path *old_cpath = pgs->view_clip; @@ -415,9 +360,10 @@ /* Restore the graphics state. Can fully empty graphics stack */ int /* return 0 if ok, 1 if stack was empty */ -gs_grestore_only(gs_state * pgs) +gs_grestore_only(gs_gstate * pgs) { - gs_state *saved = pgs->saved; + gs_gstate *saved = pgs->saved; + gs_gstate tmp_gstate; void *pdata = pgs->client_data; void *sdata; bool prior_overprint = pgs->overprint; @@ -435,9 +381,11 @@ if (pdata != 0 && sdata != 0) gstate_copy_client_data(pgs, pdata, sdata, copy_for_grestore); gstate_free_contents(pgs); + tmp_gstate = *pgs; /* temp after contents freed (with pointers zeroed) */ *pgs = *saved; if (pgs->show_gstate == saved) pgs->show_gstate = pgs; + *saved = tmp_gstate; /* restore "freed" state (pointers zeroed after contents freed) */ gs_free_object(pgs->memory, saved, "gs_grestore"); /* update the overprint compositor, if necessary */ @@ -450,7 +398,7 @@ /* Restore the graphics state per PostScript semantics */ int -gs_grestore(gs_state * pgs) +gs_grestore(gs_gstate * pgs) { int code; if (!pgs->saved) @@ -468,7 +416,7 @@ /* Restore the graphics state for a 'restore', splicing the old stack */ /* back on. Note that we actually do a grestoreall + 2 grestores. */ int -gs_grestoreall_for_restore(gs_state * pgs, gs_state * saved) +gs_grestoreall_for_restore(gs_gstate * pgs, gs_gstate * saved) { int code; @@ -493,7 +441,7 @@ /* Restore to the bottommost graphics state (at this save level). */ int -gs_grestoreall(gs_state * pgs) +gs_grestoreall(gs_gstate * pgs) { if (!pgs->saved) /* shouldn't happen */ return gs_gsave(pgs); @@ -507,15 +455,10 @@ } /* Allocate and return a new graphics state. */ -gs_state * -gs_gstate(gs_state * pgs) -{ - return gs_state_copy(pgs, pgs->memory); -} -gs_state * -gs_state_copy(gs_state * pgs, gs_memory_t * mem) +gs_gstate * +gs_gstate_copy(gs_gstate * pgs, gs_memory_t * mem) { - gs_state *pnew; + gs_gstate *pnew; /* Prevent 'capturing' the view clip path. */ gx_clip_path *view_clip = pgs->view_clip; @@ -523,8 +466,7 @@ pnew = gstate_clone(pgs, mem, "gs_gstate", copy_for_gstate); if (pnew == 0) return 0; - clip_stack_rc_adjust(pnew->clip_stack, 1, "gs_state_copy"); - rc_increment(pnew->dfilter_stack); + clip_stack_rc_adjust(pnew->clip_stack, 1, "gs_gstate_copy"); pgs->view_clip = view_clip; pnew->saved = 0; /* @@ -540,14 +482,14 @@ /* Copy one previously allocated graphics state to another. */ int -gs_copygstate(gs_state * pto, const gs_state * pfrom) +gs_copygstate(gs_gstate * pto, const gs_gstate * pfrom) { return gstate_copy(pto, pfrom, copy_for_copygstate, "gs_copygstate"); } /* Copy the current graphics state to a previously allocated one. */ int -gs_currentgstate(gs_state * pto, const gs_state * pgs) +gs_currentgstate(gs_gstate * pto, const gs_gstate * pgs) { int code = gstate_copy(pto, pgs, copy_for_currentgstate, "gs_currentgstate"); @@ -559,18 +501,17 @@ /* Restore the current graphics state from a previously allocated one. */ int -gs_setgstate(gs_state * pgs, const gs_state * pfrom) +gs_setgstate(gs_gstate * pgs, const gs_gstate * pfrom) { /* * The implementation is the same as currentgstate, * except we must preserve the saved pointer, the level, * the view clip, and possibly the show_gstate. */ - gs_state *saved_show = pgs->show_gstate; + gs_gstate *saved_show = pgs->show_gstate; int level = pgs->level; gx_clip_path *view_clip = pgs->view_clip; int code; - int prior_op = pfrom->overprint; pgs->view_clip = 0; /* prevent refcount decrementing */ code = gstate_copy(pgs, pfrom, copy_for_setgstate, "gs_setgstate"); @@ -581,36 +522,36 @@ pgs->show_gstate = (pgs->show_gstate == pfrom ? pgs : saved_show); - /* update the overprint compositor but only if it is different */ - if (pgs->overprint != prior_op ) - return(gs_do_set_overprint(pgs)); - - return(0); + /* update the overprint compositor, unconditionally. Unlike grestore, this */ + /* may skip over states where overprint was set, so the prior state can */ + /* not be relied on to avoid this call. setgstate is not as commonly used */ + /* as grestore, so the overhead of the compositor call is acceptable. */ + return(gs_do_set_overprint(pgs)); } /* Get the allocator pointer of a graphics state. */ /* This is provided only for the interpreter */ /* and for color space implementation. */ gs_memory_t * -gs_state_memory(const gs_state * pgs) +gs_gstate_memory(const gs_gstate * pgs) { return pgs->memory; } /* Get the saved pointer of the graphics state. */ /* This is provided only for Level 2 grestore. */ -gs_state * -gs_state_saved(const gs_state * pgs) +gs_gstate * +gs_gstate_saved(const gs_gstate * pgs) { return pgs->saved; } /* Swap the saved pointer of the graphics state. */ /* This is provided only for save/restore. */ -gs_state * -gs_state_swap_saved(gs_state * pgs, gs_state * new_saved) +gs_gstate * +gs_gstate_swap_saved(gs_gstate * pgs, gs_gstate * new_saved) { - gs_state *saved = pgs->saved; + gs_gstate *saved = pgs->saved; pgs->saved = new_saved; return saved; @@ -619,7 +560,7 @@ /* Swap the memory pointer of the graphics state. */ /* This is provided only for the interpreter. */ gs_memory_t * -gs_state_swap_memory(gs_state * pgs, gs_memory_t * mem) +gs_gstate_swap_memory(gs_gstate * pgs, gs_memory_t * mem) { gs_memory_t *memory = pgs->memory; @@ -636,26 +577,29 @@ * compositor device. */ int -gs_state_update_overprint(gs_state * pgs, const gs_overprint_params_t * pparams) +gs_gstate_update_overprint(gs_gstate * pgs, const gs_overprint_params_t * pparams) { gs_composite_t * pct = 0; - gs_imager_state * pis = (gs_imager_state *)pgs; int code; gx_device * dev = pgs->device; gx_device * ovptdev; - if ( (code = gs_create_overprint(&pct, pparams, pgs->memory)) >= 0 && - (code = dev_proc(dev, create_compositor)( dev, + code = gs_create_overprint(&pct, pparams, pgs->memory); + if (code >= 0) { + code = dev_proc(dev, create_compositor)( dev, &ovptdev, pct, - pis, + pgs, pgs->memory, - NULL)) >= 0 ) { - if (ovptdev != dev) - gx_set_device_only(pgs, ovptdev); + NULL); + if (code >= 0 || code == gs_error_handled){ + if (ovptdev != dev) + gx_set_device_only(pgs, ovptdev); + code = 0; + } } if (pct != 0) - gs_free_object(pgs->memory, pct, "gs_state_update_overprint"); + gs_free_object(pgs->memory, pct, "gs_gstate_update_overprint"); /* the following hack handles devices that don't support compositors */ if (code == gs_error_unknownerror && !pparams->retain_any_comps) @@ -680,7 +624,7 @@ * components "drawn". */ int -gs_do_set_overprint(gs_state * pgs) +gs_do_set_overprint(gs_gstate * pgs) { const gs_color_space * pcs = gs_currentcolorspace_inline(pgs); const gs_client_color * pcc = gs_currentcolor_inline(pgs); @@ -695,36 +639,58 @@ /* setoverprint */ void -gs_setoverprint(gs_state * pgs, bool ovp) +gs_setoverprint(gs_gstate * pgs, bool ovp) { bool prior_ovp = pgs->overprint; - cmm_dev_profile_t *profile_struct; - gx_device *dev = pgs->device; - /* Check if overprint is disabled */ - if (dev != NULL) { - if (dev->procs.get_profile == NULL) { - profile_struct = dev->icc_struct; - } else { - dev_proc(dev, get_profile)(dev, &profile_struct); - } - if (profile_struct->sim_overprint == false) return; - } pgs->overprint = ovp; + pgs->stroke_overprint = ovp; if (prior_ovp != ovp) (void)gs_do_set_overprint(pgs); } /* currentoverprint */ bool -gs_currentoverprint(const gs_state * pgs) +gs_currentoverprint(const gs_gstate * pgs) +{ + return pgs->overprint; +} + +/* setstrokeoverprint */ +void +gs_setstrokeoverprint(gs_gstate * pgs, bool ovp) +{ + pgs->stroke_overprint = ovp; +} + +/* currentstrokeoverprint */ +bool +gs_currentstrokeoverprint(const gs_gstate * pgs) +{ + return pgs->stroke_overprint; +} + +/* setstrokeoverprint */ +void +gs_setfilloverprint(gs_gstate * pgs, bool ovp) +{ + bool prior_ovp = pgs->overprint; + + pgs->overprint = ovp; + if (prior_ovp != ovp) + (void)gs_do_set_overprint(pgs); +} + +/* currentstrokeoverprint */ +bool +gs_currentfilloverprint(const gs_gstate * pgs) { return pgs->overprint; } /* setoverprintmode */ int -gs_setoverprintmode(gs_state * pgs, int mode) +gs_setoverprintmode(gs_gstate * pgs, int mode) { int prior_mode = pgs->effective_overprint_mode; int code = 0; @@ -739,7 +705,7 @@ /* currentoverprintmode */ int -gs_currentoverprintmode(const gs_state * pgs) +gs_currentoverprintmode(const gs_gstate * pgs) { return pgs->overprint_mode; } @@ -761,6 +727,41 @@ return libctx->CPSI_mode; } +/* The edgebuffer based scanconverter can only cope with values of 0 + * or 0.5 (i.e. 'center of pixel' or 'any part of pixel'). These + * are the only values required for correct behaviour according to + * the PDF and PS specs. Therefore, if we are using the edgebuffer + * based scan converter, force these values. */ +static void +sanitize_fill_adjust(gs_gstate * pgs) +{ + int scanconverter = gs_getscanconverter(pgs->memory); + if (scanconverter >= GS_SCANCONVERTER_EDGEBUFFER || (GS_SCANCONVERTER_DEFAULT_IS_EDGEBUFFER && scanconverter == GS_SCANCONVERTER_DEFAULT)) { + fixed adjust = (pgs->fill_adjust.x >= float2fixed(0.25) || pgs->fill_adjust.y >= float2fixed(0.25) ? fixed_half : 0); + pgs->fill_adjust.x = adjust; + pgs->fill_adjust.y = adjust; + } +} + +void +gs_setscanconverter(gs_gstate * gs, int converter) +{ + gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(gs->memory); + + libctx->scanconverter = converter; + + sanitize_fill_adjust(gs); +} + +/* getscanconverter */ +int +gs_getscanconverter(const gs_memory_t * mem) +{ + gs_lib_ctx_t *libctx = gs_lib_ctx_get_interp_instance(mem); + + return libctx->scanconverter; +} + /* setrenderingintent * * Use ICC numbers from Table 18 (section 6.1.11) rather than the PDF order @@ -771,7 +772,7 @@ * AbsoluteColorimetric 3 */ int -gs_setrenderingintent(gs_state *pgs, int ri) { +gs_setrenderingintent(gs_gstate *pgs, int ri) { if (ri < 0 || ri > 3) return_error(gs_error_rangecheck); pgs->renderingintent = ri; @@ -780,36 +781,34 @@ /* currentrenderingintent */ int -gs_currentrenderingintent(const gs_state * pgs) +gs_currentrenderingintent(const gs_gstate * pgs) { return pgs->renderingintent; } int -gs_setblackptcomp(gs_state *pgs, bool bkpt) { +gs_setblackptcomp(gs_gstate *pgs, bool bkpt) { pgs->blackptcomp = bkpt; return 0; } /* currentrenderingintent */ bool -gs_currentblackptcomp(const gs_state * pgs) +gs_currentblackptcomp(const gs_gstate * pgs) { return pgs->blackptcomp; } /* * Reset most of the graphics state. - * - * NB: This routine no longer resets the current color or current color - * space. It cannot do this for PostScript, due to color substitution. - * Clients should perform the appropriate color/colorspace - * initializaion themselves. */ int -gs_initgraphics(gs_state * pgs) +gs_initgraphics(gs_gstate * pgs) { int code; + const gs_gstate gstate_initial = { + gs_gstate_initial(1.0) + }; gs_initmatrix(pgs); if ((code = gs_newpath(pgs)) < 0 || @@ -828,25 +827,106 @@ ) return code; gs_init_rop(pgs); + /* Initialize things so that gx_remap_color won't crash. */ + if (pgs->icc_manager->default_gray == 0x00) { + gs_color_space *pcs1, *pcs2; + + pcs1 = gs_cspace_new_DeviceGray(pgs->memory); + if (pcs1 == NULL) + return_error(gs_error_unknownerror); + + if (pgs->color[0].color_space != NULL) { + gs_setcolorspace(pgs, pcs1); + rc_decrement_cs(pcs1, "gs_initgraphics"); + } else { + pgs->color[0].color_space = pcs1; + gs_setcolorspace(pgs, pcs1); + } + code = gx_set_dev_color(pgs); + if (code < 0) + return code; + + gs_swapcolors_quick(pgs); /* To color 1 */ + + pcs2 = gs_cspace_new_DeviceGray(pgs->memory); + if (pcs2 == NULL) + return_error(gs_error_unknownerror); + + if (pgs->color[0].color_space != NULL) { + gs_setcolorspace(pgs, pcs2); + rc_decrement_cs(pcs2, "gs_initgraphics"); + } else { + pgs->color[0].color_space = pcs2; + gs_setcolorspace(pgs, pcs2); + } + code = gx_set_dev_color(pgs); + + gs_swapcolors_quick(pgs); /* To color 0 */ + + if (code < 0) + return code; + + } else { + gs_color_space *pcs1, *pcs2; + + pcs1 = gs_cspace_new_ICC(pgs->memory, pgs, 1); + if (pcs1 == NULL) + return_error(gs_error_unknownerror); + + if (pgs->color[0].color_space != NULL) { + gs_setcolorspace(pgs, pcs1); + rc_decrement_cs(pcs1, "gs_initgraphics"); + } else { + pgs->color[0].color_space = pcs1; + gs_setcolorspace(pgs, pcs1); + } + code = gx_set_dev_color(pgs); + if (code < 0) + return code; + + gs_swapcolors_quick(pgs); /* To color 1 */ + pcs2 = gs_cspace_new_ICC(pgs->memory, pgs, 1); + if (pcs2 == NULL) + return_error(gs_error_unknownerror); + + if (pgs->color[0].color_space != NULL) { + gs_setcolorspace(pgs, pcs2); + rc_decrement_cs(pcs2, "gs_initgraphics"); + } else { + pgs->color[0].color_space = pcs2; + gs_setcolorspace(pgs, pcs2); + } + code = gx_set_dev_color(pgs); + + gs_swapcolors_quick(pgs); /* To color 0 */ + + if (code < 0) + return code; + } + pgs->in_cachedevice = 0; + return 0; } /* setfilladjust */ int -gs_setfilladjust(gs_state * pgs, floatp adjust_x, floatp adjust_y) +gs_setfilladjust(gs_gstate * pgs, double adjust_x, double adjust_y) { #define CLAMP_TO_HALF(v)\ ((v) <= 0 ? fixed_0 : (v) >= 0.5 ? fixed_half : float2fixed(v)); pgs->fill_adjust.x = CLAMP_TO_HALF(adjust_x); pgs->fill_adjust.y = CLAMP_TO_HALF(adjust_y); + + sanitize_fill_adjust(pgs); + return 0; #undef CLAMP_TO_HALF } /* currentfilladjust */ int -gs_currentfilladjust(const gs_state * pgs, gs_point * adjust) +gs_currentfilladjust(const gs_gstate * pgs, gs_point * adjust) { adjust->x = fixed2float(pgs->fill_adjust.x); adjust->y = fixed2float(pgs->fill_adjust.y); @@ -855,42 +935,167 @@ /* setlimitclamp */ void -gs_setlimitclamp(gs_state * pgs, bool clamp) +gs_setlimitclamp(gs_gstate * pgs, bool clamp) { pgs->clamp_coordinates = clamp; } /* currentlimitclamp */ bool -gs_currentlimitclamp(const gs_state * pgs) +gs_currentlimitclamp(const gs_gstate * pgs) { return pgs->clamp_coordinates; } /* settextrenderingmode */ void -gs_settextrenderingmode(gs_state * pgs, uint trm) +gs_settextrenderingmode(gs_gstate * pgs, uint trm) { pgs->text_rendering_mode = trm; } /* currenttextrenderingmode */ uint -gs_currenttextrenderingmode(const gs_state * pgs) +gs_currenttextrenderingmode(const gs_gstate * pgs) { return pgs->text_rendering_mode; } +double +gs_currenttextspacing(const gs_gstate *pgs) +{ + return pgs->textspacing; +} + +int +gs_settextspacing(gs_gstate *pgs, double Tc) +{ + pgs->textspacing = (float)Tc; + return 0; +} + +double +gs_currenttextleading(const gs_gstate *pgs) +{ + return pgs->textleading; +} + +int +gs_settextleading(gs_gstate *pgs, double TL) +{ + pgs->textleading = (float)TL; + return 0; +} + +double +gs_currenttextrise(const gs_gstate *pgs) +{ + return pgs->textrise; +} + +int +gs_settextrise(gs_gstate *pgs, double Ts) +{ + pgs->textrise = (float)Ts; + return 0; +} + +double +gs_currentwordspacing(const gs_gstate *pgs) +{ + return pgs->wordspacing; +} + +int +gs_setwordspacing(gs_gstate *pgs, double Tw) +{ + pgs->wordspacing = (float)Tw; + return 0; +} + +int +gs_settexthscaling(gs_gstate *pgs, double Tz) +{ + pgs->texthscaling = (float)Tz; + return 0; +} + +double +gs_currenttexthscaling(const gs_gstate *pgs) +{ + return pgs->texthscaling; +} + +int +gs_setPDFfontsize(gs_gstate *pgs, double Tf) +{ + pgs->PDFfontsize = (float)Tf; + return 0; +} + +double +gs_currentPDFfontsize(const gs_gstate *pgs) +{ + return pgs->PDFfontsize; +} + +int +gs_settextlinematrix(gs_gstate *pgs, gs_matrix *m) +{ + pgs->textlinematrix.xx = m->xx; + pgs->textlinematrix.xy = m->xy; + pgs->textlinematrix.yx = m->yx; + pgs->textlinematrix.yy = m->yy; + pgs->textlinematrix.tx = m->tx; + pgs->textlinematrix.ty = m->ty; + return 0; +} +int +gs_gettextlinematrix(gs_gstate *pgs, gs_matrix *m) +{ + m->xx = pgs->textlinematrix.xx; + m->xy = pgs->textlinematrix.xy; + m->yx = pgs->textlinematrix.yx; + m->yy = pgs->textlinematrix.yy; + m->tx = pgs->textlinematrix.tx; + m->ty = pgs->textlinematrix.ty; + return 0; +} + +int +gs_settextmatrix(gs_gstate *pgs, gs_matrix *m) +{ + pgs->textmatrix.xx = m->xx; + pgs->textmatrix.xy = m->xy; + pgs->textmatrix.yx = m->yx; + pgs->textmatrix.yy = m->yy; + pgs->textmatrix.tx = m->tx; + pgs->textmatrix.ty = m->ty; + return 0; +} +int +gs_gettextmatrix(gs_gstate *pgs, gs_matrix *m) +{ + m->xx = pgs->textmatrix.xx; + m->xy = pgs->textmatrix.xy; + m->yx = pgs->textmatrix.yx; + m->yy = pgs->textmatrix.yy; + m->tx = pgs->textmatrix.tx; + m->ty = pgs->textmatrix.ty; + return 0; +} + + /* sethpglpathmode */ void -gs_sethpglpathmode(gs_state * pgs, bool path) +gs_sethpglpathmode(gs_gstate * pgs, bool path) { pgs->hpgl_path_mode = path; } /* currenthpglpathmode */ bool -gs_currenthpglpathmode(const gs_state * pgs) +gs_currenthpglpathmode(const gs_gstate * pgs) { return pgs->hpgl_path_mode; } @@ -899,22 +1104,31 @@ /* Free the privately allocated parts of a gstate. */ static void -gstate_free_parts(const gs_state * parts, gs_memory_t * mem, client_name_t cname) +gstate_free_parts(gs_gstate * parts, gs_memory_t * mem, client_name_t cname) { gs_free_object(mem, parts->color[1].dev_color, cname); gs_free_object(mem, parts->color[1].ccolor, cname); gs_free_object(mem, parts->color[0].dev_color, cname); gs_free_object(mem, parts->color[0].ccolor, cname); - if (!parts->effective_clip_shared) + parts->color[1].dev_color = 0; + parts->color[1].ccolor = 0; + parts->color[0].dev_color = 0; + parts->color[0].ccolor = 0; + if (!parts->effective_clip_shared && parts->effective_clip_path) { gx_cpath_free(parts->effective_clip_path, cname); + parts->effective_clip_path = 0; + } gx_cpath_free(parts->clip_path, cname); - if (parts->path) + parts->clip_path = 0; + if (parts->path) { gx_path_free(parts->path, cname); + parts->path = 0; + } } /* Allocate the privately allocated parts of a gstate. */ static int -gstate_alloc_parts(gs_state * parts, const gs_state * shared, +gstate_alloc_parts(gs_gstate * parts, const gs_gstate * shared, gs_memory_t * mem, client_name_t cname) { gs_memory_t *path_mem = gstate_path_memory(mem); @@ -965,14 +1179,15 @@ * clip_path and view_clip) effective_clip_path share the segments of * pfrom's corresponding path(s). */ -static gs_state * -gstate_alloc(gs_memory_t * mem, client_name_t cname, const gs_state * pfrom) +static gs_gstate * +gstate_alloc(gs_memory_t * mem, client_name_t cname, const gs_gstate * pfrom) { - gs_state *pgs = - gs_alloc_struct(mem, gs_state, &st_gs_state, cname); + gs_gstate *pgs = + gs_alloc_struct(mem, gs_gstate, &st_gs_gstate, cname); if (pgs == 0) return 0; + memset(pgs, 0x00, sizeof(gs_gstate)); if (gstate_alloc_parts(pgs, pfrom, mem, cname) < 0) { gs_free_object(mem, pgs, cname); return 0; @@ -983,7 +1198,7 @@ /* Copy the dash pattern from one gstate to another. */ static int -gstate_copy_dash(gs_state * pto, const gs_state * pfrom) +gstate_copy_dash(gs_gstate * pto, const gs_gstate * pfrom) { return gs_setdash(pto, pfrom->line_params.dash.pattern, pfrom->line_params.dash.pattern_size, @@ -994,12 +1209,12 @@ /* Return 0 if the allocation fails. */ /* If reason is for_gsave, the clone refers to the old contents, */ /* and we switch the old state to refer to the new contents. */ -static gs_state * -gstate_clone(gs_state * pfrom, gs_memory_t * mem, client_name_t cname, - gs_state_copy_reason_t reason) +static gs_gstate * +gstate_clone(gs_gstate * pfrom, gs_memory_t * mem, client_name_t cname, + gs_gstate_copy_reason_t reason) { - gs_state *pgs = gstate_alloc(mem, cname, pfrom); - gs_state_parts parts; + gs_gstate *pgs = gstate_alloc(mem, cname, pfrom); + gs_gstate_parts parts; if (pgs == 0) return 0; @@ -1022,8 +1237,9 @@ ) goto fail; } - gs_imager_state_copied((gs_imager_state *)pgs); + gs_gstate_copied(pgs); /* Don't do anything to clip_stack. */ + rc_increment(pgs->device); *parts.color[0].ccolor = *pfrom->color[0].ccolor; *parts.color[0].dev_color = *pfrom->color[0].dev_color; @@ -1045,6 +1261,7 @@ cs_adjust_counts_icc(pgs, 1); return pgs; fail: + memset(pgs->color, 0, 2*sizeof(gs_gstate_color)); gs_free_object(mem, pgs->line_params.dash.pattern, cname); GSTATE_ASSIGN_PARTS(pgs, &parts); gstate_free_parts(pgs, mem, cname); @@ -1066,34 +1283,58 @@ } } +/* + * Finalization for graphics states. This is where we handle RC for those + * elements. + */ +void +gs_gstate_finalize(const gs_memory_t *cmem,void *vptr) +{ + gs_gstate *pgs = (gs_gstate *)vptr; + (void)cmem; /* unused */ + + if (cmem == NULL) + return; /* place for breakpoint */ + gstate_free_contents(pgs); +} + /* Release the composite parts of a graphics state, */ /* but not the state itself. */ static void -gstate_free_contents(gs_state * pgs) +gstate_free_contents(gs_gstate * pgs) { gs_memory_t *mem = pgs->memory; const char *const cname = "gstate_free_contents"; rc_decrement(pgs->device, cname); + pgs->device = 0; clip_stack_rc_adjust(pgs->clip_stack, -1, cname); - rc_decrement(pgs->dfilter_stack, cname); + pgs->clip_stack = 0; + if (pgs->view_clip != NULL && pgs->level == 0) { + gx_cpath_free(pgs->view_clip, cname); + pgs->view_clip = NULL; + } gs_swapcolors_quick(pgs); cs_adjust_counts_icc(pgs, -1); gs_swapcolors_quick(pgs); cs_adjust_counts_icc(pgs, -1); + pgs->color[0].color_space = 0; + pgs->color[1].color_space = 0; if (pgs->client_data != 0) (*pgs->client_procs.free) (pgs->client_data, mem); + pgs->client_data = 0; gs_free_object(mem, pgs->line_params.dash.pattern, cname); - gstate_free_parts(pgs, mem, cname); - gs_imager_state_release((gs_imager_state *)pgs); + pgs->line_params.dash.pattern = 0; + gstate_free_parts(pgs, mem, cname); /* this also clears pointers to freed elements */ + gs_gstate_release(pgs); } /* Copy one gstate to another. */ static int -gstate_copy(gs_state * pto, const gs_state * pfrom, - gs_state_copy_reason_t reason, client_name_t cname) +gstate_copy(gs_gstate * pto, const gs_gstate * pfrom, + gs_gstate_copy_reason_t reason, client_name_t cname) { - gs_state_parts parts; + gs_gstate_parts parts; GSTATE_ASSIGN_PARTS(&parts, pto); /* Copy the dash pattern if necessary. */ @@ -1136,7 +1377,6 @@ *parts.color[1].dev_color = *pfrom->color[1].dev_color; /* Handle references from gstate object. */ rc_pre_assign(pto->device, pfrom->device, cname); - rc_pre_assign(pto->dfilter_stack, pfrom->dfilter_stack, cname); if (pto->clip_stack != pfrom->clip_stack) { clip_stack_rc_adjust(pfrom->clip_stack, 1, cname); clip_stack_rc_adjust(pto->clip_stack, -1, cname); @@ -1145,11 +1385,10 @@ struct gx_pattern_cache_s *pcache = pto->pattern_cache; void *pdata = pto->client_data; gs_memory_t *mem = pto->memory; - gs_state *saved = pto->saved; + gs_gstate *saved = pto->saved; float *pattern = pto->line_params.dash.pattern; - gs_imager_state_pre_assign((gs_imager_state *)pto, - (const gs_imager_state *)pfrom); + gs_gstate_pre_assign(pto, (const gs_gstate *)pfrom); *pto = *pfrom; pto->client_data = pdata; pto->memory = mem; @@ -1159,7 +1398,7 @@ pto->pattern_cache = pcache; if (pfrom->client_data != 0) { /* We need to break 'const' here. */ - gstate_copy_client_data((gs_state *) pfrom, pdata, + gstate_copy_client_data((gs_gstate *) pfrom, pdata, pfrom->client_data, reason); } } @@ -1174,12 +1413,12 @@ } /* Accessories. */ -gs_id gx_get_clip_path_id(gs_state *pgs) +gs_id gx_get_clip_path_id(gs_gstate *pgs) { return pgs->clip_path->id; } -void gs_swapcolors_quick(gs_state *pgs) +void gs_swapcolors_quick(gs_gstate *pgs) { struct gx_cie_joint_caches_s *tmp_cie; gs_devicen_color_map tmp_ccm; @@ -1200,7 +1439,7 @@ pgs->color[0].color_space = pgs->color[1].color_space; pgs->color[1].color_space = tmp_cs; - /* Swap the bits of the imager state that depend on the current color */ + /* Swap the bits of the gs_gstate that depend on the current color */ tmp_cie = pgs->cie_joint_caches; pgs->cie_joint_caches = pgs->cie_joint_caches_alt; pgs->cie_joint_caches_alt = tmp_cie; @@ -1210,8 +1449,8 @@ pgs->color_component_map_alt = tmp_ccm; tmp = pgs->overprint; - pgs->overprint = pgs->overprint_alt; - pgs->overprint_alt = tmp; + pgs->overprint = pgs->stroke_overprint; + pgs->stroke_overprint = tmp; tmp = pgs->overprint_mode; pgs->overprint_mode = pgs->overprint_mode_alt; @@ -1223,7 +1462,7 @@ } -int gs_swapcolors(gs_state *pgs) +int gs_swapcolors(gs_gstate *pgs) { int prior_overprint = pgs->overprint; diff -Nru ghostscript-9.10~dfsg/base/gsstate.h ghostscript-9.25~dfsg+1/base/gsstate.h --- ghostscript-9.10~dfsg/base/gsstate.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstate.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,9 +20,9 @@ # define gsstate_INCLUDED /* Opaque type for a graphics state */ -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif /* opague type for overprint compositor parameters */ @@ -32,39 +32,48 @@ #endif /* Initial allocation and freeing */ -gs_state *gs_state_alloc(gs_memory_t *); /* 0 if fails */ -int gs_state_free(gs_state *); -int gs_state_free_chain(gs_state *); +gs_gstate *gs_gstate_alloc(gs_memory_t *); /* 0 if fails */ +int gs_gstate_free(gs_gstate *); +int gs_gstate_free_chain(gs_gstate *); /* Initialization, saving, restoring, and copying */ -int gs_gsave(gs_state *), gs_grestore(gs_state *), gs_grestoreall(gs_state *); -int gs_grestore_only(gs_state *); -int gs_gsave_for_save(gs_state *, gs_state **), gs_grestoreall_for_restore(gs_state *, gs_state *); -gs_state *gs_gstate(gs_state *); -gs_state *gs_state_copy(gs_state *, gs_memory_t *); -int gs_copygstate(gs_state * /*to */ , const gs_state * /*from */ ), - gs_currentgstate(gs_state * /*to */ , const gs_state * /*from */ ), - gs_setgstate(gs_state * /*to */ , const gs_state * /*from */ ); - -int gs_state_update_overprint(gs_state *, const gs_overprint_params_t *); -bool gs_currentoverprint(const gs_state *); -void gs_setoverprint(gs_state *, bool); -int gs_currentoverprintmode(const gs_state *); -int gs_setoverprintmode(gs_state *, int); - -int gs_do_set_overprint(gs_state *); +int gs_gsave(gs_gstate *), gs_grestore(gs_gstate *), gs_grestoreall(gs_gstate *); +int gs_grestore_only(gs_gstate *); +int gs_gsave_for_save(gs_gstate *, gs_gstate **), gs_grestoreall_for_restore(gs_gstate *, gs_gstate *); + +gs_gstate *gs_gstate_copy(gs_gstate *, gs_memory_t *); +int gs_copygstate(gs_gstate * /*to */ , const gs_gstate * /*from */ ), + gs_currentgstate(gs_gstate * /*to */ , const gs_gstate * /*from */ ), + gs_setgstate(gs_gstate * /*to */ , const gs_gstate * /*from */ ); + +int gs_gstate_update_overprint(gs_gstate *, const gs_overprint_params_t *); +bool gs_currentoverprint(const gs_gstate *); +void gs_setoverprint(gs_gstate *, bool); +bool gs_currentstrokeoverprint(const gs_gstate *); +void gs_setstrokeoverprint(gs_gstate *, bool); +bool gs_currentfilloverprint(const gs_gstate *); +void gs_setfilloverprint(gs_gstate *, bool); + +int gs_currentoverprintmode(const gs_gstate *); +int gs_setoverprintmode(gs_gstate *, int); + +int gs_do_set_overprint(gs_gstate *); -int gs_currentrenderingintent(const gs_state *); -int gs_setrenderingintent(gs_state *, int); +int gs_currentrenderingintent(const gs_gstate *); +int gs_setrenderingintent(gs_gstate *, int); -int gs_currentblackptcomp(const gs_state *); -int gs_setblackptcomp(gs_state *, int); +int gs_currentblackptcomp(const gs_gstate *); +int gs_setblackptcomp(gs_gstate *, int); -int gs_initgraphics(gs_state *); +int gs_initgraphics(gs_gstate *); +int gs_initgraphics_no_cspace(gs_gstate *); bool gs_currentcpsimode(const gs_memory_t *); void gs_setcpsimode(gs_memory_t *, bool); +int gs_getscanconverter(const gs_memory_t *); +void gs_setscanconverter(gs_gstate *, int); + /* Device control */ #include "gsdevice.h" @@ -77,25 +86,42 @@ /* Halftone screen */ #include "gsht.h" #include "gscsel.h" -int gs_setscreenphase(gs_state *, int, int, gs_color_select_t); -int gs_currentscreenphase(const gs_state *, gs_int_point *, gs_color_select_t); +int gs_setscreenphase(gs_gstate *, int, int, gs_color_select_t); +int gs_currentscreenphase(const gs_gstate *, gs_int_point *, gs_color_select_t); #define gs_sethalftonephase(pgs, px, py)\ gs_setscreenphase(pgs, px, py, gs_color_select_all) #define gs_currenthalftonephase(pgs, ppt)\ gs_currentscreenphase(pgs, ppt, 0) -int gx_imager_setscreenphase(gs_imager_state *, int, int, gs_color_select_t); +int gx_gstate_setscreenphase(gs_gstate *, int, int, gs_color_select_t); /* Miscellaneous */ -int gs_setfilladjust(gs_state *, floatp, floatp); -int gs_currentfilladjust(const gs_state *, gs_point *); -void gs_setlimitclamp(gs_state *, bool); -bool gs_currentlimitclamp(const gs_state *); -void gs_settextrenderingmode(gs_state * pgs, uint trm); -uint gs_currenttextrenderingmode(const gs_state * pgs); +int gs_setfilladjust(gs_gstate *, double, double); +int gs_currentfilladjust(const gs_gstate *, gs_point *); +void gs_setlimitclamp(gs_gstate *, bool); +bool gs_currentlimitclamp(const gs_gstate *); +void gs_settextrenderingmode(gs_gstate * pgs, uint trm); +uint gs_currenttextrenderingmode(const gs_gstate * pgs); +int gs_settextspacing(gs_gstate *pgs, double Tc); +double gs_currenttextspacing(const gs_gstate *pgs); +int gs_settextleading(gs_gstate *pgs, double TL); +double gs_currenttextleading(const gs_gstate *pgs); +int gs_settextrise(gs_gstate *pgs, double Ts); +double gs_currenttextrise(const gs_gstate *pgs); +int gs_setwordspacing(gs_gstate *pgs, double Tz); +double gs_currentwordspacing(const gs_gstate *pgs); +int gs_settexthscaling(gs_gstate *pgs, double Tw); +double gs_currenttexthscaling(const gs_gstate *pgs); +int gs_settextlinematrix(gs_gstate *pgs, gs_matrix *m); +int gs_gettextlinematrix(gs_gstate *pgs, gs_matrix *m); +int gs_settextmatrix(gs_gstate *pgs, gs_matrix *m); +int gs_gettextmatrix(gs_gstate *pgs, gs_matrix *m); +int gs_setPDFfontsize(gs_gstate *pgs, double Tw); +double gs_currentPDFfontsize(const gs_gstate *pgs); + #include "gscpm.h" -gs_in_cache_device_t gs_incachedevice(const gs_state *); -void gs_sethpglpathmode(gs_state *, bool); -bool gs_currenthpglpathmode(const gs_state *); +gs_in_cache_device_t gs_incachedevice(const gs_gstate *); +void gs_sethpglpathmode(gs_gstate *, bool); +bool gs_currenthpglpathmode(const gs_gstate *); #endif /* gsstate_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gsstrl.c ghostscript-9.25~dfsg+1/base/gsstrl.c --- ghostscript-9.10~dfsg/base/gsstrl.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstrl.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c and lib/libc/string/strlcat.c */ + +/* strlcpy and strlcat modified for use by ghostscript */ + +#include "string_.h" +#include "gsstrl.h" + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +gs_strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ + +size_t +gs_strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff -Nru ghostscript-9.10~dfsg/base/gsstrl.h ghostscript-9.25~dfsg+1/base/gsstrl.h --- ghostscript-9.10~dfsg/base/gsstrl.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstrl.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,24 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#ifndef gsstrl_INCLUDED +# define gsstrl_INCLUDED + +size_t gs_strlcat(char *dst, const char *src, size_t siz); + +size_t gs_strlcpy(char *dst, const char *src, size_t siz); + +#endif + diff -Nru ghostscript-9.10~dfsg/base/gsstrtok.c ghostscript-9.25~dfsg+1/base/gsstrtok.c --- ghostscript-9.10~dfsg/base/gsstrtok.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstrtok.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,58 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* From: https://svn.apache.org/repos/asf/apr/apr/trunk/strings/apr_strtok.c */ +/* with changes to work in Ghostscript */ + +#include "string_.h" +#include "gsstrtok.h" + +#define APR_DECLARE(X) static X + +APR_DECLARE(char *) apr_strtok(char *str, const char *sep, char **last) +{ + char *token; + + if (!str) /* subsequent call */ + str = *last; /* start where we left off */ + + /* skip characters in sep (will terminate at '\0') */ + while (*str && strchr(sep, *str)) + ++str; + + if (!*str) /* no more tokens */ + return NULL; + + token = str; + + /* skip valid token characters to terminate token and + * prepare for the next call (will terminate at '\0) + */ + *last = token + 1; + while (**last && !strchr(sep, **last)) + ++*last; + + if (**last) { + **last = '\0'; + ++*last; + } + + return token; +} + +char * gs_strtok(char *str, const char *sep, char **last) +{ + return apr_strtok(str, sep, last); +} diff -Nru ghostscript-9.10~dfsg/base/gsstrtok.h ghostscript-9.25~dfsg+1/base/gsstrtok.h --- ghostscript-9.10~dfsg/base/gsstrtok.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstrtok.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,21 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#ifndef gsstrtok_INCLUDED +# define gsstrtok_INCLUDED + +char * gs_strtok(char *str, const char *sep, char **last); + +#endif diff -Nru ghostscript-9.10~dfsg/base/gsstruct.h ghostscript-9.25~dfsg+1/base/gsstruct.h --- ghostscript-9.10~dfsg/base/gsstruct.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstruct.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -970,6 +970,16 @@ #define gs_private_st_const_strings1_ptrs1(stname, stype, sname, penum, preloc, e1, e2)\ gs__st_const_strings1_ptrs1(private_st, stname, stype, sname, penum, preloc, e1, e2) +#define gs__st_const_strings1_ptrs1_final(scope_st, stname, stype, sname, penum, preloc, pfinal, e1, e2)\ + BASIC_PTRS(penum) {\ + GC_CONST_STRING_ELT(stype, e1), GC_OBJ_ELT(stype, e2)\ + };\ + gs__st_basic_final(scope_st, stname, stype, sname, penum, preloc, pfinal) +#define gs_public_st_const_strings1_ptrs1_final(stname, stype, sname, penum, preloc, pfinal, e1, e2)\ + gs__st_const_strings1_ptrs1_final(public_st, stname, stype, sname, penum, preloc, pfinal, e1, e2) +#define gs_private_st_const_strings1_ptrs1_final(stname, stype, sname, penum, preloc, e1, e2)\ + gs__st_const_strings1_ptrs1_final(private_st, stname, stype, sname, penum, preloc, pfinal, e1, e2) + /* Structures with 1 const string and 4 pointers. */ #define gs__st_strings1_ptrs4(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\ diff -Nru ghostscript-9.10~dfsg/base/gsstype.h ghostscript-9.25~dfsg+1/base/gsstype.h --- ghostscript-9.10~dfsg/base/gsstype.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsstype.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,6 +19,8 @@ #ifndef gsstype_INCLUDED # define gsstype_INCLUDED +#include "gsmemory.h" + /* Define an opaque type for the garbage collector state. */ typedef struct gc_state_s gc_state_t; diff -Nru ghostscript-9.10~dfsg/base/gstext.c ghostscript-9.25~dfsg+1/base/gstext.c --- ghostscript-9.10~dfsg/base/gstext.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstext.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,7 @@ #include "gstypes.h" #include "gxfcache.h" #include "gxdevcli.h" -#include "gxdcolor.h" /* for gs_state_color_load */ +#include "gxdcolor.h" /* for gs_gstate_color_load */ #include "gxfont.h" /* for init_fstack */ #include "gxpath.h" #include "gxtext.h" @@ -94,7 +94,7 @@ } case 0: return ENUM_OBJ(gx_device_enum_ptr(eptr->dev)); case 1: return ENUM_OBJ(gx_device_enum_ptr(eptr->imaging_dev)); -ENUM_PTR3(2, gs_text_enum_t, pis, orig_font, path); +ENUM_PTR3(2, gs_text_enum_t, pgs, orig_font, path); ENUM_PTR3(5, gs_text_enum_t, pdcolor, pcpath, current_font); ENUM_PTRS_END @@ -105,7 +105,7 @@ RELOC_USING(st_gs_text_params, &eptr->text, sizeof(eptr->text)); eptr->dev = gx_device_reloc_ptr(eptr->dev, gcst); eptr->imaging_dev = gx_device_reloc_ptr(eptr->imaging_dev, gcst); - RELOC_PTR3(gs_text_enum_t, pis, orig_font, path); + RELOC_PTR3(gs_text_enum_t, pgs, orig_font, path); RELOC_PTR3(gs_text_enum_t, pdcolor, pcpath, current_font); if (eptr->pair != NULL) eptr->pair = (cached_fm_pair *)RELOC_OBJ(eptr->pair - eptr->pair->index) + @@ -117,7 +117,7 @@ /* Begin processing text. */ int -gx_device_text_begin(gx_device * dev, gs_imager_state * pis, +gx_device_text_begin(gx_device * dev, gs_gstate * pgs, const gs_text_params_t * text, gs_font * font, gx_path * path, /* unless DO_NONE & !RETURN_WIDTH */ const gx_device_color * pdcolor, /* DO_DRAW */ @@ -138,7 +138,7 @@ Since the accumulation may happen while stringwidth. we pass the device color unconditionally. */ return dev_proc(dev, text_begin) - (dev, pis, text, font, tpath, pdcolor, tcpath, mem, ppte); + (dev, pgs, text, font, tpath, pdcolor, tcpath, mem, ppte); } } @@ -161,7 +161,7 @@ } int gs_text_enum_init(gs_text_enum_t *pte, const gs_text_enum_procs_t *procs, - gx_device *dev, gs_imager_state *pis, + gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *mem) @@ -171,7 +171,7 @@ pte->text = *text; pte->dev = dev; pte->imaging_dev = NULL; - pte->pis = pis; + pte->pgs = pgs; pte->orig_font = font; pte->path = path; pte->pdcolor = pdcolor; @@ -195,6 +195,25 @@ return code; } +gs_text_enum_t * +gs_text_enum_alloc(gs_memory_t * mem, gs_gstate * pgs, client_name_t cname) +{ + gs_text_enum_t *penum; + + rc_alloc_struct_1(penum, gs_text_enum_t, &st_gs_text_enum, mem, + return 0, cname); + penum->rc.free = rc_free_text_enum; + + /* Initialize pointers for GC */ + penum->text.operation = 0; /* no pointers relevant */ + penum->dev = 0; + penum->pgs = pgs; + penum->fapi_log2_scale.x = penum->fapi_log2_scale.y = -1; + penum->fapi_glyph_shift.x = penum->fapi_glyph_shift.y = 0; + penum->fstack.depth = -1; + return penum; +} + /* * Copy the dynamically changing elements from one enumerator to another. * This is useful primarily for enumerators that sometimes pass the @@ -208,6 +227,7 @@ pto->current_font = pfrom->current_font; pto->index = pfrom->index; + pto->bytes_decoded = pfrom->bytes_decoded; pto->xy_index = pfrom->xy_index; pto->fstack.depth = depth; pto->FontBBox_as_Metrics2 = pfrom->FontBBox_as_Metrics2; @@ -225,7 +245,7 @@ /* Begin processing text based on a graphics state. */ int -gs_text_begin(gs_state * pgs, const gs_text_params_t * text, +gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, gs_memory_t * mem, gs_text_enum_t ** ppte) { gx_clip_path *pcpath = 0; @@ -260,16 +280,16 @@ Unfortunately we can't effectively know a leaf font type here, so we load the color unconditionally . */ /* Processing a text object operation */ - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_TEXT_TAG); + ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ code = gx_set_dev_color(pgs); if (code != 0) return code; - code = gs_state_color_load(pgs); + code = gs_gstate_color_load(pgs); if (code < 0) return code; pgs->device->sgr.stroke_stored = false; - return gx_device_text_begin(pgs->device, (gs_imager_state *) pgs, + return gx_device_text_begin(pgs->device, pgs, text, pgs->font, pgs->path, gs_currentdevicecolor_inline(pgs), pcpath, mem, ppte); @@ -280,7 +300,7 @@ * cshow procedure may have changed the current color). */ int -gs_text_update_dev_color(gs_state * pgs, gs_text_enum_t * pte) +gs_text_update_dev_color(gs_gstate * pgs, gs_text_enum_t * pte) { /* * The text enumerator holds a device color pointer, which may be a @@ -291,7 +311,7 @@ * well. */ /* Processing a text object operation */ - dev_proc(pgs->device, set_graphics_type_tag)(pgs->device, GS_TEXT_TAG); + ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ if (pte->pdcolor != 0) { int code = gx_set_dev_color(pgs); @@ -301,7 +321,7 @@ return 0; } -static inline uint text_do_draw(gs_state * pgs) +static inline uint text_do_draw(gs_gstate * pgs) { return (pgs->text_rendering_mode == 3 ? TEXT_DO_NONE | TEXT_RENDER_MODE_3 : TEXT_DO_DRAW); @@ -309,7 +329,7 @@ /* Begin PostScript-equivalent text operations. */ int -gs_show_begin(gs_state * pgs, const byte * str, uint size, +gs_show_begin(gs_gstate * pgs, const byte * str, uint size, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -319,7 +339,7 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_ashow_begin(gs_state * pgs, floatp ax, floatp ay, const byte * str, uint size, +gs_ashow_begin(gs_gstate * pgs, double ax, double ay, const byte * str, uint size, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -332,7 +352,7 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_widthshow_begin(gs_state * pgs, floatp cx, floatp cy, gs_char chr, +gs_widthshow_begin(gs_gstate * pgs, double cx, double cy, gs_char chr, const byte * str, uint size, gs_memory_t * mem, gs_text_enum_t ** ppte) { @@ -347,8 +367,8 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_awidthshow_begin(gs_state * pgs, floatp cx, floatp cy, gs_char chr, - floatp ax, floatp ay, const byte * str, uint size, +gs_awidthshow_begin(gs_gstate * pgs, double cx, double cy, gs_char chr, + double ax, double ay, const byte * str, uint size, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -365,7 +385,7 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_kshow_begin(gs_state * pgs, const byte * str, uint size, +gs_kshow_begin(gs_gstate * pgs, const byte * str, uint size, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -387,7 +407,7 @@ } int -gs_xyshow_begin(gs_state * pgs, const byte * str, uint size, +gs_xyshow_begin(gs_gstate * pgs, const byte * str, uint size, const float *x_widths, const float *y_widths, uint widths_size, gs_memory_t * mem, gs_text_enum_t ** ppte) { @@ -437,7 +457,7 @@ } int -gs_glyphshow_begin(gs_state * pgs, gs_glyph glyph, +gs_glyphshow_begin(gs_gstate * pgs, gs_glyph glyph, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -452,7 +472,7 @@ return result; } int -gs_cshow_begin(gs_state * pgs, const byte * str, uint size, +gs_cshow_begin(gs_gstate * pgs, const byte * str, uint size, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -462,7 +482,7 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_stringwidth_begin(gs_state * pgs, const byte * str, uint size, +gs_stringwidth_begin(gs_gstate * pgs, const byte * str, uint size, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -472,7 +492,7 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_charpath_begin(gs_state * pgs, const byte * str, uint size, bool stroke_path, +gs_charpath_begin(gs_gstate * pgs, const byte * str, uint size, bool stroke_path, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -483,7 +503,7 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_charboxpath_begin(gs_state * pgs, const byte * str, uint size, +gs_charboxpath_begin(gs_gstate * pgs, const byte * str, uint size, bool stroke_path, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -494,7 +514,7 @@ return gs_text_begin(pgs, &text, mem, ppte); } int -gs_glyphpath_begin(gs_state * pgs, gs_glyph glyph, bool stroke_path, +gs_glyphpath_begin(gs_gstate * pgs, gs_glyph glyph, bool stroke_path, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -510,7 +530,7 @@ return result; } int -gs_glyphwidth_begin(gs_state * pgs, gs_glyph glyph, +gs_glyphwidth_begin(gs_gstate * pgs, gs_glyph glyph, gs_memory_t * mem, gs_text_enum_t ** ppte) { gs_text_params_t text; @@ -704,7 +724,7 @@ if (pte->outer_CID != GS_NO_GLYPH) *pglyph = pte->outer_CID; else - *pglyph = gs_no_glyph; + *pglyph = GS_NO_GLYPH; } else if (pte->text.operation & TEXT_FROM_SINGLE_GLYPH) { /* glyphshow or glyphpath */ *pchr = gs_no_char; @@ -714,10 +734,10 @@ *pglyph = pte->text.data.glyphs[pte->index]; } else if (pte->text.operation & TEXT_FROM_SINGLE_CHAR) { *pchr = pte->text.data.d_char; - *pglyph = gs_no_glyph; + *pglyph = GS_NO_GLYPH; } else if (pte->text.operation & TEXT_FROM_CHARS) { *pchr = pte->text.data.chars[pte->index]; - *pglyph = gs_no_glyph; + *pglyph = GS_NO_GLYPH; } else return_error(gs_error_rangecheck); /* shouldn't happen */ pte->index++; @@ -726,7 +746,7 @@ /* Dummy (ineffective) BuildChar/BuildGlyph procedure */ int -gs_no_build_char(gs_show_enum *pte, gs_state *pgs, gs_font *pfont, +gs_no_build_char(gs_show_enum *pte, gs_gstate *pgs, gs_font *pfont, gs_char chr, gs_glyph glyph) { return 1; /* failure, but not error */ diff -Nru ghostscript-9.10~dfsg/base/gstext.h ghostscript-9.25~dfsg+1/base/gstext.h --- ghostscript-9.10~dfsg/base/gstext.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstext.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -90,6 +90,8 @@ #define TEXT_RETURN_WIDTH 0x20000 /* PDF mode "3 Tr" */ #define TEXT_RENDER_MODE_3 0x40000 +/* Do not pull a glyph from the glyph cache */ +#define TEXT_NO_CACHE 0x80000 /* * Define the structure of parameters passed in for text display. @@ -149,9 +151,9 @@ # define gx_device_DEFINED typedef struct gx_device_s gx_device; #endif -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_device_color_DEFINED # define gx_device_color_DEFINED @@ -176,7 +178,7 @@ */ #define dev_t_proc_text_begin(proc, dev_t)\ int proc(dev_t *dev,\ - gs_imager_state *pis,\ + gs_gstate *pgs,\ const gs_text_params_t *text,\ gs_font *font,\ gx_path *path, /* unless DO_NONE */\ @@ -194,53 +196,53 @@ dev_proc_text_begin(gx_device_text_begin); /* Begin processing text with a graphics state. */ -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif -int gs_text_begin(gs_state * pgs, const gs_text_params_t * text, +int gs_text_begin(gs_gstate * pgs, const gs_text_params_t * text, gs_memory_t * mem, gs_text_enum_t ** ppenum); /* * Update the device color to be used with text (because a kshow or * cshow procedure may have changed the current color). */ -int gs_text_update_dev_color(gs_state * pgs, gs_text_enum_t * pte); +int gs_text_update_dev_color(gs_gstate * pgs, gs_text_enum_t * pte); /* Begin the PostScript-equivalent text operators. */ int -gs_show_begin(gs_state *, const byte *, uint, +gs_show_begin(gs_gstate *, const byte *, uint, gs_memory_t *, gs_text_enum_t **), - gs_ashow_begin(gs_state *, floatp, floatp, const byte *, uint, + gs_ashow_begin(gs_gstate *, double, double, const byte *, uint, gs_memory_t *, gs_text_enum_t **), - gs_widthshow_begin(gs_state *, floatp, floatp, gs_char, + gs_widthshow_begin(gs_gstate *, double, double, gs_char, const byte *, uint, gs_memory_t *, gs_text_enum_t **), - gs_awidthshow_begin(gs_state *, floatp, floatp, gs_char, - floatp, floatp, const byte *, uint, + gs_awidthshow_begin(gs_gstate *, double, double, gs_char, + double, double, const byte *, uint, gs_memory_t *, gs_text_enum_t **), - gs_kshow_begin(gs_state *, const byte *, uint, + gs_kshow_begin(gs_gstate *, const byte *, uint, gs_memory_t *, gs_text_enum_t **), - gs_xyshow_begin(gs_state *, const byte *, uint, + gs_xyshow_begin(gs_gstate *, const byte *, uint, const float *, const float *, uint, gs_memory_t *, gs_text_enum_t **), - gs_glyphshow_begin(gs_state *, gs_glyph, + gs_glyphshow_begin(gs_gstate *, gs_glyph, gs_memory_t *, gs_text_enum_t **), - gs_cshow_begin(gs_state *, const byte *, uint, + gs_cshow_begin(gs_gstate *, const byte *, uint, gs_memory_t *, gs_text_enum_t **), - gs_stringwidth_begin(gs_state *, const byte *, uint, + gs_stringwidth_begin(gs_gstate *, const byte *, uint, gs_memory_t *, gs_text_enum_t **), - gs_charpath_begin(gs_state *, const byte *, uint, bool, + gs_charpath_begin(gs_gstate *, const byte *, uint, bool, gs_memory_t *, gs_text_enum_t **), - gs_glyphpath_begin(gs_state *, gs_glyph, bool, + gs_glyphpath_begin(gs_gstate *, gs_glyph, bool, gs_memory_t *, gs_text_enum_t **), - gs_glyphwidth_begin(gs_state *, gs_glyph, + gs_glyphwidth_begin(gs_gstate *, gs_glyph, gs_memory_t *, gs_text_enum_t **), - gs_charboxpath_begin(gs_state *, const byte *, uint, bool, + gs_charboxpath_begin(gs_gstate *, const byte *, uint, bool, gs_memory_t *, gs_text_enum_t **); /* Compute the number of characters in a text. */ -int gs_text_size(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem); +int gs_text_size(gs_gstate * pgs, gs_text_params_t *text, gs_memory_t * mem); /* Retrieve text params from enumerator. */ gs_text_params_t *gs_get_text_params(gs_text_enum_t *pte); @@ -328,6 +330,6 @@ void gs_text_release(gs_text_enum_t *pte, client_name_t cname); /* Compute the number of characters in a text. */ -int gs_text_count_chars(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem); +int gs_text_count_chars(gs_gstate * pgs, gs_text_params_t *text, gs_memory_t * mem); #endif /* gstext_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gstiffio.c ghostscript-9.25~dfsg+1/base/gstiffio.c --- ghostscript-9.10~dfsg/base/gstiffio.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstiffio.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -244,6 +244,17 @@ return (malloc((size_t) s)); } +void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) +{ + void *m = NULL; + if( nmemb != 0 && siz != 0 ) { + m = malloc((size_t)(nmemb * siz)); + } + if (m) + memset(m, 0x00, (size_t)(nmemb * siz)); + return m; +} + void _TIFFfree(void* p) { diff -Nru ghostscript-9.10~dfsg/base/gstiffio.h ghostscript-9.25~dfsg+1/base/gstiffio.h --- ghostscript-9.10~dfsg/base/gstiffio.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstiffio.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ #ifndef gstiffio_INCLUDED diff -Nru ghostscript-9.10~dfsg/base/gstparam.h ghostscript-9.25~dfsg+1/base/gstparam.h --- ghostscript-9.10~dfsg/base/gstparam.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstparam.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -42,7 +42,8 @@ BLEND_MODE_Hue, BLEND_MODE_Saturation, BLEND_MODE_Color, -#define MAX_BLEND_MODE BLEND_MODE_Color + BLEND_MODE_CompatibleOverprint, +#define MAX_BLEND_MODE BLEND_MODE_CompatibleOverprint /* For compatibility with old PDFs */ BLEND_MODE_Compatible @@ -51,7 +52,7 @@ "Normal", "Multiply", "Screen", "Difference",\ "Darken", "Lighten", "ColorDodge", "ColorBurn", "Exclusion",\ "HardLight", "Overlay", "SoftLight", "Luminosity", "Hue",\ - "Saturation", "Color", "Compatible" + "Saturation", "Color", "CompatibleOverprint", "Compatible" /* Define the parameter structure for a transparency group. */ #ifndef gs_color_space_DEFINED @@ -69,6 +70,7 @@ bool Isolated; bool Knockout; bool image_with_SMask; + int text_group; bool idle; uint mask_id; int group_color_numcomps; @@ -80,11 +82,12 @@ /* Define the parameter structure for a transparency mask. */ typedef enum { TRANSPARENCY_MASK_Alpha, - TRANSPARENCY_MASK_Luminosity + TRANSPARENCY_MASK_Luminosity, + TRANSPARENCY_MASK_None /* special case for removing a SMask from the tos */ } gs_transparency_mask_subtype_t; #define GS_TRANSPARENCY_MASK_SUBTYPE_NAMES\ - "Alpha", "Luminosity" + "Alpha", "Luminosity", "None" /* See the gx_transparency_mask_params_t type below */ /* (Update gs_trans_mask_params_init if these change.) */ @@ -92,9 +95,11 @@ const gs_color_space *ColorSpace; gs_transparency_mask_subtype_t subtype; int Background_components; + int Matte_components; float Background[GS_CLIENT_COLOR_MAX_COMPONENTS]; + float Matte[GS_CLIENT_COLOR_MAX_COMPONENTS]; float GrayBackground; - int (*TransferFunction)(floatp in, float *out, void *proc_data); + int (*TransferFunction)(double in, float *out, void *proc_data); gs_function_t *TransferFunction_data; bool replacing; int64_t icc_hashcode; /* Needed when we are doing clist reading */ @@ -109,7 +114,9 @@ int group_color_numcomps; gs_transparency_color_t group_color; int Background_components; + int Matte_components; float Background[GS_CLIENT_COLOR_MAX_COMPONENTS]; + float Matte[GS_CLIENT_COLOR_MAX_COMPONENTS]; float GrayBackground; bool function_is_identity; bool idle; @@ -130,10 +137,11 @@ 1 + sizeof(float) * 6 /* See sput_matrix. */ + \ sizeof(((gs_pdf14trans_params_t *)0)->subtype) + \ sizeof(((gs_pdf14trans_params_t *)0)->group_color_numcomps) + \ - 4 /* group color, replacing, function_is_identity, Background_components */ + \ + 5 /* group color, replacing, function_is_identity, Background_components, Matte_components */ + \ sizeof(((gs_pdf14trans_params_t *)0)->bbox) + \ sizeof(((gs_pdf14trans_params_t *)0)->mask_id) + \ sizeof(((gs_pdf14trans_params_t *)0)->Background) + \ + sizeof(((gs_pdf14trans_params_t *)0)->Matte) + \ sizeof(float)*4 + /* If cmyk background */ \ sizeof(((gs_pdf14trans_params_t *)0)->GrayBackground) + \ sizeof(int64_t)) /* ICC band information */ diff -Nru ghostscript-9.10~dfsg/base/gstrans.c ghostscript-9.25~dfsg+1/base/gstrans.c --- ghostscript-9.10~dfsg/base/gstrans.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstrans.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -34,7 +34,7 @@ /* ------ Transparency-related graphics state elements ------ */ int -gs_setblendmode(gs_state *pgs, gs_blend_mode_t mode) +gs_setblendmode(gs_gstate *pgs, gs_blend_mode_t mode) { #ifdef DEBUG if (gs_debug_c('v')) { @@ -52,20 +52,20 @@ /* Compatible is now specified to be the same. */ if (mode == BLEND_MODE_Compatible) mode = BLEND_MODE_Normal; - if (mode < 0 || mode > MAX_BLEND_MODE) + if ((int)mode < 0 || (int)mode > MAX_BLEND_MODE) return_error(gs_error_rangecheck); pgs->blend_mode = mode; return 0; } gs_blend_mode_t -gs_currentblendmode(const gs_state *pgs) +gs_currentblendmode(const gs_gstate *pgs) { return pgs->blend_mode; } int -gs_setopacityalpha(gs_state *pgs, floatp alpha) +gs_setopacityalpha(gs_gstate *pgs, double alpha) { if_debug2m('v', pgs->memory, "[v](0x%lx)opacity.alpha = %g\n", (ulong)pgs, alpha); pgs->opacity.alpha = (alpha < 0.0 ? 0.0 : alpha > 1.0 ? 1.0 : alpha); @@ -73,13 +73,13 @@ } float -gs_currentopacityalpha(const gs_state *pgs) +gs_currentopacityalpha(const gs_gstate *pgs) { return pgs->opacity.alpha; } int -gs_setshapealpha(gs_state *pgs, floatp alpha) +gs_setshapealpha(gs_gstate *pgs, double alpha) { if_debug2m('v', pgs->memory, "[v](0x%lx)shape.alpha = %g\n", (ulong)pgs, alpha); pgs->shape.alpha = (alpha < 0.0 ? 0.0 : alpha > 1.0 ? 1.0 : alpha); @@ -87,13 +87,13 @@ } float -gs_currentshapealpha(const gs_state *pgs) +gs_currentshapealpha(const gs_gstate *pgs) { return pgs->shape.alpha; } int -gs_settextknockout(gs_state *pgs, bool knockout) +gs_settextknockout(gs_gstate *pgs, bool knockout) { if_debug2m('v', pgs->memory, "[v](0x%lx)text_knockout = %s\n", (ulong)pgs, (knockout ? "true" : "false")); @@ -102,7 +102,7 @@ } bool -gs_currenttextknockout(const gs_state *pgs) +gs_currenttextknockout(const gs_gstate *pgs) { return pgs->text_knockout; } @@ -115,11 +115,11 @@ be entered as compositor actions in the pattern clist */ static int -check_for_nontrans_pattern(gs_state *pgs, unsigned char *comp_name) +check_for_nontrans_pattern(gs_gstate *pgs, unsigned char *comp_name) { gx_device * dev = pgs->device; - bool is_patt_clist = (strcmp("pattern-clist",dev->dname) == 0); - bool is_patt_acum = (strcmp("pattern accumulator",dev->dname) == 0); + bool is_patt_clist = gx_device_is_pattern_clist(dev); + bool is_patt_acum = gx_device_is_pattern_accum(dev); /* Check if we are collecting data for a pattern that has no transparency. In that case, we need to ignore the state changes */ @@ -155,24 +155,33 @@ * compositor device. */ static int -gs_state_update_pdf14trans(gs_state * pgs, gs_pdf14trans_params_t * pparams) +gs_gstate_update_pdf14trans(gs_gstate * pgs, gs_pdf14trans_params_t * pparams) { - gs_imager_state * pis = (gs_imager_state *)pgs; gx_device * dev = pgs->device; gx_device *pdf14dev = NULL; int code; + int curr_num = dev->color_info.num_components; /* * Send the PDF 1.4 create compositor action specified by the parameters. */ - code = send_pdf14trans(pis, dev, &pdf14dev, pparams, pgs->memory); + code = send_pdf14trans(pgs, dev, &pdf14dev, pparams, pgs->memory); + if (code < 0) + return code; /* * If we created a new PDF 1.4 compositor device then we need to install it * into the graphics state. */ - if (code >= 0 && pdf14dev != dev) { + if (pdf14dev != dev) { gx_set_device_only(pgs, pdf14dev); } + + /* If we had a color space change and we are in overprint, then we need to + update the drawn_comps */ + if (pgs->overprint && curr_num != pdf14dev->color_info.num_components) { + code = gs_do_set_overprint(pgs); + } + return code; } @@ -182,29 +191,29 @@ ptgp->ColorSpace = NULL; /* bogus, but can't do better */ ptgp->Isolated = false; ptgp->Knockout = false; + ptgp->text_group = PDF14_TEXTGROUP_NO_BT; ptgp->image_with_SMask = false; ptgp->mask_id = 0; ptgp->iccprofile = NULL; } int -gs_update_trans_marking_params(gs_state * pgs) +gs_update_trans_marking_params(gs_gstate * pgs) { gs_pdf14trans_params_t params = { 0 }; if_debug0m('v', pgs->memory, "[v]gs_update_trans_marking_params\n"); params.pdf14_op = PDF14_SET_BLEND_PARAMS; - return gs_state_update_pdf14trans(pgs, ¶ms); + return gs_gstate_update_pdf14trans(pgs, ¶ms); } int -gs_begin_transparency_group(gs_state *pgs, +gs_begin_transparency_group(gs_gstate *pgs, const gs_transparency_group_params_t *ptgp, const gs_rect *pbbox) { gs_pdf14trans_params_t params = { 0 }; const gs_color_space *blend_color_space; - gs_imager_state * pis = (gs_imager_state *)pgs; cmm_profile_t *profile; if (check_for_nontrans_pattern(pgs, @@ -223,6 +232,7 @@ params.opacity = pgs->opacity; params.shape = pgs->shape; params.blend_mode = pgs->blend_mode; + params.text_group = ptgp->text_group; /* This function is called during the c-list writer side. Store some information so that we know what the color space is so that we can adjust according later during the clist reader. @@ -237,7 +247,9 @@ ICC default color space in these cases. */ blend_color_space = gs_currentcolorspace_inline(pgs); } else { - blend_color_space = cs_concrete_space(blend_color_space, pis); + blend_color_space = cs_concrete_space(blend_color_space, pgs); + if (!blend_color_space) + return_error(gs_error_undefined); } /* Note that if the /CS parameter was NOT present in the push of the transparency group, then we must actually inherent @@ -245,8 +257,10 @@ target device (process color model). Here we just want to set it as a unknown type for clist writing, as we will take care of using the parent group color space later during clist reading. + Also, if the group was not isolated we MUST use the parent group + color space regardless of what the group color space is specified to be */ - if (ptgp->ColorSpace == NULL) { + if (ptgp->ColorSpace == NULL || params.Isolated != true) { params.group_color = UNKNOWN; params.group_color_numcomps = 0; } else { @@ -310,16 +324,16 @@ else dmputs(pgs->memory, " (no CS)"); - dmprintf2(pgs->memory, " Isolated = %d Knockout = %d\n", - ptgp->Isolated, ptgp->Knockout); + dmprintf3(pgs->memory, " Isolated = %d Knockout = %d text_group = %d\n", + ptgp->Isolated, ptgp->Knockout, ptgp->text_group); } #endif params.bbox = *pbbox; - return gs_state_update_pdf14trans(pgs, ¶ms); + return gs_gstate_update_pdf14trans(pgs, ¶ms); } int -gx_begin_transparency_group(gs_imager_state * pis, gx_device * pdev, +gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev, const gs_pdf14trans_params_t * pparams) { gs_transparency_group_params_t tgp = {0}; @@ -332,6 +346,7 @@ tgp.Knockout = pparams->Knockout; tgp.idle = pparams->idle; tgp.mask_id = pparams->mask_id; + tgp.text_group = pparams->text_group; /* Needed so that we do proper blending */ tgp.group_color = pparams->group_color; @@ -339,9 +354,9 @@ tgp.iccprofile = pparams->iccprofile; tgp.icc_hashcode = pparams->icc_hash; - pis->opacity.alpha = pparams->opacity.alpha; - pis->shape.alpha = pparams->shape.alpha; - pis->blend_mode = pparams->blend_mode; + pgs->opacity.alpha = pparams->opacity.alpha; + pgs->shape.alpha = pparams->shape.alpha; + pgs->blend_mode = pparams->blend_mode; bbox = pparams->bbox; #ifdef DEBUG if (gs_debug_c('v')) { @@ -349,7 +364,7 @@ GS_COLOR_SPACE_TYPE_NAMES }; dmlprintf6(pdev->memory, "[v](0x%lx)gx_begin_transparency_group [%g %g %g %g] Num_grp_clr_comp = %d\n", - (ulong)pis, bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y, + (ulong)pgs, bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y, pparams->group_color_numcomps); if (tgp.ColorSpace) dmprintf1(pdev->memory, " CS = %s", @@ -362,44 +377,65 @@ dmprintf(pdev->memory, " Have ICC Profile for blending\n"); } #endif - if (dev_proc(pdev, begin_transparency_group) != 0) - return (*dev_proc(pdev, begin_transparency_group)) (pdev, &tgp, - &bbox, pis, NULL); - else - return 0; + return (*dev_proc(pdev, begin_transparency_group)) (pdev, &tgp, &bbox, pgs, + NULL); } int -gs_end_transparency_group(gs_state *pgs) +gs_end_transparency_group(gs_gstate *pgs) { gs_pdf14trans_params_t params = { 0 }; - if (pgs->is_gstate && check_for_nontrans_pattern(pgs, + if (check_for_nontrans_pattern(pgs, (unsigned char *)"gs_end_transparency_group")) { return(0); } if_debug0m('v', pgs->memory, "[v]gs_end_transparency_group\n"); params.pdf14_op = PDF14_END_TRANS_GROUP; /* Other parameters not used */ - return gs_state_update_pdf14trans(pgs, ¶ms); + return gs_gstate_update_pdf14trans(pgs, ¶ms); +} + +int +gs_end_transparency_text_group(gs_gstate *pgs) +{ + gs_pdf14trans_params_t params = { 0 }; + + if (check_for_nontrans_pattern(pgs, + (unsigned char *)"gs_end_transparency_text_group")) { + return(0); + } + if_debug0m('v', pgs->memory, "[v]gs_end_transparency_text_group\n"); + params.pdf14_op = PDF14_END_TRANS_TEXT_GROUP; /* Other parameters not used */ + return gs_gstate_update_pdf14trans(pgs, ¶ms); +} + +int +gs_begin_transparency_text_group(gs_gstate *pgs) +{ + gs_pdf14trans_params_t params = { 0 }; + + if (check_for_nontrans_pattern(pgs, + (unsigned char *)"gs_begin_transparency_text_group")) { + return(0); + } + if_debug0m('v', pgs->memory, "[v]gs_begin_transparency_text_group\n"); + params.pdf14_op = PDF14_BEGIN_TRANS_TEXT_GROUP; /* Other parameters not used */ + return gs_gstate_update_pdf14trans(pgs, ¶ms); } int -gx_end_transparency_group(gs_imager_state * pis, gx_device * pdev) +gx_end_transparency_group(gs_gstate * pgs, gx_device * pdev) { - if_debug0m('v', pis->memory, "[v]gx_end_transparency_group\n"); - if (dev_proc(pdev, end_transparency_group) != 0) - return (*dev_proc(pdev, end_transparency_group)) (pdev, pis); - else - return 0; + if_debug0m('v', pgs->memory, "[v]gx_end_transparency_group\n"); + return (*dev_proc(pdev, end_transparency_group)) (pdev, pgs); } /* Commands for handling q softmask Q in graphic states */ int -gs_push_transparency_state(gs_state *pgs) +gs_push_transparency_state(gs_gstate *pgs) { gs_pdf14trans_params_t params = { 0 }; - gs_imager_state * pis = (gs_imager_state *)pgs; int code; if (check_for_nontrans_pattern(pgs, @@ -410,7 +446,7 @@ that we need to watch for end transparency soft masks when we are at this graphic state level */ - /* pis->trans_flags.xstate_pending = true; */ + /* pgs->trans_flags.xstate_pending = true; */ /* Actually I believe the above flag is not needed. We really should be watching for the softmask even at the base level. What @@ -421,10 +457,10 @@ We will need to send a push state to save the current soft mask, so that we can restore it later */ - if (pis->trans_flags.xstate_change) { + if (pgs->trans_flags.xstate_change) { if_debug0m('v', pgs->memory, "[v]gs_push_transparency_state sending\n"); params.pdf14_op = PDF14_PUSH_TRANS_STATE; - code = gs_state_update_pdf14trans(pgs, ¶ms); + code = gs_gstate_update_pdf14trans(pgs, ¶ms); if (code < 0) return(code); } else { @@ -434,10 +470,9 @@ } int -gs_pop_transparency_state(gs_state *pgs, bool force) +gs_pop_transparency_state(gs_gstate *pgs, bool force) { gs_pdf14trans_params_t params = { 0 }; - gs_imager_state * pis = (gs_imager_state *)pgs; int code; if (check_for_nontrans_pattern(pgs, @@ -448,10 +483,10 @@ an active softmask for the graphic state. We need to communicate to the compositor to pop the softmask */ - if ( pis->trans_flags.xstate_change || force) { + if ( pgs->trans_flags.xstate_change || force) { if_debug0m('v', pgs->memory, "[v]gs_pop_transparency_state sending\n"); params.pdf14_op = PDF14_POP_TRANS_STATE; - code = gs_state_update_pdf14trans(pgs, ¶ms); + code = gs_gstate_update_pdf14trans(pgs, ¶ms); if ( code < 0 ) return (code); } else { @@ -463,30 +498,24 @@ } int -gx_pop_transparency_state(gs_imager_state * pis, gx_device * pdev) +gx_pop_transparency_state(gs_gstate * pgs, gx_device * pdev) { - if_debug0m('v', pis->memory, "[v]gx_pop_transparency_state\n"); - if (dev_proc(pdev, pop_transparency_state) != 0) - return (*dev_proc(pdev, pop_transparency_state)) (pdev, pis); - else - return 0; + if_debug0m('v', pgs->memory, "[v]gx_pop_transparency_state\n"); + return (*dev_proc(pdev, pop_transparency_state)) (pdev, pgs); } int -gx_push_transparency_state(gs_imager_state * pis, gx_device * pdev) +gx_push_transparency_state(gs_gstate * pgs, gx_device * pdev) { - if_debug0m('v', pis->memory, "[v]gx_push_transparency_state\n"); - if (dev_proc(pdev, push_transparency_state) != 0) - return (*dev_proc(pdev, push_transparency_state)) (pdev, pis); - else - return 0; + if_debug0m('v', pgs->memory, "[v]gx_push_transparency_state\n"); + return (*dev_proc(pdev, push_transparency_state)) (pdev, pgs); } /* * Handler for identity mask transfer functions. */ static int -mask_transfer_identity(floatp in, float *out, void *proc_data) +mask_transfer_identity(double in, float *out, void *proc_data) { *out = (float) in; return 0; @@ -499,6 +528,7 @@ ptmp->ColorSpace = 0; ptmp->subtype = subtype; ptmp->Background_components = 0; + ptmp->Matte_components = 0; ptmp->GrayBackground = 0.0; ptmp->TransferFunction = mask_transfer_identity; ptmp->TransferFunction_data = 0; @@ -507,13 +537,14 @@ } int -gs_begin_transparency_mask(gs_state * pgs, +gs_begin_transparency_mask(gs_gstate * pgs, const gs_transparency_mask_params_t * ptmp, const gs_rect * pbbox, bool mask_is_image) { gs_pdf14trans_params_t params = { 0 }; gs_pdf14trans_params_t params_color = { 0 }; const int l = sizeof(params.Background[0]) * ptmp->Background_components; + const int m = sizeof(params.Matte[0]) * ptmp->Matte_components; int i, code; gs_color_space *blend_color_space; gsicc_manager_t *icc_manager = pgs->icc_manager; @@ -527,6 +558,8 @@ params.subtype = ptmp->subtype; params.Background_components = ptmp->Background_components; memcpy(params.Background, ptmp->Background, l); + params.Matte_components = ptmp->Matte_components; + memcpy(params.Matte, ptmp->Matte, m); params.GrayBackground = ptmp->GrayBackground; params.transfer_function = ptmp->TransferFunction_data; params.function_is_identity = @@ -550,60 +583,74 @@ } /* A new soft mask group, make sure the profiles are set */ if_debug0m('v', pgs->memory, "[v]pushing soft mask color sending\n"); - params_color.pdf14_op = PDF14_PUSH_SMASK_COLOR; - code = gs_state_update_pdf14trans(pgs, ¶ms_color); - if (code < 0) - return(code); - blend_color_space = gs_cspace_new_DeviceGray(pgs->memory); - blend_color_space->cmm_icc_profile_data = pgs->icc_manager->default_gray; - rc_increment(blend_color_space->cmm_icc_profile_data); - if_debug8m('v', pgs->memory, "[v](0x%lx)gs_begin_transparency_mask [%g %g %g %g]\n\ - subtype = %d Background_components = %d %s\n", - (ulong)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y, - (int)ptmp->subtype, ptmp->Background_components, - (ptmp->TransferFunction == mask_transfer_identity ? "no TR" : - "has TR")); - /* Sample the transfer function */ - for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) { - float in = (float)(i * (1.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1))); - float out; - - ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data); - params.transfer_fn[i] = (byte)floor((double)(out * 255 + 0.5)); - } - /* Note: This function is called during the c-list writer side. */ - if ( blend_color_space->cmm_icc_profile_data != NULL ) { - /* Blending space is ICC based. If we are doing c-list rendering we will - need to write this color space into the clist. */ - params.group_color = ICC; - params.group_color_numcomps = - blend_color_space->cmm_icc_profile_data->num_comps; - /* Get the ICC profile */ - params.iccprofile = blend_color_space->cmm_icc_profile_data; - params.icc_hash = blend_color_space->cmm_icc_profile_data->hashcode; - rc_increment(params.iccprofile); - } else { - params.group_color = GRAY_SCALE; - params.group_color_numcomps = 1; /* Need to check */ + if (params.subtype != TRANSPARENCY_MASK_None) { + params_color.pdf14_op = PDF14_PUSH_SMASK_COLOR; + code = gs_gstate_update_pdf14trans(pgs, ¶ms_color); + if (code < 0) + return(code); + blend_color_space = gs_cspace_new_DeviceGray(pgs->memory); + if (blend_color_space == NULL) + return_error(gs_error_VMerror); + blend_color_space->cmm_icc_profile_data = pgs->icc_manager->default_gray; + gsicc_adjust_profile_rc(blend_color_space->cmm_icc_profile_data, 1, "gs_begin_transparency_mask"); + if_debug9m('v', pgs->memory, "[v](0x%lx)gs_begin_transparency_mask [%g %g %g %g]\n\ + subtype = %d Background_components = %d, Matte_components = %d, %s\n", + (ulong)pgs, pbbox->p.x, pbbox->p.y, pbbox->q.x, pbbox->q.y, + (int)ptmp->subtype, ptmp->Background_components, + ptmp->Matte_components, + (ptmp->TransferFunction == mask_transfer_identity ? "no TR" : + "has TR")); + /* Sample the transfer function */ + for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) { + float in = (float)(i * (1.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1))); + float out; + + ptmp->TransferFunction(in, &out, ptmp->TransferFunction_data); + params.transfer_fn[i] = (byte)floor((double)(out * 255 + 0.5)); + } + /* Note: This function is called during the c-list writer side. */ + if ( blend_color_space->cmm_icc_profile_data != NULL ) { + /* Blending space is ICC based. If we are doing c-list rendering we will + need to write this color space into the clist. */ + params.group_color = ICC; + params.group_color_numcomps = + blend_color_space->cmm_icc_profile_data->num_comps; + /* Get the ICC profile */ + /* We don't reference count this - see comment in + * pdf14_update_device_color_procs_pop_c() + */ + params.iccprofile = blend_color_space->cmm_icc_profile_data; + params.icc_hash = blend_color_space->cmm_icc_profile_data->hashcode; + } else { + params.group_color = GRAY_SCALE; + params.group_color_numcomps = 1; /* Need to check */ + } + /* Explicitly decrement the profile data since blend_color_space may not + * be an ICC color space object. + */ + gsicc_adjust_profile_rc(blend_color_space->cmm_icc_profile_data, -1, "gs_begin_transparency_mask"); + rc_decrement_only_cs(blend_color_space, "gs_begin_transparency_mask"); } - rc_decrement_only_cs(blend_color_space, "gs_begin_transparency_mask"); - return gs_state_update_pdf14trans(pgs, ¶ms); + return gs_gstate_update_pdf14trans(pgs, ¶ms); } /* This occurs on the c-list reader side */ int -gx_begin_transparency_mask(gs_imager_state * pis, gx_device * pdev, +gx_begin_transparency_mask(gs_gstate * pgs, gx_device * pdev, const gs_pdf14trans_params_t * pparams) { gx_transparency_mask_params_t tmp; const int l = sizeof(pparams->Background[0]) * pparams->Background_components; + const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components; tmp.group_color = pparams->group_color; tmp.subtype = pparams->subtype; tmp.group_color_numcomps = pparams->group_color_numcomps; tmp.Background_components = pparams->Background_components; memcpy(tmp.Background, pparams->Background, l); + tmp.Matte_components = pparams->Matte_components; + memcpy(tmp.Matte, pparams->Matte, m); tmp.GrayBackground = pparams->GrayBackground; tmp.function_is_identity = pparams->function_is_identity; tmp.idle = pparams->idle; @@ -619,29 +666,25 @@ tmp.icc_hashcode = 0; } memcpy(tmp.transfer_fn, pparams->transfer_fn, size_of(tmp.transfer_fn)); - if_debug9m('v', pis->memory, + if_debug10m('v', pgs->memory, "[v](0x%lx)gx_begin_transparency_mask [%g %g %g %g]\n" - " subtype = %d Background_components = %d Num_grp_clr_comp = %d %s\n", - (ulong)pis, pparams->bbox.p.x, pparams->bbox.p.y, + " subtype = %d Background_components = %d Matte_components = %d Num_grp_clr_comp = %d %s\n", + (ulong)pgs, pparams->bbox.p.x, pparams->bbox.p.y, pparams->bbox.q.x, pparams->bbox.q.y, - (int)tmp.subtype, tmp.Background_components, + (int)tmp.subtype, tmp.Background_components, tmp.Matte_components, tmp.group_color_numcomps, (tmp.function_is_identity ? "no TR" : "has TR")); - if (dev_proc(pdev, begin_transparency_mask) != 0) - return (*dev_proc(pdev, begin_transparency_mask)) - (pdev, &tmp, &(pparams->bbox), pis, NULL); - else - return 0; + return (*dev_proc(pdev, begin_transparency_mask)) + (pdev, &tmp, &(pparams->bbox), pgs, NULL); } int -gs_end_transparency_mask(gs_state *pgs, +gs_end_transparency_mask(gs_gstate *pgs, gs_transparency_channel_selector_t csel) { gs_pdf14trans_params_t params = { 0 }; gs_pdf14trans_params_t params_color = { 0 }; - gs_imager_state * pis = (gs_imager_state *)pgs; int code; if (check_for_nontrans_pattern(pgs, @@ -649,42 +692,39 @@ return(0); } /* If we have done a q then set a flag to watch for any Qs */ - /* if (pis->trans_flags.xstate_pending) - pis->trans_flags.xstate_change = true; */ + /* if (pgs->trans_flags.xstate_pending) + pgs->trans_flags.xstate_change = true; */ /* This should not depend upon if we have encountered a q operation. We could be setting a softmask, before there is any q operation. Unlikely but it could happen. Then if we encouter a q operation (and this flag is true) we will need to push the mask graphic state (PDF14_PUSH_TRANS_STATE). */ - pis->trans_flags.xstate_change = true; - if_debug1m('v', pis->memory, + pgs->trans_flags.xstate_change = true; + if_debug1m('v', pgs->memory, "[v]xstate_changed set true, gstate level is %d\n", pgs->level); - if_debug2m('v', pis->memory, + if_debug2m('v', pgs->memory, "[v](0x%lx)gs_end_transparency_mask(%d)\n", (ulong)pgs, (int)csel); params.pdf14_op = PDF14_END_TRANS_MASK; /* Other parameters not used */ params.csel = csel; /* If this is the outer end then return us to our normal defaults */ - if_debug0m('v', pis->memory, "[v]popping soft mask color sending\n"); + if_debug0m('v', pgs->memory, "[v]popping soft mask color sending\n"); params_color.pdf14_op = PDF14_POP_SMASK_COLOR; - code = gs_state_update_pdf14trans(pgs, ¶ms_color); + code = gs_gstate_update_pdf14trans(pgs, ¶ms_color); if (code < 0) return(code); - return gs_state_update_pdf14trans(pgs, ¶ms); + return gs_gstate_update_pdf14trans(pgs, ¶ms); } int -gx_end_transparency_mask(gs_imager_state * pis, gx_device * pdev, +gx_end_transparency_mask(gs_gstate * pgs, gx_device * pdev, const gs_pdf14trans_params_t * pparams) { - if_debug2m('v', pis->memory, - "[v](0x%lx)gx_end_transparency_mask(%d)\n", (ulong)pis, + if_debug2m('v', pgs->memory, + "[v](0x%lx)gx_end_transparency_mask(%d)\n", (ulong)pgs, (int)pparams->csel); - if (dev_proc(pdev, end_transparency_mask) != 0) - return (*dev_proc(pdev, end_transparency_mask)) (pdev, pis); - else - return 0; + return (*dev_proc(pdev, end_transparency_mask)) (pdev, pgs); } /* @@ -694,7 +734,7 @@ * and convert spot colors into process colors. */ static int -get_num_pdf14_spot_colors(gs_state * pgs) +get_num_pdf14_spot_colors(gs_gstate * pgs) { gx_device * dev = pgs->device; gs_devn_params * pclist_devn_params = dev_proc(dev, ret_devn_params)(dev); @@ -723,17 +763,19 @@ } int -gs_push_pdf14trans_device(gs_state * pgs, bool is_pattern) +gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern) { gs_pdf14trans_params_t params = { 0 }; cmm_profile_t *icc_profile; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; int code; cmm_dev_profile_t *dev_profile; code = dev_proc(pgs->device, get_profile)(pgs->device, &dev_profile); - gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, - &render_cond); + if (code < 0) + return code; + gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile, + &render_cond); params.pdf14_op = PDF14_PUSH_DEVICE; /* * We really only care about the number of spot colors when we have @@ -752,15 +794,66 @@ params.iccprofile = pgs->icc_manager->default_rgb; } /* Note: Other parameters not used */ - return gs_state_update_pdf14trans(pgs, ¶ms); + return gs_gstate_update_pdf14trans(pgs, ¶ms); } int -gs_pop_pdf14trans_device(gs_state * pgs, bool is_pattern) +gs_pop_pdf14trans_device(gs_gstate * pgs, bool is_pattern) { gs_pdf14trans_params_t params = { 0 }; params.is_pattern = is_pattern; params.pdf14_op = PDF14_POP_DEVICE; /* Other parameters not used */ - return gs_state_update_pdf14trans(pgs, ¶ms); + return gs_gstate_update_pdf14trans(pgs, ¶ms); +} + +int +gs_abort_pdf14trans_device(gs_gstate * pgs) +{ + gs_pdf14trans_params_t params = { 0 }; + + params.pdf14_op = PDF14_ABORT_DEVICE; /* Other parameters not used */ + return gs_gstate_update_pdf14trans(pgs, ¶ms); +} + +/* Something has gone wrong have the device clean up everything */ + +int +gx_abort_trans_device(gs_gstate * pgs, gx_device * pdev) +{ + if_debug1m('v', pgs->memory, "[v](0x%lx)gx_abort_trans_device\n", (ulong)pgs); + return (*dev_proc(pdev, discard_transparency_layer)) (pdev, pgs); +} + +int gs_setstrokeconstantalpha(gs_gstate *pgs, float alpha) +{ + pgs->strokeconstantalpha = alpha; + return 0; +} + +float gs_getstrokeconstantalpha(const gs_gstate *pgs) +{ + return pgs->strokeconstantalpha; +} + +int gs_setfillconstantalpha(gs_gstate *pgs, float alpha) +{ + pgs->fillconstantalpha = (float)alpha; + return 0; +} + +float gs_getfillconstantalpha(const gs_gstate *pgs) +{ + return pgs->fillconstantalpha; +} + +int gs_setalphaisshape(gs_gstate *pgs, bool AIS) +{ + pgs->alphaisshape = AIS; + return 0; +} + +bool gs_getalphaisshape(gs_gstate *pgs) +{ + return pgs->alphaisshape; } diff -Nru ghostscript-9.10~dfsg/base/gstrans.h ghostscript-9.25~dfsg+1/base/gstrans.h --- ghostscript-9.10~dfsg/base/gstrans.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstrans.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,8 +30,11 @@ typedef enum { PDF14_PUSH_DEVICE, PDF14_POP_DEVICE, + PDF14_ABORT_DEVICE, PDF14_BEGIN_TRANS_GROUP, PDF14_END_TRANS_GROUP, + PDF14_BEGIN_TRANS_TEXT_GROUP, + PDF14_END_TRANS_TEXT_GROUP, PDF14_BEGIN_TRANS_MASK, PDF14_END_TRANS_MASK, PDF14_SET_BLEND_PARAMS, @@ -45,8 +48,11 @@ {\ "PDF14_PUSH_DEVICE ",\ "PDF14_POP_DEVICE ",\ + "PDF14_ABORT_DEVICE ",\ "PDF14_BEGIN_TRANS_GROUP",\ "PDF14_END_TRANS_GROUP ",\ + "PDF14_BEGIN_TRANS_TEXT_GROUP ",\ + "PDF14_END_TRANS_TEXT_GROUP ",\ "PDF14_BEGIN_TRANS_MASK ",\ "PDF14_END_TRANS_MASK ",\ "PDF14_SET_BLEND_PARAMS ",\ @@ -63,7 +69,16 @@ #define PDF14_SET_OPACITY_ALPHA (1 << 3) #define PDF14_SET_OVERPRINT (1 << 4) #define PDF14_SET_OVERPRINT_MODE (1 << 5) -#define PDF14_SET_OVERPRINT_BLEND (1 << 6) + +/* Used for keeping track of the text group madness, since we have the pdf14 + device needs to know if we are int an BT/ET group vs. a FreeText Annotation + as well as if we have already pushed a special knockout non-isolated group + for doing text knockout */ +typedef enum { + PDF14_TEXTGROUP_NO_BT, /* We are not in a BT/ET. Avoids Annotation Texts */ + PDF14_TEXTGROUP_BT_NOT_PUSHED, /* We are in a BT/ET but no group pushed */ + PDF14_TEXTGROUP_BT_PUSHED /* We are in a BT/ET section and group was pushed */ +} pdf14_text_group_state; #ifndef gs_function_DEFINED typedef struct gs_function_s gs_function_t; @@ -89,9 +104,11 @@ gs_transparency_channel_selector_t csel; /* Parameters from the gx_transparency_mask_params_t structure */ gs_transparency_mask_subtype_t subtype; - int Background_components; bool function_is_identity; + int Background_components; float Background[GS_CLIENT_COLOR_MAX_COMPONENTS]; + int Matte_components; + float Matte[GS_CLIENT_COLOR_MAX_COMPONENTS]; float GrayBackground; /* This is used to determine if the softmask's bbox needs to be adjusted to the parent groups bbox. Since @@ -103,6 +120,7 @@ /* Individual transparency parameters */ gs_blend_mode_t blend_mode; bool text_knockout; + int text_group; gs_transparency_source_t opacity; gs_transparency_source_t shape; bool mask_is_image; @@ -110,7 +128,6 @@ bool replacing; bool overprint; bool overprint_mode; - bool blendspot; bool idle; /* For clist reader.*/ uint mask_id; /* For clist reader.*/ int group_color_numcomps; @@ -138,57 +155,65 @@ } gs_pdf14trans_t; /* Access transparency-related graphics state elements. */ -int gs_setblendmode(gs_state *, gs_blend_mode_t); -gs_blend_mode_t gs_currentblendmode(const gs_state *); -int gs_setopacityalpha(gs_state *, floatp); -float gs_currentopacityalpha(const gs_state *); -int gs_setshapealpha(gs_state *, floatp); -float gs_currentshapealpha(const gs_state *); -int gs_settextknockout(gs_state *, bool); -bool gs_currenttextknockout(const gs_state *); +int gs_setblendmode(gs_gstate *, gs_blend_mode_t); +gs_blend_mode_t gs_currentblendmode(const gs_gstate *); +int gs_setopacityalpha(gs_gstate *, double); +float gs_currentopacityalpha(const gs_gstate *); +int gs_setshapealpha(gs_gstate *, double); +float gs_currentshapealpha(const gs_gstate *); +int gs_settextknockout(gs_gstate *, bool); +bool gs_currenttextknockout(const gs_gstate *); /* * We have to abbreviate the procedure name because procedure names are * only unique to 23 characters on VMS. */ -int gs_push_pdf14trans_device(gs_state * pgs, bool is_pattern); +int gs_push_pdf14trans_device(gs_gstate * pgs, bool is_pattern); + +int gs_pop_pdf14trans_device(gs_gstate * pgs, bool is_pattern); -int gs_pop_pdf14trans_device(gs_state * pgs, bool is_pattern); +int gs_abort_pdf14trans_device(gs_gstate * pgs); void gs_trans_group_params_init(gs_transparency_group_params_t *ptgp); -int gs_update_trans_marking_params(gs_state * pgs); +int gs_update_trans_marking_params(gs_gstate * pgs); -int gs_begin_transparency_group(gs_state * pgs, +int gs_begin_transparency_group(gs_gstate * pgs, const gs_transparency_group_params_t *ptgp, const gs_rect *pbbox); -int gs_end_transparency_group(gs_state *pgs); +int gs_end_transparency_group(gs_gstate *pgs); + +int gs_end_transparency_text_group(gs_gstate *pgs); +int gs_begin_transparency_text_group(gs_gstate *pgs); void gs_trans_mask_params_init(gs_transparency_mask_params_t *ptmp, gs_transparency_mask_subtype_t subtype); -int gs_begin_transparency_mask(gs_state *pgs, +int gs_begin_transparency_mask(gs_gstate *pgs, const gs_transparency_mask_params_t *ptmp, const gs_rect *pbbox, bool mask_is_image); -int gs_end_transparency_mask(gs_state *pgs, +int gs_end_transparency_mask(gs_gstate *pgs, gs_transparency_channel_selector_t csel); /* * Imager level routines for the PDF 1.4 transparency operations. */ -int gx_begin_transparency_group(gs_imager_state * pis, gx_device * pdev, +int gx_begin_transparency_group(gs_gstate * pgs, gx_device * pdev, const gs_pdf14trans_params_t * pparams); -int gx_end_transparency_group(gs_imager_state * pis, gx_device * pdev); +int gx_end_transparency_group(gs_gstate * pgs, gx_device * pdev); -int gx_begin_transparency_mask(gs_imager_state * pis, gx_device * pdev, +int gx_begin_transparency_mask(gs_gstate * pgs, gx_device * pdev, const gs_pdf14trans_params_t * pparams); -int gx_end_transparency_mask(gs_imager_state * pis, gx_device * pdev, +int gx_end_transparency_mask(gs_gstate * pgs, gx_device * pdev, const gs_pdf14trans_params_t * pparams); +int gx_abort_trans_device(gs_gstate * pgs, gx_device * pdev); + + /* These are used for watching for q Smask Q events. We need to send special compositor commands to keep the bands in sync with the current softmask during clist rendering. Like the @@ -196,19 +221,26 @@ clist writer side and the gx functions occur on the clist reader side */ -int gs_push_transparency_state(gs_state *pgs); +int gs_push_transparency_state(gs_gstate *pgs); -int gs_pop_transparency_state(gs_state *pgs, bool force); +int gs_pop_transparency_state(gs_gstate *pgs, bool force); -int gx_push_transparency_state(gs_imager_state * pis, gx_device * pdev); +int gx_push_transparency_state(gs_gstate * pgs, gx_device * pdev); -int gx_pop_transparency_state(gs_imager_state * pis, gx_device * pdev); +int gx_pop_transparency_state(gs_gstate * pgs, gx_device * pdev); /* * Verify that a compositor data structure is for the PDF 1.4 compositor. */ int gs_is_pdf14trans_compositor(const gs_composite_t * pct); +int gs_setstrokeconstantalpha(gs_gstate *pgs, float alpha); +float gs_getstrokeconstantalpha(const gs_gstate *pgs); +int gs_setfillconstantalpha(gs_gstate *pgs, float alpha); +float gs_getfillconstantalpha(const gs_gstate *pgs); +int gs_setalphaisshape(gs_gstate *pgs, bool AIS); +bool gs_getalphaisshape(gs_gstate *pgs); + /* * Estimate the amount of space that will be required by the PDF 1.4 * transparency buffers for doing the blending operations. These buffers @@ -222,13 +254,13 @@ * since it is a hack, we may exceed our desired buffer space while * processing the file. */ -#define NUM_PDF14_BUFFERS 3 /* totally a random guess */ +#define NUM_PDF14_BUFFERS 4 /* totally a random guess */ #define NUM_ALPHA_CHANNELS 1 /* common, but doesn't include possible tag, shape or group alpha */ #define NUM_COLOR_CHANNELS 4 /* CMYK is most common 'worst case' */ #define BITS_PER_CHANNEL 8 /* currently pdf14 device is always 8-bit */ /* The estimated size of an individual PDF 1.4 buffer row (in bits) */ #define ESTIMATED_PDF14_ROW_SIZE(width, target_num_components) ((width) * BITS_PER_CHANNEL\ - * (NUM_ALPHA_CHANNELS + NUM_COLOR_CHANNELS)) + * (NUM_ALPHA_CHANNELS + max(target_num_components,NUM_COLOR_CHANNELS))) /* The estimated size of one row in all PDF 1.4 buffers (in bits) */ #define ESTIMATED_PDF14_ROW_SPACE(width, target_num_components) \ (NUM_PDF14_BUFFERS * ESTIMATED_PDF14_ROW_SIZE(width, target_num_components)) diff -Nru ghostscript-9.10~dfsg/base/gstrap.c ghostscript-9.25~dfsg+1/base/gstrap.c --- ghostscript-9.10~dfsg/base/gstrap.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstrap.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gstrap.h ghostscript-9.25~dfsg+1/base/gstrap.h --- ghostscript-9.10~dfsg/base/gstrap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstrap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gstype1.c ghostscript-9.25~dfsg+1/base/gstype1.c --- ghostscript-9.10~dfsg/base/gstype1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstype1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ #include "gxfixed.h" #include "gxmatrix.h" #include "gxcoord.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxpath.h" #include "gxfont.h" #include "gxfont1.h" @@ -127,11 +127,10 @@ cs_ptr csp; #define clear CLEAR_CSTACK(cstack, csp) ip_state_t *ipsp = &pcis->ipstack[pcis->ips_count - 1]; - const byte *cip; + const byte *cip, *cipend; crypt_state state; register int c; int code = 0; - fixed ftx = pcis->origin.x, fty = pcis->origin.y; switch (pcis->init_done) { case -1: @@ -139,8 +138,7 @@ break; case 0: gs_type1_finish_init(pcis); /* sets origin */ - ftx = pcis->origin.x, fty = pcis->origin.y; - code = t1_hinter__set_mapping(h, &pcis->pis->ctm, + code = t1_hinter__set_mapping(h, &pcis->pgs->ctm, &pfont->FontMatrix, &pfont->base->FontMatrix, pcis->scale.x.log2_unit, pcis->scale.x.log2_unit, pcis->scale.x.log2_unit - pcis->log2_subpixels.x, @@ -149,7 +147,7 @@ gs_currentaligntopixels(pfont->dir)); if (code < 0) return code; - code = t1_hinter__set_font_data(h, 1, pdata, pcis->no_grid_fitting, + code = t1_hinter__set_font_data(pfont->memory, h, 1, pdata, pcis->no_grid_fitting, pcis->pfont->is_resource); if (code < 0) return code; @@ -165,6 +163,7 @@ cip = pgd->bits.data; if (cip == 0) return (gs_note_error(gs_error_invalidfont)); + cipend = cip + pgd->bits.size; call:state = crypt_charstring_seed; if (encrypted) { int skip = pdata->lenIV; @@ -177,9 +176,12 @@ cont:if (ipsp < pcis->ipstack || ipsp->ip == 0) return (gs_note_error(gs_error_invalidfont)); cip = ipsp->ip; + cipend = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size; state = ipsp->dstate; top:for (;;) { uint c0 = *cip++; + if (cip > cipend) + return_error(gs_error_invalidfont); charstring_next(c0, state, c, encrypted); if (c >= c_num1) { @@ -234,18 +236,22 @@ case c_undef17: return_error(gs_error_invalidfont); case c_callsubr: + CS_CHECK_POP(csp, cstack); c = fixed2int_var(*csp) + pdata->subroutineNumberBias; code = pdata->procs.subr_data (pfont, c, false, &ipsp[1].cs_data); if (code < 0) - return_error(code); + return code; --csp; ipsp->ip = cip, ipsp->dstate = state; ++ipsp; + CS_CHECK_IPSTACK(ipsp, pcis->ipstack); cip = ipsp->cs_data.bits.data; + cipend = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size; goto call; case c_return: gs_glyph_data_free(&ipsp->cs_data, "gs_type1_interpret"); + CS_CHECK_IPSTACK(ipsp, pcis->ipstack); --ipsp; goto cont; case c_undoc15: @@ -294,7 +300,10 @@ Rewind the data pointer to the beginning of the glyph, re-initialise the hinter, execute a '0' sbw op, and then carry on as if we had actually received one. */ - cip = pgd->bits.data; + if (pgd) { + cip = pgd->bits.data; + cipend = pgd->bits.data + pgd->bits.size; + } t1_hinter__init(h, pcis->path); code = t1_hinter__sbw(h, fixed_0, fixed_0, fixed_0, fixed_0); if (code < 0) @@ -305,7 +314,7 @@ code = t1_hinter__endglyph(h); if (code < 0) return code; - code = gx_setcurrentpoint_from_path(pcis->pis, pcis->path); + code = gx_setcurrentpoint_from_path(pcis->pgs, pcis->path); if (code < 0) return code; } else { @@ -319,6 +328,7 @@ /* do accent of seac */ ipsp = &pcis->ipstack[pcis->ips_count - 1]; cip = ipsp->cs_data.bits.data; + cipend = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size; goto call; } return code; @@ -382,6 +392,8 @@ case cx_escape: charstring_next(*cip, state, c, encrypted); ++cip; + if (cip > cipend) + return_error(gs_error_invalidfont); #ifdef DEBUG if (gs_debug['1'] && c < char1_extended_command_count) { static const char *const ce1names[] = @@ -420,6 +432,7 @@ } clear; cip = ipsp->cs_data.bits.data; + cipend = ipsp->cs_data.bits.data + ipsp->cs_data.bits.size; goto call; case ce1_sbw: if (!pcis->seac_flag) @@ -431,6 +444,7 @@ gs_type1_sbw(pcis, cs0, cs1, cs2, cs3); goto rsbw; case ce1_div: + CS_CHECK_POP(&csp[-1], cstack); csp[-1] = float2fixed((double)csp[-1] / (double)*csp); --csp; goto pushed; @@ -440,10 +454,13 @@ case ce1_callothersubr: { int num_results; + /* We must remember to pop both the othersubr # */ /* and the argument count off the stack. */ switch (*pindex = fixed2int_var(*csp)) { case 0: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-4], cstack)) + return_error(gs_error_invalidfont); { fixed fheight = csp[-4]; /* Assume the next two opcodes */ @@ -462,6 +479,7 @@ pcis->flex_count = flex_max; /* not inside flex */ inext; case 1: + CS_CHECK_POP(csp, cstack); code = t1_hinter__flex_beg(h); if (code < 0) return code; @@ -469,6 +487,7 @@ csp -= 2; inext; case 2: + CS_CHECK_POP(csp, cstack); if (pcis->flex_count >= flex_max) return_error(gs_error_invalidfont); code = t1_hinter__flex_point(h); @@ -477,6 +496,7 @@ csp -= 2; inext; case 3: + CS_CHECK_POP(csp, cstack); /* Assume the next opcode is a `pop'. */ /* See above as to why we don't just */ /* look ahead in the opcode stream. */ @@ -497,6 +517,8 @@ num_results); if (code < 0) return code; + if (!CS_CHECK_CSTACK_BOUNDS(&csp[1 - code], cstack)) + return_error(gs_error_invalidfont); csp -= code; inext; case 15: @@ -519,6 +541,8 @@ int scount = csp - cstack; int n; + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); /* Copy the arguments to the caller's stack. */ if (scount < 1 || csp[-1] < 0 || csp[-1] > int2fixed(scount - 1) diff -Nru ghostscript-9.10~dfsg/base/gstype1.h ghostscript-9.25~dfsg+1/base/gstype1.h --- ghostscript-9.10~dfsg/base/gstype1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstype1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -35,7 +35,7 @@ #ifndef gs_type1_data_s_DEFINED struct gs_type1_data_s; #endif -int gs_type1_interp_init(gs_type1_state * pcis, gs_imager_state * pis, +int gs_type1_interp_init(gs_type1_state * pcis, gs_gstate * pgs, gx_path * ppath, const gs_log2_scale_point * pscale, const gs_log2_scale_point * psubpixels, bool no_grid_fitting, int paint_type, gs_font_type1 * pfont); @@ -45,7 +45,7 @@ /* Backward compatibility */ #define gs_type1_init(pcis, penum, psbpt, charpath_flag, paint_type, pfont)\ - (gs_type1_interp_init(pcis, (gs_imager_state *)((penum)->pgs),\ + (gs_type1_interp_init(pcis, (gs_gstate *)((penum)->pgs),\ (penum)->pgs->path, &(penum)->log2_current_scale,\ charpath_flag, paint_type, pfont) |\ ((psbpt) == 0 ? 0 : (gs_type1_set_lsb(pcis, psbpt), 0))) diff -Nru ghostscript-9.10~dfsg/base/gstype2.c ghostscript-9.25~dfsg+1/base/gstype2.c --- ghostscript-9.10~dfsg/base/gstype2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstype2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ #include "gxfixed.h" #include "gxmatrix.h" #include "gxcoord.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxpath.h" #include "gxfont.h" #include "gxfont1.h" @@ -112,7 +112,6 @@ } /* ------ Main interpreter ------ */ - /* * Continue interpreting a Type 2 charstring. If str != 0, it is taken as * the byte string to interpret. Return 0 on successful completion, <0 on @@ -152,7 +151,7 @@ break; case 0: gs_type1_finish_init(pcis); /* sets origin */ - code = t1_hinter__set_mapping(h, &pcis->pis->ctm, + code = t1_hinter__set_mapping(h, &pcis->pgs->ctm, &pfont->FontMatrix, &pfont->base->FontMatrix, pcis->scale.x.log2_unit, pcis->scale.x.log2_unit, pcis->scale.x.log2_unit - pcis->log2_subpixels.x, @@ -161,7 +160,7 @@ gs_currentaligntopixels(pfont->dir)); if (code < 0) return code; - code = t1_hinter__set_font_data(h, 2, pdata, pcis->no_grid_fitting, + code = t1_hinter__set_font_data(pfont->memory, h, 2, pdata, pcis->no_grid_fitting, pcis->pfont->is_resource); if (code < 0) return code; @@ -238,25 +237,35 @@ case c_undef17: return_error(gs_error_invalidfont); case c_callsubr: - c = fixed2int_var(*csp) + pdata->subroutineNumberBias; - code = pdata->procs.subr_data - (pfont, c, false, &ipsp[1].cs_data); - subr:if (code < 0) { - /* Calling a Subr with an out-of-range index is clearly a error: - * the Adobe documentation says the results of doing this are - * undefined. However, we have seen a PDF file produced by Adobe - * PDF Library 4.16 that included a Type 2 font that called an - * out-of-range Subr, and Acrobat Reader did not signal an error. - * Therefore, we ignore such calls. + if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { + c = fixed2int_var(*csp) + pdata->subroutineNumberBias; + code = pdata->procs.subr_data + (pfont, c, false, &ipsp[1].cs_data); + subr: + if (code < 0) { + /* Calling a Subr with an out-of-range index is clearly a error: + * the Adobe documentation says the results of doing this are + * undefined. However, we have seen a PDF file produced by Adobe + * PDF Library 4.16 that included a Type 2 font that called an + * out-of-range Subr, and Acrobat Reader did not signal an error. + * Therefore, we ignore such calls. + */ + cip++; + goto top; + } + --csp; + ipsp->ip = cip, ipsp->dstate = state; + ++ipsp; + cip = ipsp->cs_data.bits.data; + goto call; + } + else { + /* Consider a missing index to be "out-of-range", and see above + * comment. */ cip++; goto top; } - --csp; - ipsp->ip = cip, ipsp->dstate = state; - ++ipsp; - cip = ipsp->cs_data.bits.data; - goto call; case c_return: gs_glyph_data_free(&ipsp->cs_data, "gs_type2_interpret"); --ipsp; @@ -273,13 +282,18 @@ case cx_vstem: goto vstem; case cx_vmoveto: - check_first_operator(csp > cstack); - code = t1_hinter__rmoveto(h, 0, *csp); + if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { + check_first_operator(csp > cstack); + code = t1_hinter__rmoveto(h, 0, *csp); move: cc: - if (code < 0) - return code; - goto pp; + if (code < 0) + return code; + goto pp; + } + else { + return_error(gs_error_invalidfont); + } case cx_rlineto: for (ap = cstack; ap + 1 <= csp; ap += 2) { code = t1_hinter__rlineto(h, ap[0], ap[1]); @@ -340,7 +354,7 @@ code = t1_hinter__endglyph(h); if (code < 0) return code; - code = gx_setcurrentpoint_from_path(pcis->pis, pcis->path); + code = gx_setcurrentpoint_from_path(pcis->pgs, pcis->path); if (code < 0) return code; } else { @@ -368,23 +382,30 @@ case cx_rmoveto: /* See vmoveto above re closing the subpath. */ check_first_operator(!((csp - cstack) & 1)); - if (csp > cstack + 1) { - /* Some Type 2 charstrings omit the vstemhm operator before rmoveto, - even though this is only allowed before hintmask and cntrmask. - Thanks to Felix Pahl. - */ - type2_vstem(pcis, csp - 2, cstack); - cstack [0] = csp [-1]; - cstack [1] = csp [ 0]; - csp = cstack + 1; + if (CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) { + if (csp > cstack + 1) { + /* Some Type 2 charstrings omit the vstemhm operator before rmoveto, + even though this is only allowed before hintmask and cntrmask. + Thanks to Felix Pahl. + */ + type2_vstem(pcis, csp - 2, cstack); + cstack [0] = csp [-1]; + cstack [1] = csp [ 0]; + csp = cstack + 1; + } + code = t1_hinter__rmoveto(h, csp[-1], *csp); + goto move; } - code = t1_hinter__rmoveto(h, csp[-1], *csp); - goto move; + else + return_error(gs_error_invalidfont); case cx_hmoveto: - /* See vmoveto above re closing the subpath. */ - check_first_operator(csp > cstack); - code = t1_hinter__rmoveto(h, *csp, 0); - goto move; + if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { + /* See vmoveto above re closing the subpath. */ + check_first_operator(csp > cstack); + code = t1_hinter__rmoveto(h, *csp, 0); + goto move; + } else + return_error(gs_error_invalidfont); case cx_vhcurveto: vertical = true; goto hvc; @@ -414,6 +435,7 @@ ***********************/ case c2_blend: + if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { int n = fixed2int_var(*csp); int num_values = csp - cstack; @@ -428,10 +450,11 @@ for (i = 1; i < k; i++) *base += (fixed)(deltas[i] * pfont->data.WeightVector.values[i]); - } + } else + return gs_note_error(gs_error_invalidfont); cnext; case c2_hstemhm: - hstem:check_first_operator(!((csp - cstack) & 1)); + hstem: check_first_operator(!((csp - cstack) & 1)); { fixed x = 0; @@ -450,8 +473,10 @@ * this interpretation everywhere. */ case c2_cntrmask: - check_first_operator(!((csp - cstack) & 1)); - type2_vstem(pcis, csp, cstack); + if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { + check_first_operator(!((csp - cstack) & 1)); + type2_vstem(pcis, csp, cstack); + } /* * We should clear the stack here only if this is the * initial mask operator that includes the implicit @@ -482,8 +507,12 @@ } break; case c2_vstemhm: - vstem:check_first_operator(!((csp - cstack) & 1)); - type2_vstem(pcis, csp, cstack); + vstem: + if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { + check_first_operator(!((csp - cstack) & 1)); + type2_vstem(pcis, csp, cstack); + }else + return gs_note_error(gs_error_invalidfont); cnext; case c2_rcurveline: for (ap = cstack; ap + 5 <= csp; ap += 6) { @@ -546,10 +575,15 @@ } goto pushed; case c2_callgsubr: - c = fixed2int_var(*csp) + pdata->gsubrNumberBias; - code = pdata->procs.subr_data - (pfont, c, true, &ipsp[1].cs_data); - goto subr; + if (CS_CHECK_CSTACK_BOUNDS(csp, cstack)) { + c = fixed2int_var(*csp) + pdata->gsubrNumberBias; + code = pdata->procs.subr_data + (pfont, c, true, &ipsp[1].cs_data); + goto subr; + } else { + cip++; + goto top; + } case cx_escape: charstring_next(*cip, state, c, encrypted); ++cip; @@ -568,10 +602,14 @@ #endif switch ((char2_extended_command) c) { case ce2_and: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); csp[-1] = ((csp[-1] != 0) & (*csp != 0) ? fixed_1 : 0); --csp; break; case ce2_or: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); csp[-1] = (csp[-1] | *csp ? fixed_1 : 0); --csp; break; @@ -579,15 +617,23 @@ *csp = (*csp ? 0 : fixed_1); break; case ce2_store: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-3], cstack)) + return_error(gs_error_invalidfont); { int i, n = fixed2int_var(*csp); - float *to = Registry[fixed2int_var(csp[-3])].values + - fixed2int_var(csp[-2]); - const fixed *from = - pcis->transient_array + fixed2int_var(csp[-1]); + int ind = fixed2int_var(csp[-3]); + int offs = fixed2int_var(csp[-2]); + float *to; + const fixed *from = pcis->transient_array + fixed2int_var(csp[-1]); - for (i = 0; i < n; ++i) - to[i] = fixed2float(from[i]); + if (!CS_CHECK_TRANSIENT_BOUNDS(from, pcis->transient_array)) + return_error(gs_error_invalidfont); + + if (ind < countof(Registry)) { + to = Registry[ind].values + offs; + for (i = 0; i < n; ++i) + to[i] = fixed2float(from[i]); + } } csp -= 4; break; @@ -596,28 +642,43 @@ *csp = -*csp; break; case ce2_add: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); csp[-1] += *csp; --csp; break; case ce2_sub: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); csp[-1] -= *csp; --csp; break; case ce2_div: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); + if (*csp == 0) + return_error(gs_error_invalidfont); csp[-1] = float2fixed((double)csp[-1] / *csp); --csp; break; case ce2_load: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-2], cstack)) + return_error(gs_error_invalidfont); /* The specification says there is no j (starting index */ /* in registry array) argument.... */ { int i, n = fixed2int_var(*csp); - const float *from = Registry[fixed2int_var(csp[-2])].values; - fixed *to = - pcis->transient_array + fixed2int_var(csp[-1]); + int ind = fixed2int_var(csp[-2]); + const float *from; + fixed *to = pcis->transient_array + fixed2int_var(csp[-1]); - for (i = 0; i < n; ++i) - to[i] = float2fixed(from[i]); + if (!CS_CHECK_TRANSIENT_BOUNDS(to, pcis->transient_array)) + return_error(gs_error_invalidfont); + if (ind < countof(Registry)) { + from = Registry[ind].values; + for (i = 0; i < n; ++i) + to[i] = float2fixed(from[i]); + } } csp -= 3; break; @@ -625,20 +686,43 @@ *csp = -*csp; break; case ce2_eq: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); csp[-1] = (csp[-1] == *csp ? fixed_1 : 0); --csp; break; case ce2_drop: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); --csp; break; case ce2_put: - pcis->transient_array[fixed2int_var(*csp)] = csp[-1]; - csp -= 2; + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); + { + fixed *to = pcis->transient_array + fixed2int_var(*csp); + + if (!CS_CHECK_TRANSIENT_BOUNDS(to, pcis->transient_array)) + return_error(gs_error_invalidfont); + + *to = csp[-1]; + csp -= 2; + } break; case ce2_get: - *csp = pcis->transient_array[fixed2int_var(*csp)]; + if (!CS_CHECK_CSTACK_BOUNDS(csp, cstack)) + return_error(gs_error_invalidfont); + { + fixed *from = pcis->transient_array + fixed2int_var(*csp); + if (!CS_CHECK_TRANSIENT_BOUNDS(from, pcis->transient_array)) + return_error(gs_error_invalidfont); + + *csp = *from; + } break; case ce2_ifelse: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-3], cstack)) + return_error(gs_error_invalidfont); if (csp[-1] > *csp) csp[-3] = csp[-2]; csp -= 3; @@ -649,6 +733,8 @@ /****** NYI ******/ break; case ce2_mul: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); { double prod = fixed2float(csp[-1]) * *csp; @@ -668,6 +754,8 @@ ++csp; break; case ce2_exch: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); { fixed top = *csp; @@ -675,10 +763,14 @@ } break; case ce2_index: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); *csp = (*csp < 0 ? csp[-1] : csp[-1 - fixed2int_var(csp[-1])]); break; case ce2_roll: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) + return_error(gs_error_invalidfont); { int distance = fixed2int_var(*csp); int count = fixed2int_var(csp[-1]); @@ -702,6 +794,9 @@ } break; case ce2_hflex: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-5], cstack)) + return_error(gs_error_invalidfont); + CS_CHECK_PUSHN(csp, cstack, 6); csp[6] = fixed_half; /* fd/100 */ csp[4] = *csp, csp[5] = 0; /* dx6, dy6 */ csp[2] = csp[-1], csp[3] = -csp[-4]; /* dx5, dy5 */ @@ -712,6 +807,8 @@ csp += 6; goto flex; case ce2_flex: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-12], cstack)) + return_error(gs_error_invalidfont); *csp /= 100; /* fd/100 */ flex: { fixed x_join = csp[-12] + csp[-10] + csp[-8]; @@ -724,12 +821,12 @@ if ((code = gs_distance_transform(fixed2float(x_join), fixed2float(y_join), - &ctm_only(pcis->pis), + &ctm_only(pcis->pgs), &join)) < 0 || (code = gs_distance_transform(fixed2float(x_end), fixed2float(y_end), - &ctm_only(pcis->pis), + &ctm_only(pcis->pgs), &end)) < 0 ) return code; @@ -762,10 +859,12 @@ } if (code < 0) return code; - csp -= 13; } cnext; case ce2_hflex1: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-3], cstack)) + return_error(gs_error_invalidfont); + CS_CHECK_PUSHN(csp, cstack, 4); csp[4] = fixed_half; /* fd/100 */ csp[2] = *csp; /* dx6 */ csp[3] = -(csp[-7] + csp[-5] + csp[-1]); /* dy6 */ @@ -775,6 +874,9 @@ csp += 4; goto flex; case ce2_flex1: + if (!CS_CHECK_CSTACK_BOUNDS(&csp[-10], cstack)) + return_error(gs_error_invalidfont); + CS_CHECK_PUSHN(csp, cstack, 2); { fixed dx = csp[-10] + csp[-8] + csp[-6] + csp[-4] + csp[-2]; fixed dy = csp[-9] + csp[-7] + csp[-5] + csp[-3] + csp[-1]; @@ -792,7 +894,7 @@ /* Fill up the dispatch up to 32. */ - case_c2_undefs: + case_c2_undefs: default: /* pacify compiler */ return_error(gs_error_invalidfont); } diff -Nru ghostscript-9.10~dfsg/base/gstype42.c ghostscript-9.25~dfsg+1/base/gstype42.c --- ghostscript-9.10~dfsg/base/gstype42.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstype42.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,19 +9,21 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Type 42 (TrueType) font library routines */ +#include /* for qsort */ + #include "memory_.h" #include "stdint_.h" #include "gx.h" #include "gserrors.h" #include "gsstruct.h" #include "gsccode.h" -#include "gsline.h" /* for gs_imager_setflat */ +#include "gsline.h" /* for gs_gstate_setflat */ #include "gsmatrix.h" #include "gsutil.h" #include "gxchrout.h" @@ -34,10 +36,15 @@ #include "gxtext.h" #include "gxchar.h" #include "gxfcache.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gzstate.h" #include "stream.h" -#include /* for qsort */ + +/* For WOFF Support */ +#include "strimpl.h" +#include "stream.h" +#include "strmio.h" +#include "szlibx.h" /* Structure descriptor */ public_st_gs_font_type42(); @@ -59,6 +66,9 @@ #define S16(p) (int)((U16(p) ^ 0x8000) - 0x8000) #define u32(p) get_u32_msb(p) +#define PUTU16(p, n, offs) {(p + offs)[0] = n >> 8 & 255; (p + offs)[1] = n & 255;} + + /* ---------------- Font level ---------------- */ GS_NOTIFY_PROC(gs_len_glyphs_release); @@ -145,7 +155,7 @@ byte TableDirectory[MAX_NUM_TT_TABLES * 16]; uint i; int code; - byte head_box[8]; + byte head_box[8] = {0}; ulong loca_size = 0; ulong glyph_start, glyph_offset, glyph_length, glyph_size = 0; uint numFonts, version; @@ -200,6 +210,8 @@ pfont->data.glyf = offset; glyph_size = (uint)u32(tab + 12); } else if (!memcmp(tab, "GSUB", 4)) { + if (pfont->data.gsub_size != 0) + return_error(gs_error_invalidfont); pfont->data.gsub_size = u32(tab + 12); pfont->data.gsub = gs_alloc_byte_array(pfont->memory, pfont->data.gsub_size, 1, "gs_type42_font_init(GSUB)"); @@ -236,6 +248,10 @@ READ_SFNTS(pfont, offset, 30, maxp); pfont->data.trueNumGlyphs = U16(maxp + 4); + pfont->data.maxPoints = U16(maxp + 6); + pfont->data.maxContours = U16(maxp + 8); + pfont->data.maxCPoints = U16(maxp + 10); + pfont->data.maxCContours = U16(maxp + 12); } else if (!memcmp(tab, "name", 4)) { pfont->data.name_offset = offset; } else if (!memcmp(tab, "vhea", 4)) { @@ -253,19 +269,6 @@ loca_size >>= pfont->data.indexToLocFormat + 1; pfont->data.numGlyphs = (loca_size == 0 ? 0 : loca_size - 1); if (pfont->data.numGlyphs > pfont->data.trueNumGlyphs) { - /* Some fonts have excessive data at end of 'loca' table - - see bug 688467. - We're not sure why old versions of Ghostscript maintain - two different fileds - numGlyphs and trueNumGlyphs. - (A related comment in gxfont42.h isn't explanatory about important cases.) - Our reading of TrueType specification and FreeType experience - is that only trueNumGlyphs should be used. - Maybe (I guess) sometimes somebody observed a font, - in which trueNumGlyphs counts real glyphs, - and numGlyphs counts all subglyphs ? - Continue using trueNumGlyphs since the document of - the bug 688467 fails otherwise. - */ /* pfont->key_name.chars is ASCIIZ due to copy_font_name. */ char buf[gs_font_name_max + 2]; @@ -293,13 +296,12 @@ if (glyph_offset < glyph_size) break; } - if (i > pfont->data.trueNumGlyphs) { - /* loca contains more good offsets, fix maxp.numGlyphs. + if (i > pfont->data.numGlyphs) { + /* loca contains more good offsets . Note a code below will fix bad offsets if any. */ - pfont->data.numGlyphs = pfont->data.trueNumGlyphs = loca_size - 1; + pfont->data.numGlyphs = loca_size - 1; } } - pfont->data.numGlyphs = pfont->data.trueNumGlyphs; loca_size = pfont->data.numGlyphs + 1; } @@ -329,83 +331,90 @@ */ pfont->data.len_glyphs = NULL; } else { - /* Now build the len_glyphs array since 'loca' may not be properly sorted */ - pfont->data.len_glyphs = (uint *)gs_alloc_byte_array(pfont->memory, loca_size, sizeof(uint), - "gs_type42_font_init"); - if (pfont->data.len_glyphs == 0) - return_error(gs_error_VMerror); - code = gs_font_notify_register((gs_font *)pfont, gs_len_glyphs_release, (void *)pfont); - if (code < 0) - return code; - - /* The 'loca' may not be in order, so we construct a glyph length array */ - /* Since 'loca' is usually sorted, first try the simple linear scan to */ - /* avoid the need to perform the more expensive process. */ - glyph_start = get_glyph_offset(pfont, 0); - for (i = 1; i < loca_size; i++) { - glyph_offset = get_glyph_offset(pfont, i); - glyph_length = glyph_offset - glyph_start; - if (glyph_length > 0x80000000) - break; - if (glyph_offset > glyph_size) - break; - /* out of order loca */ - pfont->data.len_glyphs[i - 1] = glyph_length; - glyph_start = glyph_offset; + if (loca_size == 0) { + pfont->data.len_glyphs = NULL; } - if (i < loca_size) { - /* - * loca was out of order, build the len_glyphs the hard way. - * For each glyph, we use the next higher or equal - * glyph offset to compute the glyph length. - * It assumes no overlapping and no duplicate glyphs. - */ - ulong last_glyph_offset = glyph_size; - ulong num_valid_loca_elm = loca_size; - long last_offset = 0; - gs_type42_font_init_sort_t *psort; - gs_type42_font_init_sort_t *psortary = - (gs_type42_font_init_sort_t *)gs_alloc_byte_array(pfont->memory, - loca_size, sizeof(gs_type42_font_init_sort_t), "gs_type42_font_init(sort loca)"); - - if (psortary == 0) + else { + /* Now build the len_glyphs array since 'loca' may not be properly sorted */ + pfont->data.len_glyphs = (uint *)gs_alloc_byte_array(pfont->memory, loca_size, sizeof(uint), + "gs_type42_font_init"); + if (pfont->data.len_glyphs == 0) return_error(gs_error_VMerror); - /* loca_size > 0 due to condition above, so we always have the 0th element. */ - psortary->glyph_num = 0; - psortary->glyph_offset = get_glyph_offset(pfont, 0); - for (i = 1, psort = psortary + 1; i < loca_size; i++, psort++) { - psort->glyph_num = i; - psort->glyph_offset = get_glyph_offset(pfont, i); - psort[-1].glyph_length = psort->glyph_offset - last_offset; - last_offset = psort->glyph_offset; + code = gs_font_notify_register((gs_font *)pfont, gs_len_glyphs_release, (void *)pfont); + if (code < 0) { + gs_free_object(pfont->memory, pfont->data.len_glyphs, "gs_len_glyphs_release"); + return code; } - psort[-1].glyph_length = 0; /* Dummy element. */ - qsort(psortary, loca_size, sizeof(gs_type42_font_init_sort_t), gs_type42_font_init_compare); - while (num_valid_loca_elm > 0 && psortary[num_valid_loca_elm - 1].glyph_offset > glyph_size) - num_valid_loca_elm --; - if (0 == num_valid_loca_elm) - return_error(gs_error_invalidfont); - for (i = num_valid_loca_elm; i--;) { - long old_length; - - psort = psortary + i; - old_length = psort->glyph_length; - if (old_length < 0 || old_length > 2000 /* arbitrary */) { - pfont->data.len_glyphs[psort->glyph_num] = last_glyph_offset - psort->glyph_offset; - /* Note the new length may be so big as old_length. */ - } else - pfont->data.len_glyphs[psort->glyph_num] = old_length; - last_glyph_offset = psort->glyph_offset; + + /* The 'loca' may not be in order, so we construct a glyph length array */ + /* Since 'loca' is usually sorted, first try the simple linear scan to */ + /* avoid the need to perform the more expensive process. */ + glyph_start = get_glyph_offset(pfont, 0); + for (i = 1; i < loca_size; i++) { + glyph_offset = get_glyph_offset(pfont, i); + glyph_length = glyph_offset - glyph_start; + if (glyph_length > 0x80000000) + break; + if (glyph_offset > glyph_size) + break; + /* out of order loca */ + pfont->data.len_glyphs[i - 1] = glyph_length; + glyph_start = glyph_offset; } - for (i = num_valid_loca_elm; i < loca_size; i++) { - psort = psortary + i; - pfont->data.len_glyphs[psort->glyph_num] = 0; + if (i < loca_size) { + /* + * loca was out of order, build the len_glyphs the hard way. + * For each glyph, we use the next higher or equal + * glyph offset to compute the glyph length. + * It assumes no overlapping and no duplicate glyphs. + */ + ulong last_glyph_offset = glyph_size; + ulong num_valid_loca_elm = loca_size; + long last_offset = 0; + gs_type42_font_init_sort_t *psort; + gs_type42_font_init_sort_t *psortary = + (gs_type42_font_init_sort_t *)gs_alloc_byte_array(pfont->memory, + loca_size, sizeof(gs_type42_font_init_sort_t), "gs_type42_font_init(sort loca)"); + + if (psortary == 0) + return_error(gs_error_VMerror); + /* loca_size > 0 due to condition above, so we always have the 0th element. */ + psortary->glyph_num = 0; + psortary->glyph_offset = get_glyph_offset(pfont, 0); + for (i = 1, psort = psortary + 1; i < loca_size; i++, psort++) { + psort->glyph_num = i; + psort->glyph_offset = get_glyph_offset(pfont, i); + psort[-1].glyph_length = psort->glyph_offset - last_offset; + last_offset = psort->glyph_offset; + } + psort[-1].glyph_length = 0; /* Dummy element. */ + qsort(psortary, loca_size, sizeof(gs_type42_font_init_sort_t), gs_type42_font_init_compare); + while (num_valid_loca_elm > 0 && psortary[num_valid_loca_elm - 1].glyph_offset > glyph_size) + num_valid_loca_elm --; + if (0 == num_valid_loca_elm) + return_error(gs_error_invalidfont); + for (i = num_valid_loca_elm; i--;) { + long old_length; + + psort = psortary + i; + old_length = psort->glyph_length; + if (old_length < 0 || old_length > 2000 /* arbitrary */) { + pfont->data.len_glyphs[psort->glyph_num] = last_glyph_offset - psort->glyph_offset; + /* Note the new length may be so big as old_length. */ + } else + pfont->data.len_glyphs[psort->glyph_num] = old_length; + last_glyph_offset = psort->glyph_offset; + } + for (i = num_valid_loca_elm; i < loca_size; i++) { + psort = psortary + i; + pfont->data.len_glyphs[psort->glyph_num] = 0; + } + /* Well the last element of len_glyphs is never used. + We compute it because we're interesting whether it is not zero sometimes. + To know that, set a conditional breakpoint at the next statement. + */ + gs_free_object(pfont->memory, psortary, "gs_type42_font_init(sort loca)"); } - /* Well the last element of len_glyphs is never used. - We compute it because we're interesting whether it is not zero sometimes. - To know that, set a conditional breakpoint at the next statement. - */ - gs_free_object(pfont->memory, psortary, "gs_type42_font_init(sort loca)"); } } /* @@ -539,6 +548,7 @@ *psmat = mat; } +#if 0 /* not called */ /* Compute the total number of points in a (possibly composite) glyph. */ static int total_points(gs_font_type42 *pfont, uint glyph_index) @@ -583,6 +593,7 @@ gs_glyph_data_free(&glyph_data, "total_points"); return total; } +#endif /* not called */ /* * Define the default implementation for getting the glyph index from a @@ -609,10 +620,13 @@ uint glyph_length; int code; - if (glyph_index >= pfont->data.trueNumGlyphs) + if (glyph_index >= pfont->data.numGlyphs) return_error(gs_error_invalidfont); glyph_start = get_glyph_offset(pfont, glyph_index); - glyph_length = pfont->data.len_glyphs[glyph_index]; + if (pfont->data.len_glyphs) + glyph_length = pfont->data.len_glyphs[glyph_index]; + else + glyph_length = 0; if (glyph_length == 0) gs_glyph_data_from_null(pgd); else { @@ -778,7 +792,7 @@ LookupListTable lookup_list_table; byte *lookup_list_ptr; - if (WMode == 0) + if (WMode == 0 || gsub_ptr == NULL) return glyph_index; /* GSUB header */ @@ -815,6 +829,7 @@ subst.SubstFormat = format; /* Debug purpose. */ subst.Coverage = U16(subtable_ptr + offset_of(SingleSubstFormat1, Coverage)); subst.DeltaGlyphId = U16(subtable_ptr + offset_of(SingleSubstFormat1, DeltaGlyphId)); + format = subst.SubstFormat; /* Stops gcc warning */ } else { SingleSubstFormat2 subst; byte *coverage_ptr; @@ -848,7 +863,6 @@ return new_glyph; } } else if (k0 >= k1 - 1) { - k += 0; /* A place for breakpoint. */ break; /* Not found. */ } else if (glyph_index < glyph) k1 = k; @@ -887,7 +901,6 @@ return new_glyph; } } else if (k0 >= k1 - 1) { - k += 0; /* A place for breakpoint. */ break; /* Not found. */ } else if (glyph_index < rr.Start) k1 = k; @@ -977,6 +990,12 @@ return code; if (pmat == 0) pmat = &imat; + if (!pair->ttf) { + void *FAPI_store = ((gs_font_base *)font)->FAPI; + ((gs_font_base *)font)->FAPI = NULL; + gx_provide_fm_pair_attributes(font->dir, font, pair, pmat, &log2_scale, false); + ((gs_font_base *)font)->FAPI = FAPI_store; + } if ((code = gx_path_current_point(ppath, &origin)) < 0 || (code = append_outline_fitted(glyph_index, pmat, ppath, pair, &log2_scale, design_grid)) < 0 || @@ -1154,7 +1173,7 @@ */ int gs_type42_default_get_metrics(gs_font_type42 * pfont, uint glyph_index, - gs_type42_metrics_options_t options, float sbw[4]) + gs_type42_metrics_options_t options, float *sbw) { gs_glyph_data_t glyph_data; int code; @@ -1192,6 +1211,11 @@ do { uint comp_index = U16(gdata + 2); + if (comp_index == glyph_index) { + result = gs_note_error(gs_error_invalidfont); + goto done; + } + gs_type42_parse_component(&gdata, &flags, &mat, NULL, pfont, &mat); if (flags & TT_CG_USE_MY_METRICS) { result = pfont->data.get_metrics(pfont, comp_index, wmode, sbw); @@ -1226,7 +1250,7 @@ /* Append a TrueType outline to a path. */ /* Note that this does not append the final moveto for the width. */ int -gs_type42_append(uint glyph_index, gs_state * pgs, +gs_type42_append(uint glyph_index, gs_gstate * pgs, gx_path * ppath, gs_text_enum_t *penum, gs_font *pfont, bool charpath_flag) { @@ -1251,12 +1275,11 @@ } return code; } - code = gx_setcurrentpoint_from_path((gs_imager_state *)pgs, ppath); + code = gx_setcurrentpoint_from_path(pgs, ppath); if (code < 0) return code; /* Set the flatness for curve rendering. */ - return gs_imager_setflat((gs_imager_state *)pgs, - gs_char_flatness((gs_imager_state *)pgs, 1.0)); + return gs_gstate_setflat(pgs, gs_char_flatness(pgs, 1.0)); } #if 0 /* Used only by add_simple below, which has been removed as unused. */ @@ -1647,9 +1670,13 @@ if (pfont->data.name_offset == 0) return 0; if (!(info->members & FONT_INFO_COPYRIGHT) && (members & FONT_INFO_COPYRIGHT)) { - code = get_from_names_table(pfont, info, &info->Copyright, FONT_INFO_COPYRIGHT, 0); - if (code < 0) - return code; + /* One way we can arrive here is from gs_copy_font() -> z42_font_info(), in + * that case we definitely want to copy the copyright informatoin if there is any, + * but we don't want to throw an error if we find a Type 42 font which has no + * copyright information. So get the informaton, but ignore the return code. + * Bug #696174. + */ + get_from_names_table(pfont, info, &info->Copyright, FONT_INFO_COPYRIGHT, 0); } if (!(info->members & FONT_INFO_FAMILY_NAME) && (members & FONT_INFO_FAMILY_NAME)) { code = get_from_names_table(pfont, info, &info->FamilyName, FONT_INFO_FAMILY_NAME, 1); @@ -1675,3 +1702,221 @@ return code; return gs_truetype_font_info(font, pscale, members, info); } + +/******************** WOFF Support *************************/ +static int +gs_woff_tabdir_compare (const void *a, const void *b) +{ + uint32_t poffs, qoffs; + + poffs = u32((*(byte **)a) + 4); + qoffs = u32((*(byte **)b) + 4); + + return poffs > qoffs ? 1 : poffs < qoffs ? -1 : 0; +} + +static stream * +gs_woff_push_flate_filter(stream *s) +{ + gs_memory_t *mem = s->memory; + stream *fs, *ffs = NULL; + byte *buf; + stream_zlib_state *st; + + fs = s_alloc(mem, "gs_woff_push_flate_filter(fs)"); + buf = gs_alloc_bytes(mem, 4096, "gs_woff_push_flate_filter(buf)"); + st = gs_alloc_struct(mem, stream_zlib_state, s_zlibD_template.stype, "gs_woff_push_flate_filter(st)"); + if (fs == 0 || st == 0 || buf == 0) { + gs_free_object(mem, fs, "gs_woff_push_flate_filter(fs)"); + gs_free_object(mem, buf, "gs_woff_push_flate_filter(buf)"); + gs_free_object(mem, st, "gs_woff_push_flate_filter(st)"); + goto done; + } + s_std_init(fs, buf, 4096, &s_filter_read_procs, s_mode_read); + st->memory = mem; + st->templat = &s_zlibD_template; + fs->state = (stream_state *) st; + fs->procs.process = s_zlibD_template.process; + fs->strm = s; + (*s_zlibD_template.set_defaults) ((stream_state *) st); + (*s_zlibD_template.init) ((stream_state *) st); + ffs = fs; +done: + return ffs; +} + +static stream * +gs_woff_pop_flate_filter(stream *s) +{ + gs_memory_t *mem = s->memory; + stream *strm = s->strm; + byte *buf = s->cbuf; + + sclose(s); + gs_free_object(mem, s, "gs_woff_pop_flate_filter(s)"); + gs_free_object(mem, buf, "gs_woff_pop_flate_filter(buf)"); + + return strm; +} + +#define WOFFHDR_LEN 44 +#define WOFFHDR_SFNT_FLAVOR_OFFS 4 +#define WOFFHDR_SFNT_NUMTABS_OFFS 12 +#define WOFFHDR_SFNT_LEN_OFFS 16 + +#define WOFF_TABDIR_ENT_LEN 20 +#define WOFF_TABDIR_TAG_OFFS 0 +#define WOFF_TABDIR_OFFSET_OFFS 4 +#define WOFF_TABDIR_CLEN_OFFS 8 +#define WOFF_TABDIR_OLEN_OFFS 12 +#define WOFF_TABDIR_CSUM_OFFS 16 + +#define WOFF_TABDIR_FIELD_LEN 4 + +#define SFNT_TABDIR_ENT_LEN 16 +#define SFNT_TABDIR_CSUM_OFFS 4 +#define SFNT_TABDIR_OFFSET_OFFS 8 +#define SFNT_TABDIR_LEN_OFFS 12 + + +static int +gs_woff2sfnt(gs_memory_t *mem, stream *s, byte *outbuf, int *outbuflen) +{ + int code = 0; + gs_offset_t start; + uint32_t sfntlen, ntables, sr, es, rs, i; + byte woffhdr[44], *tabbuf = NULL; + byte **tabbufptrs = NULL; + byte *obuf = outbuf, *tdir; + + if (!sseekable(s)) { + code = gs_note_error(gs_error_ioerror); + goto done; + } + start = stell(s); + if (s->bsize < 44){ + code = gs_note_error(gs_error_invalidfont); + goto done; + } + + if ((code = sfread(woffhdr, WOFFHDR_LEN, 1, s)) < 0) + goto done; + + if (memcmp(woffhdr, "wOFF", 4) != 0 + || memcmp(woffhdr + WOFFHDR_SFNT_FLAVOR_OFFS, "OTTO", 4) == 0) { + (void)sseek(s, start); + code = gs_note_error(gs_error_invalidfont); + goto done; + } + sfntlen = u32(woffhdr + WOFFHDR_SFNT_LEN_OFFS); + if (!outbuf || *outbuflen < sfntlen) { + *outbuflen = sfntlen; + (void)sseek(s, start); + goto done; + } + ntables = U16(woffhdr + WOFFHDR_SFNT_NUMTABS_OFFS); + memcpy(obuf, woffhdr + WOFFHDR_SFNT_FLAVOR_OFFS, 4); + obuf += 4; + memcpy(obuf, woffhdr + WOFFHDR_SFNT_NUMTABS_OFFS, 2); + obuf += 2; + sr = ntables; + sr |= (sr >> 1); + sr |= (sr >> 2); + sr |= (sr >> 4); + sr |= (sr >> 8); + sr &= ~(sr >> 1); + sr *= 16; + PUTU16(obuf, (ushort)sr, 0) + rs = ntables * 16 - sr; + es = 0; + while (sr > 16) { + es++; + sr >>= 1; + } + PUTU16(obuf, (ushort)es, 2) + PUTU16(obuf, (ushort)rs, 4); + obuf += 6; + + tabbuf = gs_alloc_bytes(mem, WOFF_TABDIR_ENT_LEN * ntables, "gs_woff2sfnt(tabbuf)"); + tabbufptrs = (byte **)gs_alloc_bytes(mem, (ntables + 1) * sizeof(byte *), "gs_woff2sfnt(tabbufptrs)"); + if (!tabbuf || !tabbufptrs) { + code = gs_note_error(gs_error_VMerror); + goto done; + } + if ((code = sfread(tabbuf, WOFF_TABDIR_ENT_LEN * ntables, 1, s)) < 0) + goto done; + + for (i = 0; i < ntables; i++) + tabbufptrs[i] = tabbuf + (i * WOFF_TABDIR_ENT_LEN); + tabbufptrs[i] = NULL; + qsort(tabbufptrs, ntables, sizeof(byte *), gs_woff_tabdir_compare); + + /* Two pointers into the output buffer: tdir and obuf. + * tdir is the beginning of the current entry in the table directory + * and obuf is the beginning of the current table. + */ + tdir = obuf; + obuf += (16 * ntables); + for (i = 0; i < ntables; i++) { + byte *tdirent = tabbufptrs[i]; + uint32_t len, clen, pad; + len = u32(tdirent + WOFF_TABDIR_OLEN_OFFS); + clen = u32(tdirent + WOFF_TABDIR_CLEN_OFFS); + /* Build the sfnts table directory entry. + * For those cases where encoded fields are the same in WOFF and SFNT, + * we just copy the bytes over + */ + memcpy(tdir, tdirent, WOFF_TABDIR_FIELD_LEN); + memcpy(tdir + SFNT_TABDIR_CSUM_OFFS, tdirent + WOFF_TABDIR_CSUM_OFFS, WOFF_TABDIR_FIELD_LEN); + memcpy(tdir + SFNT_TABDIR_LEN_OFFS, tdirent + WOFF_TABDIR_OLEN_OFFS, WOFF_TABDIR_FIELD_LEN); + put_u32_msb(tdir, (uint32_t)(obuf - outbuf), SFNT_TABDIR_OFFSET_OFFS); + tdir += SFNT_TABDIR_ENT_LEN; + /* Now handle the actual table data */ + sseek(s, u32(tdirent + WOFF_TABDIR_OFFSET_OFFS)); + if (clen != len) + s = gs_woff_push_flate_filter(s); + code = sfread(obuf, 1, len, s); + if (clen != len) + s = gs_woff_pop_flate_filter(s); + if (code < 0) + goto done; + obuf += len; + /* TTF requires each table to start on a 4 byte boundary, and + * padding to be zeroed bytes. + */ + pad = ((len + 3) & ~3) - len; + while (pad > 0) { + *obuf = (byte)0; + obuf++; + pad--; + } + } +done: + gs_free_object(mem, tabbuf, "gs_woff2sfnt(tabbuf)"); + gs_free_object(mem, tabbufptrs, "gs_woff2sfnt(tabbufptrs)"); + return code; +} + +int +gs_woff2sfnt_stream(gs_memory_t *mem, stream *s, byte *outbuf, int *outbuflen) +{ + return gs_woff2sfnt(mem, s, outbuf, outbuflen); +} + +int +gs_woff2sfnt_buffer(gs_memory_t *mem, byte *inbuf, int inbuflen, byte *outbuf, int *outbuflen) +{ + stream *sstrm; + int code = 0; + sstrm = file_alloc_stream(mem, "gs_woff2sfnt_buffer(buf stream)"); + if (sstrm) { + sread_string(sstrm, inbuf, inbuflen); + code = gs_woff2sfnt(mem,sstrm , outbuf, outbuflen); + sclose(sstrm); + gs_free_object(mem, sstrm, "gs_woff2sfnt_buffer(buf stream)"); + } + else { + code = gs_note_error(gs_error_VMerror); + } + return code; +} diff -Nru ghostscript-9.10~dfsg/base/gstypes.h ghostscript-9.25~dfsg+1/base/gstypes.h --- ghostscript-9.10~dfsg/base/gstypes.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gstypes.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsuid.h ghostscript-9.25~dfsg+1/base/gsuid.h --- ghostscript-9.10~dfsg/base/gsuid.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsuid.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsutil.c ghostscript-9.25~dfsg+1/base/gsutil.c --- ghostscript-9.10~dfsg/base/gsutil.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsutil.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -119,6 +119,16 @@ return ((uint)p[0] << 24) + ((uint)p[1] << 16) + ((uint)p[2] << 8) + p[3]; } +/* Put an unsigned, big-endian 32-bit value. */ +void +put_u32_msb(byte *p, const ulong n, const int offs) +{ + (p + offs)[0] = n >> 24 & 255; + (p + offs)[1] = n >> 16 & 255; + (p + offs)[2] = n >> 8 & 255; + (p + offs)[3] = n & 255; +} + /* ------ String utilities ------ */ /* Compare two strings, returning -1 if the first is less, */ diff -Nru ghostscript-9.10~dfsg/base/gsutil.h ghostscript-9.25~dfsg+1/base/gsutil.h --- ghostscript-9.10~dfsg/base/gsutil.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsutil.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -37,6 +37,10 @@ /* Get an unsigned, big-endian 32-bit value. */ ulong get_u32_msb(const byte *p); +/* Put an unsigned, big-endian 32-bit value. */ +void +put_u32_msb(byte *p, const ulong n, const int offs); + /* ------ String utilities ------ */ /* Compare two strings, returning -1 if the first is less, */ diff -Nru ghostscript-9.10~dfsg/base/gswin.rc ghostscript-9.25~dfsg+1/base/gswin.rc --- ghostscript-9.10~dfsg/base/gswin.rc 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gswin.rc 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gsxfont.h ghostscript-9.25~dfsg+1/base/gsxfont.h --- ghostscript-9.10~dfsg/base/gsxfont.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gsxfont.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxacpath.c ghostscript-9.25~dfsg+1/base/gxacpath.c --- ghostscript-9.10~dfsg/base/gxacpath.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxacpath.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ #include "gsstate.h" #include "gxdevice.h" #include "gxfixed.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gzpath.h" #include "gxpaint.h" #include "gzcpath.h" @@ -132,7 +132,7 @@ /* Start accumulating a clipping path. */ void -gx_cpath_accum_begin(gx_device_cpath_accum * padev, gs_memory_t * mem) +gx_cpath_accum_begin(gx_device_cpath_accum * padev, gs_memory_t * mem, bool transpose) { gx_device_init_on_stack((gx_device *) padev, (const gx_device *) & gs_cpath_accum_device, mem); @@ -140,21 +140,30 @@ set_dev_proc(padev, encode_color, gx_default_gray_encode); set_dev_proc(padev, decode_color, gx_default_decode_color); (*dev_proc(padev, open_device)) ((gx_device *) padev); + padev->list.transpose = transpose; } void gx_cpath_accum_set_cbox(gx_device_cpath_accum * padev, const gs_fixed_rect * pbox) { - padev->clip_box.p.x = fixed2int_var(pbox->p.x); - padev->clip_box.p.y = fixed2int_var(pbox->p.y); - padev->clip_box.q.x = fixed2int_var_ceiling(pbox->q.x); - padev->clip_box.q.y = fixed2int_var_ceiling(pbox->q.y); + if (padev->list.transpose) { + padev->clip_box.p.x = fixed2int_var(pbox->p.y); + padev->clip_box.p.y = fixed2int_var(pbox->p.x); + padev->clip_box.q.x = fixed2int_var_ceiling(pbox->q.y); + padev->clip_box.q.y = fixed2int_var_ceiling(pbox->q.x); + } else { + padev->clip_box.p.x = fixed2int_var(pbox->p.x); + padev->clip_box.p.y = fixed2int_var(pbox->p.y); + padev->clip_box.q.x = fixed2int_var_ceiling(pbox->q.x); + padev->clip_box.q.y = fixed2int_var_ceiling(pbox->q.y); + } } /* Finish accumulating a clipping path. */ +/* NB: After this the padev bbox will be restored to "normal" untransposed */ int -gx_cpath_accum_end(const gx_device_cpath_accum * padev, gx_clip_path * pcpath) +gx_cpath_accum_end(gx_device_cpath_accum * padev, gx_clip_path * pcpath) { int code = (*dev_proc(padev, close_device)) ((gx_device *) padev); /* Make an entire clipping path so we can use cpath_assign. */ @@ -168,6 +177,16 @@ apath.path.bbox.p.x = apath.path.bbox.p.y = apath.path.bbox.q.x = apath.path.bbox.q.y = 0; else { + if (padev->list.transpose) { + int tmp; + + tmp = padev->bbox.p.x; + padev->bbox.p.x = padev->bbox.p.y; + padev->bbox.p.y = tmp; + tmp = padev->bbox.q.x; + padev->bbox.q.x = padev->bbox.q.y; + padev->bbox.q.y = tmp; + } apath.path.bbox.p.x = int2fixed(padev->bbox.p.x); apath.path.bbox.p.y = int2fixed(padev->bbox.p.y); apath.path.bbox.q.x = int2fixed(padev->bbox.q.x); @@ -189,6 +208,7 @@ gx_cpath_set_outer_box(&apath); apath.path_valid = false; apath.id = gs_next_ids(padev->list_memory, 1); /* path changed => change id */ + apath.cached = NULL; gx_cpath_assign_free(pcpath, &apath); return 0; } @@ -203,33 +223,33 @@ /* Intersect two clipping paths using an accumulator. */ int gx_cpath_intersect_path_slow(gx_clip_path * pcpath, gx_path * ppath, - int rule, gs_imager_state *pis, + int rule, gs_gstate *pgs, const gx_fill_params * params0) { - gs_logical_operation_t save_lop = gs_current_logical_op_inline(pis); + gs_logical_operation_t save_lop = gs_current_logical_op_inline(pgs); gx_device_cpath_accum adev; gx_device_color devc; gx_fill_params params; int code; - gx_cpath_accum_begin(&adev, pcpath->path.memory); + gx_cpath_accum_begin(&adev, pcpath->path.memory, false); set_nonclient_dev_color(&devc, 0); /* arbitrary, but not transparent */ - gs_set_logical_op_inline(pis, lop_default); + gs_set_logical_op_inline(pgs, lop_default); if (params0 != 0) params = *params0; else { gs_point fadjust; params.rule = rule; - gs_currentfilladjust((gs_state *)pis, &fadjust); + gs_currentfilladjust(pgs, &fadjust); params.adjust.x = float2fixed(fadjust.x); params.adjust.y = float2fixed(fadjust.y); - params.flatness = gs_currentflat_inline(pis); + params.flatness = gs_currentflat_inline(pgs); } - code = gx_fill_path_only(ppath, (gx_device *)&adev, pis, + code = gx_fill_path_only(ppath, (gx_device *)&adev, pgs, ¶ms, &devc, pcpath); if (code < 0 || (code = gx_cpath_accum_end(&adev, pcpath)) < 0) gx_cpath_accum_discard(&adev); - gs_set_logical_op_inline(pis, save_lop); + gs_set_logical_op_inline(pgs, save_lop); return code; } @@ -286,8 +306,13 @@ { gx_device_cpath_accum * const adev = (gx_device_cpath_accum *)dev; - adev->list.xmin = adev->bbox.p.x; - adev->list.xmax = adev->bbox.q.x; + if (adev->list.transpose) { + adev->list.xmin = adev->bbox.p.y; + adev->list.xmax = adev->bbox.q.y; + } else { + adev->list.xmin = adev->bbox.p.x; + adev->list.xmax = adev->bbox.q.x; + } #ifdef DEBUG if (gs_debug_c('q')) { gx_clip_rect *rp = @@ -423,16 +448,24 @@ * this is possible. */ static int -accum_fill_rectangle(gx_device * dev, int x, int y, int w, int h, +accum_fill_rectangle(gx_device * dev, int xi, int yi, int w, int h, gx_color_index color) { gx_device_cpath_accum * const adev = (gx_device_cpath_accum *)dev; - int xe = x + w, ye = y + h; + int x, y, xe, ye; gx_clip_rect *nr; gx_clip_rect *ar; register gx_clip_rect *rptr; int ymin, ymax; + if (adev->list.transpose) { + x = yi, xe = yi + h; + y = xi, ye = xi + w; + } else { + x = xi, xe = x + w; + y = yi, ye = y + h; + } + /* Clip the rectangle being added. */ if (y < adev->clip_box.p.y) y = adev->clip_box.p.y; @@ -544,7 +577,6 @@ rsplit->ymax = ye; rsplit = rsplit->prev; } - ymax = ye; } /* Now ye = ymax. If necessary, split off the part of the */ /* existing band that is below the new band. */ diff -Nru ghostscript-9.10~dfsg/base/gxalloc.h ghostscript-9.25~dfsg+1/base/gxalloc.h --- ghostscript-9.10~dfsg/base/gxalloc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxalloc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,10 +28,10 @@ #include "gsalloc.h" #include "gxobj.h" -/* ================ Chunks ================ */ +/* ================ Clumps ================ */ /* - * We obtain memory from the operating system in `chunks'. A chunk + * We obtain memory from the operating system in `clumps'. A clump * may hold only a single large object (or string), or it may hold * many objects (allocated from the bottom up, always aligned) * and strings (allocated from the top down, not aligned). @@ -50,8 +50,8 @@ */ /* - * When we do a save, we create a new 'inner' chunk out of the remaining - * space in the currently active chunk. Inner chunks must not be freed + * When we do a save, we create a new 'inner' clump out of the remaining + * space in the currently active clump. Inner clumps must not be freed * by a restore. * * The garbage collector implements relocation for refs by scanning @@ -64,14 +64,14 @@ /* * Strings carry some additional overhead for use by the GC. - * At the top of the chunk is a table of relocation values for + * At the top of the clump is a table of relocation values for * 16N-character blocks of strings, where N is sizeof(uint). * This table is aligned, by adding padding above it if necessary. * Just below it is a mark table for the strings. This table is also aligned, * to improve GC performance. The actual string data start below - * the mark table. These tables are not needed for a chunk that holds + * the mark table. These tables are not needed for a clump that holds * a single large (non-string) object, but they are needed for all other - * chunks, including chunks created to hold a single large string. + * clumps, including clumps created to hold a single large string. */ /* @@ -79,7 +79,7 @@ */ typedef uint string_mark_unit; -#define log2_sizeof_string_mark_unit arch_log2_sizeof_int +#define log2_sizeof_string_mark_unit ARCH_LOG2_SIZEOF_INT /* * Define the quantum of relocation for strings, which determines * the quantum for reserving space. This value must be a power of 2, @@ -88,7 +88,7 @@ */ typedef uint string_reloc_offset; -#define log2_string_data_quantum (arch_log2_sizeof_int + 4) +#define log2_string_data_quantum (ARCH_LOG2_SIZEOF_INT + 4) #define string_data_quantum (1 << log2_string_data_quantum) /* * Define the quantum for reserving string space, including data, @@ -98,10 +98,10 @@ (string_data_quantum + (string_data_quantum / 8) +\ sizeof(string_reloc_offset)) /* - * Compute the amount of space needed for a chunk that holds only + * Compute the amount of space needed for a clump that holds only * a string of a given size. */ -#define string_chunk_space(nbytes)\ +#define string_clump_space(nbytes)\ (((nbytes) + (string_data_quantum - 1)) / string_data_quantum *\ string_space_quantum) /* @@ -115,28 +115,28 @@ #define string_quanta_mark_size(nquanta)\ ((nquanta) * (string_data_quantum / 8)) /* - * Compute the size of the string freelists for a chunk. + * Compute the size of the string freelists for a clump. */ #define STRING_FREELIST_SPACE(cp)\ (((cp->climit - csbase(cp) + 255) >> 8) * sizeof(*cp->sfree1)) /* - * To allow the garbage collector to combine chunks, we store in the - * head of each chunk the address to which its contents will be moved. + * To allow the garbage collector to combine clumps, we store in the + * head of each clump the address to which its contents will be moved. */ -/*typedef struct chunk_head_s chunk_head_t; *//* in gxobj.h */ +/*typedef struct clump_head_s clump_head_t; *//* in gxobj.h */ -/* Structure for a chunk. */ -typedef struct chunk_s chunk_t; -struct chunk_s { - chunk_head_t *chead; /* chunk head, bottom of chunk; */ +/* Structure for a clump. */ +typedef struct clump_s clump_t; +struct clump_s { + clump_head_t *chead; /* clump head, bottom of clump; */ /* csbase is an alias for chead */ #define csbase(cp) ((byte *)(cp)->chead) /* Note that allocation takes place both from the bottom up */ /* (aligned objects) and from the top down (strings). */ - byte *cbase; /* bottom of chunk data area */ + byte *cbase; /* bottom of clump data area */ byte *int_freed_top; /* top of most recent internal free area */ - /* in chunk (which may no longer be free), */ + /* in clump (which may no longer be free), */ /* used to decide when to consolidate */ /* trailing free space in allocated area */ byte *cbot; /* bottom of free area */ @@ -146,14 +146,16 @@ byte *ctop; /* top of free area */ /* (bottom of strings) */ byte *climit; /* top of strings */ - byte *cend; /* top of chunk */ - chunk_t *cprev; /* chain chunks together, */ - chunk_t *cnext; /* sorted by address */ - chunk_t *outer; /* the chunk of which this is */ - /* an inner chunk, if any */ - uint inner_count; /* number of chunks of which this is */ - /* the outer chunk, if any */ - bool has_refs; /* true if any refs in chunk */ + byte *cend; /* top of clump */ + clump_t *parent; /* splay tree parent clump */ + clump_t *left; /* splay tree left clump */ + clump_t *right; /* splay tree right clump */ + clump_t *outer; /* the clump of which this is */ + /* an inner clump, if any */ + uint inner_count; /* number of clumps of which this is */ + /* the outer clump, if any */ + bool has_refs; /* true if any refs in clump */ + bool c_alone; /* this clump is for a single allocation */ /* * Free lists for single bytes in blocks of 1 to 2*N-1 bytes, one per * 256 bytes in [csbase..climit), where N is sizeof(uint). The chain @@ -185,15 +187,15 @@ byte *rescan_top; /* top of range ditto */ }; -/* The chunk descriptor is exported only for isave.c. */ -extern_st(st_chunk); -#define public_st_chunk() /* in ialloc.c */\ - gs_public_st_ptrs2(st_chunk, chunk_t, "chunk_t",\ - chunk_enum_ptrs, chunk_reloc_ptrs, cprev, cnext) +/* The clump descriptor is exported only for isave.c. */ +extern_st(st_clump); +#define public_st_clump() /* in ialloc.c */\ + gs_public_st_ptrs3(st_clump, clump_t, "clump_t",\ + clump_enum_ptrs, clump_reloc_ptrs, left, right, parent) /* - * Macros for scanning a chunk linearly, with the following schema: - * SCAN_CHUNK_OBJECTS(cp) << declares pre, size >> + * Macros for scanning a clump linearly, with the following schema: + * SCAN_CLUMP_OBJECTS(cp) << declares pre, size >> * << code for all objects -- size not set yet >> * DO_ALL * << code for all objects -- size is set >> @@ -201,7 +203,7 @@ * * NB on error END_OBJECTS_SCAN calls gs_abort in debug systems. */ -#define SCAN_CHUNK_OBJECTS(cp)\ +#define SCAN_CLUMP_OBJECTS(cp)\ { obj_header_t *pre = (obj_header_t *)((cp)->cbase);\ obj_header_t *end = (obj_header_t *)((cp)->cbot);\ uint size;\ @@ -222,7 +224,7 @@ }\ }\ if ( pre != end )\ - { lprintf2("Chunk parsing error, 0x%lx != 0x%lx\n",\ + { lprintf2("Clump parsing error, 0x%lx != 0x%lx\n",\ (ulong)pre, (ulong)end);\ /*gs_abort((const gs_memory_t *)NULL);*/ \ }\ @@ -231,59 +233,60 @@ # define END_OBJECTS_SCAN END_OBJECTS_SCAN_NO_ABORT #endif -/* Initialize a chunk. */ +/* Initialize a clump. */ /* This is exported for save/restore. */ -void alloc_init_chunk(chunk_t *, byte *, byte *, bool, chunk_t *); +void alloc_init_clump(clump_t *, byte *, byte *, bool, clump_t *); -/* Initialize the string freelists in a chunk. */ -void alloc_init_free_strings(chunk_t *); +/* Initialize the string freelists in a clump. */ +void alloc_init_free_strings(clump_t *); -/* Find the chunk for a pointer. */ -/* Note that ptr_is_within_chunk returns true even if the pointer */ -/* is in an inner chunk of the chunk being tested. */ -#define ptr_is_within_chunk(ptr, cp)\ +/* Find the clump for a pointer. */ +/* Note that ptr_is_within_clump returns true even if the pointer */ +/* is in an inner clump of the clump being tested. */ +#define ptr_is_within_clump(ptr, cp)\ PTR_BETWEEN((const byte *)(ptr), (cp)->cbase, (cp)->cend) -#define ptr_is_in_inner_chunk(ptr, cp)\ +#define ptr_is_in_inner_clump(ptr, cp)\ ((cp)->inner_count != 0 &&\ PTR_BETWEEN((const byte *)(ptr), (cp)->cbot, (cp)->ctop)) -#define ptr_is_in_chunk(ptr, cp)\ - (ptr_is_within_chunk(ptr, cp) && !ptr_is_in_inner_chunk(ptr, cp)) -typedef struct chunk_locator_s { - const gs_ref_memory_t *memory; /* for head & tail of chain */ - chunk_t *cp; /* one-element cache */ -} chunk_locator_t; -bool chunk_locate_ptr(const void *, chunk_locator_t *); - -#define chunk_locate(ptr, clp)\ - (((clp)->cp != 0 && ptr_is_in_chunk(ptr, (clp)->cp)) ||\ - chunk_locate_ptr(ptr, clp)) +#define ptr_is_in_clump(ptr, cp)\ + (ptr_is_within_clump(ptr, cp) && !ptr_is_in_inner_clump(ptr, cp)) +typedef struct clump_locator_s { + gs_ref_memory_t *memory; /* for head & tail of chain */ + clump_t *cp; /* one-element cache */ +} clump_locator_t; +bool clump_locate_ptr(const void *, clump_locator_t *); +bool ptr_is_within_mem_clumps(const void *ptr, gs_ref_memory_t *mem); + +#define clump_locate(ptr, clp)\ + (((clp)->cp != 0 && ptr_is_in_clump(ptr, (clp)->cp)) ||\ + clump_locate_ptr(ptr, clp)) -/* Close up the current chunk. */ +/* Close up the current clump. */ /* This is exported for save/restore and for the GC. */ -void alloc_close_chunk(gs_ref_memory_t * mem); +void alloc_close_clump(gs_ref_memory_t * mem); -/* Reopen the current chunk after a GC. */ -void alloc_open_chunk(gs_ref_memory_t * mem); +/* Reopen the current clump after a GC. */ +void alloc_open_clump(gs_ref_memory_t * mem); -/* Insert or remove a chunk in the address-ordered chain. */ +/* Insert or remove a clump in the address-ordered chain. */ /* These are exported for the GC. */ -void alloc_link_chunk(chunk_t *, gs_ref_memory_t *); -void alloc_unlink_chunk(chunk_t *, gs_ref_memory_t *); +void alloc_link_clump(clump_t *, gs_ref_memory_t *); +void alloc_unlink_clump(clump_t *, gs_ref_memory_t *); -/* Free a chunk. This is exported for save/restore and for the GC. */ -void alloc_free_chunk(chunk_t *, gs_ref_memory_t *); +/* Free a clump. This is exported for save/restore and for the GC. */ +void alloc_free_clump(clump_t *, gs_ref_memory_t *); -/* Print a chunk debugging message. */ +/* Print a clump debugging message. */ /* Unfortunately, the ANSI C preprocessor doesn't allow us to */ /* define the list of variables being printed as a macro. */ -#define dprintf_chunk_format\ +#define dprintf_clump_format\ "%s 0x%lx (0x%lx..0x%lx, 0x%lx..0x%lx..0x%lx)\n" -#define dmprintf_chunk(mem, msg, cp)\ - dmprintf7(mem, dprintf_chunk_format,\ +#define dmprintf_clump(mem, msg, cp)\ + dmprintf7(mem, dprintf_clump_format,\ msg, (ulong)(cp), (ulong)(cp)->cbase, (ulong)(cp)->cbot,\ (ulong)(cp)->ctop, (ulong)(cp)->climit, (ulong)(cp)->cend) -#define if_debug_chunk(c, mem, msg, cp)\ - if_debug7m(c, mem,dprintf_chunk_format,\ +#define if_debug_clump(c, mem, msg, cp)\ + if_debug7m(c, mem,dprintf_clump_format,\ msg, (ulong)(cp), (ulong)(cp)->cbase, (ulong)(cp)->cbot,\ (ulong)(cp)->ctop, (ulong)(cp)->climit, (ulong)(cp)->cend) @@ -332,9 +335,9 @@ struct gs_ref_memory_s { /* The following are set at initialization time. */ gs_memory_common; - uint chunk_size; + uint clump_size; uint large_size; /* min size to give large object */ - /* its own chunk: must be */ + /* its own clump: must be */ /* 1 mod obj_align_mod */ uint space; /* a_local, a_global, a_system */ # if IGC_PTR_STABILITY_CHECK @@ -345,15 +348,13 @@ gs_memory_gc_status_t gc_status; /* The following are updated dynamically. */ bool is_controlled; /* if true, this allocator doesn't manage */ - /* its own chunks */ + /* its own clumps */ ulong limit; /* signal a VMerror when total */ /* allocated exceeds this */ - chunk_t *cfirst; /* head of chunk list */ - chunk_t *clast; /* tail of chunk list */ - chunk_t cc; /* current chunk */ - chunk_t *pcc; /* where to store cc */ - chunk_locator_t cfreed; /* chunk where last object freed */ - ulong allocated; /* total size of all chunks */ + clump_t *root; /* root of clump splay tree */ + clump_t *cc; /* current clump */ + clump_locator_t cfreed; /* clump where last object freed */ + ulong allocated; /* total size of all clumps */ /* allocated at this save level */ ulong gc_allocated; /* value of (allocated + */ /* previous_status.allocated) after last GC */ @@ -402,16 +403,17 @@ extern const gs_memory_procs_t gs_ref_memory_procs; /* - * Scan the chunks of an allocator: - * SCAN_MEM_CHUNKS(mem, cp) - * << code to process chunk cp >> - * END_CHUNKS_SCAN - */ -#define SCAN_MEM_CHUNKS(mem, cp)\ - { chunk_t *cp = (mem)->cfirst;\ - for ( ; cp != 0; cp = cp->cnext )\ + * Scan the clumps of an allocator: + * SCAN_MEM_CLUMPS(mem, cp) + * << code to process clump cp >> + * END_CLUMPS_SCAN + */ +#define SCAN_MEM_CLUMPS(mem, cp)\ + { clump_splay_walker sw;\ + clump_t *cp;\ + for (cp = clump_splay_walk_init(&sw, mem); cp != 0; cp = clump_splay_walk_fwd(&sw))\ { -#define END_CHUNKS_SCAN\ +#define END_CLUMPS_SCAN\ }\ } @@ -453,12 +455,12 @@ /* contents. */ void debug_print_object(const gs_memory_t *mem, const void *obj, const dump_control_t * control); -/* Print the contents of a chunk with the given options. */ +/* Print the contents of a clump with the given options. */ /* Relevant options: all. */ -void debug_dump_chunk(const gs_memory_t *mem, const chunk_t * cp, const dump_control_t * control); -void debug_print_chunk(const gs_memory_t *mem, const chunk_t * cp); /* default options */ +void debug_dump_clump(const gs_memory_t *mem, const clump_t * cp, const dump_control_t * control); +void debug_print_clump(const gs_memory_t *mem, const clump_t * cp); /* default options */ -/* Print the contents of all chunks managed by an allocator. */ +/* Print the contents of all clumps managed by an allocator. */ /* Relevant options: all. */ void debug_dump_memory(const gs_ref_memory_t *mem, const dump_control_t *control); @@ -470,6 +472,76 @@ /* Find all the objects that contain a given pointer. */ void debug_find_pointers(const gs_ref_memory_t *mem, const void *target); +/* Dump the splay tree of clumps */ +void debug_dump_clump_tree(const gs_ref_memory_t *mem); + #endif /* DEBUG */ +/* Routines for walking/manipulating the splay tree of clumps */ +typedef enum { + SPLAY_APP_CONTINUE = 0, + SPLAY_APP_STOP = 1 +} splay_app_result_t; + +/* Apply function 'fn' to every node in the clump splay tree. + * These are applied in depth first order, which means that + * 'fn' is free to perform any operation it likes on the subtree + * rooted at the current node, as long as it doesn't affect + * any nodes higher in the tree than the current node. The + * classic example of this is deletion, which can cause the + * subtree to be rrarranged. */ +clump_t *clump_splay_app(clump_t *root, gs_ref_memory_t *imem, splay_app_result_t (*fn)(clump_t *, void *), void *arg); + +typedef enum +{ + /* As we step, keep track of where we just stepped from. */ + SPLAY_FROM_ABOVE = 0, + SPLAY_FROM_LEFT = 1, + SPLAY_FROM_RIGHT = 2 +} splay_dir_t; + +/* Structure to contain details of a 'walker' for the clump + * splay tree. Treat this as opaque. Only defined at this + * public level to avoid the need for mallocs. + * No user servicable parts inside. */ +typedef struct +{ + /* The direction we most recently moved in the + * splay tree traversal. */ + splay_dir_t from; + /* The current node in the splay tree traversal. */ + clump_t *cp; + /* The node that marks the end of the splay tree traversal. + * (NULL for top of tree). */ + clump_t *end; +} clump_splay_walker; + +/* Prepare a splay walker for walking forwards. + * It will perform an in-order traversal of the entire tree, + * starting at min and stopping after max with NULL. */ +clump_t *clump_splay_walk_init(clump_splay_walker *sw, const gs_ref_memory_t *imem); + +/* Prepare a splay walker for walking forwards, + * starting from a point somewhere in the middle of the tree. + * The traveral starts at cp, proceeds in-order to max, then + * restarts at min, stopping with NULL after reaching mid again. + */ +clump_t *clump_splay_walk_init_mid(clump_splay_walker *sw, clump_t *cp); + +/* Return the next node in the traversal of the clump + * splay tree as set up by clump_splay_walk_init{,_mid}. + * Will return NULL at the end point. */ +clump_t *clump_splay_walk_fwd(clump_splay_walker *sw); + +/* Prepare a splay walker for walking backwards. + * It will perform a reverse-in-order traversal of the + * entire tree, starting at max, and stopping after min + * with NULL. */ +clump_t *clump_splay_walk_bwd_init(clump_splay_walker *sw, const gs_ref_memory_t *imem); + +/* Return the next node in the traversal of the clump + * splay tree as set up by clump_splay_walk_bwd_init. + * Will return NULL at the end point. */ +clump_t *clump_splay_walk_bwd(clump_splay_walker *sw); + #endif /* gxalloc_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxalpha.h ghostscript-9.25~dfsg+1/base/gxalpha.h --- ghostscript-9.10~dfsg/base/gxalpha.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxalpha.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxarith.h ghostscript-9.25~dfsg+1/base/gxarith.h --- ghostscript-9.10~dfsg/base/gxarith.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxarith.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxband.h ghostscript-9.25~dfsg+1/base/gxband.h --- ghostscript-9.10~dfsg/base/gxband.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxband.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,21 +21,6 @@ #include "gxclio.h" -/* - * Define the parameters controlling banding. - */ -/* if you make any additions/changes to this structure you need to make - the appropriate additions/changes to the compare_gdev_prn_space_params() - function in gdevprn.c */ -typedef struct gx_band_params_s { - bool page_uses_transparency; /* PDF 1.4 transparency is used on the page */ - int BandWidth; /* (optional) band width in pixels */ - int BandHeight; /* (optional) */ - long BandBufferSpace; /* (optional) */ -} gx_band_params_t; - -#define BAND_PARAMS_INITIAL_VALUES 0, 0, 0, 0 - /* We hold color usage as a bitfield that needs to be at least as wide as * a gx_color_index - so for simplicity define it that way, even though * the two are not equal. */ @@ -67,12 +52,13 @@ clist_file_ptr bfile; /* block file, normally 0 */ const clist_io_procs_t *io_procs; uint tile_cache_size; /* size of tile cache */ + ulong line_ptrs_offset; /* Offset of line_ptrs within tile cache */ int64_t bfile_end_pos; /* ftell at end of bfile */ gx_band_params_t band_params; /* parameters used when writing band list */ /* (actual values, no 0s) */ } gx_band_page_info_t; #define PAGE_INFO_NULL_VALUES\ - { 0 }, 0, { 0 }, NULL, 0, 0, 0, { BAND_PARAMS_INITIAL_VALUES } + { 0 }, 0, { 0 }, NULL, 0, 0, 0, 0, { BAND_PARAMS_INITIAL_VALUES } /* * By convention, the structure member containing the above is called @@ -83,6 +69,7 @@ #define page_bfile page_info.bfile #define page_bfname page_info.bfname #define page_tile_cache_size page_info.tile_cache_size +#define page_line_ptrs_offset page_info.line_ptrs_offset #define page_bfile_end_pos page_info.bfile_end_pos #define page_band_height page_info.band_params.BandHeight diff -Nru ghostscript-9.10~dfsg/base/gxbcache.c ghostscript-9.25~dfsg+1/base/gxbcache.c --- ghostscript-9.10~dfsg/base/gxbcache.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxbcache.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxbcache.h ghostscript-9.25~dfsg+1/base/gxbcache.h --- ghostscript-9.10~dfsg/base/gxbcache.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxbcache.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxbitfmt.h ghostscript-9.25~dfsg+1/base/gxbitfmt.h --- ghostscript-9.10~dfsg/base/gxbitfmt.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxbitfmt.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxbitmap.h ghostscript-9.25~dfsg+1/base/gxbitmap.h --- ghostscript-9.10~dfsg/base/gxbitmap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxbitmap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -65,6 +65,13 @@ ((uint)((((width_bits) + (align_bitmap_mod * 8 - 1))\ >> (log2_align_bitmap_mod + 3)) << log2_align_bitmap_mod)) +#define bitmap_raster_pad_align_(width_bits, pad, log2_align)\ + ((uint)((((width_bits) + (pad<<3) + ((8<> (log2_align + 3)) << log2_align)) + +#define bitmap_raster_pad_align(width_bits, pad, log2_align)\ + bitmap_raster_pad_align_(width_bits, pad, (log2_align < log2_align_bitmap_mod ? log2_align_bitmap_mod : log2_align)) + /* * Define the gx analogue of the basic bitmap structure. Note that since * all scan lines must be aligned, the requirement on raster is: diff -Nru ghostscript-9.10~dfsg/base/gxbitops.h ghostscript-9.25~dfsg+1/base/gxbitops.h --- ghostscript-9.10~dfsg/base/gxbitops.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxbitops.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -86,7 +86,7 @@ /* * Define the chunk size for monobit copying operations. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN # define mono_copy_chunk uint # define set_mono_right_mask(var, w)\ (var = ((w) == chunk_bits ? chunk_all_bits : chunk_hi_bits(w))) diff -Nru ghostscript-9.10~dfsg/base/gxblend1.c ghostscript-9.25~dfsg+1/base/gxblend1.c --- ghostscript-9.10~dfsg/base/gxblend1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxblend1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* PDF 1.4 blending functions */ @@ -23,16 +23,41 @@ #include "gxblend.h" #include "gxdcconv.h" #include "gxdevcli.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gdevdevn.h" #include "gdevp14.h" -#include "vdtrace.h" #include "gxdcconv.h" +#include "gsicc_cache.h" #ifdef DUMP_TO_PNG #include "png_.h" #endif +/* A case where we have RGB + spots. This is actually an RGB color and we + * should zero out the spot colorants */ +void +pdf14_unpack_rgb_mix(int num_comp, gx_color_index color, + pdf14_device * p14dev, byte * out) +{ + int i; + + memset(out, 0, num_comp); + for (i = 2; i >= 0; i--) { + out[i] = (byte)(color & 0xff); + color >>= 8; + } +} + +/* A case where we have Gray + spots. This is actually a Gray color and we +* should zero out the spot colorants */ +void +pdf14_unpack_gray_mix(int num_comp, gx_color_index color, + pdf14_device * p14dev, byte * out) +{ + memset(out, 0, num_comp); + out[0] = (byte)(color & 0xff); +} + /* * Unpack a device color. This routine is similar to the device's * decode_color procedure except for two things. The procedure produces 1 @@ -71,59 +96,6 @@ } /* - * Unpack a 'compressed' CMYK color index. The color index value is unpacked - * into a set of 8 bit values. For more information about 'compressed' color - * index values see the comments before the devn_encode_compressed_color routine. - * - * Note: For simplicity of coding the calling routines, this routine will also - * handle 'uncompressed' color index values. - */ -void -pdf14_unpack_compressed(int num_comp, gx_color_index color, - pdf14_device * p14dev, byte * out) -{ - int comp_num; - - if (p14dev->devn_params.compressed_color_list == NULL) { - /* - * For 'uncompressed' data we simply have to unpack the gx_color_index - * value directly. - */ - for (comp_num = num_comp - 1; comp_num >= 0; comp_num--) { - out[comp_num] = 0xff - (byte)(color & 0xff); - color >>= 8; - } - } - else { - int factor, bit_count, bit_mask; - comp_bit_map_list_t * pbitmap; - gx_color_value solid_color = 0xff; - - pbitmap = find_bit_map(color, - p14dev->devn_params.compressed_color_list); - bit_count = num_comp_bits[pbitmap->num_non_solid_comp]; - bit_mask = (1 << bit_count) - 1; - factor = comp_bit_factor[pbitmap->num_non_solid_comp]; - if (pbitmap->solid_not_100) { - solid_color = 0xff - ((factor * ((int)color & bit_mask)) >> 16); - color >>= bit_count; - } - for (comp_num = 0; comp_num < num_comp; comp_num++) { - if (colorant_present(pbitmap, colorants, comp_num)) { - if (colorant_present(pbitmap, solid_colorants, comp_num)) - *out++ = (byte)solid_color; - else { - *out++ = 0xff - ((factor * ((int)color & bit_mask)) >> 16); - color >>= bit_count; - } - } - else - *out++ = 0xff; - } - } -} - -/* * Unpack a device color. This routine is used for devices in which we do * not know the details of the process color model. In this case we use * the device's decode_color procedure. @@ -145,10 +117,49 @@ extern unsigned int global_index; #endif -void -pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool has_shape) +static void +copy_plane_part(byte *des_ptr, int des_rowstride, byte *src_ptr, int src_rowstride, + int width, int height) { - /* make copy of backdrop for compositing */ + int y; + + if (width == des_rowstride && width == src_rowstride) { + width *= height; + height = 1; + } + + for (y = 0; y < height; ++y) { + memcpy(des_ptr, src_ptr, width); + des_ptr += des_rowstride; + src_ptr += src_rowstride; + } +} + +static void +copy_extra_planes(byte *des_buf, pdf14_buf *des_info, byte *src_buf, + pdf14_buf *src_info, int width, int height) +{ + /* alpha_g and shape do not copy */ + des_buf += des_info->planestride * ((des_info->has_shape ? 1 : 0) + + (des_info->has_alpha_g ? 1 : 0)); + src_buf += src_info->planestride * ((src_info->has_shape ? 1 : 0) + + (src_info->has_alpha_g ? 1 : 0)); + /* tags plane does copy */ + if (des_info->has_tags) { + if (src_info->has_tags) { + copy_plane_part(des_buf, des_info->rowstride, src_buf, + src_info->rowstride, width, height); + } + } +} + +int +pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile, + pdf14_buf *tos, cmm_profile_t *tos_profile, + gs_memory_t *memory, gs_gstate *pgs, gx_device *dev, + bool knockout_buff) +{ + /* Make copy of backdrop, but convert to new group's colorspace */ int x0 = max(buf->rect.p.x, tos->rect.p.x); int x1 = min(buf->rect.q.x, tos->rect.q.x); int y0 = max(buf->rect.p.y, tos->rect.p.y); @@ -156,306 +167,153 @@ if (x0 < x1 && y0 < y1) { int width = x1 - x0; - byte *buf_plane = buf->data + x0 - buf->rect.p.x + (y0 - buf->rect.p.y) * buf->rowstride; - byte *tos_plane = tos->data + x0 - tos->rect.p.x + (y0 - tos->rect.p.y) * tos->rowstride; - int i; - /*int n_chan_copy = buf->n_chan + (tos->has_shape ? 1 : 0);*/ - int n_chan_copy = tos->n_chan + (tos->has_shape ? 1 : 0) + (tos->has_tags ? 1 : 0); + int height = y1 - y0; + byte *buf_plane, *tos_plane; + gsicc_rendering_param_t rendering_params; + gsicc_link_t *icc_link; + gsicc_bufferdesc_t input_buff_desc; + gsicc_bufferdesc_t output_buff_desc; + + /* Define the rendering intents */ + rendering_params.black_point_comp = gsBLACKPTCOMP_ON; + rendering_params.graphics_type_tag = GS_IMAGE_TAG; + rendering_params.override_icc = false; + rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; + rendering_params.rendering_intent = gsPERCEPTUAL; + rendering_params.cmm = gsCMM_DEFAULT; + /* Request the ICC link for the transform that we will need to use */ + icc_link = gsicc_get_link_profile(pgs, dev, tos_profile, group_profile, + &rendering_params, memory, false); + if (icc_link == NULL) + return gs_throw(gs_error_unknownerror, "ICC link failed. Trans backdrop"); + + if (icc_link->is_identity) { + pdf14_preserve_backdrop(buf, tos, knockout_buff); + gsicc_release_link(icc_link); + return 0; + } else { + if (knockout_buff) { + buf_plane = buf->backdrop + x0 - buf->rect.p.x + + (y0 - buf->rect.p.y) * buf->rowstride; + tos_plane = tos->backdrop + x0 - tos->rect.p.x + + (y0 - tos->rect.p.y) * tos->rowstride; + memset(buf->backdrop, 0, buf->n_chan * buf->planestride); + } else { + buf_plane = buf->data + x0 - buf->rect.p.x + + (y0 - buf->rect.p.y) * buf->rowstride; + tos_plane = tos->data + x0 - tos->rect.p.x + + (y0 - tos->rect.p.y) * tos->rowstride; + /* First clear out everything. There are cases where the incoming buf + has a region outside the existing tos group. Need to check if this + is getting clipped in which case we need to fix the allocation of + the buffer to be smaller */ + memset(buf->data, 0, buf->n_planes * buf->planestride); + } + /* Set up the buffer descriptors. */ + gsicc_init_buffer(&input_buff_desc, tos_profile->num_comps, 1, false, + false, true, tos->planestride, tos->rowstride, height, + width); + gsicc_init_buffer(&output_buff_desc, group_profile->num_comps, 1, false, + false, true, buf->planestride, buf->rowstride, height, + width); + /* Transform the data. */ + (icc_link->procs.map_buffer)(dev, icc_link, &input_buff_desc, + &output_buff_desc, tos_plane, buf_plane); + gsicc_release_link(icc_link); + } + /* Copy the alpha data */ + buf_plane += buf->planestride * (buf->n_chan - 1); + tos_plane += tos->planestride * (tos->n_chan - 1); + copy_plane_part(buf_plane, buf->rowstride, tos_plane, tos->rowstride, width, + height); + buf_plane += buf->planestride; + tos_plane += tos->planestride; - for (i = 0; i < n_chan_copy; i++) { - byte *buf_ptr = buf_plane; - byte *tos_ptr = tos_plane; - int y; - - for (y = y0; y < y1; ++y) { - memcpy (buf_ptr, tos_ptr, width); - buf_ptr += buf->rowstride; - tos_ptr += tos->rowstride; - } - buf_plane += buf->planestride; - tos_plane += tos->planestride; - } - if (has_shape && !tos->has_shape) { - if (tos->has_tags) { - buf_plane -= buf->planestride; - } - memset (buf_plane, 0, buf->planestride); - } + if (!knockout_buff) + copy_extra_planes(buf_plane, buf, tos_plane, tos, width, height); } #if RAW_DUMP if (x0 < x1 && y0 < y1) { byte *buf_plane = buf->data + x0 - buf->rect.p.x + (y0 - buf->rect.p.y) * buf->rowstride; - dump_raw_buffer(y1-y0, x1 - x0, buf->n_planes, - buf->planestride, buf->rowstride, - "BackDropInit",buf_plane); + dump_raw_buffer(y1 - y0, x1 - x0, buf->n_planes, buf->planestride, + buf->rowstride, "BackDropInit_CM", buf_plane); global_index++; } #endif + return 0; } void -pdf14_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, - int x0, int x1, int y0, int y1, int n_chan, bool additive, - const pdf14_nonseparable_blending_procs_t * pblend_procs, - bool overprint, gx_color_index drawn_comps, bool blendspot, - gs_memory_t *memory) -{ - byte alpha = tos->alpha; - byte shape = tos->shape; - byte blend_mode = tos->blend_mode; - byte *tos_ptr = tos->data + x0 - tos->rect.p.x + - (y0 - tos->rect.p.y) * tos->rowstride; - byte *nos_ptr = nos->data + x0 - nos->rect.p.x + - (y0 - nos->rect.p.y) * nos->rowstride; - byte *mask_row_ptr = NULL; - byte *mask_curr_ptr = NULL; - int tos_planestride = tos->planestride; - int nos_planestride = nos->planestride; - int mask_planestride = 0x0badf00d; /* Quiet compiler. */ - byte mask_bg_alpha = 0; /* Quiet compiler. */ - int width = x1 - x0; - int x, y; - int i; - byte tos_pixel[PDF14_MAX_PLANES]; - byte nos_pixel[PDF14_MAX_PLANES]; - bool tos_isolated = tos->isolated; - bool nos_knockout = nos->knockout; - byte *nos_alpha_g_ptr; - int tos_shape_offset = n_chan * tos_planestride; - int tos_alpha_g_offset = tos_shape_offset + - (tos->has_shape ? tos_planestride : 0); - bool tos_has_tag = tos->has_tags; - int tos_tag_offset = tos_planestride * (tos->n_planes - 1); - int nos_shape_offset = n_chan * nos_planestride; - int nos_tag_offset = nos_planestride * (nos->n_planes - 1); - byte *mask_tr_fn = NULL; /* Quiet compiler. */ - gx_color_index comps; - bool has_mask = false; - bool in_mask_rect_y = false; - bool in_mask_rect = false; - byte pix_alpha; - -#if RAW_DUMP - byte *composed_ptr = NULL; -#endif +pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool knockout_buff) +{ + /* make copy of backdrop for compositing */ + int x0 = max(buf->rect.p.x, tos->rect.p.x); + int x1 = min(buf->rect.q.x, tos->rect.q.x); + int y0 = max(buf->rect.p.y, tos->rect.p.y); + int y1 = min(buf->rect.q.y, tos->rect.q.y); - if ((tos->n_chan == 0) || (nos->n_chan == 0)) - return; - rect_merge(nos->dirty, tos->dirty); - if_debug6m('v', memory, - "pdf14_pop_transparency_group y0 = %d, y1 = %d, w = %d, alpha = %d, shape = %d, tag = bm = %d\n", - y0, y1, width, alpha, shape, blend_mode); - if (!nos->has_shape) - nos_shape_offset = 0; - if (!nos->has_tags) - nos_tag_offset = 0; - if (nos->has_alpha_g) - nos_alpha_g_ptr = nos_ptr + n_chan * nos_planestride; - else - nos_alpha_g_ptr = NULL; - - if (maskbuf != NULL) { - int tmp; - - mask_tr_fn = maskbuf->transfer_fn; - /* Make sure we are in the mask buffer */ - if (maskbuf->data != NULL) { - mask_row_ptr = maskbuf->data + x0 - maskbuf->rect.p.x + - (y0 - maskbuf->rect.p.y) * maskbuf->rowstride; - mask_planestride = maskbuf->planestride; - has_mask = true; - } - /* We may have a case, where we are outside the maskbuf rect. */ - /* We would have avoided creating the maskbuf->data */ - /* In that case, we should use the background alpha value */ - /* See discussion on the BC entry in the PDF spec. */ - mask_bg_alpha = maskbuf->alpha; - /* Adjust alpha by the mask background alpha. This is only used - if we are outside the soft mask rect during the filling operation */ - mask_bg_alpha = mask_tr_fn[mask_bg_alpha]; - tmp = alpha * mask_bg_alpha + 0x80; - mask_bg_alpha = (tmp + (tmp >> 8)) >> 8; - } - n_chan--; -#if RAW_DUMP - composed_ptr = nos_ptr; - dump_raw_buffer(y1-y0, width, tos->n_planes, - tos_planestride, tos->rowstride, - "bImageTOS",tos_ptr); - dump_raw_buffer(y1-y0, width, nos->n_planes, - nos_planestride, nos->rowstride, - "cImageNOS",nos_ptr); - if (maskbuf !=NULL && maskbuf->data != NULL){ - dump_raw_buffer(maskbuf->rect.q.y - maskbuf->rect.p.y, - maskbuf->rect.q.x - maskbuf->rect.p.x, maskbuf->n_planes, - maskbuf->planestride, maskbuf->rowstride, - "dMask", maskbuf->data); - } -#endif - for (y = y1-y0; y > 0; --y) { - mask_curr_ptr = mask_row_ptr; - if (has_mask && y1 - y >= maskbuf->rect.p.y && y1 - y < maskbuf->rect.q.y) { - in_mask_rect_y = true; + if (x0 < x1 && y0 < y1) { + int width = x1 - x0; + int height = y1 - y0; + byte *buf_plane, *tos_plane; + int i, n_planes; + + if (knockout_buff) { + buf_plane = buf->backdrop; + tos_plane = tos->backdrop; + n_planes = buf->n_chan; } else { - in_mask_rect_y = false; + buf_plane = buf->data; + tos_plane = tos->data; + n_planes = buf->n_planes; + } + /* First clear out everything. There are cases where the incoming buf + has a region outside the existing tos group. Need to check if this + is getting clipped in which case we need to fix the allocation of + the buffer to be smaller */ + if (x0 > buf->rect.p.x || x1 < buf->rect.q.x || + y0 > buf->rect.p.y || y1 < buf->rect.q.y) { + /* FIXME: There is potential for more optimisation here, + * but I don't know how often we hit this case. */ + memset(buf_plane, 0, n_planes * buf->planestride); + } else if (n_planes > tos->n_chan) { + /* The next planes are alpha_g, shape, tags. We need to clear + * alpha_g and shape, but don't need to clear the tag plane + * if it would be copied below (and if it exists). */ + int tag_plane_num = tos->n_chan + !!buf->has_shape + !!buf->has_alpha_g; + if (!knockout_buff && n_planes > tag_plane_num) + n_planes = tag_plane_num; + if (n_planes > tos->n_chan) + memset(buf->data + tos->n_chan * buf->planestride, 0, (n_planes - tos->n_chan) * buf->planestride); + } + buf_plane += x0 - buf->rect.p.x + + (y0 - buf->rect.p.y) * buf->rowstride; + tos_plane += x0 - tos->rect.p.x + + (y0 - tos->rect.p.y) * tos->rowstride; + /* Color and alpha plane */ + for (i = 0; i < tos->n_chan; i++) { + copy_plane_part(buf_plane, buf->rowstride, tos_plane, tos->rowstride, + width, height); + buf_plane += buf->planestride; + tos_plane += tos->planestride; } - for (x = 0; x < width; x++) { - if (in_mask_rect_y && has_mask && x0 + x >= maskbuf->rect.p.x && x0 + x < maskbuf->rect.q.x) { - in_mask_rect = true; - } else { - in_mask_rect = false; - } - - pix_alpha = alpha; - /* If we have a soft mask, then we have some special handling of the - group alpha value */ - if (has_mask) { - if (!in_mask_rect) { - /* Special case where we have a soft mask but are outside the - range of the soft mask and must use the background alpha value */ - pix_alpha = mask_bg_alpha; - } else { - /* If we are isolated, do not double apply the alpha */ - if (tos_isolated) { - pix_alpha = 0xff; - } - } - } - - /* Complement the components for subtractive color spaces */ - if (additive) { - for (i = 0; i <= n_chan; ++i) { - tos_pixel[i] = tos_ptr[i * tos_planestride]; - nos_pixel[i] = nos_ptr[i * nos_planestride]; - } - } else { - for (i = 0; i < n_chan; ++i) { - tos_pixel[i] = 255 - tos_ptr[i * tos_planestride]; - nos_pixel[i] = 255 - nos_ptr[i * nos_planestride]; - } - tos_pixel[n_chan] = tos_ptr[n_chan * tos_planestride]; - nos_pixel[n_chan] = nos_ptr[n_chan * nos_planestride]; - } - if (mask_curr_ptr != NULL) { - if (in_mask_rect) { - byte mask = mask_tr_fn[*mask_curr_ptr++]; - int tmp = pix_alpha * mask + 0x80; - pix_alpha = (tmp + (tmp >> 8)) >> 8; - } else { - mask_curr_ptr++; - } - } -# if VD_PAINT_MASK - vd_pixel(int2fixed(x), int2fixed(y1-y), mask); -# endif - - if (nos_knockout) { - byte *nos_shape_ptr = nos_shape_offset ? - &nos_ptr[nos_shape_offset] : NULL; - byte *nos_tag_ptr = nos_tag_offset ? - &nos_ptr[nos_tag_offset] : NULL; - byte tos_shape = tos_ptr[tos_shape_offset]; - byte tos_tag = tos_ptr[tos_tag_offset]; - art_pdf_composite_knockout_isolated_8(nos_pixel, - nos_shape_ptr, - nos_tag_ptr, - tos_pixel, - n_chan, - tos_shape, - tos_tag, - pix_alpha, shape, - has_mask); - } else { - if (tos_isolated) { - art_pdf_composite_group_8(nos_pixel, nos_alpha_g_ptr, - tos_pixel, n_chan, - pix_alpha, blend_mode, pblend_procs); - } else { - byte tos_alpha_g = tos_ptr[tos_alpha_g_offset]; - art_pdf_recomposite_group_8(nos_pixel, nos_alpha_g_ptr, - tos_pixel, tos_alpha_g, n_chan, - pix_alpha, blend_mode, pblend_procs); - } - if (tos_has_tag) { - if (pix_alpha == 255) { - nos_ptr[nos_tag_offset] = tos_ptr[tos_tag_offset]; - } else if (pix_alpha != 0 && tos_ptr[tos_tag_offset] != - GS_UNTOUCHED_TAG) { - nos_ptr[nos_tag_offset] = - (nos_ptr[nos_tag_offset] | - tos_ptr[tos_tag_offset]) & - ~GS_UNTOUCHED_TAG; - } - } - } - if (nos_shape_offset) { - nos_ptr[nos_shape_offset] = - art_pdf_union_mul_8 (nos_ptr[nos_shape_offset], - tos_ptr[tos_shape_offset], - shape); - } - /* Complement the results for subtractive color spaces */ - if (additive) { - for (i = 0; i <= n_chan; ++i) { - nos_ptr[i * nos_planestride] = nos_pixel[i]; - } - } else { - if (overprint) { - if (blendspot) { - /* Overprint simulation of spot colorants */ - for (i = 0; i < n_chan; ++i) { - int temp = - (255 - nos_ptr[i * nos_planestride]) * - (nos_pixel[i]); - temp = temp >> 8; - nos_ptr[i * nos_planestride] = (255 - temp); - } - } else { - for (i = 0, comps = drawn_comps; comps != 0; ++i, comps >>= 1) { - if ((comps & 0x1) != 0) { - nos_ptr[i * nos_planestride] = 255 - nos_pixel[i]; - } - } - } - } else { - for (i = 0; i < n_chan; ++i) - nos_ptr[i * nos_planestride] = 255 - nos_pixel[i]; - } - nos_ptr[n_chan * nos_planestride] = nos_pixel[n_chan]; - } -# if VD_PAINT_COLORS - vd_pixel(int2fixed(x), int2fixed(y1-y), n_chan == 0 ? - (nos_pixel[0] << 16) + (nos_pixel[0] << 8) + nos_pixel[0] : - (nos_pixel[0] << 16) + (nos_pixel[1] << 8) + nos_pixel[2]); -# endif -# if VD_PAINT_ALPHA - vd_pixel(int2fixed(x), int2fixed(y1-y), - (nos_pixel[n_chan] << 16) + (nos_pixel[n_chan] << 8) + - nos_pixel[n_chan]); -# endif - if (nos_alpha_g_ptr != NULL) - ++nos_alpha_g_ptr; - ++tos_ptr; - ++nos_ptr; - } - tos_ptr += tos->rowstride - width; - nos_ptr += nos->rowstride - width; - if (nos_alpha_g_ptr != NULL) - nos_alpha_g_ptr += nos->rowstride - width; - if (mask_row_ptr != NULL) - mask_row_ptr += maskbuf->rowstride; + if (!knockout_buff) + copy_extra_planes(buf_plane, buf, tos_plane, tos, width, height); } - /* Lets look at composed result */ #if RAW_DUMP - /* The group alpha should disappear */ - dump_raw_buffer(y1-y0, width, tos->n_planes - tos->has_alpha_g - tos->has_shape, - nos_planestride, nos->rowstride, - "eComposed",composed_ptr); - global_index++; + if (x0 < x1 && y0 < y1) { + byte *buf_plane = (knockout_buff ? buf->backdrop : buf->data); + buf_plane += x0 - buf->rect.p.x + + (y0 - buf->rect.p.y) * buf->rowstride; + dump_raw_buffer(y1 - y0, x1 - x0, buf->n_planes, buf->planestride, + buf->rowstride, "BackDropInit", buf_plane); + global_index++; + } #endif } + /* * Encode a list of colorant values into a gx_color_index_value. */ @@ -463,8 +321,8 @@ pdf14_encode_color(gx_device *dev, const gx_color_value colors[]) { gx_color_index color = 0; - int i; - int ncomp = dev->color_info.num_components; + uchar i; + uchar ncomp = dev->color_info.num_components; COLROUND_VARS; COLROUND_SETUP(8); @@ -483,8 +341,8 @@ pdf14_encode_color_tag(gx_device *dev, const gx_color_value colors[]) { gx_color_index color; - int i; - int ncomp = dev->color_info.num_components; + uchar i; + uchar ncomp = dev->color_info.num_components; COLROUND_VARS; COLROUND_SETUP(8); @@ -503,8 +361,8 @@ int pdf14_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out) { - int i; - int ncomp = dev->color_info.num_components; + uchar i; + uchar ncomp = dev->color_info.num_components; for (i = 0; i < ncomp; i++) { out[ncomp - i - 1] = (gx_color_value) ((color & 0xff) * 0x101); @@ -513,65 +371,80 @@ return 0; } -/* - * Encode a list of colorant values into a gx_color_index_value. For more - * information about 'compressed' color index values see the comments before - * the devn_encode_compressed_color routine. - */ -gx_color_index -pdf14_compressed_encode_color(gx_device *dev, const gx_color_value colors[]) +void +pdf14_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) { - gs_devn_params *pdevn_params = NULL; + uchar num_comp = dev->color_info.num_components; - if (dev->procs.ret_devn_params != NULL) - pdevn_params = dev_proc(dev, ret_devn_params)(dev); - /* If there was no dev_proc or it returned NULL, assume pdf14 device devn_params */ - if (pdevn_params == NULL) { -#ifdef DEBUG - if (strncmp(dev->dname, "pdf14", 5)) - emprintf1(dev->memory, - "pdf14_compressed_encode_color devn_params not from pdf14 device, device = '%s'\n", - dev->dname); -#endif - pdevn_params = &(((pdf14_device *)dev)->devn_params); - } - return devn_encode_compressed_color(dev, colors, pdevn_params); + out[0] = out[1] = out[2] = frac_0; + out[3] = frac_1 - gray; + for (--num_comp; num_comp > 3; num_comp--) + out[num_comp] = 0; } -/* - * Decode a gx_color_index value back to a list of colorant values. For more - * information about 'compressed' color index values see the comments before - * the devn_encode_compressed_color routine. - */ -int -pdf14_compressed_decode_color(gx_device * dev, gx_color_index color, - gx_color_value * out) +/* These three must handle rgb + spot */ +void +pdf14_gray_cs_to_rgbspot_cm(gx_device * dev, frac gray, frac out[]) { - gs_devn_params *pdevn_params = NULL; + uchar num_comp = dev->color_info.num_components; - if (dev->procs.ret_devn_params != NULL) - pdevn_params = dev_proc(dev, ret_devn_params)(dev); - /* If there was no dev_proc or it returned NULL, assume pdf14 device devn_params */ - if (pdevn_params == NULL) { -#ifdef DEBUG - if (strncmp(dev->dname, "pdf14", 5)) - emprintf1(dev->memory, - "pdf14_compressed_decode_color devn_params not from pdf14 device, device = '%s'\n", - dev->dname); -#endif - pdevn_params = &(((pdf14_device *)dev)->devn_params); - } - return devn_decode_compressed_color(dev, color, out, pdevn_params); + out[0] = out[1] = out[2] = gray; + for (--num_comp; num_comp > 2; num_comp--) + out[num_comp] = 0; } void -pdf14_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]) +pdf14_rgb_cs_to_rgbspot_cm(gx_device * dev, const gs_gstate *pgs, + frac r, frac g, frac b, frac out[]) { - int num_comp = dev->color_info.num_components; + uchar num_comp = dev->color_info.num_components; - out[0] = out[1] = out[2] = frac_0; - out[3] = frac_1 - gray; - for (--num_comp; num_comp > 3; num_comp--) + out[0] = r; + out[1] = g; + out[2] = b; + for (--num_comp; num_comp > 2; num_comp--) + out[num_comp] = 0; +} + +void +pdf14_cmyk_cs_to_rgbspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +{ + uchar num_comp = dev->color_info.num_components; + + color_cmyk_to_rgb(c, m, y, k, NULL, out, dev->memory); + for (--num_comp; num_comp > 2; num_comp--) + out[num_comp] = 0; +} + +/* These three must handle gray + spot */ +void +pdf14_gray_cs_to_grayspot_cm(gx_device * dev, frac gray, frac out[]) +{ + uchar num_comp = dev->color_info.num_components; + + out[0] = gray; + for (--num_comp; num_comp > 0; num_comp--) + out[num_comp] = 0; +} + +void +pdf14_rgb_cs_to_grayspot_cm(gx_device * dev, const gs_gstate *pgs, + frac r, frac g, frac b, frac out[]) +{ + uchar num_comp = dev->color_info.num_components; + + out[0] = (r + g + b) / 3; + for (--num_comp; num_comp > 0; num_comp--) + out[num_comp] = 0; +} + +void +pdf14_cmyk_cs_to_grayspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) +{ + uchar num_comp = dev->color_info.num_components; + + out[0] = color_cmyk_to_gray(c, m, y, k, NULL); + for (--num_comp; num_comp > 0; num_comp--) out[num_comp] = 0; } @@ -581,7 +454,7 @@ * it is unlikely that any device with a DeviceCMYK color model * would define this mapping on its own. * - * If the imager state is not available, map as though the black + * If the gs_gstate is not available, map as though the black * generation and undercolor removal functions are identity * transformations. This mode is used primarily to support the * raster operation (rop) feature of PCL, which requires that @@ -591,13 +464,13 @@ * often they are { pop 0 }. */ void -pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_imager_state *pis, +pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { - int num_comp = dev->color_info.num_components; + uchar num_comp = dev->color_info.num_components; - if (pis != 0) - color_rgb_to_cmyk(r, g, b, pis, out, dev->memory); + if (pgs != 0) + color_rgb_to_cmyk(r, g, b, pgs, out, dev->memory); else { frac c = frac_1 - r, m = frac_1 - g, y = frac_1 - b; frac k = min(c, min(m, y)); @@ -614,7 +487,7 @@ void pdf14_cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]) { - int num_comp = dev->color_info.num_components; + uchar num_comp = dev->color_info.num_components; out[0] = c; out[1] = m; @@ -731,33 +604,37 @@ #endif void -gx_build_blended_image_row(byte *buf_ptr, int y, int planestride, - int width, int num_comp, byte bg, byte *linebuf) +gx_build_blended_image_row(const byte *gs_restrict buf_ptr, int planestride, + int width, int num_comp, byte bg, byte *gs_restrict linebuf) { - int x; - for (x = 0; x < width; x++) { - byte comp, a; - int tmp, comp_num; + int inc = planestride * num_comp; + buf_ptr += inc - 1; + for (; width > 0; width--) { /* composite RGBA (or CMYKA, etc.) pixel with over solid background */ - a = buf_ptr[x + planestride * num_comp]; + byte a = *++buf_ptr; + int i = num_comp; - if ((a + 1) & 0xfe) { - a ^= 0xff; - for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[x + planestride * comp_num]; - tmp = ((bg - comp) * a) + 0x80; - comp += (tmp + (tmp >> 8)) >> 8; - linebuf[x * num_comp + comp_num] = comp; - } - } else if (a == 0) { - for (comp_num = 0; comp_num < num_comp; comp_num++) { - linebuf[x * num_comp + comp_num] = bg; - } + if (a == 0) { + do { + *linebuf++ = bg; + } while (--i); } else { - for (comp_num = 0; comp_num < num_comp; comp_num++) { - comp = buf_ptr[x + planestride * comp_num]; - linebuf[x * num_comp + comp_num] = comp; + buf_ptr -= inc; + if (a == 0xff) { + do { + *linebuf++ = *buf_ptr; + buf_ptr += planestride; + } while (--i); + } else { + a ^= 0xff; + do { + byte comp = *buf_ptr; + int tmp = ((bg - comp) * a) + 0x80; + buf_ptr += planestride; + comp += (tmp + (tmp >> 8)) >> 8; + *linebuf++ = comp; + } while (--i); } } } @@ -796,10 +673,10 @@ } int -gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr, - int planestride, int rowstride, - int x0, int y0, int width, int height, int num_comp, byte bg, - bool has_tags, gs_int_rect rect, gs_separations * pseparations) +gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr, int planestride, + int rowstride, int x0, int y0, int width, int height, + int num_comp, byte bg, bool has_tags, gs_int_rect rect, + gs_separations * pseparations) { int code = 0; int x, y, tmp, comp_num, output_comp_num; @@ -812,7 +689,6 @@ int num_known_comp = 0; int output_num_comp = target->color_info.num_components; int num_sep = pseparations->num_separations++; - bool data_blended = false; int num_rows_left; /* @@ -847,15 +723,19 @@ } } /* See if the target device has a put_image command. If - yes then see if it can handle the image data directly. */ - if (target->procs.put_image != NULL) { + yes then see if it can handle the image data directly. */ + if (target->procs.put_image != gx_default_put_image) { /* See if the target device can handle the data in its current form with the alpha component */ int alpha_offset = num_comp; int tag_offset = has_tags ? num_comp+1 : 0; - code = dev_proc(target, put_image) (target, buf_ptr, num_comp, + const byte *buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS]; + int i; + for (i = 0; i < num_comp; i++) + buf_ptrs[i] = buf_ptr + i * planestride; + code = dev_proc(target, put_image) (target, buf_ptrs, num_comp, rect.p.x, rect.p.y, width, height, - rowstride, planestride, + rowstride, num_comp,tag_offset); if (code == 0) { /* Device could not handle the alpha data. Go ahead and @@ -867,7 +747,7 @@ "pre_final_blend",buf_ptr); global_index++; #endif - gx_blend_image_buffer(buf_ptr, width, height, rowstride, + gx_blend_image_buffer(buf_ptr, width, height, rowstride, planestride, num_comp, bg); #if RAW_DUMP /* Dump before and after the blend to make sure we are doing that ok */ @@ -876,23 +756,23 @@ global_index++; /* clist_band_count++; */ #endif - data_blended = true; /* Try again now */ alpha_offset = 0; - code = dev_proc(target, put_image) (target, buf_ptr, num_comp, + code = dev_proc(target, put_image) (target, buf_ptrs, num_comp, rect.p.x, rect.p.y, width, height, - rowstride, planestride, + rowstride, alpha_offset, tag_offset); } if (code > 0) { /* We processed some or all of the rows. Continue until we are done */ num_rows_left = height - code; while (num_rows_left > 0) { - code = dev_proc(target, put_image) (target, buf_ptr, num_comp, + code = dev_proc(target, put_image) (target, buf_ptrs, num_comp, rect.p.x, rect.p.y+code, width, num_rows_left, rowstride, - planestride, alpha_offset, tag_offset); + if (code < 0) + return code; num_rows_left = num_rows_left - code; } return 0; @@ -929,15 +809,13 @@ } } color = dev_proc(target, encode_color)(target, cv); - code = dev_proc(target, fill_rectangle)(target, x + x0, - y + y0, 1, 1, color); + code = dev_proc(target, fill_rectangle)(target, x + x0, y + y0, 1, 1, color); if (code < 0) return code; } buf_ptr += rowstride; } - return code; } @@ -981,10 +859,11 @@ color = dev_proc(target, encode_color)(target, cv); code = dev_proc(target, fill_rectangle)(target, x + x0, y + y0, 1, 1, color); + if (code < 0) + return code; } buf_ptr += rowstride; } - return code; } diff -Nru ghostscript-9.10~dfsg/base/gxblend.c ghostscript-9.25~dfsg+1/base/gxblend.c --- ghostscript-9.10~dfsg/base/gxblend.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxblend.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* PDF 1.4 blending functions */ @@ -23,6 +23,9 @@ #include "gxcolor2.h" #include "gsicc_cache.h" #include "gsicc_manage.h" +#include "gdevp14.h" +#include "gsrect.h" /* for rect_merge */ +#include "math_.h" /* for ceil, floor */ typedef int art_s32; @@ -31,6 +34,32 @@ extern unsigned int clist_band_count; #endif +#undef TRACK_COMPOSE_GROUPS +#ifdef TRACK_COMPOSE_GROUPS +int compose_groups[1<<17]; + +static int track_compose_groups = 0; + +static void dump_track_compose_groups(void); +#endif + + +/* For spot colors, blend modes must be white preserving and separable. The + * order of the blend modes should be reordered so this is a single compare */ +bool +blend_valid_for_spot(gs_blend_mode_t blend_mode) +{ + if (blend_mode == BLEND_MODE_Difference || + blend_mode == BLEND_MODE_Exclusion || + blend_mode == BLEND_MODE_Hue || + blend_mode == BLEND_MODE_Saturation || + blend_mode == BLEND_MODE_Color || + blend_mode == BLEND_MODE_Luminosity) + return false; + else + return true; +} + /* This function is used for mapping the SMask source to a monochrome luminosity value which basically is the alpha value Note, that separation colors are not allowed here. Everything @@ -40,7 +69,7 @@ void smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, - int plane_stride, byte *src, const byte *dst, bool isadditive, + int plane_stride, byte *gs_restrict src, const byte *gs_restrict dst, bool isadditive, gs_transparency_mask_subtype_t SMask_SubType) { int x,y; @@ -155,8 +184,8 @@ mask. This situation is detected in the code so that we only do this blending in those rare situations */ void -smask_blend(byte *src, int width, int height, int rowstride, - int planestride) +smask_blend(byte *gs_restrict src, int width, int height, int rowstride, + int planestride) { int x, y; int position; @@ -183,7 +212,7 @@ } void smask_copy(int num_rows, int num_cols, int row_stride, - byte *src, const byte *dst) + byte *gs_restrict src, const byte *gs_restrict dst) { int y; byte *dstptr,*srcptr; @@ -197,8 +226,8 @@ } } -void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, - int row_stride, int plane_stride, byte *src, const byte *dst, +void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, + int row_stride, int plane_stride, byte *gs_restrict src, const byte *gs_restrict dst, gsicc_link_t *icclink) { gsicc_bufferdesc_t input_buff_desc; @@ -222,13 +251,13 @@ false, false, true, plane_stride, row_stride, num_rows, num_cols); /* Transform the data */ - (icclink->procs.map_buffer)(dev, icclink, &input_buff_desc, &output_buff_desc, + (icclink->procs.map_buffer)(dev, icclink, &input_buff_desc, &output_buff_desc, (void*) src, (void*) dst); } void -art_blend_luminosity_rgb_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) +art_blend_luminosity_rgb_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src) { int rb = backdrop[0], gb = backdrop[1], bb = backdrop[2]; int rs = src[0], gs = src[1], bs = src[2]; @@ -271,8 +300,8 @@ } void -art_blend_luminosity_custom_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) +art_blend_luminosity_custom_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src) { int delta_y = 0, test = 0; int r[ART_MAX_CHAN]; @@ -343,8 +372,8 @@ * Our component values have already been complemented, i.e. (1 - X). */ void -art_blend_luminosity_cmyk_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) +art_blend_luminosity_cmyk_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src) { int i; @@ -355,8 +384,8 @@ } void -art_blend_saturation_rgb_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) +art_blend_saturation_rgb_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src) { int rb = backdrop[0], gb = backdrop[1], bb = backdrop[2]; int rs = src[0], gs = src[1], bs = src[2]; @@ -420,8 +449,8 @@ } void -art_blend_saturation_custom_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) +art_blend_saturation_custom_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src) { int minb, maxb; int mins, maxs; @@ -501,8 +530,8 @@ /* Our component values have already been complemented, i.e. (1 - X). */ void -art_blend_saturation_cmyk_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src) +art_blend_saturation_cmyk_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src) { int i; @@ -574,10 +603,11 @@ 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0 }; -void -art_blend_pixel_8(byte *dst, const byte *backdrop, - const byte *src, int n_chan, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) +static forceinline void +art_blend_pixel_8_inline(byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev) { int i; byte b, s; @@ -726,6 +756,45 @@ pblend_procs->blend_saturation(n_chan, dst, tmp, backdrop); } break; + /* This mode requires information about the color space as + * well as the overprint mode. See Section 7.6.3 of + * PDF specification */ + case BLEND_MODE_CompatibleOverprint: + { + gx_color_index drawn_comps = p14dev->drawn_comps; + gx_color_index comps; + /* If overprint mode is true and the current color space and + * the group color space are CMYK (or CMYK and spots), then + * B(cb, cs) = cs if cs is nonzero otherwise it is cb for CMYK. + * Spot colors are always set to cb. The nice thing about the PDF14 + * compositor is that it always has CMYK + spots with spots after + * the CMYK colorants (see gx_put_blended_image_cmykspot). + * that way we don't have to worry about where the process colors + * are. */ + if (p14dev->overprint_mode && p14dev->color_info.num_components > 3 + && !(p14dev->ctx->additive)) { + for (i = 0; i < 4; i++) { + b = backdrop[i]; + s = src[i]; + dst[i] = s < 0xff ? s : b; /* Subtractive zero */ + } + for (i = 4; i < n_chan; i++) { + dst[i] = backdrop[i]; + } + } else { + /* Otherwise we have B(cb, cs)= cs if cs is specified in + * the current color space all other color should get cb. + * Essentially the standard overprint case. */ + for (i = 0, comps = drawn_comps; comps != 0; ++i, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst[i] = src[i]; + } else { + dst[i] = backdrop[i]; + } + } + } + break; + } default: #ifndef GS_THREADSAFE dlprintf1("art_blend_pixel_8: blend mode %d not implemented\n", @@ -737,132 +806,16 @@ } void -art_blend_pixel(ArtPixMaxDepth* dst, const ArtPixMaxDepth *backdrop, - const ArtPixMaxDepth* src, int n_chan, - gs_blend_mode_t blend_mode) +art_blend_pixel_8(byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev) { - int i; - ArtPixMaxDepth b, s; - bits32 t; - - switch (blend_mode) { - case BLEND_MODE_Normal: - case BLEND_MODE_Compatible: /* todo */ - memcpy(dst, src, n_chan * sizeof(ArtPixMaxDepth)); - break; - case BLEND_MODE_Multiply: - for (i = 0; i < n_chan; i++) { - t = ((bits32) backdrop[i]) * ((bits32) src[i]); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - case BLEND_MODE_Screen: - for (i = 0; i < n_chan; i++) { - t = - ((bits32) (0xffff - backdrop[i])) * - ((bits32) (0xffff - src[i])); - t += 0x8000; - t += (t >> 16); - dst[i] = 0xffff - (t >> 16); - } - break; - case BLEND_MODE_Overlay: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (b < 0x8000) - t = 2 * ((bits32) b) * ((bits32) s); - else - t = 0xfffe0001u - - 2 * ((bits32) (0xffff - b)) * ((bits32) (0xffff - s)); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - case BLEND_MODE_HardLight: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (s < 0x8000) - t = 2 * ((bits32) b) * ((bits32) s); - else - t = 0xfffe0001u - - 2 * ((bits32) (0xffff - b)) * ((bits32) (0xffff - s)); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - case BLEND_MODE_ColorDodge: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - if (b == 0) - dst[i] = 0; - else if (s >= b) - dst[i] = 0xffff; - else - dst[i] = (0x1fffe * s + b) / (b << 1); - } - break; - case BLEND_MODE_ColorBurn: - for (i = 0; i < n_chan; i++) { - b = 0xffff - backdrop[i]; - s = src[i]; - if (b == 0) - dst[i] = 0xffff; - else if (b >= s) - dst[i] = 0; - else - dst[i] = 0xffff - (0x1fffe * b + s) / (s << 1); - } - break; - case BLEND_MODE_Darken: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = b < s ? b : s; - } - break; - case BLEND_MODE_Lighten: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - dst[i] = b > s ? b : s; - } - break; - case BLEND_MODE_Difference: - for (i = 0; i < n_chan; i++) { - art_s32 tmp; - - tmp = ((art_s32) backdrop[i]) - ((art_s32) src[i]); - dst[i] = tmp < 0 ? -tmp : tmp; - } - break; - case BLEND_MODE_Exclusion: - for (i = 0; i < n_chan; i++) { - b = backdrop[i]; - s = src[i]; - t = ((bits32) (0xffff - b)) * ((bits32) s) + - ((bits32) b) * ((bits32) (0xffff - s)); - t += 0x8000; - t += (t >> 16); - dst[i] = t >> 16; - } - break; - default: -#ifndef GS_THREADSAFE - dlprintf1("art_blend_pixel: blend mode %d not implemented\n", - blend_mode); -#endif - memcpy(dst, src, n_chan); - break; - } + art_blend_pixel_8_inline(dst, backdrop, src, n_chan, blend_mode, + pblend_procs, p14dev); } +#ifdef UNUSED byte art_pdf_union_8(byte alpha1, byte alpha2) { @@ -871,27 +824,81 @@ tmp = (0xff - alpha1) * (0xff - alpha2) + 0x80; return 0xff - ((tmp + (tmp >> 8)) >> 8); } +#endif -byte -art_pdf_union_mul_8(byte alpha1, byte alpha2, byte alpha_mask) +static void +art_pdf_knockout_composite_pixel_alpha_8(byte *gs_restrict backdrop, byte tos_shape, byte *gs_restrict dst, + const byte *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev) { + byte a_b, a_s; + unsigned int a_r; int tmp; + int src_scale; + int c_b, c_s; + int i; + + a_s = src[n_chan]; + a_b = backdrop[n_chan]; + if (a_s == 0) { + /* source alpha is zero, if we have a src shape value there then copy + the backdrop, else leave it alone */ + if (tos_shape) + memcpy(dst, backdrop, n_chan + 1); + return; + } + + /* In this case a_s is not zero */ + if (a_b == 0) { + /* backdrop alpha is zero but not source alpha, just copy source pixels and + avoid computation. */ + memcpy(dst, src, n_chan + 1); + return; + } + + /* Result alpha is Union of backdrop and source alpha */ + tmp = (0xff - a_b) * (0xff - a_s) + 0x80; + a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + /* todo: verify that a_r is nonzero in all cases */ + + /* Compute a_s / a_r in 16.16 format */ + src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; - if (alpha_mask == 0xff) { - tmp = (0xff - alpha1) * (0xff - alpha2) + 0x80; - return 0xff - ((tmp + (tmp >> 8)) >> 8); + if (blend_mode == BLEND_MODE_Normal) { + /* Do simple compositing of source over backdrop */ + for (i = 0; i < n_chan; i++) { + c_s = src[i]; + c_b = backdrop[i]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst[i] = tmp >> 16; + } } else { - tmp = alpha2 * alpha_mask + 0x80; - tmp = (tmp + (tmp >> 8)) >> 8; - tmp = (0xff - alpha1) * (0xff - tmp) + 0x80; - return 0xff - ((tmp + (tmp >> 8)) >> 8); + /* Do compositing with blending */ + byte blend[ART_MAX_CHAN]; + + art_blend_pixel_8(blend, backdrop, src, n_chan, blend_mode, pblend_procs, + p14dev); + for (i = 0; i < n_chan; i++) { + int c_bl; /* Result of blend function */ + int c_mix; /* Blend result mixed with source color */ + + c_s = src[i]; + c_b = backdrop[i]; + c_bl = blend[i]; + tmp = a_b * (c_bl - ((int)c_s)) + 0x80; + c_mix = c_s + (((tmp >> 8) + tmp) >> 8); + tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; + dst[i] = tmp >> 16; + } } + dst[n_chan] = a_r; } void -art_pdf_composite_pixel_alpha_8(byte *dst, const byte *src, int n_chan, - gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) +art_pdf_composite_pixel_alpha_8(byte *gs_restrict dst, const byte *gs_restrict src, int n_chan, + gs_blend_mode_t blend_mode, int first_spot, + const pdf14_nonseparable_blending_procs_t * pblend_procs, pdf14_device *p14dev) { byte a_b, a_s; unsigned int a_r; @@ -925,20 +932,12 @@ /* Compute a_s / a_r in 16.16 format */ src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; - if (blend_mode == BLEND_MODE_Normal) { - /* Do simple compositing of source over backdrop */ - for (i = 0; i < n_chan; i++) { - c_s = src[i]; - c_b = dst[i]; - tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; - dst[i] = tmp >> 16; - } - } else { + if (first_spot != 0) { /* Do compositing with blending */ byte blend[ART_MAX_CHAN]; - art_blend_pixel_8(blend, dst, src, n_chan, blend_mode, pblend_procs); - for (i = 0; i < n_chan; i++) { + art_blend_pixel_8(blend, dst, src, first_spot, blend_mode, pblend_procs, p14dev); + for (i = 0; i < first_spot; i++) { int c_bl; /* Result of blend function */ int c_mix; /* Blend result mixed with source color */ @@ -952,13 +951,26 @@ } } dst[n_chan] = a_r; + + dst += first_spot; + src += first_spot; + n_chan -= first_spot; + if (n_chan == 0) + return; + + /* Do simple compositing of source over backdrop */ + for (i = 0; i < n_chan; i++) { + c_s = src[i]; + c_b = dst[i]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst[i] = tmp >> 16; + } } -void -art_pdf_composite_pixel_alpha_8_fast(byte *dst, const byte *src, int n_chan, - gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs, - int stride) +static forceinline byte * +art_pdf_composite_pixel_alpha_8_inline(byte *gs_restrict dst, byte *gs_restrict src, int n_chan, + gs_blend_mode_t blend_mode, int first_spot, + const pdf14_nonseparable_blending_procs_t * pblend_procs, pdf14_device *p14dev) { byte a_b, a_s; unsigned int a_r; @@ -968,8 +980,18 @@ int i; a_s = src[n_chan]; + if (a_s == 0) { + /* source alpha is zero, avoid all computations and possible + divide by zero errors. */ + return NULL; /* No change to destination at all! */ + } - a_b = dst[n_chan * stride]; + a_b = dst[n_chan]; + if (a_b == 0) { + /* backdrop alpha is zero, just copy source pixels and avoid + computation. */ + return src; + } /* Result alpha is Union of backdrop and source alpha */ tmp = (0xff - a_b) * (0xff - a_s) + 0x80; @@ -979,50 +1001,62 @@ /* Compute a_s / a_r in 16.16 format */ src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; - if (blend_mode == BLEND_MODE_Normal) { - /* Do simple compositing of source over backdrop */ - for (i = 0; i < n_chan; i++) { - c_s = src[i]; - c_b = dst[i * stride]; - tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; - dst[i * stride] = tmp >> 16; - } - } else { + if (first_spot != 0) { /* Do compositing with blending */ byte blend[ART_MAX_CHAN]; - byte dst_tmp[ART_MAX_CHAN]; - for (i = 0; i < n_chan; i++) { - dst_tmp[i] = dst[i * stride]; - } - art_blend_pixel_8(blend, dst_tmp, src, n_chan, blend_mode, pblend_procs); - for (i = 0; i < n_chan; i++) { + art_blend_pixel_8_inline(blend, dst, src, first_spot, blend_mode, pblend_procs, p14dev); + for (i = 0; i < first_spot; i++) { int c_bl; /* Result of blend function */ int c_mix; /* Blend result mixed with source color */ c_s = src[i]; - c_b = dst_tmp[i]; + c_b = dst[i]; c_bl = blend[i]; tmp = a_b * (c_bl - ((int)c_s)) + 0x80; c_mix = c_s + (((tmp >> 8) + tmp) >> 8); tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; - dst[i * stride] = tmp >> 16; + dst[i] = tmp >> 16; } } - dst[n_chan * stride] = a_r; + dst[n_chan] = a_r; + + n_chan -= first_spot; + if (n_chan == 0) + return dst; + dst += first_spot; + src += first_spot; + + /* Do simple compositing of source over backdrop */ + for (i = 0; i < n_chan; i++) { + c_s = src[i]; + c_b = dst[i]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst[i] = tmp >> 16; + } + return dst - first_spot; } -void -art_pdf_composite_pixel_alpha_8_fast_mono(byte *dst, const byte *src, +/** + * art_pdf_composite_pixel_alpha_8_fast_mono: Tweaked version of art_pdf_composite_pixel_alpha_8_fast. + * Same args, except n_chan, which is assumed to be 1: + * @stride: stride between dst pixel values. + * @p14dev: pdf14 device + * Dst data is therefore in dst[i * stride] for 0 <= i <= 1. + * Called with the guarantee that dst[stride] != 0, src[1] != 0, and that blend_mode != Normal + */ +static inline void +art_pdf_composite_pixel_alpha_8_fast_mono(byte *gs_restrict dst, const byte *gs_restrict src, gs_blend_mode_t blend_mode, const pdf14_nonseparable_blending_procs_t * pblend_procs, - int stride) + int stride, pdf14_device *p14dev) { byte a_b, a_s; unsigned int a_r; int tmp; int src_scale; int c_b, c_s; + byte blend[ART_MAX_CHAN]; a_s = src[1]; @@ -1036,212 +1070,82 @@ /* Compute a_s / a_r in 16.16 format */ src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; - if (blend_mode == BLEND_MODE_Normal) { - /* Do simple compositing of source over backdrop */ + /* Do compositing with blending */ + art_blend_pixel_8(blend, dst, src, 1, blend_mode, pblend_procs, p14dev); + { + int c_bl; /* Result of blend function */ + int c_mix; /* Blend result mixed with source color */ + c_s = src[0]; c_b = dst[0]; - tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + c_bl = blend[0]; + tmp = a_b * (c_bl - ((int)c_s)) + 0x80; + c_mix = c_s + (((tmp >> 8) + tmp) >> 8); + tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; dst[0] = tmp >> 16; - } else { - /* Do compositing with blending */ - byte blend[ART_MAX_CHAN]; - - art_blend_pixel_8(blend, dst, src, 1, blend_mode, pblend_procs); - { - int c_bl; /* Result of blend function */ - int c_mix; /* Blend result mixed with source color */ - - c_s = src[0]; - c_b = dst[0]; - c_bl = blend[0]; - tmp = a_b * (c_bl - ((int)c_s)) + 0x80; - c_mix = c_s + (((tmp >> 8) + tmp) >> 8); - tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; - dst[0] = tmp >> 16; - } } dst[stride] = a_r; } -#if 0 /** - * art_pdf_composite_pixel_knockout_8: Composite two pixels with knockout. - * @dst: Where to store resulting pixel, also immediate backdrop. - * @backdrop: Initial backdrop color. - * @src: Source pixel color. - * @n_chan: Number of channels. - * @blend_mode: Blend mode. - * - * Composites two pixels using the compositing operation specialized - * for knockout groups (Section 5.5). A few things to keep in mind: - * - * 1. This is a reference implementation, not a high-performance one. - * - * 2. All pixels are assumed to have a single alpha channel. + * art_pdf_recomposite_group_8: Recomposite group pixel. + * @dst: Where to store pixel, also initial backdrop of group. + * @dst_alpha_g: Optional pointer to alpha g value associated with @dst. + * @alpha: Alpha mask value. + * @src_alpha_g: alpha_g value associated with @src. + * @blend_mode: Blend mode for compositing. + * @first_blend_spot: The first component for which Normal blending should be used. + * @pblend_procs: Procs for handling non separable blending modes. + * @p14dev: pdf14 device * - * 3. Zero is black, one is white. + * Note: this is only for non-isolated groups. This covers only the + * single-alpha case. A separate function is needed for dual-alpha, + * and that probably needs to treat knockout separately. + * Also note the need to know if the spot colorants should be blended + * normal. This occurs when we have spot colorants and the blending is set + * for non-separable or non-white preserving blend modes + * @src_alpha_g corresponds to $\alpha g_n$ in the Adobe notation. * - * Also note that src and dst are expected to be allocated aligned to - * 32 bit boundaries, ie bytes from [0] to [(n_chan + 3) & -4] may - * be accessed. + * @alpha corresponds to $fk_i \cdot fm_i \cdot qk_i \cdot qm_i$. * - * All pixel values have both alpha and shape channels, ie with those - * included the total number of channels is @n_chan + 2. + * @NOTE: This function may corrupt src. * - * An invariant: shape >= alpha. + * Returns 1 if we need to call art_pdf_composite_pixel_alpha_8. **/ -void -art_pdf_composite_pixel_knockout_8(byte *dst, - const byte *backdrop, const byte *src, - int n_chan, gs_blend_mode_t blend_mode) +static forceinline int +art_pdf_recomposite_group_8(byte *gs_restrict *dstp, byte *gs_restrict dst_alpha_g, + byte *gs_restrict src, byte src_alpha_g, int n_chan, + byte alpha, gs_blend_mode_t blend_mode, int first_blend_spot, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev) { - int i; - byte ct[ART_MAX_CHAN + 1]; - byte src_shape; - byte backdrop_alpha; byte dst_alpha; - bits32 src_opacity; - bits32 backdrop_weight, t_weight; + int i; int tmp; + int scale; + byte *gs_restrict dst = *dstp; - if (src[n_chan] == 0) - return; - if (src[n_chan + 1] == 255 && blend_mode == BLEND_MODE_Normal || - dst[n_chan] == 0) { - - memcpy (dst, src, n_chan + 2); - - return; - } - - src_shape = src[n_chan + 1]; /* $fs_i$ */ - src_opacity = (255 * src[n_chan] + 0x80) / src_shape; /* $qs_i$ */ -#if 0 - for (i = 0; i < (n_chan + 3) >> 2; i++) { - ((bits32 *) src_tmp)[i] = ((const bits32 *)src[i]); - } - src_tmp[n_chan] = src_opacity; + if (src_alpha_g == 0) + return 0; - for (i = 0; i <= n_chan >> 2; i++) { - ((bits32 *) tmp)[i] = ((bits32 *) backdrop[i]); - } -#endif + if (blend_mode == BLEND_MODE_Normal && alpha == 255) { + /* In this case, uncompositing and recompositing cancel each + other out. Note: if the reason that alpha == 255 is that + there is no constant mask and no soft mask, then this + operation should be optimized away at a higher level. */ - backdrop_scale = if (blend_mode == BLEND_MODE_Normal) { - /* Do simple compositing of source over backdrop */ - for (i = 0; i < n_chan; i++) { - c_s = src[i]; - c_b = dst[i]; - tmp = (c_b << 16) + ct_scale * (c_s - c_b) + 0x8000; - ct[i] = tmp >> 16; + if (dst_alpha_g != NULL) { + tmp = (255 - *dst_alpha_g) * (255 - src_alpha_g) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); } - } else { - /* Do compositing with blending */ - byte blend[ART_MAX_CHAN]; - - art_blend_pixel_8(blend, backdrop, src, n_chan, blend_mode, pblend_procs); - for (i = 0; i < n_chan; i++) { - int c_bl; /* Result of blend function */ - int c_mix; /* Blend result mixed with source color */ - - c_s = src[i]; - c_b = dst[i]; - c_bl = blend[i]; - tmp = a_b * (((int)c_bl) - ((int)c_s)) + 0x80; - c_mix = c_s + (((tmp >> 8) + tmp) >> 8); - tmp = (c_b << 16) + ct_scale * (c_mix - c_b) + 0x8000; - ct[i] = tmp >> 16; - } - } - - /* do weighted average of $Ct$ using relative alpha contribution as weight */ - backdrop_alpha = backdrop[n_chan]; - tmp = (0xff - blend_alpha) * (0xff - backdrop_alpha) + 0x80; - dst_alpha = 0xff - (((tmp >> 8) + tmp) >> 8); - dst[n_chan] = dst_alpha; - t_weight = ((blend_alpha << 16) + 0x8000) / dst_alpha; - for (i = 0; i < n_chan; i++) { - - } -} -#endif - -void -art_pdf_uncomposite_group_8(byte *dst, - const byte *backdrop, - const byte *src, byte src_alpha_g, int n_chan) -{ - byte backdrop_alpha = backdrop[n_chan]; - int i; - int tmp; - int scale; - - dst[n_chan] = src_alpha_g; - - if (src_alpha_g == 0) - return; - - scale = (backdrop_alpha * 255 * 2 + src_alpha_g) / (src_alpha_g << 1) - - backdrop_alpha; - for (i = 0; i < n_chan; i++) { - int si, di; - - si = src[i]; - di = backdrop[i]; - tmp = (si - di) * scale + 0x80; - tmp = si + ((tmp + (tmp >> 8)) >> 8); - - /* todo: it should be possible to optimize these cond branches */ - if (tmp < 0) - tmp = 0; - if (tmp > 255) - tmp = 255; - dst[i] = tmp; - } - -} - -void -art_pdf_recomposite_group_8(byte *dst, byte *dst_alpha_g, - const byte *src, byte src_alpha_g, int n_chan, - byte alpha, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) -{ - byte dst_alpha; - int i; - int tmp; - int scale; - - if (src_alpha_g == 0) - return; - - if (blend_mode == BLEND_MODE_Normal && alpha == 255) { - /* In this case, uncompositing and recompositing cancel each - other out. Note: if the reason that alpha == 255 is that - there is no constant mask and no soft mask, then this - operation should be optimized away at a higher level. */ - - memcpy(dst, src, n_chan + 1); - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - src_alpha_g) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } - return; + *dstp = src; + return 0; } else { /* "interesting" blend mode */ - byte ca[ART_MAX_CHAN + 1]; /* $C, \alpha$ */ - dst_alpha = dst[n_chan]; - if (src_alpha_g == 255 || dst_alpha == 0) { - memcpy(ca, src, n_chan + 3); - } else { + if (src_alpha_g != 255 && dst_alpha != 0) { /* Uncomposite the color. In other words, solve - "src = (ca, src_alpha_g) over dst" for ca */ - - /* todo (maybe?): replace this code with call to - art_pdf_uncomposite_group_8() to reduce code - duplication. */ - + "src = (src, src_alpha_g) over dst" for src */ scale = (dst_alpha * 255 * 2 + src_alpha_g) / (src_alpha_g << 1) - dst_alpha; for (i = 0; i < n_chan; i++) { @@ -1257,59 +1161,122 @@ tmp = 0; if (tmp > 255) tmp = 255; - ca[i] = tmp; + src[i] = tmp; } } tmp = src_alpha_g * alpha + 0x80; tmp = (tmp + (tmp >> 8)) >> 8; - ca[n_chan] = tmp; + src[n_chan] = tmp; if (dst_alpha_g != NULL) { tmp = (255 - *dst_alpha_g) * (255 - tmp) + 0x80; *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); } - art_pdf_composite_pixel_alpha_8(dst, ca, n_chan, - blend_mode, pblend_procs); } + return 1; /* todo: optimize BLEND_MODE_Normal buf alpha != 255 case */ } -void -art_pdf_composite_group_8(byte *dst, byte *dst_alpha_g, - const byte *src, int n_chan, byte alpha, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) +/** + * art_pdf_composite_knockout_group_8: Composite group pixel. + * @backdrop: Backdrop of original parent group. + * @tos_shape: So that we know to copy the backdrop or not even if a_s is zero + * @dst: Where to store pixel. + * @dst_alpha_g: Optional pointer to alpha g value. + * @alpha: Alpha mask value. + * @blend_mode: Blend mode for compositing. + * @pblend_procs: Procs for handling non separable blending modes. + * @p14dev: PDF14 device + * @has_mask: needed for knowing to pass back the soft mask value if shape = 0 + * + * Note: this is only for knockout nonisolated groups. + * + * @alpha corresponds to $fk_i \cdot fm_i \cdot qk_i \cdot qm_i$. + * + * @NOTE: This function may corrupt src. + **/ +static forceinline void +art_pdf_composite_knockout_group_8(byte *gs_restrict backdrop, byte tos_shape, byte *gs_restrict dst, + byte *gs_restrict dst_alpha_g, byte *gs_restrict src, int n_chan, byte alpha, + gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev, bool has_mask) { byte src_alpha; /* $\alpha g_n$ */ - byte src_tmp[ART_MAX_CHAN + 1]; int tmp; - if (alpha == 255) { - art_pdf_composite_pixel_alpha_8(dst, src, n_chan, - blend_mode, pblend_procs); - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - src[n_chan]) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } - } else { + if (tos_shape == 0) { + /* If a softmask was present pass it along Bug 693548 */ + if (has_mask) + dst[n_chan] = alpha; + return; + } + + if (alpha != 255) { + if (tos_shape != 255) return; src_alpha = src[n_chan]; if (src_alpha == 0) return; - memcpy(src_tmp, src, n_chan + 3); tmp = src_alpha * alpha + 0x80; - src_tmp[n_chan] = (tmp + (tmp >> 8)) >> 8; - art_pdf_composite_pixel_alpha_8(dst, src_tmp, n_chan, - blend_mode, pblend_procs); - if (dst_alpha_g != NULL) { - tmp = (255 - *dst_alpha_g) * (255 - src_tmp[n_chan]) + 0x80; - *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); - } + src[n_chan] = (tmp + (tmp >> 8)) >> 8; + } + + if (dst_alpha_g != NULL) { + tmp = (255 - *dst_alpha_g) * (255 - src[n_chan]) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); + } + art_pdf_knockout_composite_pixel_alpha_8(backdrop, tos_shape, dst, src, + n_chan, blend_mode, pblend_procs, + p14dev); +} + +/** + * art_pdf_composite_group_8: Composite group pixel. + * @dst: Where to store pixel, also initial backdrop of group. + * @dst_alpha_g: Optional pointer to alpha g value. + * @alpha: Alpha mask value. + * @blend_mode: Blend mode for compositing. + * @pblend_procs: Procs for handling non separable blending modes. + * + * Note: this is only for isolated groups. This covers only the + * single-alpha case. A separate function is needed for dual-alpha, + * and that probably needs to treat knockout separately. + * + * Components 0 to first_spot are blended with blend_mode. + * Components first_spot to n_chan are blended with BLEND_MODE_Normal. + * + * @alpha corresponds to $fk_i \cdot fm_i \cdot qk_i \cdot qm_i$. + * + * @NOTE: This function may corrupt src. + * + * Returns 1 if we need to call art_pdf_composite_pixel_alpha_8. + **/ +static forceinline int +art_pdf_composite_group_8(byte *gs_restrict dst, byte *gs_restrict dst_alpha_g, + byte *gs_restrict src, int n_chan, byte alpha) +{ + byte src_alpha = src[n_chan]; /* $\alpha g_n$ */ + + if (src_alpha == 0) + return 0; + + if (alpha != 255) { + int tmp = src_alpha * alpha + 0x80; + src[n_chan] = (tmp + (tmp >> 8)) >> 8; + } + + if (dst_alpha_g != NULL) { + int tmp = (255 - *dst_alpha_g) * (255 - src[n_chan]) + 0x80; + *dst_alpha_g = 255 - ((tmp + (tmp >> 8)) >> 8); } + + return 1; } /* A very simple case. Knockout isolated group going to a parent that is not a knockout. Simply copy over everwhere where we have a non-zero alpha value */ void -art_pdf_knockoutisolated_group_8(byte *dst, const byte *src, int n_chan) +art_pdf_knockoutisolated_group_8(byte *gs_restrict dst, const byte *gs_restrict src, int n_chan) { byte src_alpha; @@ -1320,234 +1287,118 @@ memcpy (dst, src, n_chan + 1); } +/* An odd case where we have an alpha from the AA device and we have a current + source alpha. This is done only in the case where we are doing AA and a + stroke fill at the same time. + We have to first do a blend with the AA alpha if there + is something to blend with and then set the alpha to the source alpha. + In such a case an isolated knockout group was created and in the + copy_alpha code we end up here to handle the alpha from the AA code + differently from the other alpha. This ensures that the stroke and fill + end up blended with each other on the inside of the stroke path + but that the alpha from the AA does not end up getting blended with the + backdrop (unless the source alpha is not opaque) while the outside of the + stroke path ends up with the alpha for both the AA effect and source alpha */ void -art_pdf_composite_knockout_simple_8(byte *dst, - byte *dst_shape, - byte *dst_tag, - const byte *src, - byte tag, - int n_chan, byte opacity) +art_pdf_knockoutisolated_group_aa_8(byte *gs_restrict dst, const byte *gs_restrict src, byte src_alpha, + byte aa_alpha, int n_chan, pdf14_device *p14dev) { - byte src_shape = src[n_chan]; + int dst_alpha = dst[n_chan]; + byte temp_src[ART_MAX_CHAN + 1]; int i; - if (src_shape == 0) + /* Note: src[n_chan] is a blend of the aa_alpha and src_alpha */ + if (src[n_chan] == 0) return; - else if (src_shape == 255) { - memcpy (dst, src, n_chan + 3); - dst[n_chan] = opacity; - if (dst_shape != NULL) - *dst_shape = 255; - } else { - /* Use src_shape to interpolate (in premultiplied alpha space) - between dst and (src, opacity). */ - int dst_alpha = dst[n_chan]; - byte result_alpha; - int tmp; - tmp = (opacity - dst_alpha) * src_shape + 0x80; - result_alpha = dst_alpha + ((tmp + (tmp >> 8)) >> 8); - - if (result_alpha != 0) - for (i = 0; i < n_chan; i++) { - /* todo: optimize this - can strength-reduce so that - inner loop is a single interpolation */ - tmp = dst[i] * dst_alpha * (255 - src_shape) + - ((int)src[i]) * opacity * src_shape + (result_alpha << 7); - dst[i] = tmp / (result_alpha * 255); - } - dst[n_chan] = result_alpha; - - /* union in dst_shape if non-null */ - if (dst_shape != NULL) { - tmp = (255 - *dst_shape) * (255 - src_shape) + 0x80; - *dst_shape = 255 - ((tmp + (tmp >> 8)) >> 8); - } - } -} - -void -art_pdf_composite_knockout_isolated_8(byte *dst, - byte *dst_shape, - byte *dst_tag, - const byte *src, - int n_chan, - byte shape, - byte tag, - byte alpha_mask, byte shape_mask, - bool has_mask) -{ - int tmp; - int i; - - if (shape == 0) { - /* If a softmask was present pass it along Bug 693548 */ - if (has_mask) - dst[n_chan] = alpha_mask; + /* Check what is at the destination. If nothing there then just copy */ + if (dst_alpha == 0) { + memcpy(dst, src, n_chan + 1); return; - } else if ((shape & shape_mask) == 255) { - - memcpy(dst, src, n_chan + 3); - tmp = src[n_chan] * alpha_mask + 0x80; - dst[n_chan] = (tmp + (tmp >> 8)) >> 8; - if (dst_shape != NULL) - *dst_shape = 255; - if (dst_tag != NULL) - *dst_tag = tag; - } else { - /* Use src_shape to interpolate (in premultiplied alpha space) - between dst and (src, opacity). */ - byte src_shape, src_alpha; - int dst_alpha = dst[n_chan]; - byte result_alpha; - int tmp; - - tmp = shape * shape_mask + 0x80; - src_shape = (tmp + (tmp >> 8)) >> 8; - - tmp = src[n_chan] * alpha_mask + 0x80; - src_alpha = (tmp + (tmp >> 8)) >> 8; - - tmp = (src_alpha - dst_alpha) * src_shape + 0x80; - result_alpha = dst_alpha + ((tmp + (tmp >> 8)) >> 8); - - if (result_alpha != 0) - for (i = 0; i < n_chan; i++) { - /* todo: optimize this - can strength-reduce so that - inner loop is a single interpolation */ - tmp = dst[i] * dst_alpha * (255 - src_shape) + - ((int)src[i]) * src_alpha * src_shape + - (result_alpha << 7); - dst[i] = tmp / (result_alpha * 255); - } - dst[n_chan] = result_alpha; - - /* union in dst_shape if non-null */ - if (dst_shape != NULL) { - tmp = (255 - *dst_shape) * (255 - src_shape) + 0x80; - *dst_shape = 255 - ((tmp + (tmp >> 8)) >> 8); - } - if (dst_tag != NULL) { - *dst_tag = (*dst_tag | tag) & ~GS_UNTOUCHED_TAG; - } } + + /* Now the more complex case as something is there. First blend with the AA + alpha and then set our alpha to src_alpha so it will end up blending properly + with the backdrop if we had an global alpha for this fill/stroke */ + for (i = 0; i < n_chan; i++) + temp_src[i] = src[i]; + temp_src[n_chan] = aa_alpha; + art_pdf_composite_pixel_alpha_8(dst, temp_src, n_chan, BLEND_MODE_Normal, + n_chan, NULL, p14dev); + dst[n_chan] = src_alpha; } void -art_pdf_composite_knockout_8(byte *dst, - byte *dst_alpha_g, const byte *backdrop, const byte *src, - int n_chan, byte shape, byte alpha_mask, - byte shape_mask, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs) -{ - /* This implementation follows the Adobe spec pretty closely, rather - than trying to do anything clever. For example, in the case of a - Normal blend_mode when the top group is non-isolated, uncompositing - and recompositing is more work than needed. So be it. Right now, - I'm more worried about manageability than raw performance. */ - byte alpha_t; - byte src_alpha, src_shape; - byte src_opacity; - byte ct[ART_MAX_CHAN]; - byte backdrop_alpha; - byte alpha_g_i_1, alpha_g_i, alpha_i; - int tmp; - int i; - int scale_b; - int scale_src; - - if (shape == 0 || shape_mask == 0) - return; - - tmp = shape * shape_mask + 0x80; - /* $f s_i$ */ - src_shape = (tmp + (tmp >> 8)) >> 8; - - tmp = src[n_chan] * alpha_mask + 0x80; - src_alpha = (tmp + (tmp >> 8)) >> 8; - - /* $q s_i$ */ - src_opacity = (src_alpha * 510 + src_shape) / (2 * src_shape); - - /* $\alpha t$, \alpha g_b is always zero for knockout groups */ - alpha_t = src_opacity; - - /* $\alpha b$ */ - backdrop_alpha = backdrop[n_chan]; - - tmp = (0xff - src_opacity) * backdrop_alpha; - /* $(1 - q s_i) \cdot alpha_b$ scaled by 2^16 */ - scale_b = tmp + (tmp >> 7) + (tmp >> 14); - - /* $q s_i$ scaled by 2^16 */ - scale_src = (src_opacity << 8) + (src_opacity) + (src_opacity >> 7); +art_pdf_composite_knockout_8(byte *gs_restrict dst, + const byte *gs_restrict src, + int n_chan, + gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev) +{ + byte src_shape = src[n_chan]; + int i, tmp; - /* Do simple compositing of source over backdrop */ if (blend_mode == BLEND_MODE_Normal) { - for (i = 0; i < n_chan; i++) { - int c_s; - int c_b; - - c_s = src[i]; - c_b = backdrop[i]; - tmp = (c_b << 16) * scale_b + (c_s - c_b) + scale_src + 0x8000; - ct[i] = tmp >> 16; + /* Do simple compositing of source over backdrop */ + if (src_shape == 0) + return; + else if (src_shape == 255) { + memcpy (dst, src, n_chan + 1); + return; + } else { + /* Use src_shape to interpolate (in premultiplied alpha space) + between dst and (src, opacity). */ + int dst_alpha = dst[n_chan]; + byte result_alpha; + + tmp = (255 - dst_alpha) * src_shape + 0x80; + result_alpha = dst_alpha + ((tmp + (tmp >> 8)) >> 8); + + if (result_alpha != 0) + for (i = 0; i < n_chan; i++) { + /* todo: optimize this - can strength-reduce so that + inner loop is a single interpolation */ + tmp = dst[i] * dst_alpha * (255 - src_shape) + + ((int)src[i]) * 255 * src_shape + (result_alpha << 7); + dst[i] = tmp / (result_alpha * 255); + } + dst[n_chan] = result_alpha; } } else { + /* Do compositing with blending */ byte blend[ART_MAX_CHAN]; + byte a_b, a_s; + unsigned int a_r; + int src_scale; + int c_b, c_s; + + a_s = src[n_chan]; + a_b = dst[n_chan]; + + /* Result alpha is Union of backdrop and source alpha */ + tmp = (0xff - a_b) * (0xff - a_s) + 0x80; + a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + /* todo: verify that a_r is nonzero in all cases */ + + /* Compute a_s / a_r in 16.16 format */ + src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; - art_blend_pixel_8(blend, backdrop, src, n_chan, - blend_mode, pblend_procs); + art_blend_pixel_8(blend, dst, src, n_chan, blend_mode, pblend_procs, p14dev); for (i = 0; i < n_chan; i++) { - int c_s; - int c_b; int c_bl; /* Result of blend function */ int c_mix; /* Blend result mixed with source color */ c_s = src[i]; - c_b = backdrop[i]; + c_b = dst[i]; c_bl = blend[i]; - tmp = backdrop_alpha * (c_bl - ((int)c_s)) + 0x80; + tmp = a_b * (c_bl - ((int)c_s)) + 0x80; c_mix = c_s + (((tmp >> 8) + tmp) >> 8); - tmp = (c_b << 16) * scale_b + (c_mix - c_b) + scale_src + 0x8000; - ct[i] = tmp >> 16; - } - } - - /* $\alpha g_{i - 1}$ */ - alpha_g_i_1 = *dst_alpha_g; - - tmp = src_shape * (((int)alpha_t) - alpha_g_i_1) + 0x80; - /* $\alpha g_i$ */ - alpha_g_i = alpha_g_i_1 + ((tmp + (tmp >> 8)) >> 8); - - tmp = (0xff - backdrop_alpha) * (0xff - alpha_g_i) + 0x80; - /* $\alpha_i$ */ - alpha_i = 0xff - ((tmp + (tmp >> 8)) >> 8); - - if (alpha_i > 0) { - int scale_dst; - int scale_t; - byte dst_alpha; - - /* $f s_i / \alpha_i$ scaled by 2^16 */ - scale_t = ((src_shape << 17) + alpha_i) / (2 * alpha_i); - - /* $\alpha_{i - 1}$ */ - dst_alpha = dst[n_chan]; - - tmp = (1 - src_shape) * dst_alpha; - tmp = (tmp << 9) + (tmp << 1) + (tmp >> 7) + alpha_i; - scale_dst = tmp / (2 * alpha_i); - - for (i = 0; i < n_chan; i++) { - tmp = dst[i] * scale_dst + ct[i] * scale_t + 0x8000; - /* todo: clamp? */ + tmp = (c_b << 16) + src_scale * (c_mix - c_b) + 0x8000; dst[i] = tmp >> 16; } + dst[n_chan] = a_r; } - dst[n_chan] = alpha_i; - *dst_alpha_g = alpha_g_i; } #if RAW_DUMP @@ -1576,7 +1427,7 @@ int x; gs_sprintf(full_file_name,"%02d)%s.pam",global_index,filename); fid = gp_fopen(full_file_name,"wb"); - fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE GRAYSCALE_ALPHA\nENDHDR\n", + fprintf(fid, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 2\nMAXVAL 255\nTUPLTYPE GRAYSCALE_ALPHA\nENDHDR\n", width, num_rows); for(y=0; yshape + 0.5); + + if (!nos_knockout && num_spots > 0 && !blend_valid_for_spot(blend_mode)) { + first_blend_spot = first_spot; + } + if (blend_mode == BLEND_MODE_Normal) + first_blend_spot = 0; + if (!nos_isolated && backdrop_ptr != NULL) + has_mask2 = false; + + for (y = y1 - y0; y > 0; --y) { + mask_curr_ptr = mask_row_ptr; + in_mask_rect_y = (has_mask && y1 - y >= maskbuf->rect.p.y && y1 - y < maskbuf->rect.q.y); + for (x = 0; x < width; x++) { + in_mask_rect = (in_mask_rect_y && x0 + x >= maskbuf->rect.p.x && x0 + x < maskbuf->rect.q.x); + pix_alpha = alpha; + /* If we have a soft mask, then we have some special handling of the + group alpha value */ + if (maskbuf != NULL) { + if (!in_mask_rect) { + /* Special case where we have a soft mask but are outside + the range of the soft mask and must use the background + alpha value */ + pix_alpha = mask_bg_alpha; + matte_alpha = 0xff; + } else { + if (has_matte) + matte_alpha = mask_tr_fn[*mask_curr_ptr]; + } + } + + /* Matte present, need to undo premultiplied alpha prior to blend */ + if (has_matte && matte_alpha != 0 && matte_alpha < 0xff) { + for (i = 0; i < n_chan; i++) { + /* undo */ + int val = (tos_ptr[i * tos_planestride] - maskbuf->matte[i] < 0 ? + 0 : tos_ptr[i * tos_planestride] - maskbuf->matte[i]); + int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + maskbuf->matte[i]; + + /* clip */ + if (temp > 0xff) + tos_pixel[i] = 0xff; + else + tos_pixel[i] = temp; + + if (!additive) { + /* Pure subtractive */ + tos_pixel[i] = 255 - tos_pixel[i]; + nos_pixel[i] = 255 - nos_ptr[i * nos_planestride]; + } else { + /* additive or hybrid */ + if (i >= first_spot) + nos_pixel[i] = 255 - nos_ptr[i * nos_planestride]; + else + nos_pixel[i] = nos_ptr[i * nos_planestride]; + } + } + } else { + /* No matte present */ + if (!additive) { + /* Pure subtractive */ + for (i = 0; i < n_chan; ++i) { + tos_pixel[i] = 255 - tos_ptr[i * tos_planestride]; + nos_pixel[i] = 255 - nos_ptr[i * nos_planestride]; + } + } else { + /* Additive or hybrid */ + for (i = 0; i < first_spot; ++i) { + tos_pixel[i] = tos_ptr[i * tos_planestride]; + nos_pixel[i] = nos_ptr[i * nos_planestride]; + } + for (; i < n_chan; i++) { + tos_pixel[i] = 255 - tos_ptr[i * tos_planestride]; + nos_pixel[i] = 255 - nos_ptr[i * nos_planestride]; + } + } + } + /* alpha */ + tos_pixel[n_chan] = has_alpha ? tos_ptr[n_chan * tos_planestride] : 255; + nos_pixel[n_chan] = has_alpha ? nos_ptr[n_chan * nos_planestride] : 255; + + if (mask_curr_ptr != NULL) { + if (in_mask_rect) { + byte mask = mask_tr_fn[*mask_curr_ptr++]; + int tmp = pix_alpha * mask + 0x80; + pix_alpha = (tmp + (tmp >> 8)) >> 8; + } else { + mask_curr_ptr++; + } + } + + dst = nos_pixel; + if (nos_knockout) { + /* We need to be knocking out what ever is on the nos, but may + need to combine with it's backdrop */ + byte tos_shape = 255; + + if (tos_has_shape) + tos_shape = tos_ptr[tos_shape_offset]; + + if (nos_isolated || backdrop_ptr == NULL) { + /* We do not need to compose with the backdrop */ + back_drop[n_chan] = 0; + /* FIXME: The blend here can be simplified */ + } else { + /* Per the PDF spec, since the tos is not isolated and we are + going onto a knock out group, we do the composition with + the nos initial backdrop. */ + if (additive) { + /* additive or hybrid */ + for (i = 0; i < first_spot; ++i) { + back_drop[i] = backdrop_ptr[i * nos_planestride]; + } + for (; i < n_chan; i++) { + back_drop[i] = 255 - backdrop_ptr[i * nos_planestride]; + } + } else { + /* pure subtractive */ + for (i = 0; i < n_chan; ++i) { + back_drop[i] = 255 - backdrop_ptr[i * nos_planestride]; + } + } + /* alpha */ + back_drop[n_chan] = backdrop_ptr[n_chan * nos_planestride]; + } + art_pdf_composite_knockout_group_8(back_drop, tos_shape, + nos_pixel, nos_alpha_g_ptr, + tos_pixel, n_chan, pix_alpha, + blend_mode, pblend_procs, + pdev, has_mask2); + } else if (tos_isolated ? + art_pdf_composite_group_8(nos_pixel, nos_alpha_g_ptr, + tos_pixel, n_chan, pix_alpha) : + art_pdf_recomposite_group_8(&dst, nos_alpha_g_ptr, + tos_pixel, has_alpha ? tos_ptr[tos_alpha_g_offset] : 255, n_chan, + pix_alpha, blend_mode, first_blend_spot, + pblend_procs, pdev)) { + dst = art_pdf_composite_pixel_alpha_8_inline(nos_pixel, tos_pixel, n_chan, + blend_mode, first_blend_spot, + pblend_procs, pdev); + } + if (nos_shape_offset) { + nos_ptr[nos_shape_offset] = + art_pdf_union_mul_8 (nos_ptr[nos_shape_offset], + has_alpha ? tos_ptr[tos_shape_offset] : global_shape, + shape); + } + if (dst) + { + /* Complement the results for subtractive color spaces. Again, + * if we are in an additive blending color space, we are not + * going to be fooling with overprint of spot colors */ + if (additive) { + /* additive or hybrid */ + for (i = 0; i < first_spot; ++i) { + nos_ptr[i * nos_planestride] = dst[i]; + } + for (; i < n_chan; i++) { + nos_ptr[i * nos_planestride] = 255 - dst[i]; + } + } else { + /* Pure subtractive */ + /* If we were running in the compatible overprint blend mode + * and popping the group, we don't need to fool with the + * drawn components as that should have already have been + * handled during the blending within our special non-isolated + * group. So in other words, if the blend mode is normal + * (or compatible) and we are doing overprint, the overprint + * has NOT been handled by compatible overprint mode and we + * need to take care of it now */ + if (overprint) { + for (i = 0, comps = drawn_comps; comps != 0; ++i, comps >>= 1) { + if ((comps & 0x1) != 0) { + nos_ptr[i * nos_planestride] = 255 - dst[i]; + } + } + } else { + for (i = 0; i < n_chan; ++i) + nos_ptr[i * nos_planestride] = 255 - dst[i]; + } + } + /* alpha */ + nos_ptr[n_chan * nos_planestride] = dst[n_chan]; + } + /* tags */ + if (nos_tag_offset && tos_has_tag) { + nos_ptr[nos_tag_offset] |= tos_ptr[tos_tag_offset]; + } + + if (nos_alpha_g_ptr != NULL) + ++nos_alpha_g_ptr; + if (backdrop_ptr != NULL) + ++backdrop_ptr; + ++tos_ptr; + ++nos_ptr; + } + tos_ptr += tos_rowstride - width; + nos_ptr += nos_rowstride - width; + if (nos_alpha_g_ptr != NULL) + nos_alpha_g_ptr += nos_rowstride - width; + if (mask_row_ptr != NULL) + mask_row_ptr += maskbuf->rowstride; + if (backdrop_ptr != NULL) + backdrop_ptr += nos_rowstride - width; + } +} + +static void +compose_group_knockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */1, + nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1); +} + +static void +compose_group_nonknockout_blend(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, + nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1); +} + +static void +compose_group_nonknockout_nonblend_isolated_allmask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + int width = x1 - x0; + int x, y; + int i; + + for (y = y1 - y0; y > 0; --y) { + byte *gs_restrict mask_curr_ptr = mask_row_ptr; + for (x = 0; x < width; x++) { + byte mask = mask_tr_fn[*mask_curr_ptr++]; + byte src_alpha = tos_ptr[n_chan * tos_planestride]; + if (src_alpha != 0) { + byte a_b; + + int tmp = alpha * mask + 0x80; + byte pix_alpha = (tmp + (tmp >> 8)) >> 8; + + if (pix_alpha != 255) { + int tmp = src_alpha * pix_alpha + 0x80; + src_alpha = (tmp + (tmp >> 8)) >> 8; + } + + a_b = nos_ptr[n_chan * nos_planestride]; + if (a_b == 0) { + /* Simple copy of colors plus alpha. */ + for (i = 0; i < n_chan; i++) { + nos_ptr[i * nos_planestride] = tos_ptr[i * tos_planestride]; + } + nos_ptr[i * nos_planestride] = src_alpha; + } else { + /* Result alpha is Union of backdrop and source alpha */ + int tmp = (0xff - a_b) * (0xff - src_alpha) + 0x80; + unsigned int a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + + /* Compute src_alpha / a_r in 16.16 format */ + int src_scale = ((src_alpha << 16) + (a_r >> 1)) / a_r; + + nos_ptr[n_chan * nos_planestride] = a_r; + + /* Do simple compositing of source over backdrop */ + for (i = 0; i < n_chan; i++) { + int c_s = tos_ptr[i * tos_planestride]; + int c_b = nos_ptr[i * nos_planestride]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + nos_ptr[i * nos_planestride] = tmp >> 16; + } + } + } + ++tos_ptr; + ++nos_ptr; + } + tos_ptr += tos_rowstride - width; + nos_ptr += nos_rowstride - width; + mask_row_ptr += maskbuf->rowstride; + } +} + +static void +compose_group_nonknockout_nonblend_isolated_mask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + byte *gs_restrict mask_curr_ptr = NULL; + int width = x1 - x0; + int x, y; + int i; + bool in_mask_rect_y; + bool in_mask_rect; + byte pix_alpha, src_alpha; + + for (y = y1 - y0; y > 0; --y) { + mask_curr_ptr = mask_row_ptr; + in_mask_rect_y = (has_mask && y1 - y >= maskbuf->rect.p.y && y1 - y < maskbuf->rect.q.y); + for (x = 0; x < width; x++) { + in_mask_rect = (in_mask_rect_y && has_mask && x0 + x >= maskbuf->rect.p.x && x0 + x < maskbuf->rect.q.x); + pix_alpha = alpha; + /* If we have a soft mask, then we have some special handling of the + group alpha value */ + if (maskbuf != NULL) { + if (!in_mask_rect) { + /* Special case where we have a soft mask but are outside + the range of the soft mask and must use the background + alpha value */ + pix_alpha = mask_bg_alpha; + } + } + + if (mask_curr_ptr != NULL) { + if (in_mask_rect) { + byte mask = mask_tr_fn[*mask_curr_ptr++]; + int tmp = pix_alpha * mask + 0x80; + pix_alpha = (tmp + (tmp >> 8)) >> 8; + } else { + mask_curr_ptr++; + } + } + + src_alpha = tos_ptr[n_chan * tos_planestride]; + if (src_alpha != 0) { + byte a_b; + + if (pix_alpha != 255) { + int tmp = src_alpha * pix_alpha + 0x80; + src_alpha = (tmp + (tmp >> 8)) >> 8; + } + + a_b = nos_ptr[n_chan * nos_planestride]; + if (a_b == 0) { + /* Simple copy of colors plus alpha. */ + for (i = 0; i < n_chan; i++) { + nos_ptr[i * nos_planestride] = tos_ptr[i * tos_planestride]; + } + nos_ptr[i * nos_planestride] = src_alpha; + } else { + /* Result alpha is Union of backdrop and source alpha */ + int tmp = (0xff - a_b) * (0xff - src_alpha) + 0x80; + unsigned int a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + + /* Compute src_alpha / a_r in 16.16 format */ + int src_scale = ((src_alpha << 16) + (a_r >> 1)) / a_r; + + nos_ptr[n_chan * nos_planestride] = a_r; + + /* Do simple compositing of source over backdrop */ + for (i = 0; i < n_chan; i++) { + int c_s = tos_ptr[i * tos_planestride]; + int c_b = nos_ptr[i * nos_planestride]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + nos_ptr[i * nos_planestride] = tmp >> 16; + } + } + } + ++tos_ptr; + ++nos_ptr; + } + tos_ptr += tos_rowstride - width; + nos_ptr += nos_rowstride - width; + if (mask_row_ptr != NULL) + mask_row_ptr += maskbuf->rowstride; + } +} + +static void +compose_group_nonknockout_nonblend_isolated_nomask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, /*tos_isolated*/1, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, + /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, /*has_mask*/0, /*maskbuf*/NULL, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1); +} + +static void +compose_group_nonknockout_nonblend_nonisolated_mask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, /*tos_isolated*/0, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, + /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1); +} + +static void +compose_group_nonknockout_nonblend_nonisolated_nomask_common(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, /*tos_isolated*/0, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, /*tos_has_shape*/0, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, /*tos_has_tag*/0, + nos_ptr, /*nos_isolated*/0, nos_planestride, nos_rowstride, /*nos_alpha_g_ptr*/0, /* nos_knockout = */0, + /*nos_shape_offset*/0, /*nos_tag_offset*/0, mask_row_ptr, /*has_mask*/0, /*maskbuf*/NULL, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, /*has_matte*/0, n_chan, /*additive*/1, /*num_spots*/0, /*overprint*/0, /*drawn_comps*/0, x0, y0, x1, y1, pblend_procs, pdev, 1); +} + +static void +compose_group_nonknockout_noblend_general(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, BLEND_MODE_Normal, tos_has_shape, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, + nos_shape_offset, nos_tag_offset, mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 1); +} + +static void +compose_group_alphaless_knockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */1, + nos_shape_offset, nos_tag_offset, /* mask_row_ptr */ NULL, /* has_mask */ 0, /* maskbuf */ NULL, mask_bg_alpha, /* mask_tr_fn */ NULL, + backdrop_ptr, /* has_matte */ false , n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 0); +} + +static void +compose_group_alphaless_nonknockout(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, byte *nos_alpha_g_ptr, bool nos_knockout, + int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, + bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev) +{ + template_compose_group(tos_ptr, tos_isolated, tos_planestride, tos_rowstride, alpha, shape, blend_mode, tos_has_shape, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + nos_ptr, nos_isolated, nos_planestride, nos_rowstride, nos_alpha_g_ptr, /* nos_knockout = */0, + nos_shape_offset, nos_tag_offset, /* mask_row_ptr */ NULL, /* has_mask */ 0, /* maskbuf */ NULL, mask_bg_alpha, /* mask_tr_fn */ NULL, + backdrop_ptr, /* has_matte */ false , n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, pblend_procs, pdev, 0); +} + +void +pdf14_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, + int x0, int x1, int y0, int y1, int n_chan, bool additive, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + bool overprint, gx_color_index drawn_comps, gs_memory_t *memory, + gx_device *dev) +{ + int num_spots = tos->num_spots; + byte alpha = tos->alpha; + byte shape = tos->shape; + gs_blend_mode_t blend_mode = tos->blend_mode; + byte *tos_ptr = tos->data + x0 - tos->rect.p.x + + (y0 - tos->rect.p.y) * tos->rowstride; + byte *nos_ptr = nos->data + x0 - nos->rect.p.x + + (y0 - nos->rect.p.y) * nos->rowstride; + byte *mask_row_ptr = NULL; + int tos_planestride = tos->planestride; + int nos_planestride = nos->planestride; + byte mask_bg_alpha = 0; /* Quiet compiler. */ + bool tos_isolated = tos->isolated; + bool nos_isolated = nos->isolated; + bool nos_knockout = nos->knockout; + byte *nos_alpha_g_ptr; + int tos_shape_offset = n_chan * tos_planestride; + int tos_alpha_g_offset = tos_shape_offset + (tos->has_shape ? tos_planestride : 0); + bool tos_has_tag = tos->has_tags; + int tos_tag_offset = tos_planestride * (tos->n_planes - 1); + int nos_shape_offset = n_chan * nos_planestride; + int nos_alpha_g_offset = nos_shape_offset + (nos->has_shape ? nos_planestride : 0); + int nos_tag_offset = nos_planestride * (nos->n_planes - 1); + byte *mask_tr_fn = NULL; /* Quiet compiler. */ + bool has_mask = false; + byte *backdrop_ptr = NULL; + pdf14_device *pdev = (pdf14_device *)dev; + bool has_matte = false; +#if RAW_DUMP + byte *composed_ptr = NULL; + int width = x1 - x0; +#endif + art_pdf_compose_group_fn fn; + + if ((tos->n_chan == 0) || (nos->n_chan == 0)) + return; + rect_merge(nos->dirty, tos->dirty); + if (nos->has_tags) + if_debug7m('v', memory, + "pdf14_pop_transparency_group y0 = %d, y1 = %d, w = %d, alpha = %d, shape = %d, tag = %d, bm = %d\n", + y0, y1, x1 - x0, alpha, shape, dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS, blend_mode); + else + if_debug6m('v', memory, + "pdf14_pop_transparency_group y0 = %d, y1 = %d, w = %d, alpha = %d, shape = %d, bm = %d\n", + y0, y1, x1 - x0, alpha, shape, blend_mode); + if (!nos->has_shape) + nos_shape_offset = 0; + if (!nos->has_tags) + nos_tag_offset = 0; + if (nos->has_alpha_g) { + nos_alpha_g_ptr = nos_ptr + nos_alpha_g_offset; + } else + nos_alpha_g_ptr = NULL; + if (nos->backdrop != NULL) { + backdrop_ptr = nos->backdrop + x0 - nos->rect.p.x + + (y0 - nos->rect.p.y) * nos->rowstride; + } + if (blend_mode != BLEND_MODE_Compatible && blend_mode != BLEND_MODE_Normal) + overprint = false; + + if (maskbuf != NULL) { + int tmp; + + mask_tr_fn = maskbuf->transfer_fn; + /* Make sure we are in the mask buffer */ + if (maskbuf->data != NULL) { + mask_row_ptr = maskbuf->data + x0 - maskbuf->rect.p.x + + (y0 - maskbuf->rect.p.y) * maskbuf->rowstride; + has_mask = true; + } + /* We may have a case, where we are outside the maskbuf rect. */ + /* We would have avoided creating the maskbuf->data */ + /* In that case, we should use the background alpha value */ + /* See discussion on the BC entry in the PDF spec. */ + mask_bg_alpha = maskbuf->alpha; + /* Adjust alpha by the mask background alpha. This is only used + if we are outside the soft mask rect during the filling operation */ + mask_bg_alpha = mask_tr_fn[mask_bg_alpha]; + tmp = alpha * mask_bg_alpha + 0x80; + mask_bg_alpha = (tmp + (tmp >> 8)) >> 8; + if (maskbuf->matte != NULL) + has_matte = true; + } + n_chan--; /* Now the true number of colorants (i.e. not including alpha)*/ +#if RAW_DUMP + composed_ptr = nos_ptr; + dump_raw_buffer(y1-y0, width, tos->n_planes, tos_planestride, tos->rowstride, + "bImageTOS",tos_ptr); + dump_raw_buffer(y1-y0, width, nos->n_planes, nos_planestride, nos->rowstride, + "cImageNOS",nos_ptr); + if (maskbuf !=NULL && maskbuf->data != NULL) { + dump_raw_buffer(maskbuf->rect.q.y - maskbuf->rect.p.y, + maskbuf->rect.q.x - maskbuf->rect.p.x, maskbuf->n_planes, + maskbuf->planestride, maskbuf->rowstride, "dMask", + maskbuf->data); + } +#endif + + /* You might hope that has_mask iff maskbuf != NULL, but this is + * not the case. Certainly we can see cases where maskbuf != NULL + * and has_mask = 0. What's more, treating such cases as being + * has_mask = 0 causes diffs. */ +#ifdef TRACK_COMPOSE_GROUPS + { + int code = 0; + + code += !!nos_knockout; + code += (!!nos_isolated)<<1; + code += (!!tos_isolated)<<2; + code += (!!tos->has_shape)<<3; + code += (!!tos_has_tag)<<4; + code += (!!additive)<<5; + code += (!!overprint)<<6; + code += (!!has_mask || maskbuf != NULL)<<7; + code += (!!has_matte)<<8; + code += (backdrop_ptr != NULL)<<9; + code += (num_spots != 0)<<10; + code += blend_mode<<11; + + if (track_compose_groups == 0) + { + atexit(dump_track_compose_groups); + track_compose_groups = 1; + } + compose_groups[code]++; + } +#endif + + /* We have tested the files on the cluster to see what percentage of + * files/devices hit the different options. */ + if (nos_knockout) + fn = &compose_group_knockout; /* Small %ages, nothing more than 1.1% */ + else if (blend_mode != 0) + fn = &compose_group_nonknockout_blend; /* Small %ages, nothing more than 2% */ + else if (tos->has_shape == 0 && tos_has_tag == 0 && nos_isolated == 0 && nos_alpha_g_ptr == NULL && + nos_shape_offset == 0 && nos_tag_offset == 0 && backdrop_ptr == NULL && has_matte == 0 && num_spots == 0 && + overprint == 0) { + /* Additive vs Subtractive makes no difference in normal blend mode with no spots */ + if (tos_isolated) { + if (has_mask || maskbuf) {/* 7% */ + /* AirPrint test case hits this */ + if (maskbuf && maskbuf->rect.p.x <= x0 && maskbuf->rect.p.y <= y0 && + maskbuf->rect.q.x >= x1 && maskbuf->rect.q.y >= y1) + fn = compose_group_nonknockout_nonblend_isolated_allmask_common; + else + fn = &compose_group_nonknockout_nonblend_isolated_mask_common; + } else /* 14% */ + fn = &compose_group_nonknockout_nonblend_isolated_nomask_common; + } else { + if (has_mask || maskbuf) /* 4% */ + fn = &compose_group_nonknockout_nonblend_nonisolated_mask_common; + else /* 15% */ + fn = &compose_group_nonknockout_nonblend_nonisolated_nomask_common; + } + } else + fn = compose_group_nonknockout_noblend_general; + + fn(tos_ptr, tos_isolated, tos_planestride, tos->rowstride, alpha, shape, blend_mode, tos->has_shape, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + nos_ptr, nos_isolated, nos_planestride, nos->rowstride, nos_alpha_g_ptr, nos_knockout, + nos_shape_offset, nos_tag_offset, + mask_row_ptr, has_mask, maskbuf, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, + has_matte, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, + pblend_procs, pdev); + +#if RAW_DUMP + dump_raw_buffer(y1-y0, width, nos->n_planes, nos_planestride, nos->rowstride, + "eComposed", composed_ptr); + global_index++; +#endif +} + +void +pdf14_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos, + int x0, int x1, int y0, int y1, + gs_memory_t *memory, gx_device *dev) +{ + pdf14_device *pdev = (pdf14_device *)dev; + bool overprint = pdev->overprint; + bool additive = pdev->ctx->additive; + gx_color_index drawn_comps = pdev->drawn_comps; + int n_chan = nos->n_chan; + int num_spots = tos->num_spots; + byte alpha = tos->alpha; + byte shape = tos->shape; + gs_blend_mode_t blend_mode = tos->blend_mode; + byte *tos_ptr = tos->data + x0 - tos->rect.p.x + + (y0 - tos->rect.p.y) * tos->rowstride; + byte *nos_ptr = nos->data + x0 - nos->rect.p.x + + (y0 - nos->rect.p.y) * nos->rowstride; + byte *mask_row_ptr = NULL; + int tos_planestride = tos->planestride; + int nos_planestride = nos->planestride; + byte mask_bg_alpha = 0; /* Quiet compiler. */ + bool tos_isolated = false; + bool nos_isolated = nos->isolated; + bool nos_knockout = nos->knockout; + byte *nos_alpha_g_ptr; + int tos_shape_offset = n_chan * tos_planestride; + int tos_alpha_g_offset = tos_shape_offset + (tos->has_shape ? tos_planestride : 0); + bool tos_has_tag = tos->has_tags; + int tos_tag_offset = tos_planestride * (tos->n_planes - 1); + int nos_shape_offset = n_chan * nos_planestride; + int nos_alpha_g_offset = nos_shape_offset + (nos->has_shape ? nos_planestride : 0); + int nos_tag_offset = nos_planestride * (nos->n_planes - 1); + byte *mask_tr_fn = NULL; /* Quiet compiler. */ + bool has_mask = false; + byte *backdrop_ptr = NULL; +#if RAW_DUMP + byte *composed_ptr = NULL; + int width = x1 - x0; +#endif + art_pdf_compose_group_fn fn; + + if ((tos->n_chan == 0) || (nos->n_chan == 0)) + return; + rect_merge(nos->dirty, tos->dirty); + if (nos->has_tags) + if_debug7m('v', memory, + "pdf14_pop_transparency_group y0 = %d, y1 = %d, w = %d, alpha = %d, shape = %d, tag = %d, bm = %d\n", + y0, y1, x1 - x0, alpha, shape, dev->graphics_type_tag & ~GS_DEVICE_ENCODES_TAGS, blend_mode); + else + if_debug6m('v', memory, + "pdf14_pop_transparency_group y0 = %d, y1 = %d, w = %d, alpha = %d, shape = %d, bm = %d\n", + y0, y1, x1 - x0, alpha, shape, blend_mode); + if (!nos->has_shape) + nos_shape_offset = 0; + if (!nos->has_tags) + nos_tag_offset = 0; + if (nos->has_alpha_g) { + nos_alpha_g_ptr = nos_ptr + nos_alpha_g_offset; + } else + nos_alpha_g_ptr = NULL; + if (nos->backdrop != NULL) { + backdrop_ptr = nos->backdrop + x0 - nos->rect.p.x + + (y0 - nos->rect.p.y) * nos->rowstride; + } + if (blend_mode != BLEND_MODE_Compatible && blend_mode != BLEND_MODE_Normal) + overprint = false; + + n_chan--; /* Now the true number of colorants (i.e. not including alpha)*/ +#if RAW_DUMP + composed_ptr = nos_ptr; + dump_raw_buffer(y1-y0, width, tos->n_planes, tos_planestride, tos->rowstride, + "bImageTOS",tos_ptr); + dump_raw_buffer(y1-y0, width, nos->n_planes, nos_planestride, nos->rowstride, + "cImageNOS",nos_ptr); + /* maskbuf is NULL in here */ +#endif + + /* You might hope that has_mask iff maskbuf != NULL, but this is + * not the case. Certainly we can see cases where maskbuf != NULL + * and has_mask = 0. What's more, treating such cases as being + * has_mask = 0 causes diffs. */ +#ifdef TRACK_COMPOSE_GROUPS + { + int code = 0; + + code += !!nos_knockout; + code += (!!nos_isolated)<<1; + code += (!!tos_isolated)<<2; + code += (!!tos->has_shape)<<3; + code += (!!tos_has_tag)<<4; + code += (!!additive)<<5; + code += (!!overprint)<<6; + code += (!!has_mask)<<7; + code += (backdrop_ptr != NULL)<<9; + code += (num_spots != 0)<<10; + code += blend_mode<<11; + + if (track_compose_groups == 0) + { + atexit(dump_track_compose_groups); + track_compose_groups = 1; + } + compose_groups[code]++; + } +#endif + + /* We have tested the files on the cluster to see what percentage of + * files/devices hit the different options. */ + if (nos_knockout) + fn = &compose_group_alphaless_knockout; + else + fn = &compose_group_alphaless_nonknockout; + + fn(tos_ptr, tos_isolated, tos_planestride, tos->rowstride, alpha, shape, blend_mode, tos->has_shape, + tos_shape_offset, tos_alpha_g_offset, tos_tag_offset, tos_has_tag, + nos_ptr, nos_isolated, nos_planestride, nos->rowstride, nos_alpha_g_ptr, nos_knockout, + nos_shape_offset, nos_tag_offset, + mask_row_ptr, has_mask, /* maskbuf */ NULL, mask_bg_alpha, mask_tr_fn, + backdrop_ptr, + /* has_matte */ 0, n_chan, additive, num_spots, overprint, drawn_comps, x0, y0, x1, y1, + pdev->blend_procs, pdev); + +#if RAW_DUMP + dump_raw_buffer(y1-y0, width, nos->n_planes, nos_planestride, nos->rowstride, + "eComposed", composed_ptr); + global_index++; +#endif +} + +typedef void (*pdf14_mark_fill_rect_fn)(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape); + +static forceinline void +template_mark_fill_rect(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + int i, j, k; + gx_color_index comps; + byte dst[PDF14_MAX_PLANES] = { 0 }; + + for (j = h; j > 0; --j) { + for (i = w; i > 0; --i) { + if ((blend_mode == BLEND_MODE_Normal && src[num_comp] == 0xff && !overprint) || dst_ptr[num_comp * planestride] == 0) { + /* dest alpha is zero (or normal, and solid src) just use source. */ + if (additive) { + /* Hybrid case */ + for (k = 0; k < (num_comp - num_spots); k++) { + dst_ptr[k * planestride] = src[k]; + } + for (k = 0; k < num_spots; k++) { + dst_ptr[(k + num_comp - num_spots) * planestride] = + 255 - src[k + num_comp - num_spots]; + } + } else { + /* Pure subtractive */ + for (k = 0; k < num_comp; k++) { + dst_ptr[k * planestride] = 255 - src[k]; + } + } + /* alpha */ + dst_ptr[num_comp * planestride] = src[num_comp]; + } else if (src[num_comp] != 0) { + byte *pdst; + /* Complement subtractive planes */ + if (!additive) { + /* Pure subtractive */ + for (k = 0; k < num_comp; ++k) + dst[k] = 255 - dst_ptr[k * planestride]; + } else { + /* Hybrid case, additive with subtractive spots */ + for (k = 0; k < (num_comp - num_spots); k++) { + dst[k] = dst_ptr[k * planestride]; + } + for (k = 0; k < num_spots; k++) { + dst[k + num_comp - num_spots] = + 255 - dst_ptr[(k + num_comp - num_spots) * planestride]; + } + } + dst[num_comp] = dst_ptr[num_comp * planestride]; + pdst = art_pdf_composite_pixel_alpha_8_inline(dst, src, num_comp, blend_mode, first_blend_spot, + pdev->blend_procs, pdev); + /* Until I see otherwise in AR or the spec, do not fool + with spot overprinting while we are in an RGB or Gray + blend color space. */ + if (!additive && overprint) { + for (k = 0, comps = drawn_comps; comps != 0; ++k, comps >>= 1) { + if ((comps & 0x1) != 0) { + dst_ptr[k * planestride] = 255 - pdst[k]; + } + } + } else { + /* Post blend complement for subtractive */ + if (!additive) { + /* Pure subtractive */ + for (k = 0; k < num_comp; ++k) + dst_ptr[k * planestride] = 255 - pdst[k]; + + } else { + /* Hybrid case, additive with subtractive spots */ + for (k = 0; k < (num_comp - num_spots); k++) { + dst_ptr[k * planestride] = pdst[k]; + } + for (k = 0; k < num_spots; k++) { + dst_ptr[(k + num_comp - num_spots) * planestride] = + 255 - pdst[k + num_comp - num_spots]; + } + } + } + /* The alpha channel */ + dst_ptr[num_comp * planestride] = pdst[num_comp]; + } + if (tag_off) { + /* If src alpha is 100% then set to curr_tag, else or */ + /* other than Normal BM, we always OR */ + if (src[num_comp] == 255 && blend_mode == BLEND_MODE_Normal) { + dst_ptr[tag_off] = curr_tag; + } else { + dst_ptr[tag_off] |= curr_tag; + } + } + if (alpha_g_off) { + int tmp = (255 - dst_ptr[alpha_g_off]) * src_alpha + 0x80; + dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + if (shape_off) { + int tmp = (255 - dst_ptr[shape_off]) * shape + 0x80; + dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + ++dst_ptr; + } + dst_ptr += rowstride; + } +} + +static void +mark_fill_rect_alpha0(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + int i, j; + + for (j = h; j > 0; --j) { + for (i = w; i > 0; --i) { + if (alpha_g_off) { + int tmp = (255 - dst_ptr[alpha_g_off]) * src_alpha + 0x80; + dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + if (shape_off) { + int tmp = (255 - dst_ptr[shape_off]) * shape + 0x80; + dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + ++dst_ptr; + } + dst_ptr += rowstride; + } +} + +static void +mark_fill_rect(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + template_mark_fill_rect(w, h, dst_ptr, src, num_comp, num_spots, first_blend_spot, + src_alpha, rowstride, planestride, additive, pdev, blend_mode, + overprint, drawn_comps, tag_off, curr_tag, + alpha_g_off, shape_off, shape); +} + +static void +mark_fill_rect_sub4_fast(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + int i, j, k; + + for (j = h; j > 0; --j) { + for (i = w; i > 0; --i) { + byte a_s = src[4]; + byte a_b = dst_ptr[4 * planestride]; + if ((a_s == 0xff) || a_b == 0) { + /* dest alpha is zero (or normal, and solid src) just use source. */ + dst_ptr[0 * planestride] = 255 - src[0]; + dst_ptr[1 * planestride] = 255 - src[1]; + dst_ptr[2 * planestride] = 255 - src[2]; + dst_ptr[3 * planestride] = 255 - src[3]; + /* alpha */ + dst_ptr[4 * planestride] = a_s; + } else if (a_s != 0) { + /* Result alpha is Union of backdrop and source alpha */ + int tmp = (0xff - a_b) * (0xff - a_s) + 0x80; + unsigned int a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + + /* Compute a_s / a_r in 16.16 format */ + int src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; + + dst_ptr[4 * planestride] = a_r; + + /* Do simple compositing of source over backdrop */ + for (k = 0; k < 4; k++) { + int c_s = src[k]; + int c_b = 255 - dst_ptr[k * planestride]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst_ptr[k * planestride] = 255 - (tmp >> 16); + } + } + ++dst_ptr; + } + dst_ptr += rowstride; + } +} + +static void +mark_fill_rect_add_nospots(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + template_mark_fill_rect(w, h, dst_ptr, src, num_comp, /*num_spots*/0, first_blend_spot, + src_alpha, rowstride, planestride, /*additive*/1, pdev, blend_mode, + /*overprint*/0, /*drawn_comps*/0, tag_off, curr_tag, + alpha_g_off, shape_off, shape); +} + +static void +mark_fill_rect_add_nospots_common(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + template_mark_fill_rect(w, h, dst_ptr, src, num_comp, /*num_spots*/0, /*first_blend_spot*/0, + src_alpha, rowstride, planestride, /*additive*/1, pdev, /*blend_mode*/BLEND_MODE_Normal, + /*overprint*/0, /*drawn_comps*/0, /*tag_off*/0, curr_tag, + alpha_g_off, /*shape_off*/0, shape); +} + +static void +mark_fill_rect_add_nospots_common_no_alpha_g(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + template_mark_fill_rect(w, h, dst_ptr, src, num_comp, /*num_spots*/0, /*first_blend_spot*/0, + src_alpha, rowstride, planestride, /*additive*/1, pdev, /*blend_mode*/BLEND_MODE_Normal, + /*overprint*/0, /*drawn_comps*/0, /*tag_off*/0, curr_tag, + /*alpha_g_off*/0, /*shape_off*/0, shape); +} + +static void +mark_fill_rect_add3_common(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + int i, j, k; + + for (j = h; j > 0; --j) { + for (i = w; i > 0; --i) { + byte a_s = src[3]; + byte a_b = dst_ptr[3 * planestride]; + if (a_s == 0xff || a_b == 0) { + /* dest alpha is zero (or solid source) just use source. */ + dst_ptr[0 * planestride] = src[0]; + dst_ptr[1 * planestride] = src[1]; + dst_ptr[2 * planestride] = src[2]; + /* alpha */ + dst_ptr[3 * planestride] = a_s; + } else if (a_s != 0) { + /* Result alpha is Union of backdrop and source alpha */ + int tmp = (0xff - a_b) * (0xff - a_s) + 0x80; + unsigned int a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + /* todo: verify that a_r is nonzero in all cases */ + + /* Compute a_s / a_r in 16.16 format */ + int src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; + + dst_ptr[3 * planestride] = a_r; + + /* Do simple compositing of source over backdrop */ + for (k = 0; k < 3; k++) { + int c_s = src[k]; + int c_b = dst_ptr[k * planestride]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst_ptr[k * planestride] = tmp >> 16; + } + } + ++dst_ptr; + } + dst_ptr += rowstride; + } +} + +static void +mark_fill_rect_add1_no_spots(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + int i; + + for (; h > 0; --h) { + for (i = w; i > 0; --i) { + /* background empty, nothing to change, or solid source */ + byte a_s = src[1]; + if ((blend_mode == BLEND_MODE_Normal && a_s == 0xff) || dst_ptr[planestride] == 0) { + dst_ptr[0] = src[0]; + dst_ptr[planestride] = a_s; + } else { + art_pdf_composite_pixel_alpha_8_fast_mono(dst_ptr, src, + blend_mode, pdev->blend_procs, + planestride, pdev); + } + if (tag_off) { + /* If src alpha is 100% then set to curr_tag, else or */ + /* other than Normal BM, we always OR */ + if (blend_mode == BLEND_MODE_Normal && a_s == 255) { + dst_ptr[tag_off] = curr_tag; + } else { + dst_ptr[tag_off] |= curr_tag; + } + } + if (alpha_g_off) { + int tmp = (255 - dst_ptr[alpha_g_off]) * src_alpha + 0x80; + dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + if (shape_off) { + int tmp = (255 - dst_ptr[shape_off]) * shape + 0x80; + dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + ++dst_ptr; + } + dst_ptr += rowstride; + } +} + +static void +mark_fill_rect_add1_no_spots_normal(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + int i; + + for (; h > 0; --h) { + for (i = w; i > 0; --i) { + /* background empty, nothing to change, or solid source */ + byte a_s = src[1]; + byte a_b = dst_ptr[planestride]; + if (a_s == 0xff || a_b == 0) { + dst_ptr[0] = src[0]; + dst_ptr[planestride] = a_s; + } else { + /* Result alpha is Union of backdrop and source alpha */ + int tmp = (0xff - a_b) * (0xff - a_s) + 0x80; + unsigned int a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + + /* Compute a_s / a_r in 16.16 format */ + int src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; + + /* Do simple compositing of source over backdrop */ + int c_s = src[0]; + int c_b = dst_ptr[0]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst_ptr[0] = tmp >> 16; + dst_ptr[planestride] = a_r; + } + if (tag_off) { + /* If src alpha is 100% then set to curr_tag, else or */ + /* other than Normal BM, we always OR */ + if (a_s == 255) { + dst_ptr[tag_off] = curr_tag; + } else { + dst_ptr[tag_off] |= curr_tag; + } + } + if (alpha_g_off) { + int tmp = (255 - dst_ptr[alpha_g_off]) * src_alpha + 0x80; + dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + if (shape_off) { + int tmp = (255 - dst_ptr[shape_off]) * shape + 0x80; + dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8); + } + ++dst_ptr; + } + dst_ptr += rowstride; + } +} + +static void +mark_fill_rect_add1_no_spots_fast(int w, int h, byte *gs_restrict dst_ptr, byte *gs_restrict src, int num_comp, int num_spots, int first_blend_spot, + byte src_alpha, int rowstride, int planestride, bool additive, pdf14_device *pdev, gs_blend_mode_t blend_mode, + bool overprint, gx_color_index drawn_comps, int tag_off, gs_graphics_type_tag_t curr_tag, + int alpha_g_off, int shape_off, byte shape) +{ + int i; + + for (; h > 0; --h) { + for (i = w; i > 0; --i) { + /* background empty, nothing to change, or solid source */ + byte a_s = src[1]; + byte a_b = dst_ptr[planestride]; + if (a_s == 0xff || a_b == 0) { + dst_ptr[0] = src[0]; + dst_ptr[planestride] = a_s; + } else if (a_s != 0) { + /* Result alpha is Union of backdrop and source alpha */ + int tmp = (0xff - a_b) * (0xff - a_s) + 0x80; + unsigned int a_r = 0xff - (((tmp >> 8) + tmp) >> 8); + + /* Compute a_s / a_r in 16.16 format */ + int src_scale = ((a_s << 16) + (a_r >> 1)) / a_r; + + /* Do simple compositing of source over backdrop */ + int c_s = src[0]; + int c_b = dst_ptr[0]; + tmp = (c_b << 16) + src_scale * (c_s - c_b) + 0x8000; + dst_ptr[0] = tmp >> 16; + dst_ptr[planestride] = a_r; + } + ++dst_ptr; + } + dst_ptr += rowstride; + } +} + +int +pdf14_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color, const gx_device_color *pdc, + bool devn) +{ + pdf14_device *pdev = (pdf14_device *)dev; + pdf14_buf *buf = pdev->ctx->stack; + int j; + byte *dst_ptr; + byte src[PDF14_MAX_PLANES]; + gs_blend_mode_t blend_mode = pdev->blend_mode; + bool additive = pdev->ctx->additive; + int rowstride = buf->rowstride; + int planestride = buf->planestride; + gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG; /* Quite compiler */ + bool has_alpha_g = buf->has_alpha_g; + bool has_shape = buf->has_shape; + bool has_tags = buf->has_tags; + int num_chan = buf->n_chan; + int num_comp = num_chan - 1; + int shape_off = num_chan * planestride; + int alpha_g_off = shape_off + (has_shape ? planestride : 0); + int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0); + bool overprint = pdev->overprint; + gx_color_index drawn_comps = pdev->drawn_comps; + byte shape = 0; /* Quiet compiler. */ + byte src_alpha; + const gx_color_index mask = ((gx_color_index)1 << 8) - 1; + const int shift = 8; + int num_spots = buf->num_spots; + int first_blend_spot = num_comp; + pdf14_mark_fill_rect_fn fn; + + if (num_spots > 0 && !blend_valid_for_spot(blend_mode)) + first_blend_spot = num_comp - num_spots; + if (blend_mode == BLEND_MODE_Normal) + first_blend_spot = 0; + + if (buf->data == NULL) + return 0; + /* NB: gx_color_index is 4 or 8 bytes */ +#if 0 + if (sizeof(color) <= sizeof(ulong)) + if_debug8m('v', dev->memory, + "[v]pdf14_mark_fill_rectangle, (%d, %d), %d x %d color = %lx bm %d, nc %d, overprint %d\n", + x, y, w, h, (ulong)color, blend_mode, num_chan, overprint); + else + if_debug9m('v', dev->memory, + "[v]pdf14_mark_fill_rectangle, (%d, %d), %d x %d color = %08lx%08lx bm %d, nc %d, overprint %d\n", + x, y, w, h, + (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color, + blend_mode, num_chan, overprint); +#endif + /* + * Unpack the gx_color_index values. Complement the components for subtractive + * color spaces. + */ + if (has_tags) { + curr_tag = (color >> (num_comp*8)) & 0xff; + } + if (devn) { + if (additive) { + for (j = 0; j < (num_comp - num_spots); j++) { + src[j] = ((pdc->colors.devn.values[j]) >> shift & mask); + } + for (j = 0; j < num_spots; j++) { + src[j + num_comp - num_spots] = + 255 - ((pdc->colors.devn.values[j + num_comp - num_spots]) >> shift & mask); + } + } else { + for (j = 0; j < num_comp; j++) { + src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask); + } + } + } else + pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src); + src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5); + if (has_shape) + shape = (byte)floor (255 * pdev->shape + 0.5); + /* Fit the mark into the bounds of the buffer */ + if (x < buf->rect.p.x) { + w += x - buf->rect.p.x; + x = buf->rect.p.x; + } + if (y < buf->rect.p.y) { + h += y - buf->rect.p.y; + y = buf->rect.p.y; + } + if (x + w > buf->rect.q.x) w = buf->rect.q.x - x; + if (y + h > buf->rect.q.y) h = buf->rect.q.y - y; + /* Update the dirty rectangle with the mark */ + if (x < buf->dirty.p.x) buf->dirty.p.x = x; + if (y < buf->dirty.p.y) buf->dirty.p.y = y; + if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w; + if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h; + dst_ptr = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride; + src_alpha = 255-src_alpha; + shape = 255-shape; + if (!has_alpha_g) + alpha_g_off = 0; + if (!has_shape) + shape_off = 0; + if (!has_tags) + tag_off = 0; + rowstride -= w; + /* The num_comp == 1 && additive case is very common (mono output + * devices no spot support), so we optimise that specifically here. */ + if (src[num_comp] == 0) + fn = mark_fill_rect_alpha0; + else if (additive && num_spots == 0) { + if (num_comp == 1) { + if (blend_mode == BLEND_MODE_Normal) { + if (tag_off == 0 && shape_off == 0 && alpha_g_off == 0) + fn = mark_fill_rect_add1_no_spots_fast; + else + fn = mark_fill_rect_add1_no_spots_normal; + } else + fn = mark_fill_rect_add1_no_spots; + } else if (tag_off == 0 && shape_off == 0 && blend_mode == BLEND_MODE_Normal) { + if (alpha_g_off == 0) { + if (num_comp == 3) + fn = mark_fill_rect_add3_common; + else + fn = mark_fill_rect_add_nospots_common_no_alpha_g; + } else + fn = mark_fill_rect_add_nospots_common; + } else + fn = mark_fill_rect_add_nospots; + } else if (!additive && num_spots == 0 && num_comp == 4 && num_spots == 0 && + first_blend_spot == 0 && blend_mode == BLEND_MODE_Normal && + !overprint && tag_off == 0 && alpha_g_off == 0 && shape_off == 0) + fn = mark_fill_rect_sub4_fast; + else + fn = mark_fill_rect; + + fn(w, h, dst_ptr, src, num_comp, num_spots, first_blend_spot, src_alpha, + rowstride, planestride, additive, pdev, blend_mode, overprint, + drawn_comps, tag_off, curr_tag, alpha_g_off, shape_off, shape); + +#if 0 +/* #if RAW_DUMP */ + /* Dump the current buffer to see what we have. */ + + if(global_index/10.0 == (int) (global_index/10.0) ) + dump_raw_buffer(pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y, + pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x, + pdev->ctx->stack->n_planes, + pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride, + "Draw_Rect",pdev->ctx->stack->data); + + global_index++; +#endif + return 0; +} + +/* Keep this at the end because of the #undef print */ + +#ifdef TRACK_COMPOSE_GROUPS +static void +dump_track_compose_groups(void) +{ + int i; + + for (i = 0; i < (1<<17); i++) + { + if (compose_groups[i] == 0) + continue; +#undef printf + printf("COMPOSE_GROUPS: %04x:%d\n", i, compose_groups[i]); + } +} +#endif diff -Nru ghostscript-9.10~dfsg/base/gxblend.h ghostscript-9.25~dfsg+1/base/gxblend.h --- ghostscript-9.10~dfsg/base/gxblend.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxblend.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* PDF 1.4 blending functions */ @@ -23,15 +23,11 @@ #include "gxfrac.h" #include "gxdevcli.h" -/* Visual trace options : set one to 1. */ -#define VD_PAINT_MASK 0 -#define VD_PAINT_COLORS 0 -#define VD_PAINT_ALPHA 1 - #define RAW_DUMP 0 #define RAW_DUMP_AS_PAM 0 /* Useful bash fragment to batch convert pams to pngs: * for f in *.pam; do g=${f%.*}; echo $g; convert $g.pam $g.png ; done + * NB: "convert" is imagemagick convert, so may need to be installed. */ /* #define DUMP_TO_PNG */ @@ -75,13 +71,13 @@ /* * Perform luminosity and color blending. (Also used for hue blending.) */ - void (* blend_luminosity)(int n_chan, byte *dst, - const byte *backdrop, const byte *src); + void (* blend_luminosity)(int n_chan, byte *gs_restrict dst, + const byte *gs_restrict backdrop, const byte *gs_restrict src); /* * Perform saturation blending. (Also used for hue blending.) */ - void (* blend_saturation)(int n_chan, byte *dst, - const byte *backdrop, const byte *src); + void (* blend_saturation)(int n_chan, byte *gs_restrict dst, + const byte *gs_restrict backdrop, const byte *gs_restrict src); } pdf14_nonseparable_blending_procs_s; typedef pdf14_nonseparable_blending_procs_s @@ -102,45 +98,18 @@ /* This function is used for mapping Smask CMYK or RGB data to a monochrome alpha buffer */ void smask_luminosity_mapping(int num_rows, int num_cols, int n_chan, int row_stride, - int plane_stride, byte *src, const byte *des, bool isadditive, + int plane_stride, byte *gs_restrict src, const byte *gs_restrict des, bool isadditive, gs_transparency_mask_subtype_t SMask_SubType); -void smask_blend(byte *src, int width, int height, int rowstride, +void smask_blend(byte *gs_restrict src, int width, int height, int rowstride, int planestride); void smask_copy(int num_rows, int num_cols, int row_stride, - byte *src, const byte *des); -void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, - int row_stride, int plane_stride, byte *src, const byte *des, + byte *gs_restrict src, const byte *gs_restrict des); +void smask_icc(gx_device *dev, int num_rows, int num_cols, int n_chan, + int row_stride, int plane_stride, byte *gs_restrict src, const byte *gs_restrict des, gsicc_link_t *icclink); -/** - * art_blend_pixel: Compute PDF 1.4 blending function. - * @dst: Where to store resulting pixel. - * @backdrop: Backdrop pixel color. - * @src: Source pixel color. - * @n_chan: Number of channels. - * @blend_mode: Blend mode. - * - * Computes the blend of two pixels according the PDF 1.4 transparency - * spec (section 3.2, Blend Mode). A few things to keep in mind about - * this implementation: - * - * 1. This is a reference implementation, not a high-performance one. - * Blending using this function will incur a function call and switch - * statement per pixel, and will also incur the extra cost of 16 bit - * math. - * - * 2. Zero is black, one is white. In a subtractive color space such - * as CMYK, all pixels should be represented as "complemented", as - * described in section 3.1 (Blending Color Space) of the PDF 1.4 - * transparency spec. - * - * 3. I haven't really figured out how to handle the Compatible blend - * mode. I wouldn't be surprised if it required an API change. - **/ -void -art_blend_pixel(ArtPixMaxDepth * dst, const ArtPixMaxDepth * backdrop, - const ArtPixMaxDepth * src, int n_chan, - gs_blend_mode_t blend_mode); +/* For spot colors, blend modes must be white preserving and separable */ +bool blend_valid_for_spot(gs_blend_mode_t blend_mode); /** * art_blend_pixel_8: Compute PDF 1.4 blending function on 8-bit pixels. @@ -150,6 +119,7 @@ * @n_chan: Number of channels. * @blend_mode: Blend mode. * @pblend_procs: Procs for handling non separable blending modes. + * @p14dev: pdf14 device. Needed for handling CompatibleOverprint mode * * Computes the blend of two pixels according the PDF 1.4 transparency * spec (section 3.2, Blend Mode). A few things to keep in mind about @@ -169,10 +139,12 @@ * mode. I wouldn't be surprised if it required an API change. **/ void -art_blend_pixel_8(byte *dst, const byte *backdrop, - const byte *src, int n_chan, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs); +art_blend_pixel_8(byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src, int n_chan, gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev); +#ifdef UNUSED /** * art_pdf_union_8: Union together two alpha values. * @alpha1: One alpha value. @@ -181,6 +153,7 @@ * Return value: Union (@alpha1, @alpha2). **/ byte art_pdf_union_8(byte alpha1, byte alpha2); +#endif /** * art_pdf_union_mul_8: Union together two alpha values, with mask. @@ -190,7 +163,20 @@ * * Return value: Union (@alpha1, @alpha2 * @alpha_mask). **/ -byte art_pdf_union_mul_8(byte alpha1, byte alpha2, byte alpha_mask); +/* byte art_pdf_union_mul_8(byte alpha1, byte alpha2, byte alpha_mask); */ + +static inline byte +art_pdf_union_mul_8(byte alpha1, byte alpha2, byte alpha_mask) +{ + int tmp; + if (alpha_mask != 0xff) + { + tmp = alpha2 * alpha_mask + 0x80; + alpha2 = (tmp + (tmp >> 8))>>8; + } + tmp = (0xff - alpha1) * (0xff - alpha2) + 0x80; + return 0xff - ((tmp + (tmp >> 8)) >> 8); +} /** * art_pdf_composite_pixel_alpha_8: Composite two alpha pixels. @@ -199,6 +185,7 @@ * @n_chan: Number of channels. * @blend_mode: Blend mode. * @pblend_procs: Procs for handling non separable blending modes. + * @p14dev: pdf14 device. * * Composites two pixels using the basic compositing operation. A few * things to keep in mind: @@ -209,118 +196,51 @@ * * 3. Zero is black, one is white. * + * The first "first_spot" channels are blended with blend_mode. The + * remaining channels are blended with BLEND_MODE_Normal. + * * Also note that src and dst are expected to be allocated aligned to * 32 bit boundaries, ie bytes from [0] to [(n_chan + 3) & -4] may * be accessed. **/ void -art_pdf_composite_pixel_alpha_8(byte *dst, const byte *src, int n_chan, - gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs); - - -/** - * art_pdf_composite_pixel_alpha_8_fast: Tweaked version of art_pdf_composite_pixel_alpha_8. - * Same args, with an extra one: - * @stride: stride between dst pixel values. - * Dst data is therefore in dst[i * stride] for 0 <= i <= num_chan. - * Called with the guarantee that dst[stride * n_chan] != 0, src[n_chan] != 0 - */ -void -art_pdf_composite_pixel_alpha_8_fast(byte *dst, const byte *src, int n_chan, - gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs, - int stride); - -/** - * art_pdf_composite_pixel_alpha_8_fast_mono: Tweaked version of art_pdf_composite_pixel_alpha_8_fast. - * Same args, except n_chan, which is assumed to be 1: - * @stride: stride between dst pixel values. - * Dst data is therefore in dst[i * stride] for 0 <= i <= 1. - * Called with the guarantee that dst[stride] != 0, src[1] != 0 - */ -void -art_pdf_composite_pixel_alpha_8_fast_mono(byte *dst, const byte *src, - gs_blend_mode_t blend_mode, +art_pdf_composite_pixel_alpha_8(byte *gs_restrict dst, const byte *gs_restrict src, int n_chan, + gs_blend_mode_t blend_mode, int first_spot, const pdf14_nonseparable_blending_procs_t * pblend_procs, - int stride); + pdf14_device *p14dev); -/** - * art_pdf_uncomposite_group_8: Uncomposite group pixel. - * @dst: Where to store uncomposited pixel. - * @backdrop: Backdrop. - * @src: Composited source pixel. - * @src_alpha_g: alpha_g value associated with @src. - * @n_chan: Number of channels. - * - * Performs uncompositing operation as described in 5.3 of the Adobe spec. - **/ -void -art_pdf_uncomposite_group_8(byte *dst, - const byte *backdrop, - const byte *src, byte src_alpha_g, int n_chan); - -/** - * art_pdf_recomposite_group_8: Recomposite group pixel. - * @dst: Where to store pixel, also initial backdrop of group. - * @dst_alpha_g: Optional pointer to alpha g value associated with @dst. - * @alpha: Alpha mask value. - * @src_alpha_g: alpha_g value associated with @src. - * @blend_mode: Blend mode for compositing. - * @pblend_procs: Procs for handling non separable blending modes. - * - * Note: this is only for non-isolated groups. This covers only the - * single-alpha case. A separate function is needed for dual-alpha, - * and that probably needs to treat knockout separately. - * - * @src_alpha_g corresponds to $\alpha g_n$ in the Adobe notation. - * - * @alpha corresponds to $fk_i \cdot fm_i \cdot qk_i \cdot qm_i$. - **/ -void -art_pdf_recomposite_group_8(byte *dst, byte *dst_alpha_g, - const byte *src, byte src_alpha_g, int n_chan, - byte alpha, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs); - -/** - * art_pdf_composite_group_8: Composite group pixel. - * @dst: Where to store pixel, also initial backdrop of group. - * @dst_alpha_g: Optional pointer to alpha g value. - * @alpha: Alpha mask value. - * @blend_mode: Blend mode for compositing. - * @pblend_procs: Procs for handling non separable blending modes. - * - * Note: this is only for isolated groups. This covers only the - * single-alpha case. A separate function is needed for dual-alpha, - * and that probably needs to treat knockout separately. - * - * @alpha corresponds to $fk_i \cdot fm_i \cdot qk_i \cdot qm_i$. - **/ -void -art_pdf_composite_group_8(byte *dst, byte *dst_alpha_g, - const byte *src, int n_chan, byte alpha, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs); +/* + * art_pdf_compose_group_fn: Function pointer type for functions + * to compose a group. + */ +typedef void (*art_pdf_compose_group_fn)(byte *tos_ptr, bool tos_isolated, int tos_planestride, int tos_rowstride, + byte alpha, byte shape, gs_blend_mode_t blend_mode, bool tos_has_shape, + int tos_shape_offset, int tos_alpha_g_offset, int tos_tag_offset, bool tos_has_tag, + byte *nos_ptr, bool nos_isolated, int nos_planestride, int nos_rowstride, + byte *nos_alpha_g_ptr, bool nos_knockout, int nos_shape_offset, int nos_tag_offset, + byte *mask_row_ptr, int has_mask, pdf14_buf *maskbuf, byte mask_bg_alpha, byte *mask_tr_fn, + byte *backdrop_ptr, bool has_matte, int n_chan, bool additive, int num_spots, bool overprint, + gx_color_index drawn_comps, int x0, int y0, int x1, int y1, + const pdf14_nonseparable_blending_procs_t *pblend_procs, pdf14_device *pdev); /** - * art_pdf_composite_knockout_simple_8: Simple knockout compositing. - * @dst: Destination pixel. - * @dst_shape: Shape associated with @dst. + * art_pdf_composite_knockout_8: knockout compositing. + * @dst: Destination pixel array -- has been initialized with background * @src: Source pixel. - * @n_chan: Number of channels. - * @opacity: Opacity. + * n_chan: Number of channels. + * p14dev: pdf14 device * - * This function handles the simplest knockout case: an isolated - * knockout group, and an elementary shape. The alpha channel of @src - * is interpreted as shape. + * This function handles the knockout case: an isolated knockout group, + * and an elementary shape. The alpha channel of @src is interpreted as shape. **/ void -art_pdf_composite_knockout_simple_8(byte *dst, - byte *dst_shape, - byte *dst_tag, - const byte *src, byte tag, - int n_chan, byte opacity); +art_pdf_composite_knockout_8(byte *gs_restrict dst, + const byte *gs_restrict src, + int n_chan, + gs_blend_mode_t blend_mode, + const pdf14_nonseparable_blending_procs_t * pblend_procs, + pdf14_device *p14dev); /** * art_pdf_knockoutisolated_group_8: Knockout for isolated group. @@ -331,111 +251,96 @@ * This function handles the simple case with an isolated knockout group. **/ void -art_pdf_knockoutisolated_group_8(byte *dst, const byte *src, int n_chan); +art_pdf_knockoutisolated_group_8(byte *gs_restrict dst, const byte *gs_restrict src, int n_chan); /** - * art_pdf_composite_knockout_isolated_8: Simple knockout compositing. - * @dst: Destination pixel. - * @dst_shape: Shape associated with @dst. - * @dst_tag: Tag associated with @dst. - * @src: Source pixel. - * @n_chan: Number of channels. - * @shape: Shape. - * @shape: Tag. - * @alpha_mask: Alpha mask. - * @shape_mask: Shape mask. - * - * This function handles compositin in an isolated knockout case. The - * alpha channel of @src is interpreted as alpha. - **/ -void -art_pdf_composite_knockout_isolated_8(byte *dst, - byte *dst_shape, - byte *dst_tag, - const byte *src, - int n_chan, - byte shape, - byte tag, - byte alpha_mask, byte shape_mask, - bool has_mask); - -/** - * art_pdf_composite_knockout_8: General knockout compositing. - * @dst: Destination pixel. - * @dst_alpha_g: Pointer to alpha g value associated with @dst. - * @backdrop: Backdrop pixel (initial backdrop of knockout group). - * @src: Source pixel. - * @n_chan: Number of channels. - * @shape: Shape. - * @alpha_mask: Alpha mask. - * @shape_mask: Shape mask. - * @blend_mode: Blend mode for compositing. - * @pblend_procs: Procs for handling non separable blending modes. - * - * This function handles compositing in the case where the knockout - * group is non-isolated. If the @src pixels themselves come from a - * non-isolated group, they should be uncomposited before calling this - * routine. - **/ +* art_pdf_knockoutisolated_group_8: Knockout for isolated group. +* @dst: Destination pixel. +* @src: Source pixel. +* @src_alpha: current alpha from the graphic state +* @aa_alpha: alpha coming from the anti-aliasing buffer +* @n_chan: Number of channels. +* @p14dev: pdf14 device +* +* This function handles the simple case with an isolated knockout group but where +* we have an alpha from AA and from the current graphic state. +**/ void -art_pdf_composite_knockout_8(byte *dst, - byte *dst_alpha_g, const byte *backdrop, const byte *src, - int n_chan, byte shape, byte alpha_mask, - byte shape_mask, gs_blend_mode_t blend_mode, - const pdf14_nonseparable_blending_procs_t * pblend_procs); +art_pdf_knockoutisolated_group_aa_8(byte *gs_restrict dst, const byte *gs_restrict src, byte src_alpha, + byte aa_alpha, int n_chan, pdf14_device *p14dev); /* * Routines for handling the non separable blending modes. */ /* RGB blending color space */ -void art_blend_luminosity_rgb_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src); -void art_blend_saturation_rgb_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src); +void art_blend_luminosity_rgb_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src); +void art_blend_saturation_rgb_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src); /* CMYK and CMYK + spot blending color space */ -void art_blend_saturation_cmyk_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src); -void art_blend_luminosity_cmyk_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src); +void art_blend_saturation_cmyk_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src); +void art_blend_luminosity_cmyk_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src); /* 'Custom' i.e. unknown blending color space. */ -void art_blend_luminosity_custom_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src); -void art_blend_saturation_custom_8(int n_chan, byte *dst, const byte *backdrop, - const byte *src); +void art_blend_luminosity_custom_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src); +void art_blend_saturation_custom_8(int n_chan, byte *gs_restrict dst, const byte *gs_restrict backdrop, + const byte *gs_restrict src); + +void pdf14_unpack_rgb_mix(int num_comp, gx_color_index color, + pdf14_device * p14dev, byte * out); + +void pdf14_unpack_gray_mix(int num_comp, gx_color_index color, + pdf14_device * p14dev, byte * out); void pdf14_unpack_additive(int num_comp, gx_color_index color, pdf14_device * p14dev, byte * out); void pdf14_unpack_subtractive(int num_comp, gx_color_index color, pdf14_device * p14dev, byte * out); -void pdf14_unpack_compressed(int num_comp, gx_color_index color, - pdf14_device * p14dev, byte * out); void pdf14_unpack_custom(int num_comp, gx_color_index color, pdf14_device * p14dev, byte * out); -void pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool has_shape); +void pdf14_preserve_backdrop(pdf14_buf *buf, pdf14_buf *tos, bool knockout_buff); + +int pdf14_preserve_backdrop_cm(pdf14_buf *buf, cmm_profile_t *group_profile, + pdf14_buf *tos, cmm_profile_t *tos_profile, + gs_memory_t *memory, gs_gstate *pgs, + gx_device *dev, bool knockout_buff); void pdf14_compose_group(pdf14_buf *tos, pdf14_buf *nos, pdf14_buf *maskbuf, int x0, int x1, int y0, int y1, int n_chan, bool additive, const pdf14_nonseparable_blending_procs_t * pblend_procs, - bool overprint, gx_color_index drawn_comps, bool blendspot, - gs_memory_t *memory); + bool overprint, gx_color_index drawn_comps, gs_memory_t *memory, + gx_device *dev); + +void pdf14_compose_alphaless_group(pdf14_buf *tos, pdf14_buf *nos, + int x0, int x1, int y0, int y1, + gs_memory_t *memory, gx_device *dev); gx_color_index pdf14_encode_color(gx_device *dev, const gx_color_value colors[]); gx_color_index pdf14_encode_color_tag(gx_device *dev, const gx_color_value colors[]); int pdf14_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out); -gx_color_index pdf14_compressed_encode_color(gx_device *dev, const gx_color_value colors[]); -int pdf14_compressed_decode_color(gx_device * dev, gx_color_index color, - gx_color_value * out); void pdf14_gray_cs_to_cmyk_cm(gx_device * dev, frac gray, frac out[]); -void pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_imager_state *pis, +void pdf14_rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]); void pdf14_cmyk_cs_to_cmyk_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); -void gx_build_blended_image_row(byte *buf_ptr, int y, int planestride, - int width, int num_comp, byte bg, byte *linebuf); +void pdf14_gray_cs_to_rgbspot_cm(gx_device * dev, frac gray, frac out[]); +void pdf14_rgb_cs_to_rgbspot_cm(gx_device * dev, const gs_gstate *pgs, + frac r, frac g, frac b, frac out[]); +void pdf14_cmyk_cs_to_rgbspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); + +void pdf14_gray_cs_to_grayspot_cm(gx_device * dev, frac gray, frac out[]); +void pdf14_rgb_cs_to_grayspot_cm(gx_device * dev, const gs_gstate *pgs, + frac r, frac g, frac b, frac out[]); +void pdf14_cmyk_cs_to_grayspot_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[]); + +void gx_build_blended_image_row(const byte *gs_restrict buf_ptr, int planestride, + int width, int num_comp, byte bg, byte *gs_restrict linebuf); void gx_blend_image_buffer(byte *buf_ptr, int width, int height, int rowstride, int planestride, int num_comp, byte bg); int gx_put_blended_image_cmykspot(gx_device *target, byte *buf_ptr, @@ -446,6 +351,13 @@ int planestride, int rowstride, int x0, int y0, int width, int height, int num_comp, byte bg); +/* Function moved between compilation units to allow inlining. */ +int pdf14_mark_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color, const gx_device_color *pdc, + bool devn); + + + #if RAW_DUMP void dump_raw_buffer(int num_rows, int width, int n_chan, diff -Nru ghostscript-9.10~dfsg/base/gxccache.c ghostscript-9.25~dfsg+1/base/gxccache.c --- ghostscript-9.10~dfsg/base/gxccache.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxccache.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -176,7 +176,7 @@ int gx_image_cached_char(register gs_show_enum * penum, register cached_char * cc) { - register gs_state *pgs = penum->pgs; + register gs_gstate *pgs = penum->pgs; gx_device_color *pdevc = gs_currentdevicecolor_inline(pgs); int x, y, w, h, depth; int code; @@ -306,11 +306,9 @@ gx_clip_path *pcpath; - if (penum) { - penum->use_wxy_float = false; - penum->wxy_float.x = penum->wxy_float.y = 0.0; - penum->wxy = cc->wxy; - } + penum->use_wxy_float = false; + penum->wxy_float.x = penum->wxy_float.y = 0.0; + penum->wxy = cc->wxy; code = gx_effective_clip_path(pgs, &pcpath); if (code >= 0) { @@ -364,12 +362,12 @@ /* Make a matrix that will place the image */ /* at (x,y) with no transformation. */ gs_image_t_init_mask(&image, true); - gs_make_translation((floatp) - x, (floatp) - y, &image.ImageMatrix); + gs_make_translation((double) - x, (double) - y, &image.ImageMatrix); gs_matrix_multiply(&ctm_only(pgs), &image.ImageMatrix, &image.ImageMatrix); image.Width = w; image.Height = h; image.adjust = false; - code = gs_image_init(pie, &image, false, pgs); + code = gs_image_init(pie, &image, false, true, pgs); switch (code) { case 1: /* empty image */ code = 0; diff -Nru ghostscript-9.10~dfsg/base/gxccman.c ghostscript-9.25~dfsg+1/base/gxccman.c --- ghostscript-9.10~dfsg/base/gxccman.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxccman.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -159,9 +159,6 @@ cached_char *cc = dir->ccache.table[chi]; if (cc != 0 && -#ifdef GSLITE - !cc->dont_evict && -#endif (*proc) (dir->memory, cc, proc_data)) { hash_remove_cached_char(dir, chi); gx_free_cached_char(dir, cc); @@ -358,7 +355,12 @@ char_tm, log2_scale, design_grid); if (code < 0) return code; - } + } + else { + if (font->FontType == ft_TrueType) { + pair->design_grid = design_grid; + } + } pair->memory = 0; if_debug8m('k', dir->memory, "[k]adding pair 0x%lx: font=0x%lx [%g %g %g %g] UID %ld, 0x%lx\n", @@ -483,7 +485,10 @@ int log2_yscale = pscale->y; int log2_depth = ilog2(depth); uint nwidth_bits = (iwidth >> log2_xscale) << log2_depth; - ulong isize, icdsize, isize2; + ulong isize, icdsize; +#ifdef ENABLE_IMPOSSIBLE_ALPHA_CODE + ulong isize2; +#endif uint iraster; cached_char *cc; gx_device_memory mdev; @@ -534,10 +539,27 @@ pdev->retained = retained; pdev->width = iwidth; pdev->height = iheight; + pdev->raster = gx_device_raster((gx_device *)pdev, 1); gdev_mem_bitmap_size(pdev, &isize); /* Assume less than max_ulong */ pdev->HWResolution[0] = HWResolution0; pdev->HWResolution[1] = HWResolution1; } else { + /* We reckon this code has never actually been run since 2002, + * as the conditions set up in gx_compute_text_oversampling + * preclude this function ever being called in a way that + * will cause this else clause to be executed. */ +#ifndef ENABLE_IMPOSSIBLE_ALPHA_CODE + static int THIS_NEVER_HAPPENS = 0; + + if (THIS_NEVER_HAPPENS == 0) { + /* Just put the warning out once */ + dmlprintf(dev2->memory, + "Unexpected code path in gx_alloc_char_bits taken!\n" + "Please contact the Ghostscript developers.\n"); + THIS_NEVER_HAPPENS = 1; + } + return_error(gs_error_unknownerror); +#else /* ENABLE_IMPOSSIBLE_ALPHA_CODE */ /* Use an alpha-buffer device to compress as we go. */ /* Preserve the reference counts, if any. */ rc_header rc; @@ -558,6 +580,7 @@ isize += isize2; /* Assume less than max_ulong */ dev->HWResolution[0] = HWResolution0 * (1 >> log2_xscale); dev->HWResolution[1] = HWResolution1 * (1 >> log2_yscale); +#endif /* ENABLE_IMPOSSIBLE_ALPHA_CODE */ } icdsize = isize + sizeof_cached_char; code = alloc_char(dir, icdsize, &cc); @@ -587,6 +610,7 @@ /* Open the cache device(s). */ +#ifndef ENABLE_IMPOSSIBLE_ALPHA_CODE if (dev2) { /* The second device is an alpha device that targets */ /* the real storage for the character. */ byte *bits = cc_bits(cc); @@ -600,6 +624,10 @@ (*dev_proc(dev, open_device)) ((gx_device *) dev); } else if (dev) gx_open_cache_device(dev, cc); +#else /* ENABLE_IMPOSSIBLE_ALPHA_CODE */ + if (dev) + gx_open_cache_device(dev, cc); +#endif /* ENABLE_IMPOSSIBLE_ALPHA_CODE */ return 0; } @@ -975,12 +1003,6 @@ if (cch == 0) { /* Not enough room to allocate in this chunk. */ return 0; } -#ifdef GSLITE - /* We shouldn't free because it's used. */ - if (cc->dont_evict) { - return 0; - } -#endif else { /* Free the character */ cached_fm_pair *pair = cc_pair(cc); @@ -1000,10 +1022,6 @@ } } -#ifdef GSLITE - cc->dont_evict = 0; -#endif - cc->chunk = cck; cc->loc = (byte *) cc - cck->data; *pcc = cc; @@ -1049,17 +1067,3 @@ if_debug2m('K', dir->memory, "[K]shortening creates free block 0x%lx(%u)\n", (ulong) ((byte *) cc + cc->head.size), diff); } - -#ifdef GSLITE - -void gx_retain_cached_char(cached_char *cc) -{ - cc->dont_evict ++; -} - -void gx_release_cached_char(cached_char *cc) -{ - cc->dont_evict --; -} - -#endif diff -Nru ghostscript-9.10~dfsg/base/gxcdevn.h ghostscript-9.25~dfsg+1/base/gxcdevn.h --- ghostscript-9.10~dfsg/base/gxcdevn.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcdevn.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,7 +30,7 @@ struct gs_device_n_map_s { rc_header rc; int (*tint_transform)(const float *in, float *out, - const gs_imager_state *pis, void *data); + const gs_gstate *pgs, void *data); void *tint_transform_data; bool cache_valid; float tint[GS_CLIENT_COLOR_MAX_COMPONENTS]; @@ -59,6 +59,6 @@ device_n_attributes_enum_ptrs, device_n_attributes_reloc_ptrs, cspace, next) /* Check if we are using the alternate color space */ -bool using_alt_color_space(const gs_state * pgs); +bool using_alt_color_space(const gs_gstate * pgs); #endif /* gxcdevn_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxchar.c ghostscript-9.25~dfsg+1/base/gxchar.c --- ghostscript-9.10~dfsg/base/gxchar.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxchar.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -43,7 +43,7 @@ /* Structure descriptors */ public_st_gs_show_enum(); extern_st(st_gs_text_enum); -extern_st(st_gs_state); /* only for testing */ +extern_st(st_gs_gstate); /* only for testing */ static ENUM_PTRS_BEGIN(show_enum_enum_ptrs) return ENUM_USING(st_gs_text_enum, vptr, size, index - 5); @@ -67,7 +67,7 @@ static void show_set_scale(const gs_show_enum *, gs_log2_scale_point *log2_scale); static int show_cache_setup(gs_show_enum *); static int show_state_setup(gs_show_enum *); -static int show_origin_setup(gs_state *, fixed, fixed, gs_show_enum * penum); +static int show_origin_setup(gs_gstate *, fixed, fixed, gs_show_enum * penum); /* Accessors for current_char and current_glyph. */ #define CURRENT_CHAR(penum) ((penum)->returned.current_char) @@ -79,7 +79,7 @@ /* Allocate a show enumerator. */ gs_show_enum * -gs_show_enum_alloc(gs_memory_t * mem, gs_state * pgs, client_name_t cname) +gs_show_enum_alloc(gs_memory_t * mem, gs_gstate * pgs, client_name_t cname) { gs_show_enum *penum; @@ -119,7 +119,7 @@ }; int -gx_default_text_begin(gx_device * dev, gs_imager_state * pis, +gx_default_text_begin(gx_device * dev, gs_gstate * pgs1, const gs_text_params_t * text, gs_font * font, gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, @@ -128,20 +128,20 @@ uint operation = text->operation; bool propagate_charpath = (operation & TEXT_DO_DRAW) != 0; int code; - gs_state *pgs = (gs_state *)pis; + gs_gstate *pgs = (gs_gstate *)pgs1; gs_show_enum *penum; /* - * For the moment, require pis to be a gs_state *, since all the + * For the moment, require pgs to be a gs_gstate *, since all the * procedures for character rendering expect it. */ - if (gs_object_type(mem, pis) != &st_gs_state) + if (gs_object_type(mem, pgs) != &st_gs_gstate) return_error(gs_error_Fatal); penum = gs_show_enum_alloc(mem, pgs, "gx_default_text_begin"); if (!penum) return_error(gs_error_VMerror); code = gs_text_enum_init((gs_text_enum_t *)penum, &default_text_procs, - dev, pis, text, font, path, pdcolor, pcpath, mem); + dev, pgs, text, font, path, pdcolor, pcpath, mem); if (code < 0) { gs_free_object(mem, penum, "gx_default_text_begin"); return code; @@ -176,10 +176,8 @@ penum->show_gstate = (propagate_charpath && (pgs->in_charpath != 0) ? pgs->show_gstate : pgs); - if((operation & - (TEXT_DO_NONE | TEXT_RETURN_WIDTH | TEXT_RENDER_MODE_3)) == - (TEXT_DO_NONE | TEXT_RETURN_WIDTH)) { - /* This is stringwidth. */ + if (!(~operation & (TEXT_DO_NONE | TEXT_RETURN_WIDTH))) { + /* This is stringwidth (or a PDF with text in rendering mode 3) . */ gx_device_null *dev_null = gs_alloc_struct(mem, gx_device_null, &st_device_null, "stringwidth(dev_null)"); @@ -210,7 +208,7 @@ /* Compute the number of characters in a text. */ int -gs_text_count_chars(gs_state * pgs, gs_text_params_t *text, gs_memory_t * mem) +gs_text_count_chars(gs_gstate * pgs, gs_text_params_t *text, gs_memory_t * mem) { font_proc_next_char_glyph((*next_proc)) = pgs->font->procs.next_char_glyph; @@ -244,13 +242,12 @@ /* An auxiliary functions for pdfwrite to process type 3 fonts. */ int -gx_hld_stringwidth_begin(gs_imager_state * pis, gx_path **path) +gx_hld_stringwidth_begin(gs_gstate * pgs, gx_path **path) { - gs_state *pgs = (gs_state *)pis; - extern_st(st_gs_state); + extern_st(st_gs_gstate); int code; - if (gs_object_type(pis->memory, pis) != &st_gs_state) + if (gs_object_type(pgs->memory, pgs) != &st_gs_gstate) return_error(gs_error_unregistered); code = gs_gsave(pgs); if (code < 0) @@ -265,7 +262,7 @@ gx_default_text_restore_state(gs_text_enum_t *pte) { gs_show_enum *penum; - gs_state *pgs; + gs_gstate *pgs; if (SHOW_IS(pte, TEXT_DO_NONE)) return 0; @@ -276,8 +273,8 @@ /* ------ Width/cache setting ------ */ static int - set_cache_device(gs_show_enum *penum, gs_state *pgs, - floatp llx, floatp lly, floatp urx, floatp ury); + set_cache_device(gs_show_enum *penum, gs_gstate *pgs, + double llx, double lly, double urx, double ury); /* This is the default implementation of text enumerator set_cache. */ static int @@ -285,7 +282,7 @@ gs_text_cache_control_t control) { gs_show_enum *const penum = (gs_show_enum *)pte; - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; gs_font *pfont = gs_rootfont(pgs); /* Detect zero FontMatrix now for Adobe compatibility with CET tests. @@ -362,7 +359,7 @@ /* Note that this returns 1 if the current show operation is */ /* non-displaying (stringwidth or cshow). */ int -set_char_width(gs_show_enum *penum, gs_state *pgs, floatp wx, floatp wy) +set_char_width(gs_show_enum *penum, gs_gstate *pgs, double wx, double wy) { int code; @@ -436,7 +433,7 @@ int *depth, gs_fixed_point *subpix_origin, gs_log2_scale_point *log2_scale) { - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; gx_device *dev = gs_currentdevice_inline(pgs); int code; @@ -485,16 +482,16 @@ /* Return 1 if we just set up a cache device. */ /* Used by setcachedevice and setcachedevice2. */ static int -set_cache_device(gs_show_enum * penum, gs_state * pgs, floatp llx, floatp lly, - floatp urx, floatp ury) +set_cache_device(gs_show_enum * penum, gs_gstate * pgs, double llx, double lly, + double urx, double ury) { gs_glyph glyph; + int code = 0; /* See if we want to cache this character. */ if (pgs->in_cachedevice) /* no recursion! */ return 0; if (SHOW_IS_ALL_OF(penum, TEXT_DO_NONE | TEXT_INTERVENE)) { /* cshow */ - int code; if_debug0m('k', penum->memory, "[k]no cache: cshow"); code = gs_nulldevice(pgs); if (code < 0) @@ -504,7 +501,7 @@ pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING; /* disable color/gray/image operators */ /* We can only use the cache if we know the glyph. */ glyph = CURRENT_GLYPH(penum); - if (glyph == gs_no_glyph) + if (glyph == GS_NO_GLYPH) return 0; /* We can only use the cache if ctm is unchanged */ /* (aside from a possible translation). */ @@ -521,14 +518,13 @@ static const fixed max_cdim[3] = { #define max_cd(n)\ - (fixed_1 << (arch_sizeof_short * 8 - n)) - (fixed_1 >> n) * 3 + (fixed_1 << (ARCH_SIZEOF_SHORT * 8 - n)) - (fixed_1 >> n) * 3 max_cd(0), max_cd(1), max_cd(2) #undef max_cd }; ushort iwidth, iheight; cached_char *cc; gs_fixed_rect clip_box; - int code; gs_fixed_point cll, clr, cul, cur, cdim; /* Reject setcachedevice arguments that are too big and, probably, invalid */ @@ -611,6 +607,9 @@ log2_scale.x + log2_scale.y > alpha_bits ? penum->dev_cache2 : NULL), iwidth, iheight, &log2_scale, depth, &cc); + if (code < 0) + return code; + if (cc == 0) { /* too big for cache or no cache */ gx_path box_path; @@ -636,6 +635,8 @@ if (code < 0) return code; code = gx_cpath_clip(pgs, pgs->clip_path, &box_path, gx_rule_winding_number); + if (code < 0) + return code; gx_path_free(&box_path, "set_cache_device"); pgs->in_cachedevice = CACHE_DEVICE_NONE_AND_CLIP; return 0; @@ -684,24 +685,28 @@ clip_box.q.x = int2fixed(iwidth); clip_box.q.y = int2fixed(iheight); if ((code = gx_clip_to_rectangle(pgs, &clip_box)) < 0) - return code; + goto fail; code = gx_set_device_color_1(pgs); /* write 1's */ if (code < 0) - return code; + goto fail; gs_swapcolors_quick(pgs); code = gx_set_device_color_1(pgs); /* write 1's */ if (code < 0) - return code; + goto fail; gs_swapcolors_quick(pgs); pgs->in_cachedevice = CACHE_DEVICE_CACHING; } penum->width_status = sws_cache; return 1; + +fail: + gs_grestore(pgs); + return code; } /* Return the cache device status. */ gs_in_cache_device_t -gs_incachedevice(const gs_state *pgs) +gs_incachedevice(const gs_gstate *pgs) { return pgs->in_cachedevice; } @@ -776,7 +781,7 @@ static int continue_kshow(gs_show_enum * penum) { int code; - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; if (pgs->font != penum->orig_font) gs_setfont(pgs, penum->orig_font); @@ -792,7 +797,7 @@ static int show_update(gs_show_enum * penum) { - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; cached_char *cc = penum->cc; int code; @@ -843,7 +848,7 @@ code = gs_grestore(pgs); if (code < 0) return code; - code = gs_state_color_load(pgs); + code = gs_gstate_color_load(pgs); if (code < 0) return code; return gx_image_cached_char(penum, cc); @@ -863,9 +868,9 @@ /* Move to next character */ static inline int -show_fast_move(gs_state * pgs, gs_fixed_point * pwxy) +show_fast_move(gs_gstate * pgs, gs_fixed_point * pwxy) { - return gs_moveto_aux((gs_imager_state *)pgs, pgs->path, + return gs_moveto_aux(pgs, pgs->path, pgs->current_point.x + fixed2float(pwxy->x), pgs->current_point.y + fixed2float(pwxy->y)); } @@ -901,7 +906,7 @@ static int show_move(gs_show_enum * penum) { - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; int code; if (SHOW_IS(penum, TEXT_REPLACE_WIDTHS)) { @@ -921,7 +926,7 @@ */ if (SHOW_IS_ADD_TO_SPACE(penum) && (!penum->single_byte_space - || penum->fstack.depth <= 0)) { + || penum->bytes_decoded == 1)) { gs_char chr = gx_current_char((const gs_text_enum_t *)penum); if (chr == penum->text.space.s_char) { @@ -953,7 +958,7 @@ int code; if (penum->use_wxy_float) - code = gs_moveto_aux((gs_imager_state *)pgs, pgs->path, + code = gs_moveto_aux(pgs, pgs->path, pgs->current_point.x + penum->wxy_float.x + fixed2float(penum->wxy.x), pgs->current_point.y + penum->wxy_float.y + fixed2float(penum->wxy.y)); else @@ -972,7 +977,7 @@ static int show_proceed(gs_show_enum * penum) { - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; gs_font *pfont; cached_fm_pair *pair = 0; gs_font *rfont = @@ -984,12 +989,12 @@ (++(penum->xy_index), next_char_glyph(pte, pchr, pglyph)) gs_char chr; gs_glyph glyph; - int code; + int code, start; cached_char *cc; gs_log2_scale_point log2_scale; if (penum->charpath_flag == cpm_show && SHOW_USES_OUTLINE(penum)) { - code = gs_state_color_load(pgs); + code = gs_gstate_color_load(pgs); if (code < 0) return code; } @@ -1002,6 +1007,7 @@ if (penum->can_cache >= 0) { /* Loop with cache */ for (;;) { + start = penum->index; switch ((code = get_next_char_glyph((gs_text_enum_t *)penum, &chr, &glyph)) ) { @@ -1029,12 +1035,13 @@ * Store glyph now, because pdfwrite needs it while * synthezising bitmap fonts (see assign_char_code). */ - if (glyph == gs_no_glyph) { + if (glyph == GS_NO_GLYPH) { glyph = (*penum->encode_char)(pfont, chr, GLYPH_SPACE_NAME); SET_CURRENT_GLYPH(penum, glyph); } else SET_CURRENT_GLYPH(penum, glyph); + penum->bytes_decoded = penum->index - start; penum->is_pure_color = gs_color_writes_pure(penum->pgs); /* Save this data for compute_glyph_raster_params to work independently on the color change in BuildChar. @@ -1056,7 +1063,7 @@ return code; } penum->pair = pair; - if (glyph == gs_no_glyph) { + if (glyph == GS_NO_GLYPH || SHOW_IS_ALL_OF(penum, TEXT_NO_CACHE)) { cc = 0; goto no_cache; } @@ -1128,6 +1135,7 @@ } } } else { + start = penum->index; /* Can't use cache */ switch ((code = get_next_char_glyph((gs_text_enum_t *)penum, &chr, &glyph)) @@ -1146,6 +1154,7 @@ gs_log2_scale_point log2_scale; gs_fixed_point subpix_origin; + penum->bytes_decoded = penum->index - start; code = compute_glyph_raster_params(penum, false, &alpha_bits, &depth, &subpix_origin, &log2_scale); if (code < 0) return code; @@ -1159,7 +1168,7 @@ } } SET_CURRENT_CHAR(penum, chr); - if (glyph == gs_no_glyph) { + if (glyph == GS_NO_GLYPH) { glyph = (*penum->encode_char)(pfont, chr, GLYPH_SPACE_NAME); } SET_CURRENT_GLYPH(penum, glyph); @@ -1225,9 +1234,8 @@ cpt.x = float2fixed(fpx); cpt.y = float2fixed(fpy); } - gs_newpath(pgs); - code = show_origin_setup(pgs, cpt.x, cpt.y, penum); - if (code < 0) + if (((code = gs_newpath(pgs)) < 0) || + ((code = show_origin_setup(pgs, cpt.x, cpt.y, penum)) < 0)) goto rret; } penum->width_status = sws_none; @@ -1267,7 +1275,10 @@ return TEXT_PROCESS_RENDER; /* If we get an error while setting up for BuildChar, */ /* we must undo the partial setup. */ - rret:gs_grestore(pgs); +rret: + while (pgs->level > penum->level) { + gs_grestore(pgs); + } return code; #undef get_next_char_glyph } @@ -1298,7 +1309,8 @@ static int show_finish(gs_show_enum * penum) { - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; + int code = 0, rcode; if ((penum->text.operation & TEXT_DO_FALSE_CHARPATH) || (penum->text.operation & TEXT_DO_TRUE_CHARPATH)) { @@ -1308,17 +1320,16 @@ if (penum->auto_release) penum->procs->release((gs_text_enum_t *)penum, "show_finish"); - if((penum->text.operation & - (TEXT_DO_NONE | TEXT_RETURN_WIDTH | TEXT_RENDER_MODE_3)) == - (TEXT_DO_NONE | TEXT_RETURN_WIDTH)) { - /* Save the accumulated width before returning, */ - /* and undo the extra gsave. */ - int code = gs_currentpoint(pgs, &penum->returned.total_width); - int rcode = gs_grestore(pgs); + if (!SHOW_IS_STRINGWIDTH(penum)) + return 0; - return (code < 0 ? code : rcode); - } - return 0; + /* Save the accumulated width before returning, if we are not in PDF text rendering mode 3, */ + /* and undo the extra gsave. */ + if (!(penum->text.operation & TEXT_RENDER_MODE_3)) + code = gs_currentpoint(pgs, &penum->returned.total_width); + rcode = gs_grestore(pgs); + + return (code < 0 ? code : rcode); } /* Release the structure. */ @@ -1397,7 +1408,7 @@ static int show_state_setup(gs_show_enum * penum) { - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; gx_clip_path *pcpath; gs_font *pfont; @@ -1412,7 +1423,7 @@ penum->text.data.d_glyph, NULL, &fidx); if (code < 0) { /* failed to load glyph data, reload glyph for CID 0 */ code = ((gs_font_cid0 *)pfont)->cidata.glyph_data((gs_font_base *)pfont, - (gs_glyph)(gs_min_cid_glyph + 0), NULL, &fidx); + (gs_glyph)(GS_MIN_CID_GLYPH + 0), NULL, &fidx); if (code < 0) return_error(gs_error_invalidfont); } @@ -1466,7 +1477,7 @@ double fdx = pgs->char_tm.tx - pgs->ctm.tx; double fdy = pgs->char_tm.ty - pgs->ctm.ty; -#define int_bits (arch_sizeof_int * 8 - 1) +#define int_bits (ARCH_SIZEOF_INT * 8 - 1) if (!(f_fits_in_bits(fdx, int_bits) && f_fits_in_bits(fdy, int_bits)) ) @@ -1488,9 +1499,15 @@ * Decide whether to oversample. * We have to decide this each time setcachedevice is called. */ - const gs_state *pgs = penum->pgs; + const gs_gstate *pgs = NULL; + + if (gs_object_type(penum->pgs->memory, penum) == &st_gs_show_enum) { + pgs = penum->pgs; + } else { + pgs = (gs_gstate *)penum->pgs; + } - if ((penum->charpath_flag == cpm_show || + if (pgs != NULL && (penum->charpath_flag == cpm_show || penum->charpath_flag == cpm_charwidth) && SHOW_USES_OUTLINE(penum) /* && gx_path_is_void_inline(pgs->path) */ @@ -1533,7 +1550,7 @@ static int show_cache_setup(gs_show_enum * penum) { - gs_state *pgs = penum->pgs; + gs_gstate *pgs = penum->pgs; gs_memory_t *mem = penum->memory; gx_device_memory *dev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory, @@ -1543,6 +1560,12 @@ "show_cache_setup(dev_cache2)"); if (dev == 0 || dev2 == 0) { + /* + * The structure is full of garbage so must not call the + * finalize method but still need to free the structure + */ + gs_set_object_type(mem, dev2, NULL); + gs_set_object_type(mem, dev, NULL); gs_free_object(mem, dev2, "show_cache_setup(dev_cache2)"); gs_free_object(mem, dev, "show_cache_setup(dev_cache)"); return_error(gs_error_VMerror); @@ -1569,7 +1592,7 @@ /* Used before rendering characters, and for moving the origin */ /* in setcachedevice2 when WMode=1. */ static int -show_origin_setup(gs_state * pgs, fixed cpt_x, fixed cpt_y, gs_show_enum * penum) +show_origin_setup(gs_gstate * pgs, fixed cpt_x, fixed cpt_y, gs_show_enum * penum) { if (penum->charpath_flag == cpm_show) { /* Round the translation in the graphics state. */ diff -Nru ghostscript-9.10~dfsg/base/gxchar.h ghostscript-9.25~dfsg+1/base/gxchar.h --- ghostscript-9.10~dfsg/base/gxchar.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxchar.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,87 +23,11 @@ #include "gschar.h" #include "gxtext.h" -/* The type of cached characters is opaque. */ -#ifndef cached_char_DEFINED -# define cached_char_DEFINED -typedef struct cached_char_s cached_char; -#endif - -/* The type of cached font/matrix pairs is opaque. */ -#ifndef cached_fm_pair_DEFINED -# define cached_fm_pair_DEFINED -typedef struct cached_fm_pair_s cached_fm_pair; -#endif - -/* The type of font objects is opaque. */ -#ifndef gs_font_DEFINED -# define gs_font_DEFINED -typedef struct gs_font_s gs_font; -#endif - -/* The type of text enum objects is opaque. */ -#ifndef gs_text_enum_DEFINED -# define gs_text_enum_DEFINED -typedef struct gs_text_enum_s gs_text_enum_t; -#endif - -/* The types of memory and null devices may be opaque. */ -#ifndef gx_device_memory_DEFINED -# define gx_device_memory_DEFINED -typedef struct gx_device_memory_s gx_device_memory; -#endif -#ifndef gx_device_null_DEFINED -# define gx_device_null_DEFINED -typedef struct gx_device_null_s gx_device_null; -#endif - -/* An enumeration object for string display. */ -typedef enum { - sws_none, - sws_cache, /* setcachedevice[2] */ - sws_no_cache, /* setcharwidth */ - sws_cache_width_only, /* setcharwidth for xfont char */ - sws_retry /* retry setcachedevice[2] */ -} show_width_status; struct gs_show_enum_s { /* Put this first for subclassing. */ gs_text_enum_common; /* (procs, text, index) */ - /* Following are set at creation time */ - bool auto_release; /* true if old API, false if new */ - gs_state *pgs; - int level; /* save the level of pgs */ - gs_char_path_mode charpath_flag; - gs_state *show_gstate; /* for setting pgs->show_gstate */ - /* at returns/callouts */ - int can_cache; /* -1 if can't use cache at all, */ - /* 0 if can read but not load, */ - /* 1 if can read and load */ - gs_int_rect ibox; /* int version of quick-check */ - /* (inner) clipping box */ - gs_int_rect obox; /* int version of (outer) clip box */ - int ftx, fty; /* transformed font translation */ - /* Following are updated dynamically */ - gs_glyph (*encode_char)(gs_font *, gs_char, gs_glyph_space_t); /* copied from font */ - gx_device_memory *dev_cache; /* cache device */ - gx_device_memory *dev_cache2; /* underlying alpha memory device, */ - /* if dev_cache is an alpha buffer */ - gx_device_null *dev_null; /* null device for stringwidth */ - /*uint index; */ /* index within string */ - /*uint xy_index;*/ /* index within X/Y widths */ - /*gs_char returned.current_char;*/ /* current char for render or move */ - /*gs_glyph returned.current_glyph;*/ /* current glyph ditto */ - gs_fixed_point wxy; /* width of current char in device coords */ - gs_point wxy_float; /* same for huge characters */ - bool use_wxy_float; - gs_fixed_point origin; /* unrounded origin of current char */ - /* in device coords, needed for */ - /* charpath and WMode=1 */ - cached_char *cc; /* being accumulated */ - /*gs_point returned.total_width;*/ /* total width of string, set at end */ - show_width_status width_status; - /*gs_log2_scale_point log2_scale;*/ - int (*continue_proc) (gs_show_enum *); /* continuation procedure */ }; + #define gs_show_enum_s_DEFINED /* The structure descriptor is public for gschar.c. */ #define public_st_gs_show_enum() /* in gxchar.c */\ @@ -130,9 +54,9 @@ int gx_image_cached_char(gs_show_enum *, cached_char *); void gx_compute_text_oversampling(const gs_show_enum * penum, const gs_font *pfont, int alpha_bits, gs_log2_scale_point *p_log2_scale); -int set_char_width(gs_show_enum *penum, gs_state *pgs, floatp wx, floatp wy); +int set_char_width(gs_show_enum *penum, gs_gstate *pgs, double wx, double wy); int gx_default_text_restore_state(gs_text_enum_t *pte); -int gx_hld_stringwidth_begin(gs_imager_state * pis, gx_path **path); +int gx_hld_stringwidth_begin(gs_gstate * pgs, gx_path **path); /* Define the maximum size of a full temporary bitmap when rasterizing, */ /* in bits (not bytes). */ diff -Nru ghostscript-9.10~dfsg/base/gxchrout.c ghostscript-9.25~dfsg+1/base/gxchrout.c --- ghostscript-9.10~dfsg/base/gxchrout.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxchrout.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -18,16 +18,16 @@ #include "gx.h" #include "gxchrout.h" #include "gxfarith.h" -#include "gxistate.h" +#include "gxgstate.h" /* * Determine the flatness for rendering a character in an outline font. - * This may be less than the flatness in the imager state. + * This may be less than the flatness in the gs_gstate. * The second argument is the default scaling for the font: 0.001 for * Type 1 fonts, 1.0 for TrueType fonts. */ double -gs_char_flatness(const gs_imager_state *pis, floatp default_scale) +gs_char_flatness(const gs_gstate *pgs, double default_scale) { /* * Set the flatness to a value that is likely to produce reasonably @@ -35,12 +35,12 @@ * graphics state. If the character is very small, set the flatness * to zero, which will produce very accurate curves. */ - double cxx = fabs(pis->ctm.xx), cyy = fabs(pis->ctm.yy); + double cxx = fabs(pgs->ctm.xx), cyy = fabs(pgs->ctm.yy); if (is_fzero(cxx) || (cyy < cxx && !is_fzero(cyy))) cxx = cyy; - if (!is_xxyy(&pis->ctm)) { - double cxy = fabs(pis->ctm.xy), cyx = fabs(pis->ctm.yx); + if (!is_xxyy(&pgs->ctm)) { + double cxy = fabs(pgs->ctm.xy), cyx = fabs(pgs->ctm.yx); if (is_fzero(cxx) || (cxy < cxx && !is_fzero(cxy))) cxx = cxy; @@ -50,8 +50,8 @@ /* Correct for the default scaling. */ cxx *= 0.001 / default_scale; /* Don't let the flatness be worse than the default. */ - if (cxx > pis->flatness) - cxx = pis->flatness; + if (cxx > pgs->flatness) + cxx = pgs->flatness; /* If the character is tiny, force accurate curves. */ if (cxx < 0.2) cxx = 0; diff -Nru ghostscript-9.10~dfsg/base/gxchrout.h ghostscript-9.25~dfsg+1/base/gxchrout.h --- ghostscript-9.10~dfsg/base/gxchrout.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxchrout.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,17 +19,17 @@ #ifndef gxchrout_INCLUDED # define gxchrout_INCLUDED -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif /* * Determine the flatness for rendering a character in an outline font. - * This may be less than the flatness in the imager state. + * This may be less than the flatness in the gs_gstate. * The second argument is the default scaling for the font: 0.001 for * Type 1 fonts, 1.0 for TrueType fonts. */ -double gs_char_flatness(const gs_imager_state *pis, floatp default_scale); +double gs_char_flatness(const gs_gstate *pgs, double default_scale); #endif /* gxchrout_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxcht.c ghostscript-9.25~dfsg+1/base/gxcht.c --- ghostscript-9.10~dfsg/base/gxcht.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcht.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,7 @@ #include "gxdevice.h" #include "gxcmap.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gzht.h" #include "gsserial.h" #include "gxdevsop.h" @@ -36,7 +36,7 @@ /* Define the size of the tile buffer allocated on the stack. */ #define tile_longs_LARGE 256 #define tile_longs_SMALL 64 -#if arch_small_memory +#if ARCH_SMALL_MEMORY # define tile_longs_allocated tile_longs_SMALL # define tile_longs tile_longs_SMALL #else @@ -266,7 +266,7 @@ /* see if enough space is available */ if (req_size > *psize) { *psize = req_size; - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } /* write out the flag byte */ @@ -328,12 +328,12 @@ * pdevc pointer to the location in which to write the * reconstructed device color * - * pis pointer to the current imager state (to access the + * pgs pointer to the current gs_gstate (to access the * current halftone) * * prior_devc pointer to the current device color (this is provided * separately because the device color is not part of the - * imager state) + * gs_gstate) * * dev pointer to the current device, used to retrieve process * color model information @@ -353,7 +353,7 @@ static int gx_dc_ht_colored_read( gx_device_color * pdevc, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_device_color * prior_devc, const gx_device * dev, int64_t offset, @@ -379,7 +379,7 @@ /* the number of components is determined by the color model */ devc.colors.colored.num_components = num_comps; - devc.colors.colored.c_ht = pis->dev_ht; + devc.colors.colored.c_ht = pgs->dev_ht; /* * Verify that we have at least the flag bits. For performance @@ -460,10 +460,10 @@ /* set the phase as required (select value is arbitrary) */ color_set_phase_mod( &devc, - pis->screen_phase[0].x, - pis->screen_phase[0].y, - pis->dev_ht->lcm_width, - pis->dev_ht->lcm_height ); + pgs->screen_phase[0].x, + pgs->screen_phase[0].y, + pgs->dev_ht->lcm_width, + pgs->dev_ht->lcm_height ); /* everything looks OK */ *pdevc = devc; @@ -557,7 +557,7 @@ /* Prepare to use a colored halftone, by loading the default cache. */ static int -gx_dc_ht_colored_load(gx_device_color * pdevc, const gs_imager_state * pis, +gx_dc_ht_colored_load(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * ignore_dev, gs_color_select_t select) { /* TO_DO_DEVICEN */ @@ -618,6 +618,13 @@ int i; int origx, origy; + /* This routine cannot build 3bit chunky halftones, as 3 bit + * things don't pack nicely into bytes or words. Accordingly + * treat 3 bit things as 4 bit things. This is appropriate when + * generating halftones for planar. */ + if (depth == 3) + depth = 4; + if (w <= 0 || h <= 0) return 0; origx = x; diff -Nru ghostscript-9.10~dfsg/base/gxcid.h ghostscript-9.25~dfsg+1/base/gxcid.h --- ghostscript-9.10~dfsg/base/gxcid.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcid.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxcie.h ghostscript-9.25~dfsg+1/base/gxcie.h --- ghostscript-9.10~dfsg/base/gxcie.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcie.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -46,14 +46,14 @@ cs_proc_install_cspace(gx_install_CIEA); /* - * Initialize (just enough of) an imager state so that "concretizing" colors - * using this imager state will do only the CIE->XYZ mapping. This is a + * Initialize (just enough of) an gs_gstate so that "concretizing" colors + * using this gs_gstate will do only the CIE->XYZ mapping. This is a * semi-hack for the PDF writer. */ -extern int gx_cie_to_xyz_alloc(gs_imager_state **, +extern int gx_cie_to_xyz_alloc(gs_gstate **, const gs_color_space *, gs_memory_t *); -extern void gx_cie_to_xyz_free(gs_imager_state *); -extern int gx_cie_to_xyz_alloc2(gs_color_space * pcs, gs_state * pgs); +extern void gx_cie_to_xyz_free(gs_gstate *); +extern int gx_cie_to_xyz_alloc2(gs_color_space * pcs, gs_gstate * pgs); /* Defined in gsciemap.c */ @@ -62,7 +62,7 @@ * caches are loaded. Note that the procedure may return 1 if no rendering * has been defined. */ -int gx_cie_check_rendering(const gs_color_space * pcs, frac * pconc, const gs_imager_state * pis); +int gx_cie_check_rendering(const gs_color_space * pcs, frac * pconc, const gs_gstate * pgs); /* * Do the common remapping operation for CIE color spaces. Returns the @@ -71,8 +71,8 @@ * structure. */ extern int gx_cie_remap_finish( cie_cached_vector3, - frac *, - const gs_imager_state *, + frac *, float *, + const gs_gstate *, const gs_color_space * ); /* Make sure the prototype matches the one defined in gscie.h. */ extern GX_CIE_REMAP_FINISH_PROC(gx_cie_remap_finish); @@ -110,7 +110,7 @@ void * client_data ); /* Load the common caches for a CIE color space */ -extern void gx_cie_load_common_cache(gs_cie_common *, gs_state *); +extern void gx_cie_load_common_cache(gs_cie_common *, gs_gstate *); /* Complete loading of the common caches */ extern void gx_cie_common_complete(gs_cie_common *); @@ -135,15 +135,15 @@ /* Special operations used in the creation of ICC color spaces from PS spaces. These are used to map from PS color to CIEXYZ */ int gx_psconcretize_CIEDEFG(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis); + frac * pconc, float * xyz, const gs_gstate * pgs); int gx_psconcretize_CIEDEF(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis); + frac * pconc, float * xyz, const gs_gstate * pgs); int gx_psconcretize_CIEABC(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis); + frac * pconc, float * xyz, const gs_gstate * pgs); int gx_psconcretize_CIEA(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis); + frac * pconc, float * xyz, const gs_gstate * pgs); bool check_range(gs_range *ranges, int num_colorants); bool check_cie_range( const gs_color_space * pcs ); gs_range* get_cie_range( const gs_color_space * pcs ); - +bool rescale_cie_colors(const gs_color_space * pcs, gs_client_color *cc); #endif /* gxcie_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxcindex.h ghostscript-9.25~dfsg+1/base/gxcindex.h --- ghostscript-9.10~dfsg/base/gxcindex.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcindex.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,12 +19,13 @@ #ifndef gxcindex_INCLUDED # define gxcindex_INCLUDED -#include "gsbitops.h" /* for sample_store macros */ +#include "stdint_.h" /* for uint64_t and uint32_t */ +#include "gsbitops.h" /* for sample_store inline functions */ /* * Define the maximum number of components in a device color. * The minimum value is 4, to handle CMYK; the maximum value is - * arch_sizeof_color_index * 8, since for larger values, there aren't enough + * ARCH_SIZEOF_COLOR_INDEX * 8, since for larger values, there aren't enough * bits in a gx_color_index to have even 1 bit per component. */ #define GX_DEVICE_COLOR_MAX_COMPONENTS (ARCH_SIZEOF_GX_COLOR_INDEX * 8) @@ -54,11 +55,16 @@ /* Define the type for device color index (pixel value) data. */ #ifdef GX_COLOR_INDEX_TYPE +enum { ARCH_SIZEOF_GX_COLOR_INDEX__must_equal__sizeof_GX_COLOR_INDEX_TYPE = 1/!!(ARCH_SIZEOF_GX_COLOR_INDEX == sizeof(GX_COLOR_INDEX_TYPE)) }; typedef GX_COLOR_INDEX_TYPE gx_color_index_data; #else -/* this default must be kept in sync with the one in genarch.c - or ARCH_SIZEOF_GX_COLOR_INDEX will be incorrect */ -typedef ulong gx_color_index_data; +/* Usually this is set by the makefile, but if not, set + it using the ARCH_SIZEOF_GX_COLOR_INDEX */ +# if ARCH_SIZEOF_GX_COLOR_INDEX == 8 + typedef uint64_t gx_color_index_data; +# else + typedef uint32_t gx_color_index_data; +# endif #endif #endif /* (!)TEST_CINDEX_STRUCT */ @@ -67,7 +73,7 @@ /* Define the type for device color indices (pixel values). */ typedef gx_color_index_data * gx_color_index; -#define arch_sizeof_color_index arch_sizeof_ptr +#define ARCH_SIZEOF_COLOR_INDEX ARCH_SIZEOF_PTR extern const gx_color_index_data gx_no_color_index_data; #define gx_no_color_index_values (&gx_no_color_index_data) @@ -75,7 +81,7 @@ #else /* !TEST_CINDEX_POINTER */ -#define arch_sizeof_color_index sizeof(gx_color_index_data) +#define ARCH_SIZEOF_COLOR_INDEX sizeof(gx_color_index_data) /* Define the type for device color indices (pixel values). */ typedef gx_color_index_data gx_color_index; @@ -93,59 +99,4 @@ #endif /* (!)TEST_CINDEX_POINTER */ -/* - * Define macros for accumulating a scan line of a colored image. - * The usage is as follows: - * DECLARE_LINE_ACCUM(line, bpp, xo); - * for ( x = xo; x < xe; ++x ) { - * << compute color at x >> - * LINE_ACCUM(color, bpp); - * } - * This code must be enclosed in { }, since DECLARE_LINE_ACCUM declares - * variables. Supported values of bpp are 1, 2, 4, or n * 8, where n <= 8. - * - * Note that DECLARE_LINE_ACCUM declares the variables l_dptr, l_dbyte, and - * l_dbit. Other code in the loop may use these variables. - */ -#define DECLARE_LINE_ACCUM(line, bpp, xo)\ - sample_store_declare_setup(l_dptr, l_dbit, l_dbyte, line, 0, bpp) -#define LINE_ACCUM(color, bpp)\ - sample_store_next_any(color, l_dptr, l_dbit, bpp, l_dbyte) -#define LINE_ACCUM_SKIP(bpp)\ - sample_store_skip_next(l_dptr, l_dbit, bpp, l_dbyte) -#define LINE_ACCUM_STORE(bpp)\ - sample_store_flush(l_dptr, l_dbit, bpp, l_dbyte) -/* - * Declare additional macros for accumulating a scan line with copying - * to a device. Note that DECLARE_LINE_ACCUM_COPY also declares l_xprev. - * LINE_ACCUM_COPY is called after the accumulation loop. - */ -#define DECLARE_LINE_ACCUM_COPY(line, bpp, xo)\ - DECLARE_LINE_ACCUM(line, bpp, xo);\ - int l_xprev = (xo) -#define LINE_ACCUM_COPY(dev, line, bpp, xo, xe, raster, y)\ - if ( (xe) > l_xprev ) {\ - int code;\ - LINE_ACCUM_STORE(bpp);\ - code = (*dev_proc(dev, copy_color))\ - (dev, line, l_xprev - (xo), raster,\ - gx_no_bitmap_id, l_xprev, y, (xe) - l_xprev, 1);\ - if ( code < 0 )\ - return code;\ - } -/* The same thing, but transposed */ -#define LINE_ACCUM_COPY_TRANS(dev, line, bpp, xo, xe, raster, y)\ - if ( (xe) > l_xprev ) {\ - int code;\ - LINE_ACCUM_STORE(bpp);\ - code = gx_copy_color_unaligned(dev, line, l_xprev - (xo), raster,\ - gx_no_bitmap_id, y, l_xprev, 1, (xe) - l_xprev);\ - if ( code < 0 )\ - return code;\ - } -#define LINE_ACCUM_FLUSH_AND_RESTART(dev, line, bpp, xo, xe, raster, y)\ - { LINE_ACCUM_COPY(dev, line, bpp, xo, xe, raster, y);\ - sample_store_reset(l_dptr, l_dbit, l_dbyte, line, 0, bpp);\ - l_xprev = xe+1; } - #endif /* gxcindex_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxclbits.c ghostscript-9.25~dfsg+1/base/gxclbits.c --- ghostscript-9.10~dfsg/base/gxclbits.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclbits.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,6 +25,7 @@ #include "gdevprn.h" /* for BLS_force_memory */ #include "gxcldev.h" #include "gxfmap.h" +#include "gxpcolor.h" /* for gx_device_is_pattern_clist */ /* * Define when, if ever, to write character bitmaps in all bands. @@ -152,8 +153,8 @@ *psize = try_size; code = (pcls != 0 ? - set_cmd_put_op(dp, cldev, pcls, 0, try_size) : - set_cmd_put_all_op(dp, cldev, 0, try_size)); + set_cmd_put_op(&dp, cldev, pcls, 0, try_size) : + set_cmd_put_all_op(&dp, cldev, 0, try_size)); if (code < 0) return code; cmd_uncount_op(0, try_size); @@ -224,8 +225,8 @@ else { *psize = op_size + short_size; code = (pcls != 0 ? - set_cmd_put_op(dp, cldev, pcls, 0, *psize) : - set_cmd_put_all_op(dp, cldev, 0, *psize)); + set_cmd_put_op(&dp, cldev, pcls, 0, *psize) : + set_cmd_put_all_op(&dp, cldev, 0, *psize)); if (code < 0) return code; cmd_uncount_op(0, *psize); @@ -238,9 +239,11 @@ *psize = op_size + 1; dp[op_size] = code; compress = cmd_compress_const; - } else - bytes_copy_rectangle(dp + op_size, short_raster, data, raster, - short_raster, height); + } else { + uint copy_bytes = (width_bits + 7) >> 3; + bytes_copy_rectangle_zero_padding(dp + op_size, short_raster, data, raster, + copy_bytes, height); + } out: *pdp = dp; return compress; @@ -301,12 +304,12 @@ int code; if (!(idelta & ~15)) { - code = set_cmd_put_op(dp, cldev, pcls, + code = set_cmd_put_op(&dp, cldev, pcls, cmd_op_delta_tile_index + idelta, 1); if (code < 0) return code; } else { - code = set_cmd_put_op(dp, cldev, pcls, + code = set_cmd_put_op(&dp, cldev, pcls, cmd_op_set_tile_index + (indx >> 8), 2); if (code < 0) return code; @@ -328,7 +331,7 @@ if (map == 0) { if (pid && *pid == gs_no_id) return 0; /* no need to write */ - code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_misc, 3); + code = set_cmd_put_all_op(&dp, cldev, cmd_opv_set_misc, 3); if (code < 0) return code; dp[1] = cmd_set_misc_map + (cmd_map_none << 4) + map_index; @@ -339,13 +342,13 @@ if (pid && map->id == *pid) return 0; /* no need to write */ if (map->proc == gs_identity_transfer) { - code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_misc, 3); + code = set_cmd_put_all_op(&dp, cldev, cmd_opv_set_misc, 3); if (code < 0) return code; dp[1] = cmd_set_misc_map + (cmd_map_identity << 4) + map_index; dp[2] = comp_num; } else { - code = set_cmd_put_all_op(dp, cldev, cmd_opv_set_misc, + code = set_cmd_put_all_op(&dp, cldev, cmd_opv_set_misc, 3 + sizeof(map->values)); if (code < 0) return code; @@ -410,7 +413,7 @@ if_debug2m('L', cldev->memory, "[L]deleting index=%u, offset=%lu\n", index, (ulong) ((byte *) slot - cldev->data)); gx_bits_cache_free(&cldev->bits, (gx_cached_bits_head *) slot, - &cldev->chunk); + cldev->cache_chunk); table[index].offset = 0; /* Delete the entry from the hash table. */ /* We'd like to move up any later entries, so that we don't need */ @@ -428,7 +431,7 @@ index, offset); gx_bits_cache_free(&cldev->bits, (gx_cached_bits_head *) (cldev->data + offset), - &cldev->chunk); + cldev->cache_chunk); table[index].offset = 0; } } @@ -452,11 +455,11 @@ if (cldev->bits.csize == cldev->tile_max_count) { /* Don't let the hash table get too full: delete an entry. */ /* Since gx_bits_cache_alloc returns an entry to delete when */ /* it fails, just force it to fail. */ - gx_bits_cache_alloc(&cldev->bits, (ulong) cldev->chunk.size, + gx_bits_cache_alloc(&cldev->bits, (ulong) cldev->cache_chunk->size, &slot_head); if (slot_head == 0) { /* Wrap around and retry. */ cldev->bits.cnext = 0; - gx_bits_cache_alloc(&cldev->bits, (ulong) cldev->chunk.size, + gx_bits_cache_alloc(&cldev->bits, (ulong) cldev->cache_chunk->size, &slot_head); #ifdef DEBUG if (slot_head == 0) { @@ -546,7 +549,7 @@ if (tiles->num_planes != 1) depth /= tiles->num_planes; rep_width_bits = rep_width * depth; - max_bytes = cldev->chunk.size / (rep_width_bits * rep_height); + max_bytes = cldev->cache_chunk->size / (rep_width_bits * rep_height); max_bytes -= min(max_bytes, tile_overhead); if (max_bytes > max_tile_bytes) @@ -600,7 +603,7 @@ int band_index = pcls - cldev->states; byte *bptr = ts_mask(loc.tile) + (band_index >> 3); byte bmask = 1 << (band_index & 7); - bool for_pattern = IS_CLIST_FOR_PATTERN(cldev); + bool for_pattern = gx_device_is_pattern_clist((gx_device *)cldev); if (*bptr & bmask) { /* Already known. Just set the index. */ if (pcls->tile_index == loc.index) @@ -646,7 +649,7 @@ * compatible with those stored in the device * (cldev->tile_params). */ - ulong offset = (byte *) loc.tile - cldev->chunk.data; + ulong offset = (byte *) loc.tile - cldev->cache_chunk->data; uint rsize = extra + 1 + cmd_size_w(loc.index) + cmd_size_w(offset); byte *dp; @@ -733,7 +736,7 @@ } else { /* Not known yet. Output the bits. */ /* Note that the offset we write is the one used by */ /* the reading phase, not the writing phase. */ - ulong offset = (byte *) loc.tile - cldev->chunk.data; + ulong offset = (byte *) loc.tile - cldev->cache_chunk->data; uint rsize = 2 + cmd_size_w(loc.tile->width) + cmd_size_w(loc.tile->height) + cmd_size_w(loc.index) + cmd_size_w(offset); @@ -751,7 +754,7 @@ loc.tile->width * pdepth, loc.tile->height * loc.tile->num_planes, loc.tile->cb_raster, rsize, - decompress_elsewhere | (((gx_device_printer *)cldev->target)->BLS_force_memory ? (1 << cmd_compress_cfe) : 0), + decompress_elsewhere | (cldev->target->BLS_force_memory ? (1 << cmd_compress_cfe) : 0), &dp, &csize); if (code < 0) diff -Nru ghostscript-9.10~dfsg/base/gxcldev.h ghostscript-9.25~dfsg+1/base/gxcldev.h --- ghostscript-9.10~dfsg/base/gxcldev.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcldev.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -29,8 +29,6 @@ #include "srlx.h" /* ditto */ #include "gsdcolor.h" -#define CMM_THREAD_SAFE 0 - /* ---------------- Commands ---------------- */ /* Define the compression modes for bitmaps. */ @@ -106,12 +104,7 @@ cmd_op_tile_rect_tiny = 0x80, /* +dw+0, rect_tiny | +dw+8 */ cmd_op_copy_mono_planes = 0x90, /* +compress, plane_height, x#, y#, (w+data_x)#, */ /* h#, | */ -#define cmd_copy_ht_color 4 - /* +4+compress, x#, y#, (w+data_x)#, */ - /* h#, | */ -#define cmd_copy_use_tile 8 - /* +8 (use tile), x#, y# | */ - /* +12 (use tile), x#, y# */ +#define cmd_copy_use_tile 8 /* +8 (use tile), x#, y# | */ cmd_op_copy_color_alpha = 0xa0, /* (same as copy_mono, except: */ /* if color, ignore ht_color; */ /* if alpha & !use_tile, depth is */ @@ -327,6 +320,7 @@ dev_proc_copy_planes(clist_copy_planes); dev_proc_fill_rectangle_hl_color(clist_fill_rectangle_hl_color); dev_proc_copy_alpha_hl_color(clist_copy_alpha_hl_color); +dev_proc_process_page(clist_process_page); /* In gxclimag.c */ dev_proc_fill_mask(clist_fill_mask); @@ -347,59 +341,6 @@ /* ------ Exported by gxclist.c ------ */ -/* - * Error recovery procedures for writer-side VMerrors, for async rendering - * support. This logic assumes that the command list file and/or the - * renderer allocate memory from the same pool as the writer. Hence, when - * the writer runs out of memory, it tries to pause and let the renderer run - * for a while in hope that enough memory will be freed by it to allow the - * writer to allocate enough memory to proceed. Once a VMerror is detected, - * error recovery proceeds in two escalating stages: - * - * 1) The recovery logic repeatedly calls clist_VMerror_recover(), which - * waits until the next page has finished rendering. The recovery logic - * keeps calling clist_VMerror_recover() until enough memory is freed, - * or until clist_VMerror_recover() signals that no more pages - * remain to be rendered (when return code < 0). - * - * 2) If enough memory is not free, the recovery logic calls - * clist_VMerror_recover_flush() once. This routine terminates and - * flushes out the partially-completed page that the writer is currently - * writing to the command file, then waits for the partial page to finish - * rendering. It then opens up a new command list "file" and resets the - * state of the command list machinery to an initial state as if a new - * page were beginning. - * - * If insufficient memory is available after the 2nd step, the situation - * is the same as if it ocurred in a non-async setup: the writer program - * simply used up too much memory and cannot continue. - * - * The first stage of error recovery (no flush) is performed without - * flushing out the current page, so failing commands can simply be - * restarted after such recovery. This is not true of 2nd stage recovery - * (flush): as part of its operation, the flush resets the state of both - * writer and renderer to initial values. In this event, the recovery logic - * which called clist_try_recover_VMerror_flush() must force any pertinent - * state information to be re-emitted before re-issuing the failing command. - * - * In case of a VMerror, the internal procedures that support the driver - * procedures simply return the error code: they do not attempt recovery. - * Note that all such procedures must take care that (1) they don't update - * any writer state to reflect information written to the band list unless - * the write actually succeeds, and (2) they are idempotent, since they may - * be re-executed after first-stage VMerror recovery. - * - * Error recovery is only performed by the driver procedures themselves - * (fill_rectangle, copy_mono, fill_path, etc.) and a few other procedures - * at the same level of control. The implementation of error recovery is - * packaged up in the FOR_RECTS et al macros defined below, but -- as noted - * above -- recovery is not fully transparent. Other routines which perform - * error recovery are those which open the device, begin a new page, or - * reopen the device (put_params). - */ -int clist_VMerror_recover(gx_device_clist_writer *, int); -int clist_VMerror_recover_flush(gx_device_clist_writer *, int); - /* Write out device parameters. */ int cmd_put_params(gx_device_clist_writer *, gs_param_list *); @@ -432,9 +373,9 @@ #endif /* Call cmd_put_op and update stats if no error occurs. */ #define set_cmd_put_op(dp, cldev, pcls, op, csize)\ - ( (dp = cmd_put_op(cldev, pcls, csize)) == 0 ?\ + ( (*dp = cmd_put_op(cldev, pcls, csize)) == NULL ?\ (cldev)->error_code :\ - (*dp = cmd_count_op(op, csize, cldev->memory), 0) ) + (**dp = cmd_count_op(op, csize, cldev->memory), 0) ) /* Add a command for all bands or a range of bands. */ byte *cmd_put_range_op(gx_device_clist_writer * cldev, int band_min, @@ -444,9 +385,9 @@ cmd_put_range_op(cldev, 0, (cldev)->nbands - 1, size) /* Call cmd_put_all/range_op and update stats if no error occurs. */ #define set_cmd_put_range_op(dp, cldev, op, bmin, bmax, csize)\ - ( (dp = cmd_put_range_op(cldev, bmin, bmax, csize)) == 0 ?\ + ( (*dp = cmd_put_range_op(cldev, bmin, bmax, csize)) == NULL ?\ (cldev)->error_code :\ - (*dp = cmd_count_op(op, csize, (cldev)->memory), 0) ) + (**dp = cmd_count_op(op, csize, (cldev)->memory), 0) ) #define set_cmd_put_all_op(dp, cldev, op, csize)\ set_cmd_put_range_op(dp, cldev, op, 0, (cldev)->nbands - 1, csize) @@ -484,12 +425,12 @@ byte *cmd_put_w(uint, byte *); #define cmd_putw(w,dp)\ - (w1byte(w) ? (*dp = w, ++dp) :\ - w2byte(w) ? (*dp = (w) | 0x80, dp[1] = (w) >> 7, dp += 2) :\ - (dp = cmd_put_w((uint)(w), dp))) + (w1byte(w) ? (**dp = w, ++(*dp)) :\ + w2byte(w) ? (**dp = (w) | 0x80, (*dp)[1] = (w) >> 7, (*dp) += 2) :\ + (*dp = cmd_put_w((uint)(w), *dp))) #define cmd_put2w(wx,wy,dp)\ - (w1byte((wx) | (wy)) ? (dp[0] = (wx), dp[1] = (wy), dp += 2) :\ - (dp = cmd_put_w((uint)(wy), cmd_put_w((uint)(wx), dp)))) + (w1byte((wx) | (wy)) ? ((*dp)[0] = (wx), (*dp)[1] = (wy), (*dp) += 2) :\ + (*dp = cmd_put_w((uint)(wy), cmd_put_w((uint)(wx), *dp)))) #define cmd_putxy(xy,dp) cmd_put2w((xy).x, (xy).y, dp) int cmd_size_frac31(register frac31 w); @@ -573,12 +514,6 @@ * ... process rectangle x, y, width, height in band pcls ... * * ........ - * continue; - * error_in_rect: - * if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - * SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - * return re.band_code; - * re.y -= re.height; * } while ((re.y += re.height) < re.yend); * * Note that RECT_STEP_INIT(re) sets re.height. It is OK for the code that @@ -587,44 +522,6 @@ * use of this. The band processing code may `continue' (to reduce nesting * of conditionals). * - * The error_in_rect code detects an error that may be a recoverable - * VMerror, with calling clist_VMerror_recover_flush. It will attempt to fix the - * VMerror by flushing and closing the band and resetting the imager state, - * and then restart emitting the entire band. - * Note that re.y must not change when restarting the band. - * - * The band processing code may wrap a writing operation with a pattern like this : - * - * do { - * code = operation(...); - * } while (RECT_RECOVER(code)); - * if (code < 0 && SET_BAND_CODE(code)) - * goto error_in_rect; - * - * - * This will - * perform local first-stage VMerror recovery, by waiting for some memory to - * become free and then retrying the failed operation starting at the - * TRY_RECT. If local recovery is unsuccessful, the local recovery code - * should pass control to error_in_rect. - * - * In a few cases, the band processing code calls other driver procedures - * (e.g., clist_copy_mono calls itself recursively if it must split up the - * operation into smaller pieces) or other procedures that may attempt - * VMerror recovery. In such cases, the recursive call must not attempt - * second-stage VMerror recovery, since the caller would have no way of - * knowing that the writer state had been reset. Such recursive calls - * should be wrapped in - * - * ++cdev->driver_call_nesting; { ... } --cdev->driver_call_nesting; - * - * , which causes error_in_rect - * simply to return the error code rather than attempting - * recovery. (The local recovery with do { ... } while (RECT_RECOVER(code)); - * is still allowed since it is transparent.) By - * convention, calls to cmd_put_xxx or cmd_set_xxx never attempt recovery - * and so never require a nesting. - * * If a put_params call fails, the device will be left in a closed state, * but higher-level code won't notice this fact. We flag this by setting * permanent_error, which prevents writing to the command list. @@ -635,11 +532,10 @@ int height; int yend; int band_height; - int band_code; int band; gx_clist_state *pcls; int band_end; - int nbands; + int rect_nbands; } cmd_rects_enum_t; #define RECT_ENUM_INIT(re, yvar, heightvar)\ @@ -647,7 +543,7 @@ re.height = heightvar;\ re.yend = re.y + re.height;\ re.band_height = cdev->page_band_height;\ - re.nbands = (re.yend - re.y + re.band_height - 1) / re.band_height; + re.rect_nbands = (re.yend - re.y + re.band_height - 1) / re.band_height; #define RECT_STEP_INIT(re)\ re.band = re.y / re.band_height;\ @@ -655,9 +551,6 @@ re.band_end = (re.band + 1) * re.band_height;\ re.height = min(re.band_end, re.yend) - re.y; -#define RECT_RECOVER(codevar) (codevar < 0 && (codevar = clist_VMerror_recover(cdev, codevar)) >= 0) -#define SET_BAND_CODE(codevar) (re.band_code = codevar) - /* Read a transformation matrix. */ const byte *cmd_read_matrix(gs_matrix * pmat, const byte * cbp); @@ -745,7 +638,7 @@ * Write out any necessary color mapping data. */ int cmd_put_color_mapping(gx_device_clist_writer * cldev, - const gs_imager_state * pis); + const gs_gstate * pgs); /* * Add commands to represent a full (device) halftone. * (This routine should probably be in some other module.) diff -Nru ghostscript-9.10~dfsg/base/gxclfile.c ghostscript-9.25~dfsg+1/base/gxclfile.c --- ghostscript-9.10~dfsg/base/gxclfile.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclfile.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,12 +9,13 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* File-based command list implementation */ +#include "assert.h" #include "stdio_.h" #include "string_.h" #include "unistd_.h" @@ -27,9 +28,257 @@ #include "valgrind.h" #endif + /* This is an implementation of the command list I/O interface */ /* that uses the file system for storage. */ +/* clist cache code so that wrapped files don't incur a performance penalty */ +#define CL_CACHE_NSLOTS (3) +#define CL_CACHE_SLOT_SIZE_LOG2 (15) +#define CL_CACHE_SLOT_EMPTY (-1) + +static clist_io_procs_t clist_io_procs_file; + +typedef struct +{ + int64_t blocknum; + byte *base; +} CL_CACHE_SLOT; + +typedef struct +{ + int block_size; /* full block size, MUST BE power of 2 */ + int nslots; + int64_t filesize; + gs_memory_t *memory; /* save our allocator */ + CL_CACHE_SLOT *slots; /* array of slots */ + byte *base; /* save base of slot data area */ +} CL_CACHE; + +/* Forward references */ +CL_CACHE *cl_cache_alloc(gs_memory_t *mem); +void cl_cache_destroy(CL_CACHE *cache); +CL_CACHE *cl_cache_read_init(CL_CACHE *cache, int nslots, int64_t block_size, int64_t filesize); +int cl_cache_read(byte *data, int len, int64_t pos, CL_CACHE *cache); +CL_CACHE_SLOT * cl_cache_get_empty_slot(CL_CACHE *cache, int64_t pos); +void cl_cache_load_slot(CL_CACHE *cache, CL_CACHE_SLOT *slot, int64_t pos, byte *data, int len); + +#define CL_CACHE_NEEDS_INIT(cache) (cache != NULL && cache->filesize == 0) + +CL_CACHE * +cl_cache_alloc(gs_memory_t *mem) +{ + CL_CACHE *cache; + + /* allocate and initialilze the cache to filesize = 0 to signal read_init needed */ + cache = (CL_CACHE *)gs_alloc_bytes(mem, sizeof(CL_CACHE), "alloc CL_CACHE"); + if (cache != NULL) { + cache->filesize = 0; + cache->nslots = 0; + cache->block_size = 0; + cache->slots = NULL; + cache->base = NULL; + cache->memory = mem; + } + return cache; +} + +void +cl_cache_destroy(CL_CACHE *cache) +{ + if (cache == NULL) + return; + + if (cache->slots != NULL) { + gs_free_object(cache->memory, cache->base, "CL_CACHE SLOT data"); + gs_free_object(cache->memory, cache->slots, "CL_CACHE slots array"); + } + gs_free_object(cache->memory, cache, "CL_CACHE for IFILE"); +} + +/* Set the cache up for reading. The filesize is used for EOF */ +CL_CACHE * +cl_cache_read_init(CL_CACHE *cache, int nslots, int64_t block_size, int64_t filesize) +{ + /* NB: if fail, and cache is still NULL, proceed without cache, reading will cope */ + if (cache == NULL || cache->filesize != 0) + return cache; /* once we've done the init, filesize will be set */ + + if ((filesize+block_size)/block_size < nslots) + nslots = (filesize + block_size)/block_size; /* limit at blocks needed for entire file */ + cache->slots = (CL_CACHE_SLOT *)gs_alloc_bytes(cache->memory, nslots * sizeof(CL_CACHE_SLOT), + "CL_CACHE slots array"); + if (cache->slots == NULL) { + gs_free_object(cache->memory, cache, "Free CL_CACHE for IFILE"); + cache = NULL; /* cache not possible */ + } else { + cache->slots[0].base = (byte *)gs_alloc_bytes(cache->memory, nslots * block_size, + "CL_CACHE_SLOT data"); + if (cache->slots[0].base == NULL) { + gs_free_object(cache->memory, cache->slots, "Free CL_CACHE for IFILE"); + gs_free_object(cache->memory, cache, "Free CL_CACHE for IFILE"); + cache = NULL; /* cache not possible */ + } else { + /* success, initialize the slots */ + int i; + + for (i=0; i < nslots; i++) { + cache->slots[i].blocknum = CL_CACHE_SLOT_EMPTY; + cache->slots[i].base = cache->slots[0].base + (i * block_size); + } + cache->base = cache->slots[0].base; /* save for the 'destroy' (slots array moves around) */ + cache->nslots = nslots; + cache->block_size = block_size; + cache->filesize = filesize; + } + } + return cache; /* May be NULL. If so, no cache used */ +} + +/* Find the cache for the slot containing the 'pos'. */ +/* return the number of bytes read, up to 'len' bytes */ +/* returns 0 if 'pos' not in cache, -1 if pos at or past EOF. */ +int +cl_cache_read(byte *data, int len, int64_t pos, CL_CACHE *cache) +{ + int nread = 0; + int slot; + int offset; + int64_t blocknum = pos / cache->block_size; + + if (pos >= cache->filesize) + return -1; + + /* find the slot */ + for (slot = 0; slot < cache->nslots; slot++) { + if (blocknum == cache->slots[slot].blocknum) + break; + } + if (slot >= cache->nslots) + return 0; /* block not in cache */ + + if (slot != 0) { + /* move the slot we found to the top, moving the rest down */ + byte *base = cache->slots[slot].base; + int i; + + for (i = slot; i > 0; i--) { + cache->slots[i].base = cache->slots[i-1].base; + cache->slots[i].blocknum = cache->slots[i-1].blocknum; + } + cache->slots[0].blocknum = blocknum; + cache->slots[0].base = base; + } + offset = pos - cache->slots[0].blocknum * cache->block_size; + nread = min(cache->block_size - offset, len); + if (nread + pos > cache->filesize) + nread = cache->filesize - pos; /* limit for EOF */ + memcpy(data, cache->slots[0].base + offset, nread); + return nread; +} + +/* 'pos' not used yet */ +/* discard the LRU, move remaining slots down and return the first as new MRU */ +CL_CACHE_SLOT * +cl_cache_get_empty_slot(CL_CACHE *cache, int64_t pos) +{ + /* the LRU is in the last slot, so re-use it */ + CL_CACHE_SLOT *pslot = &(cache->slots[0]); /* slot used will always be first, possibly after moving */ + int64_t slot0_blocknum = pslot->blocknum; + + if (slot0_blocknum == CL_CACHE_SLOT_EMPTY) + return pslot; + + /* if more than on slot in the cache, handle moving slots to bump the LRU (last) */ + /* If the block at slot 0 hasn't been flushed at least once before, just use slot 0 */ + if (cache->nslots > 1) { + /* rotate the cache to re-use the last slot (LRU) and move it to the top, moving the rest down */ + byte *last_slot_base = cache->slots[cache->nslots - 1].base; /* save the base for the last slot */ + int i; + + /* move the rest down */ + for (i=cache->nslots - 1; i > 0; i--) { + cache->slots[i].blocknum = cache->slots[i-1].blocknum; + cache->slots[i].base = cache->slots[i-1].base; + } + pslot->base = last_slot_base; + } + pslot->blocknum = CL_CACHE_SLOT_EMPTY; + return pslot; +} + +void +cl_cache_load_slot(CL_CACHE *cache, CL_CACHE_SLOT *slot, int64_t pos, byte *data, int len) +{ + slot->blocknum = pos / cache->block_size; + memmove(slot->base, data, len); +} + +/* Use our own FILE structure so that, on some platforms, we write and read + * tmp files via a single file descriptor. That allows cleaning of tmp files + * to be addressed via DELETE_ON_CLOSE under Windows, and immediate unlink + * after opening under Linux. When running in this mode, we keep our own + * record of position within the file for the sake of thread safety + */ + +#define ENC_FILE_STR ("encoded_file_ptr_%p") +#define ENC_FILE_STRX ("encoded_file_ptr_0x%p") + +typedef struct +{ + gs_memory_t *mem; + FILE *f; + int64_t pos; + int64_t filesize; /* filesize maintained by clist_fwrite */ + CL_CACHE *cache; +} IFILE; + +static void +file_to_fake_path(clist_file_ptr file, char fname[gp_file_name_sizeof]) +{ + gs_sprintf(fname, ENC_FILE_STR, file); +} + +static clist_file_ptr +fake_path_to_file(const char *fname) +{ + clist_file_ptr i1, i2; + + int r1 = sscanf(fname, ENC_FILE_STR, &i1); + int r2 = sscanf(fname, ENC_FILE_STRX, &i2); + return r2 == 1 ? i2 : (r1 == 1 ? i1 : NULL); +} + +static IFILE *wrap_file(gs_memory_t *mem, FILE *f, const char *fmode) +{ + IFILE *ifile; + + if (!f) return NULL; + ifile = (IFILE *)gs_alloc_bytes(mem->non_gc_memory, sizeof(*ifile), "Allocate wrapped IFILE"); + if (!ifile) { + fclose(f); + return NULL; + } + ifile->mem = mem->non_gc_memory; + ifile->f = f; + ifile->pos = 0; + ifile->filesize = 0; + ifile->cache = cl_cache_alloc(ifile->mem); + return ifile; +} + +static int close_file(IFILE *ifile) +{ + int res = 0; + if (ifile) { + res = fclose(ifile->f); + if (ifile->cache != NULL) + cl_cache_destroy(ifile->cache); + gs_free_object(ifile->mem, ifile, "Free wrapped IFILE"); + } + return res; +} + /* ------ Open/close/unlink ------ */ static int @@ -40,30 +289,68 @@ if (*fname == 0) { if (fmode[0] == 'r') return_error(gs_error_invalidfileaccess); - *pcf = (clist_file_ptr)gp_open_scratch_file_64(mem, - gp_scratch_file_name_prefix, - fname, fmode); - } else - *pcf = gp_fopen(fname, fmode); + if (gp_can_share_fdesc()) { + *pcf = (clist_file_ptr)wrap_file(mem, gp_open_scratch_file_rm(mem, + gp_scratch_file_name_prefix, + fname, fmode), fmode); + /* If the platform supports FILE duplication then we overwrite the + * file name with an encoded form of the FILE pointer */ + if (*pcf != NULL) + file_to_fake_path(*pcf, fname); + } else { + *pcf = (clist_file_ptr)wrap_file(mem, gp_open_scratch_file_64(mem, + gp_scratch_file_name_prefix, + fname, fmode), fmode); + } + } else { + clist_file_ptr ocf = fake_path_to_file(fname); + if (ocf) { + /* A special (fake) fname is passed in. If so, clone the FILE handle */ + *pcf = wrap_file(mem, gp_fdup(((IFILE *)ocf)->f, fmode), fmode); + /* when cloning, copy other parts not done by wrap_file */ + if (*pcf) + ((IFILE *)(*pcf))->filesize = ((IFILE *)ocf)->filesize; + } else { + *pcf = wrap_file(mem, gp_fopen(fname, fmode), fmode); + } + } + if (*pcf == NULL) { emprintf1(mem, "Could not open the scratch file %s.\n", fname); return_error(gs_error_invalidfileaccess); } + return 0; } static int clist_unlink(const char *fname) { - return (unlink(fname) != 0 ? gs_note_error(gs_error_ioerror) : 0); + clist_file_ptr ocf = fake_path_to_file(fname); + if (ocf) { + /* fname is an encoded file pointer. The file will either have been + * created with the delete-on-close option, or already have been + * unlinked. We need only close the FILE */ + return close_file((IFILE *)ocf) != 0 ? gs_note_error(gs_error_ioerror) : 0; + } else { + return (unlink(fname) != 0 ? gs_note_error(gs_error_ioerror) : 0); + } } static int clist_fclose(clist_file_ptr cf, const char *fname, bool delete) { - return (fclose((FILE *) cf) != 0 ? gs_note_error(gs_error_ioerror) : - delete ? clist_unlink(fname) : - 0); + clist_file_ptr ocf = fake_path_to_file(fname); + if (ocf == cf) { + /* fname is an encoded file pointer, and cf is the FILE used to create it. + * We shouldn't close it unless we have been asked to delete it, in which + * case closing it will delete it */ + return delete ? (close_file((IFILE *)ocf) ? gs_note_error(gs_error_ioerror) : 0) : 0; + } else { + return (close_file((IFILE *) cf) != 0 ? gs_note_error(gs_error_ioerror) : + delete ? clist_unlink(fname) : + 0); + } } /* ------ Writing ------ */ @@ -71,7 +358,23 @@ static int clist_fwrite_chars(const void *data, uint len, clist_file_ptr cf) { - return fwrite(data, 1, len, (FILE *) cf); + int res = 0; + IFILE *icf = (IFILE *)cf; + + if (gp_can_share_fdesc()) { + res = gp_fpwrite((char *)data, len, ((IFILE *)cf)->pos, ((IFILE *)cf)->f); + } else { + res = fwrite(data, 1, len, ((IFILE *)cf)->f); + } + if (res >= 0) + icf->pos += len; + icf->filesize = icf->pos; /* write truncates file */ + if (!CL_CACHE_NEEDS_INIT(icf->cache)) { + /* writing invalidates the read cache */ + cl_cache_destroy(icf->cache); + icf->cache = NULL; + } + return res; } /* ------ Reading ------ */ @@ -79,33 +382,70 @@ static int clist_fread_chars(void *data, uint len, clist_file_ptr cf) { - FILE *f = (FILE *) cf; - byte *str = data; + int nread = 0; - /* The typical implementation of fread */ - /* is extremely inefficient for small counts, */ - /* so we just use straight-line code instead. */ - switch (len) { - default: - return fread(str, 1, len, f); - case 8: - *str++ = (byte) getc(f); - case 7: - *str++ = (byte) getc(f); - case 6: - *str++ = (byte) getc(f); - case 5: - *str++ = (byte) getc(f); - case 4: - *str++ = (byte) getc(f); - case 3: - *str++ = (byte) getc(f); - case 2: - *str++ = (byte) getc(f); - case 1: - *str = (byte) getc(f); + if (gp_can_share_fdesc()) { + IFILE *icf = (IFILE *)cf; + byte *dp = data; + + /* if we have a cache, check if it needs init, and do it */ + if (CL_CACHE_NEEDS_INIT(icf->cache)) { + icf->cache = cl_cache_read_init(icf->cache, CL_CACHE_NSLOTS, 1<filesize); + } + /* cl_cache_read_init may have failed, and set cache to NULL, check before using it */ + if (icf->cache != NULL) { + do { + int n; + + if ((n = cl_cache_read(dp, len-nread, icf->pos+nread, icf->cache)) < 0) + break; + if (n == 0) { + /* pos was not in cache, get a slot and load it, then loop */ + CL_CACHE_SLOT *slot = cl_cache_get_empty_slot(icf->cache, icf->pos+nread); /* cannot fail */ + int64_t block_pos = (icf->pos+nread) & ~(icf->cache->block_size - 1); + int fill_len = gp_fpread((char *)(slot->base), icf->cache->block_size, block_pos, icf->f); + + cl_cache_load_slot(icf->cache, slot, block_pos, slot->base, fill_len); + } + nread += n; + dp += n; + } while (nread < len); + } else { + /* no cache -- just do the read */ + nread = gp_fpread(data, len, icf->pos, icf->f); + } + if (nread >= 0) + icf->pos += nread; + } else { + FILE *f = ((IFILE *)cf)->f; + byte *str = data; + + /* The typical implementation of fread */ + /* is extremely inefficient for small counts, */ + /* so we just use straight-line code instead. */ + switch (len) { + default: + return fread(str, 1, len, f); + case 8: + *str++ = (byte) getc(f); + case 7: + *str++ = (byte) getc(f); + case 6: + *str++ = (byte) getc(f); + case 5: + *str++ = (byte) getc(f); + case 4: + *str++ = (byte) getc(f); + case 3: + *str++ = (byte) getc(f); + case 2: + *str++ = (byte) getc(f); + case 1: + *str = (byte) getc(f); + } + nread = len; } - return len; + return nread; } /* ------ Position/status ------ */ @@ -119,43 +459,88 @@ static int clist_ferror_code(clist_file_ptr cf) { - return (ferror((FILE *) cf) ? gs_error_ioerror : 0); + return (ferror(((IFILE *)cf)->f) ? gs_error_ioerror : 0); } static int64_t clist_ftell(clist_file_ptr cf) { - return gp_ftell_64((FILE *) cf); + IFILE *ifile = (IFILE *)cf; + + return gp_can_share_fdesc() ? ifile->pos : ftell(ifile->f); } static void clist_rewind(clist_file_ptr cf, bool discard_data, const char *fname) { - FILE *f = (FILE *) cf; - - if (discard_data) { - /* - * The ANSI C stdio specification provides no operation for - * truncating a file at a given position, or even just for - * deleting its contents; we have to use a bizarre workaround to - * get the same effect. - */ - char fmode[4]; - - /* Opening with "w" mode deletes the contents when closing. */ - (void)freopen(fname, gp_fmode_wb, f); - strcpy(fmode, "w+"); - strcat(fmode, gp_fmode_binary_suffix); - (void)freopen(fname, fmode, f); + FILE *f = ((IFILE *)cf)->f; + IFILE *ocf = fake_path_to_file(fname); + char fmode[4]; + + strcpy(fmode, "w+"); + strcat(fmode, gp_fmode_binary_suffix); + + if (ocf) { + if (discard_data) { + /* fname is an encoded ifile pointer. We can use an entirely + * new scratch file. */ + char tfname[gp_file_name_sizeof]; + fclose(ocf->f); + ocf->f = gp_open_scratch_file_rm(NULL, gp_scratch_file_name_prefix, tfname, fmode); + /* if there was a cache, get rid of it an get a new (empty) one */ + /* When we start reading, we will allocate a cache based on the filesize */ + if (ocf->cache != NULL) { + cl_cache_destroy(ocf->cache); + ocf->cache = cl_cache_alloc(ocf->mem); + } + ((IFILE *)cf)->filesize = 0; + } + ((IFILE *)cf)->pos = 0; } else { - rewind(f); + if (discard_data) { + /* + * The ANSI C stdio specification provides no operation for + * truncating a file at a given position, or even just for + * deleting its contents; we have to use a bizarre workaround to + * get the same effect. + */ + + /* Opening with "w" mode deletes the contents when closing. */ + f = freopen(fname, gp_fmode_wb, f); + ((IFILE *)cf)->f = freopen(fname, fmode, f); + ((IFILE *)cf)->pos = 0; + ((IFILE *)cf)->filesize = 0; + } else { + rewind(f); + } } } static int clist_fseek(clist_file_ptr cf, int64_t offset, int mode, const char *ignore_fname) { - return gp_fseek_64((FILE *) cf, offset, mode); + IFILE *ifile = (IFILE *)cf; + int res = 0; + + if (!gp_can_share_fdesc()) { + res = gp_fseek_64(ifile->f, offset, mode); + } + /* NB: if gp_can_share_fdesc, we don't actually seek */ + if (res >= 0) { + /* Update the ifile->pos */ + switch (mode) { + case SEEK_SET: + ifile->pos = offset; + break; + case SEEK_CUR: + ifile->pos += offset; + break; + case SEEK_END: + ifile->pos = ifile->filesize; /* filesize maintained in clist_fwrite */ + break; + } + } + return res; } static clist_io_procs_t clist_io_procs_file = { diff -Nru ghostscript-9.10~dfsg/base/gxclimag.c ghostscript-9.25~dfsg+1/base/gxclimag.c --- ghostscript-9.10~dfsg/base/gxclimag.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclimag.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,6 +24,7 @@ #include "gscdefs.h" /* for image type table */ #include "gxarith.h" #include "gxcspace.h" +#include "gxpcolor.h" #include "gxdevice.h" #include "gxdevmem.h" /* must precede gxcldev.h */ #include "gxcldev.h" @@ -43,9 +44,7 @@ #include "gxdevsop.h" #include "gscindex.h" #include "gsicc_cms.h" -#include "gxsample.h" -#include "gximage.h" -#include "gxfrac.h" +#include "gximdecode.h" extern_gx_image_type_table(); @@ -71,7 +70,6 @@ int num_entries = 1 << bps; int k; byte psrc[4]; - int code; switch(base_type) { @@ -122,7 +120,7 @@ } /* Now go through the palette with the check color function */ for (k = 0; k < num_entries; k++) { - code = gs_cspace_indexed_lookup_bytes(pcs, (float) k, psrc); + (void)gs_cspace_indexed_lookup_bytes(pcs, (float) k, psrc); /* this always returns 0 */ if (!is_neutral(psrc, 1)) { /* Has color end this now */ return true; @@ -149,12 +147,10 @@ int orig_x = rx; /* ditto */ int orig_width = rwidth; /* ditto */ int orig_height = rheight; /* ditto */ - int log2_depth = ilog2(depth); int y0; - int data_x_bit; byte copy_op = (depth > 1 ? cmd_op_copy_color_alpha : - cmd_op_copy_mono_planes + cmd_copy_ht_color); /* Plane not needed here */ + cmd_op_copy_mono_planes); /* Plane not needed here */ bool slow_rop = cmd_slow_rop(dev, lop_know_S_0(lop), pdcolor) || cmd_slow_rop(dev, lop_know_S_1(lop), pdcolor); @@ -171,7 +167,7 @@ y0 = ry; /* must do after fit_copy */ /* If non-trivial clipping & complex clipping disabled, default */ - /* Also default for uncached bitmap or non-defaul lop; */ + /* Also default for uncached bitmap or non-default lop; */ /* We could handle more RasterOp cases here directly, but it */ /* doesn't seem worth the trouble right now. */ /* Lastly, the command list will translate calls with depth > 1 to */ @@ -188,7 +184,6 @@ if (cmd_check_clip_path(cdev, pcpath)) cmd_clear_known(cdev, clip_path_known); - data_x_bit = data_x << log2_depth; if (cdev->permanent_error < 0) return (cdev->permanent_error); /* If needed, update the trans_bbox */ @@ -208,39 +203,30 @@ ulong offset_temp; RECT_STEP_INIT(re); - do { - code = cmd_update_lop(cdev, re.pcls, lop); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_update_lop(cdev, re.pcls, lop); + if (code < 0) + return code; if (depth > 1 && !re.pcls->color_is_alpha) { byte *dp; - do { - code = - set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_set_copy_alpha, 1); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_set_copy_alpha, 1); + if (code < 0) + return code; re.pcls->color_is_alpha = 1; } - do { - code = cmd_do_write_unknown(cdev, re.pcls, clip_path_known); - if (code >= 0) - code = cmd_do_enable_clip(cdev, re.pcls, pcpath != NULL); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; - do { - code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, - devn_not_tile); - if (code == gs_error_unregistered) - return code; - if (depth > 1 && code >= 0) - code = cmd_set_color1(cdev, re.pcls, pdcolor->colors.pure); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_do_write_unknown(cdev, re.pcls, clip_path_known); + if (code >= 0) + code = cmd_do_enable_clip(cdev, re.pcls, pcpath != NULL); + if (code < 0) + return code; + code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, + devn_not_tile); + if (code == gs_error_unregistered) + return code; + if (depth > 1 && code >= 0) + code = cmd_set_color1(cdev, re.pcls, pdcolor->colors.pure); + if (code < 0) + return code; re.pcls->color_usage.slow_rop |= slow_rop; /* Put it in the cache if possible. */ if (!cls_has_tile_id(cdev, re.pcls, id, offset_temp)) { @@ -253,11 +239,7 @@ tile.rep_shift = tile.shift = 0; tile.id = id; tile.num_planes = 1; - do { - code = clist_change_bits(cdev, re.pcls, &tile, depth); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code != gs_error_VMerror || !cdev->error_is_retryable) && SET_BAND_CODE(code)) - goto error_in_rect; + code = clist_change_bits(cdev, re.pcls, &tile, depth); if (code < 0) { /* Something went wrong; just copy the bits. */ goto copy; @@ -274,43 +256,33 @@ rect.width = orig_width, rect.height = re.yend - y0; rsize = 1 + cmd_sizexy(rect); if (depth == 1) rsize = rsize + cmd_sizew(0); /* need planar_height 0 setting */ - do { - code = (orig_data_x ? - cmd_put_set_data_x(cdev, re.pcls, orig_data_x) : 0); - if (code >= 0) { - byte *dp; + code = (orig_data_x ? + cmd_put_set_data_x(cdev, re.pcls, orig_data_x) : 0); + if (code >= 0) { + byte *dp; - code = set_cmd_put_op(dp, cdev, re.pcls, op, rsize); - /* - * The following conditional is unnecessary: the two - * statements inside it should go outside the - * HANDLE_RECT. They are here solely to pacify - * stupid compilers that don't understand that dp - * will always be set if control gets past the - * HANDLE_RECT. - */ - if (code >= 0) { - dp++; - if (depth == 1) { - cmd_putw(0, dp); - } - cmd_putxy(rect, dp); + code = set_cmd_put_op(&dp, cdev, re.pcls, op, rsize); + /* + * The following conditional is unnecessary: the two + * statements inside it should go outside the + * HANDLE_RECT. They are here solely to pacify + * stupid compilers that don't understand that dp + * will always be set if control gets past the + * HANDLE_RECT. + */ + if (code >= 0) { + dp++; + if (depth == 1) { + cmd_putw(0, &dp); } + cmd_putxy(rect, &dp); } - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + } + if (code < 0) + return code; re.pcls->rect = rect; - goto end; } -end: - re.y += re.height; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - } while (re.y < re.yend); + } while ((re.y += re.height) < re.yend); return 0; } @@ -323,7 +295,7 @@ gs_pixel_image_t image; /* only uses Width, Height, Interpolate */ gx_drawing_color dcolor; /* only pure right now */ gs_int_rect rect; - const gs_imager_state *pis; + const gs_gstate *pgs; const gx_clip_path *pcpath; /* Set at creation time */ gs_image_format_t format; @@ -353,17 +325,13 @@ int y; bool color_map_is_known; bool monitor_color; - int bps; - int spp; - SAMPLE_UNPACK_PROC((*unpack)); + image_decode_t decode; byte *buffer; /* needed for unpacking during monitoring */ - int spread; - sample_map map[GS_IMAGE_MAX_COMPONENTS]; } clist_image_enum; gs_private_st_suffix_add4(st_clist_image_enum, clist_image_enum, "clist_image_enum", clist_image_enum_enum_ptrs, clist_image_enum_reloc_ptrs, st_gx_image_enum_common, - pis, pcpath, color_space.space, buffer); + pgs, pcpath, color_space.space, buffer); static image_enum_proc_plane_data(clist_image_plane_data); static image_enum_proc_end_image(clist_image_end_image); @@ -378,7 +346,7 @@ { clist_color_space_t pclcs = pie_c->color_space; bool ((*is_neutral)(void*, int)); - int step_size = data_size * pie_c->spp; + int step_size = data_size * pie_c->decode.spp; byte *ptr; bool is_mono; int k; @@ -409,152 +377,6 @@ return false; } -/* We need to have the unpacking proc so that we can monitor the data. */ -static void -get_unpack_proc(clist_image_enum *pie, const float *decode) { - -static sample_unpack_proc_t procs[2][6] = { - { sample_unpack_1, sample_unpack_2, - sample_unpack_4, sample_unpack_8, - 0, 0 - }, - { sample_unpack_1_interleaved, sample_unpack_2_interleaved, - sample_unpack_4_interleaved, sample_unpack_8_interleaved, - 0, 0 - }}; - int num_planes = pie->num_planes; - bool interleaved = (num_planes == 1 && pie->plane_depths[0] != pie->bps); - int i; - int index_bps = (pie->bps < 8 ? pie->bps >> 1 : (pie->bps >> 2) + 1); - gs_image_format_t format = pie->format; - int log2_xbytes = (pie->bps <= 8 ? 0 : arch_log2_sizeof_frac); - - switch (format) { - case gs_image_format_chunky: - pie->spread = 1 << log2_xbytes; - break; - case gs_image_format_component_planar: - pie->spread = (pie->spp) << log2_xbytes; - break; - case gs_image_format_bit_planar: - pie->spread = (pie->spp) << log2_xbytes; - break; - default: - pie->spread = 0; - } - - procs[0][4] = procs[1][4] = sample_unpack_12_proc; - procs[0][5] = procs[1][5] = sample_unpackicc_16_proc; - if (interleaved) { - int num_components = pie->plane_depths[0] / pie->bps; - - for (i = 1; i < num_components; i++) { - if (decode[0] != decode[i * 2 + 0] || - decode[1] != decode[i * 2 + 1]) - break; - } - if (i == num_components) - interleaved = false; /* Use single table. */ - } - pie->unpack = procs[interleaved][index_bps]; -} - -/* We also need the mapping method for the unpacking proc */ -static void -get_map(clist_image_enum *pie, gs_image_format_t format, const float *decode) -{ - int ci, decode_type; - int bps = pie->bps; - int spp = pie->spp; - static const float default_decode[] = { - 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0 - }; - - decode_type = 3; /* 0=custom, 1=identity, 2=inverted, 3=impossible */ - for (ci = 0; ci < spp; ci +=2 ) { - decode_type &= (decode[ci] == 0. && decode[ci + 1] == 1.) | - (decode[ci] == 1. && decode[ci + 1] == 0.) << 1; - } - - /* Initialize the maps from samples to intensities. */ - for (ci = 0; ci < spp; ci++) { - sample_map *pmap = &pie->map[ci]; - - /* If the decoding is [0 1] or [1 0], we can fold it */ - /* into the expansion of the sample values; */ - /* otherwise, we have to use the floating point method. */ - - const float *this_decode = &decode[ci * 2]; - const float *map_decode; /* decoding used to */ - /* construct the expansion map */ - const float *real_decode; /* decoding for expanded samples */ - - map_decode = real_decode = this_decode; - if (!(decode_type & 1)) { - if ((decode_type & 2) && bps <= 8) { - real_decode = default_decode; - } else { - map_decode = default_decode; - } - } - if (bps > 2 || format != gs_image_format_chunky) { - if (bps <= 8) - image_init_map(&pmap->table.lookup8[0], 1 << bps, - map_decode); - } else { /* The map index encompasses more than one pixel. */ - byte map[4]; - register int i; - - image_init_map(&map[0], 1 << bps, map_decode); - switch (bps) { - case 1: - { - register bits32 *p = &pmap->table.lookup4x1to32[0]; - - if (map[0] == 0 && map[1] == 0xff) - memcpy((byte *) p, lookup4x1to32_identity, 16 * 4); - else if (map[0] == 0xff && map[1] == 0) - memcpy((byte *) p, lookup4x1to32_inverted, 16 * 4); - else - for (i = 0; i < 16; i++, p++) - ((byte *) p)[0] = map[i >> 3], - ((byte *) p)[1] = map[(i >> 2) & 1], - ((byte *) p)[2] = map[(i >> 1) & 1], - ((byte *) p)[3] = map[i & 1]; - } - break; - case 2: - { - register bits16 *p = &pmap->table.lookup2x2to16[0]; - - for (i = 0; i < 16; i++, p++) - ((byte *) p)[0] = map[i >> 2], - ((byte *) p)[1] = map[i & 3]; - } - break; - } - } - pmap->decode_base /* = decode_lookup[0] */ = real_decode[0]; - pmap->decode_factor = - (real_decode[1] - real_decode[0]) / - (bps <= 8 ? 255.0 : (float)frac_1); - pmap->decode_max /* = decode_lookup[15] */ = real_decode[1]; - if (decode_type) { - pmap->decoding = sd_none; - pmap->inverted = map_decode[0] != 0; - } else if (bps <= 4) { - int step = 15 / ((1 << bps) - 1); - int i; - - pmap->decoding = sd_lookup; - for (i = 15 - step; i > 0; i -= step) - pmap->decode_lookup[i] = pmap->decode_base + - i * (255.0 / 15) * pmap->decode_factor; - } else - pmap->decoding = sd_compute; - } -} - /* Forward declarations */ static bool image_band_box(gx_device * dev, const clist_image_enum * pie, int y, int h, gs_int_rect * pbox); @@ -617,7 +439,7 @@ /* Start processing an image. */ int -clist_begin_typed_image(gx_device * dev, const gs_imager_state * pis, +clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, @@ -644,16 +466,16 @@ clist_icc_color_t icc_zero_init = { 0 }; cmm_profile_t *src_profile; cmm_srcgtag_profile_t *srcgtag_profile; - gsicc_rendering_intents_t renderingintent = pis->renderingintent; - gsicc_blackptcomp_t blackptcomp = pis->blackptcomp; + gsicc_rendering_intents_t renderingintent = pgs->renderingintent; + gsicc_blackptcomp_t blackptcomp = pgs->blackptcomp; gsicc_rendering_param_t stored_rendering_cond; gsicc_rendering_param_t dev_render_cond; - gs_imager_state *pis_nonconst = (gs_imager_state*) pis; + gs_gstate *pgs_nonconst = (gs_gstate*) pgs; bool intent_changed = false; bool bp_changed = false; cmm_dev_profile_t *dev_profile = NULL; cmm_profile_t *gs_output_profile; - bool is_planar_dev = dev_proc(dev, dev_spec_op)(dev, gxdso_is_native_planar, NULL, 0) > 0; + bool is_planar_dev = dev->is_planar; bool render_is_valid; int csi; @@ -662,6 +484,7 @@ case 1: masked = ((const gs_image1_t *)pim)->ImageMask; has_alpha = ((const gs_image1_t *)pim)->Alpha != 0; + /* fall through */ case 4: if (pmat == 0) break; @@ -675,6 +498,19 @@ "clist_begin_typed_image"); if (pie == 0) return_error(gs_error_VMerror); +#ifdef PACIFY_VALGRIND + /* The following memset is required to avoid a valgrind warning + * in: + * gs -I./gs/lib -sOutputFile=out.pgm -dMaxBitmap=10000 + * -sDEVICE=pgmraw -r300 -Z: -sDEFAULTPAPERSIZE=letter + * -dNOPAUSE -dBATCH -K2000000 -dClusterJob -dJOBSERVER + * tests_private/ps/ps3cet/11-14.PS + * Setting the individual elements of the structure directly is + * not enough, which leads me to believe that we are writing the + * entire struct out, padding and all. + */ + memset(&pie->color_space.icc_info, 0, sizeof(pie->color_space.icc_info)); +#endif pie->memory = mem; pie->buffer = NULL; *pinfo = (gx_image_enum_common_t *) pie; @@ -701,7 +537,7 @@ indexed = false; num_components = gs_color_space_num_components(pcs); } - uses_color = pim->CombineWithColor && rop3_uses_T(pis->log_op); + uses_color = pim->CombineWithColor && rop3_uses_T(pgs->log_op); } code = gx_image_enum_common_init((gx_image_enum_common_t *) pie, (const gs_data_image_t *) pim, @@ -734,7 +570,7 @@ /****** CAN'T HANDLE IMAGES WITH IRREGULAR DEPTHS ******/ goto use_default; if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 || - (code = gs_matrix_multiply(&mat, &ctm_only(pis), &mat)) < 0 || + (code = gs_matrix_multiply(&mat, &ctm_only(pgs), &mat)) < 0 || !(cdev->disable_mask & clist_disable_nonrect_hl_image ? (is_xxyy(&mat) || is_xyyx(&mat)) : image_matrix_ok_to_band(&mat))) @@ -752,8 +588,8 @@ int bytes_per_plane, bytes_per_row; bits_per_pixel = pim->BitsPerComponent * num_components; - pie->bps = bits_per_pixel/num_components; - pie->spp = num_components; + pie->decode.bps = bits_per_pixel/num_components; + pie->decode.spp = num_components; pie->image = *pim; pie->dcolor = *pdcolor; if (prect) @@ -762,7 +598,7 @@ pie->rect.p.x = 0, pie->rect.p.y = 0; pie->rect.q.x = pim->Width, pie->rect.q.y = pim->Height; } - pie->pis = pis; + pie->pgs = pgs; pie->pcpath = pcpath; pie->buffer = NULL; pie->format = format; @@ -813,8 +649,8 @@ dev_render_cond.preserve_black; stored_rendering_cond.cmm = gsCMM_DEFAULT; /* Unless spec. below */ /* We may need to do some substitions for the source profile */ - if (pis->icc_manager->srcgtag_profile != NULL) { - srcgtag_profile = pis->icc_manager->srcgtag_profile; + if (pgs->icc_manager->srcgtag_profile != NULL) { + srcgtag_profile = pgs->icc_manager->srcgtag_profile; if (src_profile->data_cs == gsRGB) { if (srcgtag_profile->rgb_profiles[gsSRC_IMAGPRO] != NULL) { /* We only do this replacement depending upon the @@ -825,9 +661,9 @@ csi == gs_color_space_index_DeviceRGB) { src_profile = srcgtag_profile->rgb_profiles[gsSRC_IMAGPRO]; - pis_nonconst->renderingintent = + pgs_nonconst->renderingintent = srcgtag_profile->rgb_rend_cond[gsSRC_IMAGPRO].rendering_intent; - pis_nonconst->blackptcomp = + pgs_nonconst->blackptcomp = srcgtag_profile->rgb_rend_cond[gsSRC_IMAGPRO].black_point_comp; stored_rendering_cond = srcgtag_profile->rgb_rend_cond[gsSRC_IMAGPRO]; @@ -840,13 +676,13 @@ } else if (src_profile->data_cs == gsCMYK) { if (srcgtag_profile->cmyk_profiles[gsSRC_IMAGPRO] != NULL) { csi = gsicc_get_default_type(src_profile); - if (srcgtag_profile->rgb_rend_cond[gsSRC_IMAGPRO].override_icc || + if (srcgtag_profile->cmyk_rend_cond[gsSRC_IMAGPRO].override_icc || csi == gs_color_space_index_DeviceCMYK) { src_profile = srcgtag_profile->cmyk_profiles[gsSRC_IMAGPRO]; - pis_nonconst->renderingintent = + pgs_nonconst->renderingintent = srcgtag_profile->cmyk_rend_cond[gsSRC_IMAGPRO].rendering_intent; - pis_nonconst->blackptcomp = + pgs_nonconst->blackptcomp = srcgtag_profile->cmyk_rend_cond[gsSRC_IMAGPRO].black_point_comp; stored_rendering_cond = srcgtag_profile->cmyk_rend_cond[gsSRC_IMAGPRO]; @@ -861,31 +697,31 @@ /* If the device RI is set and we are not setting the RI from the source structure, then override any RI specified in the document by the RI specified in the device */ - if (!(pis_nonconst->renderingintent & gsRI_OVERRIDE)) { /* was set by source? */ + if (!(pgs_nonconst->renderingintent & gsRI_OVERRIDE)) { /* was set by source? */ /* No it was not. See if we should override with the device setting */ if (dev_render_cond.rendering_intent != gsRINOTSPECIFIED) { - pis_nonconst->renderingintent = + pgs_nonconst->renderingintent = dev_render_cond.rendering_intent; } } /* We have a similar issue to deal with with respect to the black point. */ - if (!(pis_nonconst->blackptcomp & gsBP_OVERRIDE)) { + if (!(pgs_nonconst->blackptcomp & gsBP_OVERRIDE)) { if (dev_render_cond.black_point_comp != gsBPNOTSPECIFIED) { - pis_nonconst->blackptcomp = + pgs_nonconst->blackptcomp = dev_render_cond.black_point_comp; } } - if (renderingintent != pis_nonconst->renderingintent) + if (renderingintent != pgs_nonconst->renderingintent) intent_changed = true; - if (blackptcomp != pis_nonconst->blackptcomp) + if (blackptcomp != pgs_nonconst->blackptcomp) bp_changed = true; /* Set for the rendering param structure also */ stored_rendering_cond.rendering_intent = - pis_nonconst->renderingintent; + pgs_nonconst->renderingintent; stored_rendering_cond.black_point_comp = - pis_nonconst->blackptcomp; + pgs_nonconst->blackptcomp; stored_rendering_cond.graphics_type_tag = GS_IMAGE_TAG; if (!(src_profile->hash_is_valid)) { int64_t hash; @@ -898,6 +734,7 @@ pie->color_space.icc_info.icc_num_components = src_profile->num_comps; pie->color_space.icc_info.is_lab = src_profile->islab; + pie->color_space.icc_info.default_match = src_profile->default_match; pie->color_space.icc_info.data_cs = src_profile->data_cs; src_profile->rend_cond = stored_rendering_cond; render_is_valid = src_profile->rend_is_valid; @@ -918,7 +755,7 @@ goto use_default; } if (pim->Interpolate) { - if (strcmp("pattern-clist",dev->dname) == 0) + if (gx_device_is_pattern_clist(dev)) goto use_default; pie->support.x = pie->support.y = MAX_ISCALE_SUPPORT + 1; } else { @@ -947,31 +784,37 @@ if (dev_profile == NULL) { gsicc_rendering_param_t temp_render_cond; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &(gs_output_profile), &(temp_render_cond)); } /* Decide if we need to do any monitoring of the colors. Note that multiple source (planes) is treated as color */ - pie->unpack = NULL; + pie->decode.unpack = NULL; if (dev_profile->pageneutralcolor && pie->color_space.icc_info.data_cs != gsGRAY) { /* If it is an index image, then check the pallete only */ if (!indexed) { pie->monitor_color = true; /* Set up the unpacking proc for monitoring */ - get_unpack_proc(pie, pim->Decode); - get_map(pie, pim->format, pim->Decode); - if (pie->unpack == NULL) { + get_unpack_proc((gx_image_enum_common_t*) pie, &(pie->decode), + pim->format, pim->Decode); + get_map(&(pie->decode), pim->format, pim->Decode); + if (pie->decode.unpack == NULL) { /* If we cant unpack, then end monitoring now. Treat as has color */ dev_profile->pageneutralcolor = false; - gsicc_mcm_end_monitor(pis->icc_link_cache, dev); + code = gsicc_mcm_end_monitor(pgs->icc_link_cache, dev); + if (code < 0) + return code; } else { /* We need to allocate the buffer for unpacking during monitoring. This is mainly for the 12bit case */ - int bsize = ((pie->bps > 8 ? (pim->Width) * 2 : pim->Width) + 15) * num_components; + int bsize = ((pie->decode.bps > 8 ? (pim->Width) * 2 : pim->Width) + 15) * num_components; pie->buffer = gs_alloc_bytes(mem, bsize, "image buffer"); if (pie->buffer == 0) { - gs_free_object(mem, pie->buffer, "clist_begin_typed_image"); + gs_free_object(mem, pie, "clist_begin_typed_image"); + *pinfo = NULL; return_error(gs_error_VMerror); } } @@ -981,7 +824,9 @@ if (palette_has_color(pim->ColorSpace, pim)) { /* Has color. We are done monitoring */ dev_profile->pageneutralcolor = false; - gsicc_mcm_end_monitor(pis->icc_link_cache, dev); + code = gsicc_mcm_end_monitor(pgs->icc_link_cache, dev); + if (code < 0) + return code; } } } else { @@ -990,8 +835,8 @@ if (gx_device_must_halftone(dev) && pim->BitsPerComponent == 8 && !masked && (dev->color_info.num_components == 1 || is_planar_dev) && dev_profile->prebandthreshold) { - int dev_width = dbox.q.x - dbox.p.x; - int dev_height = dbox.q.y - dbox.p.y; + int dev_width = (int)(ceil(dbox.q.x) - floor(dbox.p.x)); + int dev_height = (int)(ceil(dbox.q.y) - floor(dbox.p.y)); int src_size = pim->Height * bitmap_raster(pim->Width * pim->BitsPerComponent * @@ -1009,49 +854,36 @@ if (!masked) { /* * Calculate (conservatively) the set of colors that this image - * might generate. For single-component images with up to 4 bits - * per pixel, standard Decode values, and no Interpolate, we - * generate all the possible colors now; otherwise, we assume that - * any color might be generated. It is possible to do better than - * this, but we won't bother unless there's evidence that it's - * worthwhile. + * might generate. For single-component images we can sample + * this. We generate all the possible colors now; otherwise, + * we assume that any color might be generated. It is possible + * to do better than this, but we won't bother unless there's + * evidence that it's worthwhile. */ gx_color_usage_bits all = gx_color_usage_all(cdev); - if (bits_per_pixel > 4 || pim->Interpolate || num_components > 1) + if (num_components > 1) color_usage = all; else { - int max_value = (1 << bits_per_pixel) - 1; - float dmin = pim->Decode[0], dmax = pim->Decode[1]; - float dtemp; - - if (dmax < dmin) - dtemp = dmax, dmax = dmin, dmin = dtemp; - if (dmin != 0 || - dmax != (indexed ? max_value : 1) - ) { - color_usage = all; - } else { - /* Enumerate the possible pixel values. */ - const gs_color_space *pcs = pim->ColorSpace; - cs_proc_remap_color((*remap_color)) = pcs->type->remap_color; - gs_client_color cc; - gx_drawing_color dcolor; - int i; - double denom = (indexed ? 1 : max_value); - - for (i = 0; i <= max_value; ++i) { - cc.paint.values[0] = (double)i / denom; - remap_color(&cc, pcs, &dcolor, pis, dev, - gs_color_select_source); - color_usage |= cmd_drawing_color_usage(cdev, &dcolor); - } + const gs_color_space *pcs = pim->ColorSpace; + cs_proc_remap_color((*remap_color)) = pcs->type->remap_color; + gs_client_color cc; + gx_drawing_color dcolor; + int i; + int max_value = indexed ? pcs->params.indexed.hival : 1; + + for (i = 0; i <= max_value; ++i) { + /* Enumerate the indexed colors, or just Black (DeviceGray = 0) */ + cc.paint.values[0] = (double)i; + remap_color(&cc, pcs, &dcolor, pgs, dev, + gs_color_select_source); + color_usage |= cmd_drawing_color_usage(cdev, &dcolor); } } } pie->color_usage.or = color_usage; pie->color_usage.slow_rop = - cmd_slow_rop(dev, pis->log_op, (uses_color ? pdcolor : NULL)); + cmd_slow_rop(dev, pgs->log_op, (uses_color ? pdcolor : NULL)); pie->color_map_is_known = false; /* * Calculate a (slightly conservative) Y bounding interval for the image @@ -1064,8 +896,8 @@ if (pcpath) { gs_fixed_rect obox; gx_cpath_outer_box(pcpath, &obox); - pie->ymin = max(y0, fixed2int(obox.p.y)); - pie->ymax = min(y1, fixed2int(obox.q.y)); + pie->ymin = max(0, max(y0, fixed2int(obox.p.y))); + pie->ymax = min(min(y1, fixed2int(obox.q.y)), dev->height); } else { pie->ymin = max(y0, 0); pie->ymax = min(y1, dev->height); @@ -1080,11 +912,11 @@ cmd_clear_known(cdev, clist_image_unknowns(dev, pie) | begin_image_known); /* Because the rendering intent may be driven by the source color settings we may have needed to overide the intent. Need to break the const - on the pis here for this and reset back */ + on the pgs here for this and reset back */ if (intent_changed) - pis_nonconst->renderingintent = renderingintent; + pgs_nonconst->renderingintent = renderingintent; if (bp_changed) - pis_nonconst->blackptcomp = blackptcomp; + pgs_nonconst->blackptcomp = blackptcomp; cdev->image_enum_id = pie->id; return 0; @@ -1098,11 +930,12 @@ if (pie != NULL) gs_free_object(mem, pie->buffer, "clist_begin_typed_image"); gs_free_object(mem, pie, "clist_begin_typed_image"); + *pinfo = NULL; - if (pis->has_transparency){ + if (pgs->has_transparency){ return -1; } else { - return gx_default_begin_typed_image(dev, pis, pmat, pic, prect, + return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); } } @@ -1115,11 +948,9 @@ &((gx_device_clist *)dev)->writer; ++cdev->ignore_lo_mem_warnings; - ++cdev->driver_call_nesting; { code = write_image_end_all(dev, pie); } - --cdev->driver_call_nesting; --cdev->ignore_lo_mem_warnings; /* Update sub-rect */ if (!pie->image.Interpolate) @@ -1215,6 +1046,10 @@ clist_update_trans_bbox(cdev, &bbox); } + /* Make sure clip_path for the cdev is not stale -- update from image_enum */ + cdev->clip_path = NULL; + cmd_check_clip_path(cdev, pie->pcpath); + RECT_ENUM_INIT(re, ry, rheight); do { gs_int_rect ibox; @@ -1247,58 +1082,59 @@ /* Write out begin_image & its preamble for this band */ if (!(re.pcls->known & begin_image_known)) { - gs_logical_operation_t lop = pie->pis->log_op; + gs_logical_operation_t lop = pie->pgs->log_op; byte *dp; byte *bp = pie->begin_image_command + pie->begin_image_command_length; uint len; byte image_op = cmd_opv_begin_image; - /* Make sure the imager state is up to date. */ - do { - code = (pie->color_map_is_known ? 0 : - cmd_put_color_mapping(cdev, pie->pis)); - pie->color_map_is_known = true; - if (code >= 0) { - uint want_known = ctm_known | clip_path_known | - op_bm_tk_known | opacity_alpha_known | - shape_alpha_known | alpha_known | - (pie->color_space.id == gs_no_id ? 0 : - color_space_known); + /* Make sure the gs_gstate is up to date. */ + code = (pie->color_map_is_known ? 0 : + cmd_put_color_mapping(cdev, pie->pgs)); + pie->color_map_is_known = true; + if (code >= 0) { + uint want_known = ctm_known | clip_path_known | + op_bm_tk_known | opacity_alpha_known | + shape_alpha_known | alpha_known | + (pie->color_space.id == gs_no_id ? 0 : + color_space_known); - code = cmd_do_write_unknown(cdev, re.pcls, want_known); - } - if (code >= 0) - code = cmd_do_enable_clip(cdev, re.pcls, pie->pcpath != NULL); - if (code >= 0) - code = cmd_update_lop(cdev, re.pcls, lop); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_do_write_unknown(cdev, re.pcls, want_known); + } + if (code >= 0) + code = cmd_do_enable_clip(cdev, re.pcls, pie->pcpath != NULL); + if (code >= 0) + code = cmd_update_lop(cdev, re.pcls, lop); + if (code < 0) + return code; if (pie->uses_color) { - do { - code = cmd_put_drawing_color(cdev, re.pcls, &pie->dcolor, - &re, devn_not_tile); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + /* We want to write the color taking into account the entire image so */ + /* we set re.rect_nbands from pie->ymin and pie->ymax so that we will */ + /* make the decision to write 'all_bands' the same for the whole image */ + /* This is slightly more efficient, and is required for patterns with */ + /* transparency that push the group at the begin_image step. */ + re.rect_nbands = ((pie->ymax + re.band_height - 1) / re.band_height) - + ((pie->ymin) / re.band_height); + code = cmd_put_drawing_color(cdev, re.pcls, &pie->dcolor, + &re, devn_not_tile); + if (code < 0) + return code; } if (entire_box.p.x != 0 || entire_box.p.y != 0 || entire_box.q.x != pie->image.Width || entire_box.q.y != pie->image.Height ) { image_op = cmd_opv_begin_image_rect; - cmd_put2w(entire_box.p.x, entire_box.p.y, bp); + cmd_put2w(entire_box.p.x, entire_box.p.y, &bp); cmd_put2w(pie->image.Width - entire_box.q.x, - pie->image.Height - entire_box.q.y, bp); + pie->image.Height - entire_box.q.y, &bp); } len = bp - pie->begin_image_command; - do { - code = - set_cmd_put_op(dp, cdev, re.pcls, image_op, 1 + len); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = + set_cmd_put_op(&dp, cdev, re.pcls, image_op, 1 + len); + if (code < 0) + return code; memcpy(dp + 1, pie->begin_image_command, len); /* Mark band's begin_image as known */ @@ -1350,64 +1186,42 @@ if (pie->monitor_color) { for (iy = by0, ih = by1 - by0; ih > 0; iy += nrows, ih -= nrows) { nrows = min(ih, rows_per_cmd); - do { - if (!found_color) { - code = cmd_image_plane_data_mon(cdev, re.pcls, planes, info, - bytes_per_plane, offsets, - xoff - xskip, nrows, - &found_color); - if (found_color) { - /* Has color. We are done monitoring */ - cmm_dev_profile_t *dev_profile; - code = dev_proc(dev, get_profile)(dev, &dev_profile); - dev_profile->pageneutralcolor = false; - gsicc_mcm_end_monitor(pie->pis->icc_link_cache, dev); - pie->monitor_color = false; - } - } else { - code = cmd_image_plane_data(cdev, re.pcls, planes, info, - bytes_per_plane, offsets, - xoff - xskip, nrows); + if (!found_color) { + code = cmd_image_plane_data_mon(cdev, re.pcls, planes, info, + bytes_per_plane, offsets, + xoff - xskip, nrows, + &found_color); + if (found_color) { + /* Has color. We are done monitoring */ + cmm_dev_profile_t *dev_profile; + code = dev_proc(dev, get_profile)(dev, &dev_profile); + dev_profile->pageneutralcolor = false; + code |= gsicc_mcm_end_monitor(pie->pgs->icc_link_cache, dev); + pie->monitor_color = false; } - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + } else { + code = cmd_image_plane_data(cdev, re.pcls, planes, info, + bytes_per_plane, offsets, + xoff - xskip, nrows); + } + if (code < 0) + return code; for (i = 0; i < num_planes; ++i) offsets[i] += planes[i].raster * nrows; } } else { for (iy = by0, ih = by1 - by0; ih > 0; iy += nrows, ih -= nrows) { nrows = min(ih, rows_per_cmd); - do { - code = cmd_image_plane_data(cdev, re.pcls, planes, info, - bytes_per_plane, offsets, - xoff - xskip, nrows); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_image_plane_data(cdev, re.pcls, planes, info, + bytes_per_plane, offsets, + xoff - xskip, nrows); + if (code < 0) + return code; for (i = 0; i < num_planes; ++i) offsets[i] += planes[i].raster * nrows; } } } - continue; -error_in_rect: - if (cdev->error_is_retryable) { - code = clist_image_plane_data_retry_cleanup(dev, pie, yh_used, code); - if (code < 0) - SET_BAND_CODE(code); - else if (cdev->driver_call_nesting == 0) { - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)); - if (re.band_code >= 0) { - cmd_clear_known(cdev, clist_image_unknowns(dev, pie) | begin_image_known); - pie->color_map_is_known = false; - cdev->image_enum_id = pie->id; - re.y -= re.height; /* Retry rect. */ - continue; - } - } - } - return re.band_code; } while ((re.y += re.height) < re.yend); done: *rows_used = pie->y - y_orig; @@ -1431,24 +1245,7 @@ return_error(gs_error_Fatal); } #endif - ++cdev->driver_call_nesting; - { - do { - code = write_image_end_all(dev, pie); - } while (code < 0 && cdev->error_is_retryable && - (code = clist_VMerror_recover(cdev, code)) >= 0 - ); - /* if couldn't write successsfully, do a hard flush */ - if (code < 0 && cdev->error_is_retryable) { - int retry_code; - ++cdev->ignore_lo_mem_warnings; - retry_code = write_image_end_all(dev, pie); /* force it out */ - --cdev->ignore_lo_mem_warnings; - if (retry_code >= 0 && cdev->driver_call_nesting == 0) - code = clist_VMerror_recover_flush(cdev, code); - } - } - --cdev->driver_call_nesting; + code = write_image_end_all(dev, pie); cdev->image_enum_id = gs_no_id; gx_image_free_enum(&info); return code; @@ -1458,7 +1255,7 @@ int clist_create_compositor(gx_device * dev, gx_device ** pcdev, const gs_composite_t * pcte, - gs_imager_state * pis, gs_memory_t * mem, gx_device *cldev) + gs_gstate * pgs, gs_memory_t * mem, gx_device *cldev) { byte * dp; uint size = 0, size_dummy; @@ -1466,8 +1263,8 @@ &((gx_device_clist *)dev)->writer; int ry, rheight, cropping_op; int band_height = cdev->page_info.band_params.BandHeight; - int last_band = (cdev->height + band_height - 1) / band_height; - int first_band = 0, no_of_bands = last_band + 1; + int last_band = cdev->nbands - 1; + int first_band = 0, no_of_bands = cdev->nbands; int code = pcte->type->procs.write(pcte, 0, &size, cdev); int temp_cropping_min, temp_cropping_max; @@ -1478,7 +1275,7 @@ /* Create a compositor device for clist writing (if needed) */ code = pcte->type->procs.clist_compositor_write_update(pcte, dev, - pcdev, pis, mem); + pcdev, pgs, mem); if (code < 0) return code; @@ -1488,13 +1285,14 @@ return code; cropping_op = code; + code = 0; if (cropping_op == PUSHCROP || cropping_op == SAMEAS_PUSHCROP_BUTNOPUSH) { first_band = ry / band_height; - last_band = (ry + rheight + band_height - 1) / band_height; + last_band = (ry + rheight - 1) / band_height; } else if (cropping_op == POPCROP || cropping_op == CURRBANDS) { first_band = cdev->cropping_min / band_height; - last_band = (cdev->cropping_max + band_height - 1) / band_height; + last_band = (cdev->cropping_max - 1) / band_height; } if (last_band - first_band > no_of_bands * 2 / 3) { @@ -1527,7 +1325,7 @@ if (cropping_op == ALLBANDS) { /* overprint applies to all bands */ size_dummy = size; - code = set_cmd_put_all_op( dp, + code = set_cmd_put_all_op(& dp, (gx_device_clist_writer *)dev, cmd_opv_extend, size ); @@ -1565,24 +1363,16 @@ RECT_ENUM_INIT(re, temp_cropping_min, temp_cropping_max - temp_cropping_min); do { RECT_STEP_INIT(re); - do { - code = set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_extend, size); - if (code >= 0) { - size_dummy = size; - dp[1] = cmd_opv_ext_create_compositor; - dp[2] = pcte->type->comp_id; - code = pcte->type->procs.write(pcte, dp + 3, &size_dummy, cdev); - } - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; - re.y += re.height; - continue; - error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - } while (re.y < re.yend); + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_extend, size); + if (code >= 0) { + size_dummy = size; + dp[1] = cmd_opv_ext_create_compositor; + dp[2] = pcte->type->comp_id; + code = pcte->type->procs.write(pcte, dp + 3, &size_dummy, cdev); + } + if (code < 0) + return code; + } while ((re.y += re.height) < re.yend); } if (cropping_op == POPCROP) { code = clist_writer_pop_cropping(cdev); @@ -1606,14 +1396,14 @@ if (data_x > 0x1f) { int dx_msb = data_x >> 5; - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_misc, + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_misc, 2 + cmd_size_w(dx_msb)); if (code >= 0) { dp[1] = cmd_set_misc_data_x + 0x20 + (data_x & 0x1f); cmd_put_w(dx_msb, dp + 2); } } else { - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_misc, 2); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_misc, 2); if (code >= 0) dp[1] = cmd_set_misc_data_x + data_x; } @@ -1659,7 +1449,7 @@ req_size = 2 + enc_u_sizew(ht_size); /* output the "put halftone" command */ - if ((code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, req_size)) < 0) + if ((code = set_cmd_put_all_op(&dp, cldev, cmd_opv_extend, req_size)) < 0) return code; dp[1] = cmd_opv_ext_put_halftone; dp += 2; @@ -1675,7 +1465,7 @@ } else { /* send the only segment command */ req_size += ht_size; - code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, req_size); + code = set_cmd_put_all_op(&dp, cldev, cmd_opv_extend, req_size); if (code < 0) return code; dp0 = dp; @@ -1716,7 +1506,7 @@ seg_size = ( ht_size > cbuf_ht_seg_max_size ? cbuf_ht_seg_max_size : ht_size ); tmp_size = 2 + enc_u_sizew(seg_size) + seg_size; - code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, tmp_size); + code = set_cmd_put_all_op(&dp, cldev, cmd_opv_extend, tmp_size); if (code >= 0) { dp[1] = cmd_opv_ext_put_ht_seg; dp += 2; @@ -1739,10 +1529,10 @@ /* Write out any necessary color mapping data. */ int cmd_put_color_mapping(gx_device_clist_writer * cldev, - const gs_imager_state * pis) + const gs_gstate * pgs) { int code; - const gx_device_halftone *pdht = pis->dev_ht; + const gx_device_halftone *pdht = pgs->dev_ht; /* Put out the halftone, if present. */ if (pdht && pdht->id != cldev->device_halftone_id) { @@ -1753,19 +1543,18 @@ } /* Put the under color removal and black generation functions */ code = cmd_put_color_map(cldev, cmd_map_black_generation, - 0, pis->black_generation, + 0, pgs->black_generation, &cldev->black_generation_id); if (code < 0) return code; code = cmd_put_color_map(cldev, cmd_map_undercolor_removal, - 0, pis->undercolor_removal, + 0, pgs->undercolor_removal, &cldev->undercolor_removal_id); if (code < 0) return code; /* Now put out the transfer functions. */ { uint which = 0; - bool all_same = true; bool send_default_comp = false; int i; gs_id default_comp_id, xfer_ids[4]; @@ -1775,22 +1564,20 @@ * have in the set_transfer structure. The halftone xfer funcs * are sent in cmd_put_halftone. */ -#define get_id(pis, color, color_num) \ - ((pis->set_transfer.color != NULL && pis->set_transfer.color_num >= 0) \ - ? pis->set_transfer.color->id\ - : pis->set_transfer.gray->id) - - xfer_ids[0] = get_id(pis, red, red_component_num); - xfer_ids[1] = get_id(pis, green, green_component_num); - xfer_ids[2] = get_id(pis, blue, blue_component_num); - xfer_ids[3] = default_comp_id = pis->set_transfer.gray->id; +#define get_id(pgs, color, color_num) \ + ((pgs->set_transfer.color != NULL && pgs->set_transfer.color_num >= 0) \ + ? pgs->set_transfer.color->id\ + : pgs->set_transfer.gray->id) + + xfer_ids[0] = get_id(pgs, red, red_component_num); + xfer_ids[1] = get_id(pgs, green, green_component_num); + xfer_ids[2] = get_id(pgs, blue, blue_component_num); + xfer_ids[3] = default_comp_id = pgs->set_transfer.gray->id; #undef get_id for (i = 0; i < countof(cldev->transfer_ids); ++i) { if (xfer_ids[i] != cldev->transfer_ids[i]) which |= 1 << i; - if (xfer_ids[i] != default_comp_id) - all_same = false; if (xfer_ids[i] == default_comp_id && cldev->transfer_ids[i] != default_comp_id) send_default_comp = true; @@ -1807,7 +1594,7 @@ gs_id dummy = gs_no_id; code = cmd_put_color_map(cldev, cmd_map_transfer, 0, - pis->set_transfer.gray, &dummy); + pgs->set_transfer.gray, &dummy); if (code < 0) return code; /* Sending a default will force all xfers to default */ @@ -1817,22 +1604,22 @@ /* Send any transfer functions which have changed */ if (cldev->transfer_ids[0] != xfer_ids[0]) { code = cmd_put_color_map(cldev, cmd_map_transfer_0, - pis->set_transfer.red_component_num, - pis->set_transfer.red, &cldev->transfer_ids[0]); + pgs->set_transfer.red_component_num, + pgs->set_transfer.red, &cldev->transfer_ids[0]); if (code < 0) return code; } if (cldev->transfer_ids[1] != xfer_ids[1]) { code = cmd_put_color_map(cldev, cmd_map_transfer_1, - pis->set_transfer.green_component_num, - pis->set_transfer.green, &cldev->transfer_ids[1]); + pgs->set_transfer.green_component_num, + pgs->set_transfer.green, &cldev->transfer_ids[1]); if (code < 0) return code; } if (cldev->transfer_ids[2] != xfer_ids[2]) { code = cmd_put_color_map(cldev, cmd_map_transfer_2, - pis->set_transfer.blue_component_num, - pis->set_transfer.blue, &cldev->transfer_ids[2]); + pgs->set_transfer.blue_component_num, + pgs->set_transfer.blue, &cldev->transfer_ids[2]); if (code < 0) return code; } @@ -1851,7 +1638,7 @@ #define I_FLOOR(x) ((int)floor(x)) #define I_CEIL(x) ((int)ceil(x)) static void -box_merge_point(gs_int_rect * pbox, floatp x, floatp y) +box_merge_point(gs_int_rect * pbox, double x, double y) { int t; @@ -1984,12 +1771,12 @@ if_debug3m('b', dev->memory, " (px) t=%g => (%d,%g)\n", t, px, pa.y + t * dy); if (in_range(t, pa.y + t * dy, py, qy)) - box_merge_point(pbox, (floatp) px, t); + box_merge_point(pbox, (double) px, t); t = (qx - pa.x) / dx; if_debug3m('b', dev->memory, " (qx) t=%g => (%d,%g)\n", t, qx, pa.y + t * dy); if (in_range(t, pa.y + t * dy, py, qy)) - box_merge_point(pbox, (floatp) qx, t); + box_merge_point(pbox, (double) qx, t); } if (dy != 0) { double t = (py - pa.y) / dy; @@ -1997,12 +1784,12 @@ if_debug3m('b', dev->memory, " (py) t=%g => (%g,%d)\n", t, pa.x + t * dx, py); if (in_range(t, pa.x + t * dx, px, qx)) - box_merge_point(pbox, t, (floatp) py); + box_merge_point(pbox, t, (double) py); t = (qy - pa.y) / dy; if_debug3m('b', dev->memory, " (qy) t=%g => (%g,%d)\n", t, pa.x + t * dx, qy); if (in_range(t, pa.x + t * dx, px, qx)) - box_merge_point(pbox, t, (floatp) qy); + box_merge_point(pbox, t, (double) qy); } #undef in_range } @@ -2030,7 +1817,7 @@ { gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer; - const gs_imager_state *const pis = pie->pis; + const gs_gstate *const pgs = pie->pgs; uint unknown = 0; /* @@ -2039,15 +1826,15 @@ * are unknown. Set the device state in anticipation of the values * becoming known. */ - if (cdev->imager_state.ctm.xx != pis->ctm.xx || - cdev->imager_state.ctm.xy != pis->ctm.xy || - cdev->imager_state.ctm.yx != pis->ctm.yx || - cdev->imager_state.ctm.yy != pis->ctm.yy || - cdev->imager_state.ctm.tx != pis->ctm.tx || - cdev->imager_state.ctm.ty != pis->ctm.ty + if (cdev->gs_gstate.ctm.xx != pgs->ctm.xx || + cdev->gs_gstate.ctm.xy != pgs->ctm.xy || + cdev->gs_gstate.ctm.yx != pgs->ctm.yx || + cdev->gs_gstate.ctm.yy != pgs->ctm.yy || + cdev->gs_gstate.ctm.tx != pgs->ctm.tx || + cdev->gs_gstate.ctm.ty != pgs->ctm.ty ) { unknown |= ctm_known; - cdev->imager_state.ctm = pis->ctm; + cdev->gs_gstate.ctm = pgs->ctm; } if (pie->color_space.id == gs_no_id) { /* masked image */ cdev->color_space.space = 0; /* for GC */ @@ -2068,29 +1855,29 @@ * though both parameters are passed in the state as well, this usually * has no effect. */ - if (cdev->imager_state.overprint != pis->overprint || - cdev->imager_state.overprint_mode != pis->overprint_mode || - cdev->imager_state.blend_mode != pis->blend_mode || - cdev->imager_state.text_knockout != pis->text_knockout || - cdev->imager_state.renderingintent != pis->renderingintent) { + if (cdev->gs_gstate.overprint != pgs->overprint || + cdev->gs_gstate.overprint_mode != pgs->overprint_mode || + cdev->gs_gstate.blend_mode != pgs->blend_mode || + cdev->gs_gstate.text_knockout != pgs->text_knockout || + cdev->gs_gstate.renderingintent != pgs->renderingintent) { unknown |= op_bm_tk_known; - cdev->imager_state.overprint = pis->overprint; - cdev->imager_state.overprint_mode = pis->overprint_mode; - cdev->imager_state.blend_mode = pis->blend_mode; - cdev->imager_state.text_knockout = pis->text_knockout; - cdev->imager_state.renderingintent = pis->renderingintent; + cdev->gs_gstate.overprint = pgs->overprint; + cdev->gs_gstate.overprint_mode = pgs->overprint_mode; + cdev->gs_gstate.blend_mode = pgs->blend_mode; + cdev->gs_gstate.text_knockout = pgs->text_knockout; + cdev->gs_gstate.renderingintent = pgs->renderingintent; } - if (cdev->imager_state.opacity.alpha != pis->opacity.alpha) { + if (cdev->gs_gstate.opacity.alpha != pgs->opacity.alpha) { unknown |= opacity_alpha_known; - cdev->imager_state.opacity.alpha = pis->opacity.alpha; + cdev->gs_gstate.opacity.alpha = pgs->opacity.alpha; } - if (cdev->imager_state.shape.alpha != pis->shape.alpha) { + if (cdev->gs_gstate.shape.alpha != pgs->shape.alpha) { unknown |= shape_alpha_known; - cdev->imager_state.shape.alpha = pis->shape.alpha; + cdev->gs_gstate.shape.alpha = pgs->shape.alpha; } - if (cdev->imager_state.alpha != pis->alpha) { + if (cdev->gs_gstate.alpha != pgs->alpha) { unknown |= alpha_known; - cdev->imager_state.alpha = pis->alpha; + cdev->gs_gstate.alpha = pgs->alpha; } return unknown; } @@ -2138,11 +1925,11 @@ return code; offset = ((data_x & ~7) * cldev->clist_color_info.depth) >> 3; } - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_image_data, len); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_image_data, len); if (code < 0) return code; dp++; - cmd_put2w(h, bytes_per_plane, dp); + cmd_put2w(h, bytes_per_plane, &dp); for (plane = 0; plane < pie->num_planes; ++plane) for (i = 0; i < h; ++i) { memcpy(dp, @@ -2171,9 +1958,9 @@ int plane, i; int code; int width = pie_c->rect.q.x - pie_c->rect.p.x; - int dsize = (((width + (planes[0]).data_x) * pie_c->spp * - pie_c->bps / pie->num_planes + 7) >> 3); - int data_size = pie_c->spread / pie->num_planes; + int dsize = (((width + (planes[0]).data_x) * pie_c->decode.spp * + pie_c->decode.bps / pie->num_planes + 7) >> 3); + int data_size = pie_c->decode.spread / pie->num_planes; *found_color = false; @@ -2183,28 +1970,29 @@ return code; offset = ((data_x & ~7) * cldev->clist_color_info.depth) >> 3; } - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_image_data, len); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_image_data, len); if (code < 0) return code; dp++; - cmd_put2w(h, bytes_per_plane, dp); + cmd_put2w(h, bytes_per_plane, &dp); for (i = 0; i < h; ++i) { if (!(*found_color)) { /* Here we need to unpack and actually look at the image data to see if we have any non-neutral colors */ int pdata_x; - byte *data_ptr = planes[0].data + i * planes[0].raster + offsets[0] + offset; - byte *buffer = (*pie_c->unpack)(pie_c->buffer, &pdata_x, data_ptr, 0, dsize, pie_c->map, - pie_c->spread, pie_c->spp); + byte *data_ptr = (byte *)(planes[0].data + i * planes[0].raster + offsets[0] + offset); + byte *buffer = (byte *)(*pie_c->decode.unpack)(pie_c->buffer, &pdata_x, + data_ptr, 0, dsize, pie_c->decode.map, + pie_c->decode.spread, pie_c->decode.spp); for (plane = 1; plane < pie->num_planes; ++plane) { /* unpack planes after the first (if any), relying on spread to place the */ /* data at the correct spacing, with the buffer start adjusted for each plane */ - data_ptr = planes[plane].data + i * planes[plane].raster + offsets[plane] + offset; - (*pie_c->unpack)(pie_c->buffer + (data_size * plane), &pdata_x, data_ptr, 0, - dsize, pie_c->map, pie_c->spread, pie_c->spp); + data_ptr = (byte *)(planes[plane].data + i * planes[plane].raster + offsets[plane] + offset); + (*pie_c->decode.unpack)(pie_c->buffer + (data_size * plane), &pdata_x, data_ptr, 0, + dsize, pie_c->decode.map, pie_c->decode.spread, pie_c->decode.spp); } if (row_has_color(buffer, pie_c, data_size, width)) { /* Has color. We are done monitoring */ @@ -2246,22 +2034,14 @@ RECT_STEP_INIT(re); if (re.pcls->known & begin_image_known) { - do { - if_debug1m('L', dev->memory, "[L]image_end for band %d\n", re.band); - code = set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_image_data, 2); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + if_debug1m('L', dev->memory, "[L]image_end for band %d\n", re.band); + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_image_data, 2); + if (code < 0) + return code; dp[1] = 0; /* EOD */ re.pcls->known ^= begin_image_known; } - re.y += re.height; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - } while (re.y < re.yend); + } while ((re.y += re.height) < re.yend); /* Make sure to clean up the buffer if we were monitoring */ if (pie->buffer != NULL) { gs_free_object(pie->memory, pie->buffer, "write_image_end_all"); diff -Nru ghostscript-9.10~dfsg/base/gxclio.h ghostscript-9.25~dfsg+1/base/gxclio.h --- ghostscript-9.10~dfsg/base/gxclio.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclio.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxclip2.c ghostscript-9.25~dfsg+1/base/gxclip2.c --- ghostscript-9.10~dfsg/base/gxclip2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclip2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -155,7 +155,7 @@ /* Fill a rectangle with high level devn color by tiling with the mask. */ static int tile_clip_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_tile_clip *cdev = (gx_device_tile_clip *) dev; diff -Nru ghostscript-9.10~dfsg/base/gxclip2.h ghostscript-9.25~dfsg+1/base/gxclip2.h --- ghostscript-9.10~dfsg/base/gxclip2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclip2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxclip.c ghostscript-9.25~dfsg+1/base/gxclip.c --- ghostscript-9.10~dfsg/base/gxclip.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclip.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -131,6 +131,7 @@ gx_make_clip_device_on_stack(gx_device_clip * dev, const gx_clip_path *pcpath, gx_device *target) { gx_device_init_on_stack((gx_device *)dev, (const gx_device *)&gs_clip_device, target->memory); + dev->cpath = pcpath; dev->list = *gx_cpath_list(pcpath); dev->translation.x = 0; dev->translation.y = 0; @@ -138,11 +139,21 @@ dev->HWResolution[1] = target->HWResolution[1]; dev->sgr = target->sgr; dev->target = target; + dev->pad = target->pad; + dev->log2_align_mod = target->log2_align_mod; + dev->is_planar = target->is_planar; dev->graphics_type_tag = target->graphics_type_tag; /* initialize to same as target */ /* There is no finalization for device on stack so no rc increment */ (*dev_proc(dev, open_device)) ((gx_device *)dev); } +void +gx_destroy_clip_device_on_stack(gx_device_clip * dev) +{ + if (dev->cpath) + ((gx_clip_path *)dev->cpath)->cached = (dev->current == &dev->list.single ? NULL : dev->current); /* Cast away const */ +} + gx_device * gx_make_clip_device_on_stack_if_needed(gx_device_clip * dev, const gx_clip_path *pcpath, gx_device *target, gs_fixed_rect *rect) { @@ -155,18 +166,15 @@ rect->p.y = pcpath->outer_box.p.y; if (rect->q.y > pcpath->outer_box.q.y) rect->q.y = pcpath->outer_box.q.y; + /* Check for area being trivially clipped away. */ + if (rect->p.x >= rect->q.x || rect->p.y >= rect->q.y) + return NULL; if (pcpath->inner_box.p.x <= rect->p.x && pcpath->inner_box.p.y <= rect->p.y && pcpath->inner_box.q.x >= rect->q.x && pcpath->inner_box.q.y >= rect->q.y) { /* Area is trivially included. No need for clip. */ return target; } - else - { - /* Check for area being trivially clipped away. */ - if (rect->p.x >= rect->q.x || rect->p.y >= rect->q.y) - return NULL; - } gx_device_init_on_stack((gx_device *)dev, (const gx_device *)&gs_clip_device, target->memory); dev->list = *gx_cpath_list(pcpath); dev->translation.x = 0; @@ -175,6 +183,9 @@ dev->HWResolution[1] = target->HWResolution[1]; dev->sgr = target->sgr; dev->target = target; + dev->pad = target->pad; + dev->log2_align_mod = target->log2_align_mod; + dev->is_planar = target->is_planar; dev->graphics_type_tag = target->graphics_type_tag; /* initialize to same as target */ /* There is no finalization for device on stack so no rc increment */ (*dev_proc(dev, open_device)) ((gx_device *)dev); @@ -191,6 +202,9 @@ dev->HWResolution[0] = target->HWResolution[0]; dev->HWResolution[1] = target->HWResolution[1]; dev->sgr = target->sgr; + dev->pad = target->pad; + dev->log2_align_mod = target->log2_align_mod; + dev->is_planar = target->is_planar; gx_device_set_target((gx_device_forward *)dev, target); gx_device_retain((gx_device *)dev, true); /* will free explicitly */ (*dev_proc(dev, open_device)) ((gx_device *)dev); @@ -214,6 +228,8 @@ /* * Enumerate the rectangles of the x,w,y,h argument that fall within * the clipping region. + * NB: if the clip list is transposed, then x, y, xe, and ye are already + * transposed and will need to be switched for the call to "process" */ static int clip_enumerate_rest(gx_device_clip * rdev, @@ -238,8 +254,6 @@ stats_clip.no_x); } #endif - pccd->x = x, pccd->y = y; - pccd->w = xe - x, pccd->h = ye - y; /* * Warp the cursor forward or backward to the first rectangle row * that could include a given y value. Assumes rptr is set, and @@ -311,7 +325,10 @@ #else rptr = rptr->next; #endif - code = process(pccd, xc, yc, xec, yec); + if (rdev->list.transpose) + code = process(pccd, yc, xc, yec, xec); + else + code = process(pccd, xc, yc, xec, yec); if (code < 0) return code; } else { @@ -341,12 +358,25 @@ xe = x + w; y += rdev->translation.y; ye = y + h; + /* pccd is non-transposed */ + pccd->x = x, pccd->y = y; + pccd->w = w, pccd->h = h; + /* transpose x, y, xe, ye for clip checking */ + if (rdev->list.transpose) { + x = pccd->y; + y = pccd->x; + xe = x + h; + ye = y + w; + } /* Check for the region being entirely within the current rectangle. */ if (y >= rptr->ymin && ye <= rptr->ymax && x >= rptr->xmin && xe <= rptr->xmax ) { - pccd->x = x, pccd->y = y, pccd->w = w, pccd->h = h; - return INCR_THEN(in, process(pccd, x, y, xe, ye)); + if (rdev->list.transpose) { + return INCR_THEN(in, process(pccd, y, x, ye, xe)); + } else { + return INCR_THEN(in, process(pccd, x, y, xe, ye)); + } } return clip_enumerate_rest(rdev, x, y, xe, ye, process, pccd); } @@ -360,7 +390,7 @@ /* Initialize the cursor. */ rdev->current = - (rdev->list.head == 0 ? &rdev->list.single : rdev->list.head); + (rdev->list.head == 0 ? &rdev->list.single : (rdev->cpath && rdev->cpath->cached ? rdev->cpath->cached : rdev->list.head)); rdev->color_info = tdev->color_info; rdev->cached_colors = tdev->cached_colors; rdev->width = tdev->width; @@ -379,8 +409,8 @@ (pccd->tdev, xc, yc, xec - xc, yec - yc, pccd->color[0]); } static int -clip_fill_rectangle(gx_device * dev, int x, int y, int w, int h, - gx_color_index color) +clip_fill_rectangle_t0(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) { gx_device_clip *rdev = (gx_device_clip *) dev; clip_callback_data_t ccdata; @@ -395,6 +425,9 @@ xe = x + w; y += rdev->translation.y; ye = y + h; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; /* We open-code the most common cases here. */ if ((y >= rptr->ymin && ye <= rptr->ymax) || ((rptr = rptr->next) != 0 && @@ -414,15 +447,141 @@ x = rptr->xmin; if (xe > rptr->xmax) xe = rptr->xmax; - return - (x >= xe ? 0 : - dev_proc(tdev, fill_rectangle)(tdev, x, y, xe - x, h, color)); + if (x >= xe) + return 0; + return dev_proc(tdev, fill_rectangle)(tdev, x, y, xe - x, h, color); } } ccdata.tdev = tdev; ccdata.color[0] = color; - return clip_enumerate_rest(rdev, x, y, xe, ye, - clip_call_fill_rectangle, &ccdata); + return clip_enumerate_rest(rdev, x, y, xe, ye, clip_call_fill_rectangle, &ccdata); +} + +static int +clip_fill_rectangle_t1(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + clip_callback_data_t ccdata; + /* We handle the fastest cases in-line here. */ + gx_device *tdev = rdev->target; + /*const*/ gx_clip_rect *rptr = rdev->current; + int xe, ye; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + y += rdev->translation.y; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; + x = ccdata.y; + y = ccdata.x; + xe = x + h; + ye = y + w; + /* We open-code the most common cases here. */ + if ((y >= rptr->ymin && ye <= rptr->ymax) || + ((rptr = rptr->next) != 0 && + y >= rptr->ymin && ye <= rptr->ymax) + ) { + rdev->current = rptr; /* may be redundant, but awkward to avoid */ + INCR(in_y); + if (x >= rptr->xmin && xe <= rptr->xmax) { + INCR(in); + return dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color); + } + else if ((rptr->prev == 0 || rptr->prev->ymax != rptr->ymax) && + (rptr->next == 0 || rptr->next->ymax != rptr->ymax) + ) { + INCR(in1); + if (x < rptr->xmin) + x = rptr->xmin; + if (xe > rptr->xmax) + xe = rptr->xmax; + if (x >= xe) + return 0; + return dev_proc(tdev, fill_rectangle)(tdev, y, x, h, xe - x, color); + } + } + ccdata.tdev = tdev; + ccdata.color[0] = color; + return clip_enumerate_rest(rdev, x, y, xe, ye, clip_call_fill_rectangle, &ccdata); +} + +static int +clip_fill_rectangle_s0(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + if (x < rdev->list.single.xmin) + x = rdev->list.single.xmin; + if (w > rdev->list.single.xmax) + w = rdev->list.single.xmax; + if (y < rdev->list.single.ymin) + y = rdev->list.single.ymin; + if (h > rdev->list.single.ymax) + h = rdev->list.single.ymax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + return dev_proc(tdev, fill_rectangle)(tdev, x, y, w, h, color); +} + +static int +clip_fill_rectangle_s1(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + /* Now, treat x/w as y/h and vice versa as transposed. */ + if (x < rdev->list.single.ymin) + x = rdev->list.single.ymin; + if (w > rdev->list.single.ymax) + w = rdev->list.single.ymax; + if (y < rdev->list.single.xmin) + y = rdev->list.single.xmin; + if (h > rdev->list.single.xmax) + h = rdev->list.single.xmax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + return dev_proc(tdev, fill_rectangle)(tdev, y, x, h, w, color); +} +static int +clip_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + + if (rdev->list.transpose) { + if (rdev->list.count == 1) + dev_proc(rdev, fill_rectangle) = clip_fill_rectangle_s1; + else + dev_proc(rdev, fill_rectangle) = clip_fill_rectangle_t1; + } else { + if (rdev->list.count == 1) + dev_proc(rdev, fill_rectangle) = clip_fill_rectangle_s0; + else + dev_proc(rdev, fill_rectangle) = clip_fill_rectangle_t0; + } + return dev_proc(rdev, fill_rectangle)(dev, x, y, w, h, color); } int @@ -436,12 +595,12 @@ rect.q.x = int2fixed(xec); rect.q.y = int2fixed(yec); return (*dev_proc(pccd->tdev, fill_rectangle_hl_color)) - (pccd->tdev, &rect, pccd->pis, pccd->pdcolor, pccd->pcpath); + (pccd->tdev, &rect, pccd->pgs, pccd->pdcolor, pccd->pcpath); } static int -clip_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, +clip_fill_rectangle_hl_color_t0(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_clip *rdev = (gx_device_clip *) dev; @@ -463,6 +622,9 @@ xe = x + w; y += rdev->translation.y; ye = y + h; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; /* We open-code the most common cases here. */ if ((y >= rptr->ymin && ye <= rptr->ymax) || ((rptr = rptr->next) != 0 && @@ -476,7 +638,7 @@ newrect.p.y = int2fixed(y); newrect.q.x = int2fixed(x + w); newrect.q.y = int2fixed(y + h); - return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pis, + return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pgs, pdcolor, pcpath); } else if ((rptr->prev == 0 || rptr->prev->ymax != rptr->ymax) && @@ -494,19 +656,197 @@ newrect.p.y = int2fixed(y); newrect.q.x = int2fixed(xe); newrect.q.y = int2fixed(y + h); - return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pis, + return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pgs, + pdcolor, pcpath); + } + } + } + ccdata.tdev = tdev; + ccdata.pdcolor = pdcolor; + ccdata.pgs = pgs; + ccdata.pcpath = pcpath; + return clip_enumerate_rest(rdev, x, y, xe, ye, + clip_call_fill_rectangle_hl_color, &ccdata); +} + +static int +clip_fill_rectangle_hl_color_t1(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + clip_callback_data_t ccdata; + gx_device *tdev = rdev->target; + gx_clip_rect *rptr = rdev->current; + int xe, ye; + int w, h, x, y; + gs_fixed_rect newrect; + + x = fixed2int(rect->p.x); + y = fixed2int(rect->p.y); + w = fixed2int(rect->q.x) - x; + h = fixed2int(rect->q.y) - y; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + y += rdev->translation.y; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; + /* transpose x, y, xe, ye for clip checking */ + x = ccdata.y; + y = ccdata.x; + xe = x + h; + ye = y + w; + /* We open-code the most common cases here. */ + if ((y >= rptr->ymin && ye <= rptr->ymax) || + ((rptr = rptr->next) != 0 && + y >= rptr->ymin && ye <= rptr->ymax) + ) { + rdev->current = rptr; /* may be redundant, but awkward to avoid */ + INCR(in_y); + if (x >= rptr->xmin && xe <= rptr->xmax) { + INCR(in); + newrect.p.x = int2fixed(y); + newrect.p.y = int2fixed(x); + newrect.q.x = int2fixed(y + h); + newrect.q.y = int2fixed(x + w); + return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pgs, + pdcolor, pcpath); + } + else if ((rptr->prev == 0 || rptr->prev->ymax != rptr->ymax) && + (rptr->next == 0 || rptr->next->ymax != rptr->ymax) + ) { + INCR(in1); + if (x < rptr->xmin) + x = rptr->xmin; + if (xe > rptr->xmax) + xe = rptr->xmax; + if (x >= xe) + return 0; + else { + newrect.p.x = int2fixed(y); + newrect.p.y = int2fixed(x); + newrect.q.x = int2fixed(y+h); + newrect.q.y = int2fixed(xe); + return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pgs, pdcolor, pcpath); } } } ccdata.tdev = tdev; ccdata.pdcolor = pdcolor; - ccdata.pis = pis; + ccdata.pgs = pgs; ccdata.pcpath = pcpath; return clip_enumerate_rest(rdev, x, y, xe, ye, clip_call_fill_rectangle_hl_color, &ccdata); } +static int +clip_fill_rectangle_hl_color_s0(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + int w, h, x, y; + gs_fixed_rect newrect; + + x = fixed2int(rect->p.x); + y = fixed2int(rect->p.y); + w = fixed2int(rect->q.x) - x; + h = fixed2int(rect->q.y) - y; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + if (x < rdev->list.single.xmin) + x = rdev->list.single.xmin; + if (w > rdev->list.single.xmax) + w = rdev->list.single.xmax; + if (y < rdev->list.single.ymin) + y = rdev->list.single.ymin; + if (h > rdev->list.single.ymax) + h = rdev->list.single.ymax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + newrect.p.x = int2fixed(x); + newrect.p.y = int2fixed(y); + newrect.q.x = int2fixed(x + w); + newrect.q.y = int2fixed(y + h); + return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pgs, + pdcolor, pcpath); +} + +static int +clip_fill_rectangle_hl_color_s1(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + int w, h, x, y; + gs_fixed_rect newrect; + + x = fixed2int(rect->p.x); + y = fixed2int(rect->p.y); + w = fixed2int(rect->q.x) - x; + h = fixed2int(rect->q.y) - y; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + /* Now, treat x/w as y/h and vice versa as transposed. */ + if (x < rdev->list.single.ymin) + x = rdev->list.single.ymin; + if (w > rdev->list.single.ymax) + w = rdev->list.single.ymax; + if (y < rdev->list.single.xmin) + y = rdev->list.single.xmin; + if (h > rdev->list.single.xmax) + h = rdev->list.single.xmax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + newrect.p.x = int2fixed(y); + newrect.p.y = int2fixed(x); + newrect.q.x = int2fixed(y + h); + newrect.q.y = int2fixed(x + w); + return dev_proc(tdev, fill_rectangle_hl_color)(tdev, &newrect, pgs, + pdcolor, pcpath); +} + +static int +clip_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, + const gx_clip_path *pcpath) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + + if (rdev->list.transpose) { + if (rdev->list.count == 1) + dev_proc(rdev, fill_rectangle_hl_color) = clip_fill_rectangle_hl_color_s1; + else + dev_proc(rdev, fill_rectangle_hl_color) = clip_fill_rectangle_hl_color_t1; + } else { + if (rdev->list.count == 1) + dev_proc(rdev, fill_rectangle_hl_color) = clip_fill_rectangle_hl_color_s0; + else + dev_proc(rdev, fill_rectangle_hl_color) = clip_fill_rectangle_hl_color_t0; + } + return dev_proc(rdev, fill_rectangle_hl_color)(dev, rect, pgs, pdcolor, pcpath); +} + /* Copy a monochrome rectangle */ int clip_call_copy_mono(clip_callback_data_t * pccd, int xc, int yc, int xec, int yec) @@ -517,10 +857,10 @@ xc, yc, xec - xc, yec - yc, pccd->color[0], pccd->color[1]); } static int -clip_copy_mono(gx_device * dev, - const byte * data, int sourcex, int raster, gx_bitmap_id id, - int x, int y, int w, int h, - gx_color_index color0, gx_color_index color1) +clip_copy_mono_t0(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + gx_color_index color0, gx_color_index color1) { gx_device_clip *rdev = (gx_device_clip *) dev; clip_callback_data_t ccdata; @@ -535,12 +875,53 @@ xe = x + w; y += rdev->translation.y; ye = y + h; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; + if (y >= rptr->ymin && ye <= rptr->ymax) { + INCR(in_y); + if (x >= rptr->xmin && xe <= rptr->xmax) { + INCR(in); + return dev_proc(tdev, copy_mono) + (tdev, data, sourcex, raster, id, x, y, w, h, color0, color1); + } + } + ccdata.tdev = tdev; + ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster; + ccdata.color[0] = color0, ccdata.color[1] = color1; + return clip_enumerate_rest(rdev, x, y, xe, ye, + clip_call_copy_mono, &ccdata); +} +static int +clip_copy_mono_t1(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + gx_color_index color0, gx_color_index color1) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + clip_callback_data_t ccdata; + /* We handle the fastest case in-line here. */ + gx_device *tdev = rdev->target; + const gx_clip_rect *rptr = rdev->current; + int xe, ye; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + y += rdev->translation.y; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; + x = ccdata.y; + y = ccdata.x; + xe = x + h; + ye = y + w; if (y >= rptr->ymin && ye <= rptr->ymax) { INCR(in_y); if (x >= rptr->xmin && xe <= rptr->xmax) { INCR(in); return dev_proc(tdev, copy_mono) - (tdev, data, sourcex, raster, id, x, y, w, h, color0, color1); + (tdev, data, sourcex, raster, id, y, x, h, w, color0, color1); } } ccdata.tdev = tdev; @@ -549,6 +930,100 @@ return clip_enumerate_rest(rdev, x, y, xe, ye, clip_call_copy_mono, &ccdata); } +static int +clip_copy_mono_s0(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + gx_color_index color0, gx_color_index color1) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + if (x < rdev->list.single.xmin) + { + sourcex += (rdev->list.single.xmin - x); + x = rdev->list.single.xmin; + } + if (w > rdev->list.single.xmax) + w = rdev->list.single.xmax; + if (y < rdev->list.single.ymin) + { + data += (rdev->list.single.ymin - y) * raster; + y = rdev->list.single.ymin; + } + if (h > rdev->list.single.ymax) + h = rdev->list.single.ymax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + return dev_proc(tdev, copy_mono) + (tdev, data, sourcex, raster, id, x, y, w, h, color0, color1); +} +static int +clip_copy_mono_s1(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + gx_color_index color0, gx_color_index color1) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + /* Now, treat x/w as y/h and vice versa as transposed. */ + if (x < rdev->list.single.ymin) + { + data += (rdev->list.single.ymin - x) * raster; + x = rdev->list.single.ymin; + } + if (w > rdev->list.single.ymax) + w = rdev->list.single.ymax; + if (y < rdev->list.single.xmin) + { + sourcex += (rdev->list.single.xmin - y); + y = rdev->list.single.xmin; + } + if (h > rdev->list.single.xmax) + h = rdev->list.single.xmax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + return dev_proc(tdev, copy_mono) + (tdev, data, sourcex, raster, id, y, x, h, w, color0, color1); +} +static int +clip_copy_mono(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + gx_color_index color0, gx_color_index color1) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + + if (rdev->list.transpose) { + if (rdev->list.count == 1) + dev_proc(rdev, copy_mono) = clip_copy_mono_s1; + else + dev_proc(rdev, copy_mono) = clip_copy_mono_t1; + } else { + if (rdev->list.count == 1) + dev_proc(rdev, copy_mono) = clip_copy_mono_s0; + else + dev_proc(rdev, copy_mono) = clip_copy_mono_t0; + } + return dev_proc(rdev, copy_mono)(dev, data, sourcex, raster, id, x, y, w, h, color0, color1); +} /* Copy a plane */ int @@ -560,9 +1035,9 @@ xc, yc, xec - xc, yec - yc, pccd->plane_height); } static int -clip_copy_planes(gx_device * dev, - const byte * data, int sourcex, int raster, gx_bitmap_id id, - int x, int y, int w, int h, int plane_height) +clip_copy_planes_t0(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, int plane_height) { gx_device_clip *rdev = (gx_device_clip *) dev; clip_callback_data_t ccdata; @@ -577,12 +1052,53 @@ xe = x + w; y += rdev->translation.y; ye = y + h; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; + if (y >= rptr->ymin && ye <= rptr->ymax) { + INCR(in_y); + if (x >= rptr->xmin && xe <= rptr->xmax) { + INCR(in); + return dev_proc(tdev, copy_planes) + (tdev, data, sourcex, raster, id, x, y, w, h, plane_height); + } + } + ccdata.tdev = tdev; + ccdata.data = data, ccdata.sourcex = sourcex, ccdata.raster = raster; + ccdata.plane_height = plane_height; + return clip_enumerate_rest(rdev, x, y, xe, ye, + clip_call_copy_planes, &ccdata); +} +static int +clip_copy_planes_t1(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, int plane_height) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + clip_callback_data_t ccdata; + /* We handle the fastest case in-line here. */ + gx_device *tdev = rdev->target; + const gx_clip_rect *rptr = rdev->current; + int xe, ye; + + if (w <= 0 || h <= 0) + return 0; + x += rdev->translation.x; + y += rdev->translation.y; + /* ccdata is non-transposed */ + ccdata.x = x, ccdata.y = y; + ccdata.w = w, ccdata.h = h; + /* transpose x, y, xe, ye for clip checking */ + x = ccdata.y; + y = ccdata.x; + xe = x + h; + ye = y + w; if (y >= rptr->ymin && ye <= rptr->ymax) { INCR(in_y); if (x >= rptr->xmin && xe <= rptr->xmax) { INCR(in); return dev_proc(tdev, copy_planes) - (tdev, data, sourcex, raster, id, x, y, w, h, plane_height); + (tdev, data, sourcex, raster, id, y, x, h, w, plane_height); } } ccdata.tdev = tdev; @@ -591,6 +1107,93 @@ return clip_enumerate_rest(rdev, x, y, xe, ye, clip_call_copy_planes, &ccdata); } +static int +clip_copy_planes_s0(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, int plane_height) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + if (x < rdev->list.single.xmin) + { + sourcex += rdev->list.single.xmin - x; + x = rdev->list.single.xmin; + } + if (w > rdev->list.single.xmax) + w = rdev->list.single.xmax; + if (y < rdev->list.single.ymin) + { + data += (rdev->list.single.ymin - y) * raster; + y = rdev->list.single.ymin; + } + if (h > rdev->list.single.ymax) + h = rdev->list.single.ymax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + return dev_proc(tdev, copy_planes) + (tdev, data, sourcex, raster, id, x, y, w, h, plane_height); +} +static int +clip_copy_planes_s1(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, int plane_height) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + gx_device *tdev = rdev->target; + + x += rdev->translation.x; + w += x; + y += rdev->translation.y; + h += y; + /* Now, treat x/w as y/h and vice versa as transposed. */ + if (x < rdev->list.single.ymin) + { + data += (rdev->list.single.ymin - x) * raster; + x = rdev->list.single.ymin; + } + if (w > rdev->list.single.ymax) + w = rdev->list.single.ymax; + if (y < rdev->list.single.xmin) + { + sourcex += rdev->list.single.xmin - y; + y = rdev->list.single.xmin; + } + if (h > rdev->list.single.xmax) + h = rdev->list.single.xmax; + w -= x; + h -= y; + if (w <= 0 || h <= 0) + return 0; + return dev_proc(tdev, copy_planes) + (tdev, data, sourcex, raster, id, y, x, h, w, plane_height); +} +static int +clip_copy_planes(gx_device * dev, + const byte * data, int sourcex, int raster, gx_bitmap_id id, + int x, int y, int w, int h, int plane_height) +{ + gx_device_clip *rdev = (gx_device_clip *) dev; + + if (rdev->list.transpose) { + if (rdev->list.count == 1) + dev_proc(rdev, copy_planes) = clip_copy_planes_s1; + else + dev_proc(rdev, copy_planes) = clip_copy_planes_t1; + } else { + if (rdev->list.count == 1) + dev_proc(rdev, copy_planes) = clip_copy_planes_s0; + else + dev_proc(rdev, copy_planes) = clip_copy_planes_t0; + } + return dev_proc(rdev, copy_planes)(dev, data, sourcex, raster, id, x, y, w, h, plane_height); +} /* Copy a color rectangle */ int @@ -880,15 +1483,21 @@ gx_clip_path cpath_intersection; gx_clip_path *pcpath = (gx_clip_path *)pccd->pcpath; - if (pcpath != NULL) { + /* Previously the code here tested for pcpath != NULL, but + * we can commonly (such as from clist_playback_band) be + * called with a non-NULL, but still invalid clip path. + * Detect this by the list having at least one entry in it. */ + if (pcpath != NULL && pcpath->rect_list->list.count != 0) { gx_path rect_path; - code = gx_cpath_init_local_shared(&cpath_intersection, pcpath, pccd->ppath->memory); + code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, pccd->ppath->memory, 1); if (code < 0) return code; gx_path_init_local(&rect_path, pccd->ppath->memory); - gx_path_add_rectangle(&rect_path, int2fixed(xc), int2fixed(yc), int2fixed(xec), int2fixed(yec)); + code = gx_path_add_rectangle(&rect_path, int2fixed(xc), int2fixed(yc), int2fixed(xec), int2fixed(yec)); + if (code < 0) + return code; code = gx_cpath_intersect(&cpath_intersection, &rect_path, - gx_rule_winding_number, (gs_imager_state *)(pccd->pis)); + gx_rule_winding_number, (gs_gstate *)(pccd->pgs)); gx_path_free(&rect_path, "clip_call_fill_path"); } else { gs_fixed_rect clip_box; @@ -904,13 +1513,13 @@ proc = dev_proc(tdev, fill_path); if (proc == NULL) proc = gx_default_fill_path; - code = (*proc)(pccd->tdev, pccd->pis, pccd->ppath, pccd->params, + code = (*proc)(pccd->tdev, pccd->pgs, pccd->ppath, pccd->params, pccd->pdcolor, &cpath_intersection); gx_cpath_free(&cpath_intersection, "clip_call_fill_path"); return code; } static int -clip_fill_path(gx_device * dev, const gs_imager_state * pis, +clip_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) @@ -919,7 +1528,7 @@ clip_callback_data_t ccdata; gs_fixed_rect box; - ccdata.pis = pis; + ccdata.pgs = pgs; ccdata.ppath = ppath; ccdata.params = params; ccdata.pdcolor = pdcolor; diff -Nru ghostscript-9.10~dfsg/base/gxclip.h ghostscript-9.25~dfsg+1/base/gxclip.h --- ghostscript-9.10~dfsg/base/gxclip.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclip.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -49,7 +49,7 @@ const gx_strip_bitmap *textures; /* ibid. */ const gx_color_index *tcolors; /* ibid. */ int plane_height; /* copy_planes, strip_copy_rop2 */ - const gs_imager_state * pis; /* fill_path, fill_rectangle_hl_color */ + const gs_gstate * pgs; /* fill_path, fill_rectangle_hl_color */ gx_path * ppath; /* fill_path */ const gx_fill_params * params; /* fill_path */ } clip_callback_data_t; diff -Nru ghostscript-9.10~dfsg/base/gxclipm.c ghostscript-9.25~dfsg+1/base/gxclipm.c --- ghostscript-9.10~dfsg/base/gxclipm.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclipm.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -119,7 +119,7 @@ static int mask_clip_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_mask_clip *cdev = (gx_device_mask_clip *) dev; diff -Nru ghostscript-9.10~dfsg/base/gxclipm.h ghostscript-9.25~dfsg+1/base/gxclipm.h --- ghostscript-9.10~dfsg/base/gxclipm.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclipm.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxclipsr.h ghostscript-9.25~dfsg+1/base/gxclipsr.h --- ghostscript-9.10~dfsg/base/gxclipsr.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclipsr.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxclist.c ghostscript-9.25~dfsg+1/base/gxclist.c --- ghostscript-9.10~dfsg/base/gxclist.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclist.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -46,15 +46,17 @@ writer rather than the common. fixme: Also, if icc_cache_cl is not included in the writer, 64bit builds will seg fault */ -extern_st(st_imager_state); +extern_st(st_gs_gstate); static ENUM_PTRS_WITH(device_clist_enum_ptrs, gx_device_clist *cdev) if (index < st_device_forward_max_ptrs) { - gs_ptr_type_t ret = ENUM_USING_PREFIX(st_device_forward, 0); + gs_ptr_type_t ret = ENUM_USING_PREFIX(st_device_forward, st_device_max_ptrs); return (ret ? ret : ENUM_OBJ(0)); } index -= st_device_forward_max_ptrs; + /* RJW: We do not enumerate icc_cache_cl or icc_cache_list as they + * are allocated in non gc space */ if (CLIST_IS_WRITER(cdev)) { switch (index) { case 0: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ? @@ -64,10 +66,9 @@ case 2: return ENUM_OBJ(cdev->writer.pinst); case 3: return ENUM_OBJ(cdev->writer.cropping_stack); case 4: return ENUM_OBJ(cdev->writer.icc_table); - case 5: return ENUM_OBJ(cdev->writer.icc_cache_cl); default: - return ENUM_USING(st_imager_state, &cdev->writer.imager_state, - sizeof(gs_imager_state), index - 5); + return ENUM_USING(st_gs_gstate, &cdev->writer.gs_gstate, + sizeof(gs_gstate), index - 5); } } else { @@ -83,8 +84,6 @@ else if (index == 1) return ENUM_OBJ(cdev->reader.icc_table); else if (index == 2) - return ENUM_OBJ(cdev->reader.icc_cache_cl); - else if (index == 3) return ENUM_OBJ(cdev->reader.color_usage_array); else return 0; @@ -102,9 +101,8 @@ RELOC_VAR(cdev->writer.pinst); RELOC_VAR(cdev->writer.cropping_stack); RELOC_VAR(cdev->writer.icc_table); - RELOC_VAR(cdev->writer.icc_cache_cl); - RELOC_USING(st_imager_state, &cdev->writer.imager_state, - sizeof(gs_imager_state)); + RELOC_USING(st_gs_gstate, &cdev->writer.gs_gstate, + sizeof(gs_gstate)); } else { /* 041207 * clist is reader. @@ -112,7 +110,6 @@ */ RELOC_VAR(cdev->reader.offset_map); RELOC_VAR(cdev->reader.icc_table); - RELOC_VAR(cdev->reader.icc_cache_cl); RELOC_VAR(cdev->reader.color_usage_array); } } RELOC_PTRS_END @@ -123,7 +120,7 @@ /* Forward declarations of driver procedures */ dev_proc_open_device(clist_open); -static dev_proc_output_page(clist_output_page); +dev_proc_output_page(clist_output_page); static dev_proc_close_device(clist_close); static dev_proc_get_band(clist_get_band); /* Driver procedures defined in other files are declared in gxcldev.h. */ @@ -177,16 +174,16 @@ gx_forward_get_hardware_params, gx_default_text_begin, gx_default_finish_copydevice, - NULL, /* begin_transparency_group */ - NULL, /* end_transparency_group */ - NULL, /* begin_transparency_mask */ - NULL, /* end_transparency_mask */ - NULL, /* discard_transparency_layer */ + gx_default_begin_transparency_group, /* begin_transparency_group */ + gx_default_end_transparency_group, /* end_transparency_group */ + gx_default_begin_transparency_mask, /* begin_transparency_mask */ + gx_default_end_transparency_mask, /* end_transparency_mask */ + gx_default_discard_transparency_layer, /* discard_transparency_layer */ gx_forward_get_color_mapping_procs, gx_forward_get_color_comp_index, gx_forward_encode_color, gx_forward_decode_color, - NULL, /* pattern_manage */ + gx_default_pattern_manage, /* pattern_manage */ clist_fill_rectangle_hl_color, gx_default_include_color_space, gx_default_fill_linear_color_scanline, @@ -195,9 +192,9 @@ gx_forward_update_spot_equivalent_colors, gx_forward_ret_devn_params, clist_fillpage, - NULL, /* push_transparency_state */ - NULL, /* pop_transparency_state */ - NULL, /* put_image */ + gx_default_push_transparency_state, /* push_transparency_state */ + gx_default_pop_transparency_state, /* pop_transparency_state */ + gx_default_put_image, /* put_image */ clist_dev_spec_op, clist_copy_planes, /* copy planes */ gx_default_get_profile, @@ -205,6 +202,7 @@ clist_strip_copy_rop2, clist_strip_tile_rect_devn, clist_copy_alpha_hl_color, + clist_process_page, }; /*------------------- Choose the implementation ----------------------- @@ -233,11 +231,6 @@ /* ------ Define the command set and syntax ------ */ -/* Initialization for imager state. */ -/* The initial scale is arbitrary. */ -const gs_imager_state clist_imager_state_initial = -{gs_imager_state_initial(300.0 / 72.0, false)}; - /* * The buffer area (data, data_size) holds a bitmap cache when both writing * and reading. The rest of the space is used for the command buffer and @@ -311,8 +304,8 @@ cdev->tile_table = (tile_hash *) data; data += hsize; bits_size -= hsize; - gx_bits_cache_chunk_init(&cdev->chunk, data, bits_size); - gx_bits_cache_init(&cdev->bits, &cdev->chunk); + gx_bits_cache_chunk_init(cdev->cache_chunk, data, bits_size); + gx_bits_cache_init(&cdev->bits, cdev->cache_chunk); return 0; } @@ -329,7 +322,7 @@ int nbands; ulong space; - if (dev->procs.open_device == pattern_clist_open_device) { + if (dev_proc(dev, open_device) == pattern_clist_open_device) { /* We don't need bands really. */ cdev->page_band_height = dev->height; cdev->nbands = 1; @@ -403,6 +396,7 @@ gx_device_memory bdev; gx_device *pbdev = (gx_device *)&bdev; int code; + int align = 1 << (target->log2_align_mod > log2_align_bitmap_mod ? target->log2_align_mod : log2_align_bitmap_mod); /* the clist writer has its own color info that depends upon the transparency group color space (if transparency exists). The data that is @@ -423,36 +417,71 @@ /* copy_alpha in the commmand list device as well. */ if (dev_proc(pbdev, copy_alpha) == gx_no_copy_alpha) cdev->disable_mask |= clist_disable_copy_alpha; - if (cdev->procs.open_device == pattern_clist_open_device) { + if (dev_proc(cdev, open_device) == pattern_clist_open_device) { bits_size = data_size / 2; - } else if (band_height) { - /* - * The band height is fixed, so the band buffer requirement - * is completely determined. - */ - ulong band_data_size; - - if (gdev_mem_data_size(&bdev, band_width, band_height, &band_data_size) < 0 || - band_data_size >= band_space) { - if (pbdev->finalize) - pbdev->finalize(pbdev); - return_error(gs_error_rangecheck); - } - bits_size = min(band_space - band_data_size, data_size >> 1); + cdev->page_line_ptrs_offset = 0; } else { - /* - * Choose the largest band height that will fit in the - * rendering-time buffer. - */ - bits_size = clist_tile_cache_size(target, band_space); - bits_size = min(bits_size, data_size >> 1); - band_height = gdev_mem_max_height(&bdev, band_width, - band_space - bits_size, page_uses_transparency); - if (band_height == 0) { - if (pbdev->finalize) - pbdev->finalize(pbdev); - return_error(gs_error_rangecheck); + if (band_height) { + /* + * The band height is fixed, so the band buffer requirement + * is completely determined. + */ + ulong band_data_size; + int adjusted; + + adjusted = (dev_proc(dev, dev_spec_op)(dev, gxdso_adjust_bandheight, NULL, band_height)); + if (adjusted > 0) + band_height = adjusted; + + if (gdev_mem_data_size(&bdev, band_width, band_height, &band_data_size) < 0 || + band_data_size >= band_space) { + if (pbdev->finalize) + pbdev->finalize(pbdev); + return_error(gs_error_rangecheck); + } + /* If the tile_cache_size is specified, use it */ + if (cdev->space_params.band.tile_cache_size == 0) { + bits_size = min(band_space - band_data_size, data_size >> 1); + } else { + bits_size = cdev->space_params.band.tile_cache_size; + } + /* The top of the tile_cache is the bottom of the imagable band buffer, + * which needs to be appropriately aligned. Because the band height is + * fixed, we must round *down* the size of the cache to a appropriate + * value. See clist_render_thread() and clist_rasterize_lines() + * for where the value is used. + */ + bits_size = ROUND_DOWN(bits_size, align); + } else { + int adjusted; + /* + * Choose the largest band height that will fit in the + * rendering-time buffer. + */ + bits_size = clist_tile_cache_size(target, band_space); + bits_size = min(bits_size, data_size >> 1); + /* The top of the tile_cache is the bottom of the imagable band buffer, + * which needs to be appropriately aligned. Because the band height is + * fixed, here we round up the size of the cache, since the band height + * is variable, and it should only be a few bytes. See clist_render_thread() + * and clist_rasterize_lines() for where the value is used. + */ + bits_size = ROUND_UP(bits_size, align); + band_height = gdev_mem_max_height(&bdev, band_width, + band_space - bits_size, page_uses_transparency); + if (band_height == 0) { + if (pbdev->finalize) + pbdev->finalize(pbdev); + return_error(gs_error_rangecheck); + } + adjusted = (dev_proc(dev, dev_spec_op)(dev, gxdso_adjust_bandheight, NULL, band_height)); + if (adjusted > 0) + band_height = adjusted; } + /* The above calculated bits_size's include space for line ptrs. What is + * the offset for the line_ptrs within the buffer? */ + if (gdev_mem_bits_size(&bdev, band_width, band_height, &cdev->page_line_ptrs_offset) < 0) + return_error(gs_error_VMerror); } cdev->ins_count = 0; code = clist_init_tile_cache(dev, data, bits_size); @@ -526,7 +555,7 @@ cdev->tile_depth = 0; cdev->tile_known_min = nbands; cdev->tile_known_max = -1; - cdev->imager_state = clist_imager_state_initial; + GS_STATE_INIT_VALUES_CLIST((&cdev->gs_gstate)); cdev->clip_path = NULL; cdev->clip_path_id = gs_no_id; cdev->color_space.byte1 = 0; @@ -549,7 +578,6 @@ cdev->cropping_level = 0; cdev->mask_id_count = cdev->mask_id = cdev->temp_mask_id = 0; cdev->icc_table = NULL; - cdev->icc_cache_cl = NULL; return 0; } /* @@ -565,42 +593,11 @@ if (code >= 0) { cdev->image_enum_id = gs_no_id; - cdev->error_is_retryable = 0; - cdev->driver_call_nesting = 0; cdev->ignore_lo_mem_warnings = 0; } return code; } -/* (Re)init open band files for output (set block size, etc). */ -static int /* ret 0 ok, -ve error code */ -clist_reinit_output_file(gx_device *dev) -{ gx_device_clist_writer * const cdev = - &((gx_device_clist *)dev)->writer; - int code = 0; - - /* bfile needs to guarantee cmd_blocks for: 1 band range, nbands */ - /* & terminating entry */ - int b_block = sizeof(cmd_block) * (cdev->nbands + 2); - - /* cfile needs to guarantee one writer buffer */ - /* + one end_clip cmd (if during image's clip path setup) */ - /* + an end_image cmd for each band (if during image) */ - /* + end_cmds for each band and one band range */ - int c_block = - cdev->cend - cdev->cbuf + 2 + cdev->nbands * 2 + (cdev->nbands + 1); - - /* All this is for partial page rendering's benefit, do only */ - /* if partial page rendering is available */ - if ( clist_test_VMerror_recoverable(cdev) ) - { if (cdev->page_bfile != 0) - code = cdev->page_info.io_procs->set_memory_warning(cdev->page_bfile, b_block); - if (code >= 0 && cdev->page_cfile != 0) - code = cdev->page_info.io_procs->set_memory_warning(cdev->page_cfile, c_block); - } - return code; -} - /* Write out the current parameters that must be at the head of each page */ /* if async rendering is in effect */ static int @@ -611,13 +608,8 @@ int code = 0; if ((cdev->disable_mask & clist_disable_pass_thru_params)) { - do - if ((code = clist_put_current_params(cdev)) >= 0) - break; - while ((code = clist_VMerror_recover(cdev, code)) >= 0); + code = clist_put_current_params(cdev); cdev->permanent_error = (code < 0 ? code : 0); - if (cdev->permanent_error < 0) - cdev->error_is_retryable = 0; } return code; } @@ -655,12 +647,10 @@ true)) < 0 || (code = cdev->page_info.io_procs->fopen(cdev->page_bfname, fmode, &cdev->page_bfile, cdev->bandlist_memory, cdev->bandlist_memory, - false)) < 0 || - (code = clist_reinit_output_file(dev)) < 0 + false)) < 0 ) { clist_close_output_file(dev); cdev->permanent_error = code; - cdev->error_is_retryable = 0; } return code; } @@ -673,10 +663,12 @@ if (ppi->cfile != NULL) { ppi->io_procs->fclose(ppi->cfile, ppi->cfname, true); ppi->cfile = NULL; + ppi->cfname[0] = 0; /* prevent re-use in case this is a fake path */ } if (ppi->bfile != NULL) { ppi->io_procs->fclose(ppi->bfile, ppi->bfname, true); ppi->bfile = NULL; + ppi->bfname[0] = 0; /* prevent re-use in case this is a fake path */ } return 0; } @@ -692,20 +684,6 @@ return clist_close_page_info(&cdev->page_info); } -static void -clist_set_planar(gx_device *dev) -{ - gx_device_clist_common * cdev = &((gx_device_clist *)dev)->common; - int ret; - - ret = dev_proc(dev, dev_spec_op)(dev, gxdso_is_native_planar, NULL, 0); - if (ret > 0) { - cdev->is_planar = ret; - } else { - cdev->is_planar = 0; - } -} - /* Open the device by initializing the device state and opening the */ /* scratch files. */ int @@ -718,27 +696,52 @@ cdev->permanent_error = 0; cdev->is_open = false; - clist_set_planar(dev); + + cdev->cache_chunk = (gx_bits_cache_chunk *)gs_alloc_bytes(cdev->memory->non_gc_memory, sizeof(gx_bits_cache_chunk), "alloc tile cache for clist"); + if (!cdev->cache_chunk) + return_error(gs_error_VMerror); + memset(cdev->cache_chunk, 0x00, sizeof(gx_bits_cache_chunk)); + code = clist_init(dev); if (code < 0) return code; + cdev->icc_cache_list_len = 0; + cdev->icc_cache_list = NULL; code = clist_open_output_file(dev); if ( code >= 0) code = clist_emit_page_header(dev); - if (code >= 0) + if (code >= 0) { dev->is_open = save_is_open; - return code; + } else { + gs_free_object(cdev->memory->non_gc_memory, cdev->cache_chunk, "free tile cache for clist"); + cdev->cache_chunk = NULL; + } + + return code; } static int clist_close(gx_device *dev) { + int i; gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer; + /* I'd like to free the cache chunk in here, but we can't, because the pattern clist + * device gets closed, but not discarded, later it gets run. So we have to free the memory + * in *2* places, once in gdev_prn_tear_down() for regular clists, and once in + * gx_pattern_cache_free_entry() for pattern clists.... + */ + for(i = 0; i < cdev->icc_cache_list_len; i++) { + rc_decrement(cdev->icc_cache_list[i], "clist_close"); + } + cdev->icc_cache_list_len = 0; + gs_free_object(cdev->memory->thread_safe_memory, cdev->icc_cache_list, "clist_close"); + cdev->icc_cache_list = NULL; + if (cdev->do_not_open_or_close_bandfiles) return 0; - if (cdev->procs.open_device == pattern_clist_open_device) { + if (dev_proc(cdev, open_device) == pattern_clist_open_device) { gs_free_object(cdev->bandlist_memory, cdev->data, "clist_close"); cdev->data = NULL; } @@ -746,7 +749,7 @@ } /* The output_page procedure should never be called! */ -static int +int clist_output_page(gx_device * dev, int num_copies, int flush) { return_error(gs_error_Fatal); @@ -776,14 +779,15 @@ the above call to clist_teardown_render_threads. Since they all maintained a copy of the cache and the table there should not be any issues. */ - clist_icc_freetable(crdev->icc_table, crdev->memory); - rc_decrement(crdev->icc_cache_cl,"clist_finish_page"); + clist_free_icc_table(crdev->icc_table, crdev->memory); + crdev->icc_table = NULL; } if (flush) { if (cdev->page_cfile != 0) cdev->page_info.io_procs->rewind(cdev->page_cfile, true, cdev->page_cfname); if (cdev->page_bfile != 0) cdev->page_info.io_procs->rewind(cdev->page_bfile, true, cdev->page_bfname); + cdev->page_info.bfile_end_pos = 0; clist_reset_page(cdev); } else { if (cdev->page_cfile != 0) @@ -793,8 +797,6 @@ } code = clist_init(dev); /* reinitialize */ if (code >= 0) - code = clist_reinit_output_file(dev); - if (code >= 0) code = clist_emit_page_header(dev); return code; @@ -811,34 +813,40 @@ int ecode = 0; code = cmd_write_buffer(cldev, cmd_opv_end_page); + if (code >= 0) + ecode |= code; + else + ecode = code; + /* If we have ICC profiles present in the cfile save the table now, along with the ICC profiles. Table is stored in band maxband + 1. */ if ( cldev->icc_table != NULL ) { /* Save the table */ code = clist_icc_writetable(cldev); /* Free the table */ - clist_icc_freetable(cldev->icc_table, cldev->memory); + clist_free_icc_table(cldev->icc_table, cldev->memory); cldev->icc_table = NULL; } - if (code >= 0) - code = clist_write_color_usage_array(cldev); if (code >= 0) { - /* - * Write the terminating entry in the block file. - * Note that because of copypage, there may be many such entries. - */ - memset(&cb, 0, sizeof(cb)); /* Zero the block, including any padding */ - cb.band_min = cb.band_max = cmd_band_end; - cb.pos = (cldev->page_cfile == 0 ? 0 : cldev->page_info.io_procs->ftell(cldev->page_cfile)); - code = cldev->page_info.io_procs->fwrite_chars(&cb, sizeof(cb), cldev->page_bfile); - if (code > 0) - code = 0; + code = clist_write_color_usage_array(cldev); + if (code >= 0) { + ecode |= code; + /* + * Write the terminating entry in the block file. + * Note that because of copypage, there may be many such entries. + */ + memset(&cb, 0, sizeof(cb)); /* Zero the block, including any padding */ + cb.band_min = cb.band_max = cmd_band_end; + cb.pos = (cldev->page_cfile == 0 ? 0 : cldev->page_info.io_procs->ftell(cldev->page_cfile)); + code = cldev->page_info.io_procs->fwrite_chars(&cb, sizeof(cb), cldev->page_bfile); + if (code > 0) + code = 0; + } } if (code >= 0) { ecode |= code; cldev->page_bfile_end_pos = cldev->page_info.io_procs->ftell(cldev->page_bfile); - } - if (code < 0) + } else ecode = code; /* Reset warning margin to 0 to release reserve memory if mem files */ @@ -871,95 +879,25 @@ dprintf2("%d bands skipped out of %d\n", skip_count, cldev->nbands); } - return 0; + return ecode; } gx_color_usage_bits gx_color_index2usage(gx_device *dev, gx_color_index color) { gx_color_usage_bits bits = 0; - int i; + uchar i; + + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + color = color ^ ~0; /* white is 0 */ for (i = 0; i < dev->color_info.num_components; i++) { if (color & dev->color_info.comp_mask[i]) bits |= (1<= 0 if recovered w/# = cnt pages left in page queue */ -clist_VMerror_recover(gx_device_clist_writer *cldev, - int old_error_code) -{ - int code = old_error_code; - int pages_remain; - - if (!clist_test_VMerror_recoverable(cldev) || - !cldev->error_is_retryable || - old_error_code != gs_error_VMerror - ) - return old_error_code; - - /* Do some rendering, return if enough memory is now free */ - do { - pages_remain = - (*cldev->free_up_bandlist_memory)( (gx_device *)cldev, false ); - if (pages_remain < 0) { - code = pages_remain; /* abort, error or interrupt req */ - break; - } - if (clist_reinit_output_file( (gx_device *)cldev ) == 0) { - code = pages_remain; /* got enough memory to continue */ - break; - } - } while (pages_remain); - - if_debug1m('L', cldev->memory, "[L]soft flush of command list, status: %d\n", code); - return code; -} - -/* If recoverable VM error, flush & try to recover it */ -int /* ret 0 ok, else -ve error */ -clist_VMerror_recover_flush(gx_device_clist_writer *cldev, - int old_error_code) -{ - int free_code = 0; - int reset_code = 0; - int code; - - /* If the device has the ability to render partial pages, flush - * out the bandlist, and reset the writing state. Then, get the - * device to render this band. When done, see if there's now enough - * memory to satisfy the minimum low-memory guarantees. If not, - * get the device to render some more. If there's nothing left to - * render & still insufficient memory, declare an error condition. - */ - if (!clist_test_VMerror_recoverable(cldev) || - old_error_code != gs_error_VMerror - ) - return old_error_code; /* sorry, don't have any means to recover this error */ - free_code = (*cldev->free_up_bandlist_memory)( (gx_device *)cldev, true ); - - /* Reset the state of bands to "don't know anything" */ - reset_code = clist_reset( (gx_device *)cldev ); - if (reset_code >= 0) - reset_code = clist_open_output_file( (gx_device *)cldev ); - if ( reset_code >= 0 && - (cldev->disable_mask & clist_disable_pass_thru_params) - ) - reset_code = clist_put_current_params(cldev); - if (reset_code < 0) { - cldev->permanent_error = reset_code; - cldev->error_is_retryable = 0; - } - - code = (reset_code < 0 ? reset_code : free_code < 0 ? old_error_code : 0); - if_debug1m('L', cldev->memory, "[L]hard flush of command list, status: %d\n", code); - return code; -} - /* Write the target device's current parameter list */ static int /* ret 0 all ok, -ve error */ clist_put_current_params(gx_device_clist_writer *cldev) @@ -1026,24 +964,39 @@ return(false); /* No entry */ } -/* Free the table */ -int -clist_icc_freetable(clist_icctable_t *icc_table, gs_memory_t *memory) +static void +clist_free_icc_table_contents(clist_icctable_t *icc_table) { int number_entries; clist_icctable_entry_t *curr_entry, *next_entry; int k; - if (icc_table == NULL) - return(0); number_entries = icc_table->tablesize; curr_entry = icc_table->head; for (k = 0; k < number_entries; k++) { next_entry = curr_entry->next; - gs_free_object(icc_table->memory, curr_entry, "clist_icc_freetable"); + gsicc_adjust_profile_rc(curr_entry->icc_profile, -1, "clist_free_icc_table"); + gs_free_object(icc_table->memory, curr_entry, "clist_free_icc_table"); curr_entry = next_entry; } - gs_free_object(icc_table->memory, icc_table, "clist_icc_freetable"); +} + +void +clist_icc_table_finalize(const gs_memory_t *memory, void * vptr) +{ + clist_icctable_t *icc_table = (clist_icctable_t *)vptr; + + clist_free_icc_table_contents(icc_table); +} + +/* Free the table */ +int +clist_free_icc_table(clist_icctable_t *icc_table, gs_memory_t *memory) +{ + if (icc_table == NULL) + return(0); + + gs_free_object(icc_table->memory, icc_table, "clist_free_icc_table"); return(0); } @@ -1069,7 +1022,7 @@ curr_entry->serial_data.file_position = clist_icc_addprofile(cldev, curr_entry->icc_profile, &size_data); curr_entry->icc_profile->rend_is_valid = rend_is_valid; curr_entry->serial_data.size = size_data; - rc_decrement(curr_entry->icc_profile, "clist_icc_writetable"); + gsicc_adjust_profile_rc(curr_entry->icc_profile, -1, "clist_icc_writetable"); curr_entry->icc_profile = NULL; curr_entry = curr_entry->next; } @@ -1150,13 +1103,18 @@ "clist_icc_addentry"); if (entry == NULL) return gs_rethrow(-1, "insufficient memory to allocate entry in icc table"); +#ifdef PACIFY_VALGRIND + /* Avoid uninitialised padding upsetting valgrind when it's written + * into the clist. */ + memset(entry, 0, sizeof(*entry)); +#endif entry->next = NULL; entry->serial_data.hashcode = hashcode; entry->serial_data.size = -1; entry->serial_data.file_position = -1; entry->icc_profile = icc_profile; entry->render_is_valid = icc_profile->rend_is_valid; - rc_increment(icc_profile); + gsicc_adjust_profile_rc(icc_profile, 1, "clist_icc_addentry"); icc_table = gs_alloc_struct(stable_mem, clist_icctable_t, &st_clist_icctable, "clist_icc_addentry"); if (icc_table == NULL) @@ -1185,13 +1143,18 @@ "clist_icc_addentry"); if (entry == NULL) return gs_rethrow(-1, "insufficient memory to allocate entry in icc table"); +#ifdef PACIFY_VALGRIND + /* Avoid uninitialised padding upsetting valgrind when it's written + * into the clist. */ + memset(entry, 0, sizeof(*entry)); +#endif entry->next = NULL; entry->serial_data.hashcode = hashcode; entry->serial_data.size = -1; entry->serial_data.file_position = -1; entry->icc_profile = icc_profile; entry->render_is_valid = icc_profile->rend_is_valid; - rc_increment(icc_profile); + gsicc_adjust_profile_rc(icc_profile, 1, "clist_icc_addentry"); icc_table->final->next = entry; icc_table->final = entry; icc_table->tablesize++; @@ -1253,7 +1216,8 @@ if (buf == NULL) return_error(gs_error_VMerror); - if_debug1m('v', cdev->memory, "[v]push cropping[%d]\n", cdev->cropping_level); + if_debug4m('v', cdev->memory, "[v]push cropping[%d], min=%d, max=%d, buf=%0x\n", + cdev->cropping_level, cdev->cropping_min, cdev->cropping_max, buf); buf->next = cdev->cropping_stack; cdev->cropping_stack = buf; buf->cropping_min = cdev->cropping_min; @@ -1289,7 +1253,8 @@ cdev->temp_mask_id = buf->temp_mask_id; cdev->cropping_stack = buf->next; cdev->cropping_level--; - if_debug1m('v', cdev->memory, "[v]pop cropping[%d]\n", cdev->cropping_level); + if_debug4m('v', cdev->memory, "[v]pop cropping[%d] min=%d, max=%d, buf=%0x\n", + cdev->cropping_level, cdev->cropping_min, cdev->cropping_max, buf); gs_free_object(cdev->memory, buf, "clist_writer_transparency_pop"); return 0; } @@ -1358,3 +1323,85 @@ when the buffer is not fully written, except with an error. */ return pinfo->io_procs->fwrite_chars(buf, length, pfile); } + +gx_device_clist * +clist_make_accum_device(gx_device *target, const char *dname, void *base, int space, + gx_device_buf_procs_t *buf_procs, gx_band_params_t *band_params, + bool use_memory_clist, bool uses_transparency, + gs_pattern1_instance_t *pinst) +{ + gs_memory_t *mem = target->memory; + gx_device_clist *cdev = gs_alloc_struct(mem, gx_device_clist, + &st_device_clist, "clist_make_accum_device"); + gx_device_clist_writer *cwdev = (gx_device_clist_writer *)cdev; + + if (cdev == 0) + return 0; + memset(cdev, 0, sizeof(*cdev)); + cwdev->params_size = sizeof(gx_device_clist); + cwdev->static_procs = NULL; + cwdev->dname = dname; + cwdev->memory = mem; + cwdev->stype = &st_device_clist; + cwdev->stype_is_dynamic = false; + rc_init(cwdev, mem, 1); + cwdev->retained = true; + cwdev->is_open = false; + cwdev->color_info = target->color_info; + cwdev->pinst = pinst; + cwdev->cached_colors = target->cached_colors; + if (pinst != NULL) { + cwdev->width = pinst->size.x; + cwdev->height = pinst->size.y; + cwdev->band_params.BandHeight = pinst->size.y; + } else { + cwdev->width = target->width; + cwdev->height = target->height; + } + cwdev->LeadingEdge = target->LeadingEdge; + cwdev->is_planar = target->is_planar; + cwdev->HWResolution[0] = target->HWResolution[0]; + cwdev->HWResolution[1] = target->HWResolution[1]; + cwdev->icc_cache_cl = NULL; + cwdev->icc_table = NULL; + cwdev->UseCIEColor = target->UseCIEColor; + cwdev->LockSafetyParams = true; + cwdev->procs = gs_clist_device_procs; + gx_device_copy_color_params((gx_device *)cwdev, target); + rc_assign(cwdev->target, target, "clist_make_accum_device"); + clist_init_io_procs(cdev, use_memory_clist); + cwdev->data = base; + cwdev->data_size = space; + memcpy (&(cwdev->buf_procs), buf_procs, sizeof(gx_device_buf_procs_t)); + cwdev->page_uses_transparency = uses_transparency; + cwdev->band_params.BandWidth = cwdev->width; + cwdev->band_params.BandBufferSpace = 0; + cwdev->do_not_open_or_close_bandfiles = false; + cwdev->bandlist_memory = mem->non_gc_memory; + set_dev_proc(cwdev, get_clipping_box, gx_default_get_clipping_box); + set_dev_proc(cwdev, get_profile, gx_forward_get_profile); + set_dev_proc(cwdev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); + cwdev->graphics_type_tag = target->graphics_type_tag; /* initialize to same as target */ + cwdev->interpolate_control = target->interpolate_control; /* initialize to same as target */ + + /* to be set by caller: cwdev->finalize = finalize; */ + + /* Fields left zeroed : + int max_fill_band; + int is_printer; + float MediaSize[2]; + float ImagingBBox[4]; + bool ImagingBBox_set; + float Margins[2]; + float HWMargins[4]; + long PageCount; + long ShowpageCount; + int NumCopies; + bool NumCopies_set; + bool IgnoreNumCopies; + int disable_mask; + gx_page_device_procs page_procs; + + */ + return cdev; +} diff -Nru ghostscript-9.10~dfsg/base/gxclist.h ghostscript-9.25~dfsg+1/base/gxclist.h --- ghostscript-9.10~dfsg/base/gxclist.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclist.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,8 +24,9 @@ #include "gxband.h" #include "gxbcache.h" #include "gxclio.h" +#include "gxcolor2.h" /* for pattern1_instance */ #include "gxdevbuf.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxrplane.h" #include "gscms.h" @@ -59,11 +60,6 @@ * questions is negative, we flush the buffer. */ -#ifndef gs_pattern1_instance_t_DEFINED -# define gs_pattern1_instance_t_DEFINED -typedef struct gs_pattern1_instance_s gs_pattern1_instance_t; -#endif - /* ---------------- Public structures ---------------- */ /* @@ -75,9 +71,25 @@ */ typedef struct gx_saved_page_s { char dname[32]; /* device name for checking */ - gx_device_color_info color_info; - gx_band_page_info_t info; - int num_copies; + gx_device_color_info color_info; /* also for checking */ + gs_graphics_type_tag_t tag; + /* Elements from gx_band_page_info that we need */ + char cfname[gp_file_name_sizeof]; /* command file name */ + char bfname[gp_file_name_sizeof]; /* block file name */ + const clist_io_procs_t *io_procs; + uint tile_cache_size; /* size of tile cache */ + int64_t bfile_end_pos; /* ftell at end of bfile */ + gx_band_params_t band_params; /* parameters used when writing band list */ + /* (actual values, no 0s) */ + gs_memory_t *mem; /* allocator for paramlist */ + /* device params are expected to include info to set the icc_struct and the devn_params */ + /* as well as color_info (if it is able to change as the 'bit' devices can). */ + int paramlist_len; + byte *paramlist; /* serialized device param list */ + /* for DeviceN devices, we need the spot colors collected during parsing */ + int num_separations; + int separation_name_sizes[GS_SOFT_MAX_SPOTS]; + byte *separation_names[GS_SOFT_MAX_SPOTS]; /* AKA Spot Color names */ } gx_saved_page; /* @@ -88,13 +100,6 @@ gs_int_point offset; } gx_placed_page; -/* - * Define a procedure to cause some bandlist memory to be freed up, - * probably by rendering current bandlist contents. - */ -#define proc_free_up_bandlist_memory(proc)\ - int proc(gx_device *dev, bool flush_current) - /* ---------------- Internal structures ---------------- */ /* @@ -119,6 +124,7 @@ /* 0 means unused */ /* reading: offset from cdev->chunk.data */ } tile_hash; + typedef struct { gx_cached_bits_common; /* To save space, instead of storing rep_width and rep_height, */ @@ -150,11 +156,11 @@ /* * In order to keep the per-band state down to a reasonable size, - * we store only a single set of the imager state parameters; + * we store only a single set of the gs_gstate parameters; * for each parameter, each band has a flag that says whether that band * 'knows' the current value of the parameters. */ -extern const gs_imager_state clist_imager_state_initial; +#define GS_STATE_INIT_VALUES_CLIST(s) GS_STATE_INIT_VALUES(s, 300.0 / 72.0) /* * Define the main structure for holding command list state. @@ -175,11 +181,9 @@ uint data_size; /* size of buffer */\ gx_band_params_t band_params; /* band buffering parameters */\ bool do_not_open_or_close_bandfiles; /* if true, do not open/close bandfiles */\ - bool page_uses_transparency; /* if true then page uses PDF 1.4 transparency */\ - int is_planar; /* if non zero then we have a planar device - * with is_planar bits per component. */\ + int is_printer; /* if true, then clist is based on a prn device */\ /* Following are used for both writing and reading. */\ - gx_bits_cache_chunk chunk; /* the only chunk of bits */\ + gx_bits_cache_chunk *cache_chunk; /* the only chunk of bits */\ gx_bits_cache bits;\ uint tile_hash_mask; /* size of tile hash table -1 */\ uint tile_band_mask_size; /* size of band mask preceding */\ @@ -195,13 +199,9 @@ clist_icctable_t *icc_table; /* Table that keeps track of ICC profiles.\ It relates the hashcode to the cfile\ file location. */\ - gsicc_link_cache_t *icc_cache_cl /* Link cache */ - -/* - * Chech whether a clist is used for storing a pattern command stream. - * Useful for both reader and writer. - */ -#define IS_CLIST_FOR_PATTERN(cdev) (cdev->procs.open_device == pattern_clist_open_device) + gsicc_link_cache_t *icc_cache_cl; /* Link cache */\ + int icc_cache_list_len; /* Length of list of caches, one per rendering thread */\ + gsicc_link_cache_t **icc_cache_list /* Link cache list */ /* Define a structure to hold where the ICC profiles are stored in the clist Profiles are added into psuedo bands of the clist, these are bands that exist beyond @@ -215,17 +215,14 @@ typedef struct clist_icc_serial_entry_s clist_icc_serial_entry_t; struct clist_icc_serial_entry_s { - int64_t hashcode; /* A hash code for the icc profile */ int64_t file_position; /* File position in cfile of the profile with header */ int size; - }; typedef struct clist_icctable_entry_s clist_icctable_entry_t; struct clist_icctable_entry_s { - clist_icc_serial_entry_t serial_data; clist_icctable_entry_t *next; /* The next entry in the table */ cmm_profile_t *icc_profile; /* The profile. In non-gc memory. This is @@ -251,10 +248,13 @@ clist_icctable_entry_t *final; }; +void +clist_icc_table_finalize(const gs_memory_t *memory, void * vptr); + #define private_st_clist_icctable()\ - gs_private_st_ptrs2(st_clist_icctable,\ + gs_private_st_ptrs2_final(st_clist_icctable,\ clist_icctable_t, "clist_icctable",\ - clist_icctable_enum_ptrs, clist_icctable_reloc_ptrs, head, final) + clist_icctable_enum_ptrs, clist_icctable_reloc_ptrs, clist_icc_table_finalize, head, final) typedef struct gx_device_clist_common_s { gx_device_clist_common_members; @@ -290,6 +290,7 @@ int64_t icc_hash; /* hash code for icc profile */ byte icc_num_components; /* needed to avoid having to read icc data early */ bool is_lab; /* also needed early */ + gsicc_profile_t default_match; /* used by gsicc_get_link early for usefastcolor mode */ gsicc_colorbuffer_t data_cs; } clist_icc_color_t; @@ -318,16 +319,17 @@ /* current tile parameters */ /* * NOTE: we must not set the line_params.dash.pattern member of the - * imager state to point to the dash_pattern member of the writer + * gs_gstate to point to the dash_pattern member of the writer * state (except transiently), since this would confuse the * garbage collector. */ - gs_imager_state imager_state; /* current values of imager params */ + gs_gstate gs_gstate; /* current values of gs_gstate params */ bool pdf14_needed; /* if true then not page level opaque mode */ /* above set when not at page level with no SMask or when */ /* the page level BM, shape or opacity alpha needs tranaparency */ int pdf14_trans_group_level;/* 0 when at page level group -- push increments, pop decrements */ int pdf14_smask_level; /* 0 when at SMask None -- push increments, pop decrements */ + bool page_pdf14_needed; /* save page level pdf14_needed state */ float dash_pattern[cmd_max_dash]; /* current dash pattern */ const gx_clip_path *clip_path; /* current clip path, */ @@ -341,14 +343,9 @@ gs_id device_halftone_id; /* id of device halftone */ gs_id image_enum_id; /* non-0 if we are inside an image */ /* that we are passing through */ - int error_is_retryable; /* Extra status used to distinguish hard VMerrors */ - /* from warnings upgraded to VMerrors. */ - /* T if err ret'd by cmd_put_op et al can be retried */ int permanent_error; /* if < 0, error only cleared by clist_reset() */ - int driver_call_nesting; /* nesting level of non-retryable driver calls */ int ignore_lo_mem_warnings; /* ignore warnings from clist file/mem */ /* Following must be set before writing */ - proc_free_up_bandlist_memory((*free_up_bandlist_memory)); /* if nz, proc to free some bandlist memory */ int disable_mask; /* mask of routines to disable clist_disable_xxx */ gs_pattern1_instance_t *pinst; /* Used when it is a pattern clist. */ int cropping_min, cropping_max; @@ -425,12 +422,12 @@ "gx_device_clist", 0, device_clist_enum_ptrs, device_clist_reloc_ptrs,\ gx_device_finalize) #define st_device_clist_max_ptrs\ - (st_device_forward_max_ptrs + st_imager_state_num_ptrs + 4) + (st_device_forward_max_ptrs + st_gs_gstate_num_ptrs + 4) #define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0) /* setup before opening clist device */ -#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xfree_bandlist, xdisable, pageusestransparency)\ +#define clist_init_params(xclist, xdata, xdata_size, xtarget, xbuf_procs, xband_params, xexternal, xmemory, xdisable, pageusestransparency)\ BEGIN\ (xclist)->common.data = (xdata);\ (xclist)->common.data_size = (xdata_size);\ @@ -439,16 +436,11 @@ (xclist)->common.band_params = (xband_params);\ (xclist)->common.do_not_open_or_close_bandfiles = (xexternal);\ (xclist)->common.bandlist_memory = (xmemory);\ - (xclist)->writer.free_up_bandlist_memory = (xfree_bandlist);\ (xclist)->writer.disable_mask = (xdisable);\ (xclist)->writer.page_uses_transparency = (pageusestransparency);\ (xclist)->writer.pinst = NULL;\ END -/* Determine whether this clist device is able to recover VMerrors */ -#define clist_test_VMerror_recoverable(cldev)\ - ((cldev)->free_up_bandlist_memory != 0) - /* The device template itself is never used, only the procedures. */ extern const gx_device_procs gs_clist_device_procs; @@ -495,6 +487,14 @@ /* This function updates the clist writer states with the bbox provided. */ void clist_update_trans_bbox(gx_device_clist_writer *dev, gs_int_rect *bbox); +/* Make a clist device for accumulating. Used for pattern-clist as well as */ +/* for pdf14 pages that are too large to be done in page mode. */ +gx_device_clist * +clist_make_accum_device(gx_device *target, const char *dname, void *base, int space, + gx_device_buf_procs_t *buf_procs, gx_band_params_t *band_params, + bool use_memory_clist, bool uses_transparency, + gs_pattern1_instance_t *pinst); + /* Retrieve total size for cfile and bfile. */ int clist_data_size(const gx_device_clist *cdev, int select); /* Get command list data. */ @@ -526,7 +526,7 @@ cmm_profile_t *icc_profile); /* Free the table and its entries */ -int clist_icc_freetable(clist_icctable_t *icc_table, gs_memory_t *memory); +int clist_free_icc_table(clist_icctable_t *icc_table, gs_memory_t *memory); /* Generic read function used with ICC and could be used with others. A different of this and clist_get_data is that here we reset the diff -Nru ghostscript-9.10~dfsg/base/gxcllzw.c ghostscript-9.25~dfsg+1/base/gxcllzw.c --- ghostscript-9.10~dfsg/base/gxcllzw.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcllzw.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxclmem.c ghostscript-9.25~dfsg+1/base/gxclmem.c --- ghostscript-9.10~dfsg/base/gxclmem.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclmem.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -159,8 +159,8 @@ #define MALLOC(f, siz, cname)\ (void *)gs_alloc_bytes((f)->data_memory, siz, cname) #define FREE(f, obj, cname)\ - (gs_free_object((f)->data_memory, obj, cname),\ - (f)->total_space -= sizeof(*(obj))) + do {gs_free_object((f)->data_memory, obj, cname);\ + (f)->total_space -= sizeof(*(obj));} while (0) /* Structure descriptor for GC */ private_st_MEMFILE(); @@ -253,7 +253,7 @@ MEMFILE *base_f = NULL; /* reopening an existing file. */ - code = gs_sscanf(fname+1, "%p", &base_f); + code = sscanf(fname+1, "%p", &base_f); if (code != 1) { code = gs_note_error(gs_error_ioerror); goto finish; @@ -534,7 +534,7 @@ MEMFILE *f; /* memfile file names begin with a flag byte == 0xff */ - if (fname[0] == '\377' && (code = gs_sscanf(fname+1, "%p", &f) == 1)) { + if (fname[0] == '\377' && (code = sscanf(fname+1, "%p", &f) == 1)) { return memfile_fclose((clist_file_ptr)f, fname, true); } else return_error(gs_error_invalidfileaccess); diff -Nru ghostscript-9.10~dfsg/base/gxclmem.h ghostscript-9.25~dfsg+1/base/gxclmem.h --- ghostscript-9.10~dfsg/base/gxclmem.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclmem.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxclpage.c ghostscript-9.25~dfsg+1/base/gxclpage.c --- ghostscript-9.10~dfsg/base/gxclpage.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclpage.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,47 +9,124 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Page object management */ #include "gdevprn.h" +#include "gdevdevn.h" #include "gxcldev.h" #include "gxclpage.h" +#include "gsicc_cache.h" +#include "gsparams.h" +#include "string_.h" +#include /* for isalpha, etc. */ + +/* Save the current clist state into a saved page structure, + * and optionally stashes the files into the given save_files + * pointers. + * Does NOT alter the clist files. */ +/* RJW: Does too. The opendevice call at the end calls clist_open */ +static int +do_page_save(gx_device_printer * pdev, gx_saved_page * page, clist_file_ptr *save_files) +{ + gx_device_clist *cdev = (gx_device_clist *) pdev; + gx_device_clist_writer * const pcldev = (gx_device_clist_writer *)pdev; + int code; + gs_c_param_list paramlist; + gs_devn_params *pdevn_params; + + /* Save the device information. */ + strncpy(page->dname, pdev->dname, sizeof(page->dname)-1); + page->color_info = pdev->color_info; + page->tag = pdev->graphics_type_tag; + page->io_procs = cdev->common.page_info.io_procs; + /* Save the page information. */ + strncpy(page->cfname, pcldev->page_info.cfname, sizeof(page->cfname)-1); + strncpy(page->bfname, pcldev->page_info.bfname, sizeof(page->bfname)-1); + page->bfile_end_pos = pcldev->page_info.bfile_end_pos; + if (save_files != NULL) { + save_files[0] = pcldev->page_info.cfile; + save_files[1] = pcldev->page_info.bfile; + pcldev->page_info.cfile = NULL; + pcldev->page_info.bfile = NULL; + } + pcldev->page_info.cfname[0] = 0; + pcldev->page_info.bfname[0] = 0; + page->tile_cache_size = pcldev->page_info.tile_cache_size; + page->band_params = pcldev->page_info.band_params; + /* Now serialize and save the rest of the information from the device params */ + /* we count on this to correctly set the color_info, devn_params and icc_struct */ + page->mem = pdev->memory->non_gc_memory; + gs_c_param_list_write(¶mlist, pdev->memory); + if ((code = gs_getdeviceparams((gx_device *)pdev, (gs_param_list *)¶mlist)) < 0) { + goto params_out; + } + /* fetch bytes needed for param list */ + gs_c_param_list_read(¶mlist); + if ((code = gs_param_list_serialize((gs_param_list *)¶mlist, NULL, 0)) < 0) { + goto params_out; + } + page->paramlist_len = code; + if ((page->paramlist = gs_alloc_bytes(page->mem, + page->paramlist_len, + "saved_page paramlist")) == NULL) { + code = gs_error_VMerror; + goto params_out; + } + code = gs_param_list_serialize((gs_param_list *)¶mlist, page->paramlist, + page->paramlist_len); +params_out: + gs_c_param_list_release(¶mlist); + if (code < 0) + return code; /* all device param errors collect here */ + + /* Save other information. */ + /* If this device has spot colors that were added dynamically, we need to pass the names */ + /* through as well. These are from the devn_params->separations->names array. */ + if ((pdevn_params = dev_proc(pdev, ret_devn_params)((gx_device *)pdev)) != NULL) { + int i; + + page->num_separations = pdevn_params->separations.num_separations; + for (i=0; i < page->num_separations; i++) { + page->separation_name_sizes[i] = pdevn_params->separations.names[i].size; + page->separation_names[i] = gs_alloc_bytes(page->mem, page->separation_name_sizes[i], + "saved_page separation_names"); + if (page->separation_names[i] == NULL) { + gs_free_object(page->mem, page->paramlist, "saved_page paramlist"); + while (--i > 0) + gs_free_object(page->mem, page->separation_names[i], + "saved_page separation_names"); + return gs_error_VMerror; + } + memcpy(page->separation_names[i], pdevn_params->separations.names[i].data, + page->separation_name_sizes[i]); + } + } + /* Now re-open the clist device so that we get new files for the next page */ + return (*gs_clist_device_procs.open_device) ((gx_device *) pdev); +} -/* Save a page. */ +/* Save a page. The elements are allocated by this function in non_gc_memory */ int -gdev_prn_save_page(gx_device_printer * pdev, gx_saved_page * page, - int num_copies) +gdev_prn_save_page(gx_device_printer * pdev, gx_saved_page * page) { gx_device_clist *cdev = (gx_device_clist *) pdev; + gx_device_clist_writer * const pcldev = (gx_device_clist_writer *)pdev; + int code; /* Make sure we are banding. */ if (!PRINTER_IS_CLIST(pdev)) return_error(gs_error_rangecheck); - { - gx_device_clist_writer * const pcldev = - (gx_device_clist_writer *)pdev; - int code; - - if ((code = clist_end_page(pcldev)) < 0 || - (code = cdev->common.page_info.io_procs->fclose(pcldev->page_cfile, pcldev->page_cfname, false)) < 0 || - (code = cdev->common.page_info.io_procs->fclose(pcldev->page_bfile, pcldev->page_bfname, false)) < 0 - ) - return code; - /* Save the device information. */ - strncpy(page->dname, pdev->dname, sizeof(page->dname)); - page->color_info = pdev->color_info; - /* Save the page information. */ - page->info = pcldev->page_info; - page->info.cfile = 0; - page->info.bfile = 0; - } - /* Save other information. */ - page->num_copies = num_copies; - return (*gs_clist_device_procs.open_device) ((gx_device *) pdev); + + if ((code = clist_end_page(pcldev)) < 0 || + (code = cdev->common.page_info.io_procs->fclose(pcldev->page_info.cfile, pcldev->page_info.cfname, false)) < 0 || + (code = cdev->common.page_info.io_procs->fclose(pcldev->page_info.bfile, pcldev->page_info.bfname, false)) < 0 + ) + return code; + return do_page_save(pdev, page, NULL); } /* Render an array of saved pages. */ @@ -70,23 +147,22 @@ /* We would like to fully check the color representation, */ /* but we don't have enough information to do that. */ if (strcmp(page->dname, pdev->dname) != 0 || - memcmp(&page->color_info, &pdev->color_info, - sizeof(pdev->color_info)) != 0 + !gx_color_info_equal(&page->color_info, &pdev->color_info) ) return_error(gs_error_rangecheck); /* Currently we don't allow translation in Y. */ if (ppages[i].offset.y != 0) return_error(gs_error_rangecheck); /* Make sure the band parameters are compatible. */ - if (page->info.band_params.BandBufferSpace != + if (page->band_params.BandBufferSpace != pdev->buffer_space || - page->info.band_params.BandWidth != + page->band_params.BandWidth != pdev->width ) return_error(gs_error_rangecheck); /* Currently we require all band heights to be the same. */ - if (i > 0 && page->info.band_params.BandHeight != - ppages[0].page->info.band_params.BandHeight) + if (i > 0 && page->band_params.BandHeight != + ppages[0].page->band_params.BandHeight) return_error(gs_error_rangecheck); } } @@ -96,22 +172,785 @@ pcldev->pages = ppages; pcldev->num_pages = count; pcldev->offset_map = NULL; - pcldev->icc_table = NULL; - pcldev->icc_cache_cl = NULL; + pcldev->icc_table = NULL; /* FIXME: output_page doesn't load these */ + pcldev->icc_cache_cl = NULL; /* FIXME: output_page doesn't load these */ /* Render the pages. */ { int code = (*dev_proc(pdev, output_page)) - ((gx_device *) pdev, ppages[0].page->num_copies, true); + ((gx_device *) pdev, (pdev->IgnoreNumCopies || pdev->NumCopies_set <= 0) ? 1 : pdev->NumCopies, true); - /* Delete the temporary files. */ + /* Delete the temporary files and free the paramlist. */ int i; for (i = 0; i < count; ++i) { - const gx_saved_page *page = ppages[i].page; + gx_saved_page *page = ppages[i].page; + + pcldev->page_info.io_procs->unlink(page->cfname); + pcldev->page_info.io_procs->unlink(page->bfname); + gs_free_object(page->mem, page->paramlist, "gdev_prn_render_pages"); + page->paramlist = NULL; + } + return code; + } +} + +/* + * Allocate and initialize the list structure + */ +gx_saved_pages_list * +gx_saved_pages_list_new(gx_device_printer *pdev) +{ + gx_saved_pages_list *newlist; + gs_memory_t *non_gc_mem = pdev->memory->non_gc_memory; + + if ((newlist = + (gx_saved_pages_list *)gs_alloc_bytes(non_gc_mem, + sizeof(gx_saved_pages_list), + "gx_saved_pages_list_new")) == NULL) + return NULL; + + memset(newlist, 0, sizeof(gx_saved_pages_list)); + newlist->mem = non_gc_mem; + newlist->PageCount = pdev->PageCount; /* PageCount when list created */ + newlist->collated_copies = 1; + return newlist; +} + +/* + * Add a new saved page to the end of an in memory list. Refer to the + * documentation for gx_saved_pages_list. This allocates the saved_ + * page as well as the saved_pages_list_element and relies on the + * gdev_prn_save_page to use non_gc_memory since this list is never + * in GC memory. + */ +int +gx_saved_pages_list_add(gx_device_printer * pdev) +{ + gx_saved_pages_list *list = pdev->saved_pages_list; + gx_saved_pages_list_element *new_list_element; + gx_saved_page *newpage; + int code; + + if ((newpage = + (gx_saved_page *)gs_alloc_bytes(list->mem, + sizeof(gx_saved_page), + "gx_saved_pages_list_add")) == NULL) + return_error (gs_error_VMerror); + + if ((new_list_element = + (gx_saved_pages_list_element *)gs_alloc_bytes(list->mem, + sizeof(gx_saved_pages_list_element), + "gx_saved_pages_list_add")) == NULL) { + gs_free_object(list->mem, newpage, "gx_saved_pages_list_add"); + return_error (gs_error_VMerror); + } + + if ((code = gdev_prn_save_page(pdev, newpage)) < 0) { + gs_free_object(list->mem, new_list_element, "gx_saved_pages_list_add"); + gs_free_object(list->mem, newpage, "gx_saved_pages_list_add"); + return code; + } + new_list_element->sequence_number = ++list->count; + new_list_element->page = newpage; + new_list_element->next = NULL; + if (list->tail == NULL) { + /* list was empty, start it */ + new_list_element->prev = NULL; + list->head = list->tail = new_list_element; + } else { + /* place as new tail */ + new_list_element->prev = list->tail; + list->tail->next = new_list_element; + list->tail = new_list_element; + } + return 0; /* success */ +} + +/* Free the contents of all saved pages, unlink the files and free the + * saved_page structures. Does not free the gx_saved_pages_list struct. + */ +void +gx_saved_pages_list_free(gx_saved_pages_list *list) +{ + gx_saved_pages_list_element *curr_elem = list->head; + while (curr_elem != NULL) { + gx_saved_page *curr_page; + gx_saved_pages_list_element *next_elem; + + curr_page = curr_elem->page; + curr_page->io_procs->unlink(curr_page->cfname); + curr_page->io_procs->unlink(curr_page->bfname); + gs_free_object(curr_page->mem, curr_page->paramlist, "gx_saved_pages_list_free"); + gs_free_object(list->mem, curr_page, "gx_saved_pages_list_free"); + + next_elem = curr_elem->next; + gs_free_object(list->mem, curr_elem, "gx_saved_pages_list_free"); + curr_elem = next_elem; + }; + + /* finally free the list itself */ + gs_free_object(list->mem, list, "gx_saved_pages_list_free"); +} + + +/* This enum has to be in the same order as saved_pages_keys */ +typedef enum { + PARAM_UNKNOWN = 0, + PARAM_BEGIN, + PARAM_END, + PARAM_FLUSH, + PARAM_PRINT, + PARAM_COPIES, + PARAM_NORMAL, + PARAM_REVERSE, + PARAM_EVEN, + PARAM_EVEN0PAD, + PARAM_ODD, + /* any new keywords precede these */ + PARAM_NUMBER, + PARAM_DASH, + PARAM_STAR +} saved_pages_key_enum; + +static saved_pages_key_enum +param_find_key(byte *token, int token_size) +{ + int i; + static const char *saved_pages_keys[] = { + "begin", "end", "flush", "print", "copies", "normal", "reverse", "even", "even0pad", "odd" + }; + saved_pages_key_enum found = PARAM_UNKNOWN; + + if (*token >= '0' && *token <= '9') + return PARAM_NUMBER; + if (*token == '-') + return PARAM_DASH; + if (*token == (byte)'*') + return PARAM_STAR; + + for (i=0; i < (sizeof(saved_pages_keys)/sizeof(saved_pages_keys[0])); i++) { + if (strncasecmp((char *)token, saved_pages_keys[i], token_size) == 0) { + found = (saved_pages_key_enum) (i + 1); + break; + } + } + return found; +} + +/* Find next token, skipping any leading whitespace or non-alphanumeric */ +/* Returns pointer to next token and updates 'token_size'. Caller can */ +/* use (token - param) + token_size to update to next token in the */ +/* param string (param) and remaining char count (param_left) */ +/* Returns NULL and token_size =0 if no more alphanumeric tokens */ +static byte * +param_parse_token(byte *param, int param_left, int *token_size) +{ + int token_len = 0; + byte *token = param; + bool single_char_token = true; + + /* skip leading junk */ + while (param_left > 0) { + if (isalnum(*token)) { + single_char_token = false; /* we'll scan past this keyword */ + break; + } + if (*token == (byte)'-') /* valid in page range */ + break; + if (*token == (byte)'*') /* valid in page range */ + break; + /* skip any other junk */ + token++; + param_left--; + } + if (param_left == 0) { + *token_size = 0; /* no token found */ + return NULL; /* No more items */ + } + if (single_char_token) { + param_left--; /* we've consumed one character */ + *token_size = 1; + return token; + } + + /* token points to start, skip valid alphanumeric characters after */ + /* the first. Single character tokens terminate this scan. */ + while (param_left > 0) { + if (!isalnum(token[token_len])) + break; + token_len++; + param_left--; + } + *token_size = token_len; + return token; +} + +static int +do_page_load(gx_device_printer *pdev, gx_saved_page *page, clist_file_ptr *save_files) +{ + int code; + gx_device_clist_reader *crdev = (gx_device_clist_reader *)pdev; + gs_c_param_list paramlist; + gs_devn_params *pdevn_params; + + /* fetch and put the params we saved with the page */ + gs_c_param_list_write(¶mlist, pdev->memory); + if ((code = gs_param_list_unserialize((gs_param_list *)¶mlist, page->paramlist)) < 0) + goto out; + gs_c_param_list_read(¶mlist); + code = gs_putdeviceparams((gx_device *)pdev, (gs_param_list *)¶mlist); + gs_c_param_list_release(¶mlist); + if (code < 0) { + goto out; + } + /* if this is a DeviceN device (that supports spot colors), we need to load the */ + /* devn_params saved in the page (num_separations, separations[]) */ + if ((pdevn_params = dev_proc(pdev, ret_devn_params)((gx_device *)pdev)) != NULL) { + int i; - pcldev->page_info.io_procs->unlink(page->info.cfname); - pcldev->page_info.io_procs->unlink(page->info.bfname); + pdevn_params->separations.num_separations = page->num_separations; + for (i=0; i < page->num_separations; i++) { + pdevn_params->separations.names[i].size = page->separation_name_sizes[i]; + pdevn_params->separations.names[i].data = gs_alloc_bytes(pdev->memory->stable_memory, + page->separation_name_sizes[i], + "saved_page separation_names"); + if (pdevn_params->separations.names[i].data == NULL) { + while (--i > 0) + gs_free_object(pdev->memory->stable_memory, + pdevn_params->separations.names[i].data, + "saved_page separation_names"); + code = gs_error_VMerror; + goto out; + } + memcpy(pdevn_params->separations.names[i].data, page->separation_names[i], + page->separation_name_sizes[i]); } + } + if (code > 0) + if ((code = gs_opendevice((gx_device *)pdev)) < 0) + goto out; + + /* If the device is now a writer, that means putparams realloced the device */ + /* so we need to get back to reader mode and remove the extra clist files */ + if (CLIST_IS_WRITER((gx_device_clist *)pdev)) { + if ((code = clist_close_writer_and_init_reader((gx_device_clist *)crdev)) < 0) + goto out; + /* close and unlink the temp files just created */ + if (crdev->page_info.cfile != NULL) + crdev->page_info.io_procs->fclose(crdev->page_info.cfile, crdev->page_info.cfname, true); + if (crdev->page_info.bfile != NULL) + crdev->page_info.io_procs->fclose(crdev->page_info.bfile, crdev->page_info.bfname, true); + crdev->page_info.cfile = crdev->page_info.bfile = NULL; + } + + /* set up the page_info, after putdeviceparams that may have changed things */ + crdev->page_info.io_procs = page->io_procs; + crdev->page_info.tile_cache_size = page->tile_cache_size; + crdev->page_info.bfile_end_pos = page->bfile_end_pos; + crdev->page_info.band_params = page->band_params; + crdev->graphics_type_tag = page->tag; + + crdev->yplane.index = -1; + crdev->pages = NULL; + crdev->num_pages = 1; /* single page at a time */ + crdev->offset_map = NULL; + crdev->render_threads = NULL; + crdev->ymin = crdev->ymax = 0; /* invalidate buffer contents to force rasterizing */ + + /* We probably don't need to copy in the filenames, but do it in case something expects it */ + strncpy(crdev->page_info.cfname, page->cfname, sizeof(crdev->page_info.cfname)-1); + strncpy(crdev->page_info.bfname, page->bfname, sizeof(crdev->page_info.bfname)-1); + if (save_files != NULL) + { + crdev->page_info.cfile = save_files[0]; + crdev->page_info.bfile = save_files[1]; + } +out: + return code; +} + +static int +gx_saved_page_load(gx_device_printer *pdev, gx_saved_page *page) +{ + int code; + gx_device_clist_reader *crdev = (gx_device_clist_reader *)pdev; + + code = do_page_load(pdev, page, NULL); + if (code < 0) return code; + + /* Now open this page's files */ + code = crdev->page_info.io_procs->fopen(crdev->page_info.cfname, + gp_fmode_rb, &(crdev->page_info.cfile), crdev->bandlist_memory, + crdev->bandlist_memory, true); + if (code >= 0) { + code = crdev->page_info.io_procs->fopen(crdev->page_info.bfname, + gp_fmode_rb, &(crdev->page_info.bfile), crdev->bandlist_memory, + crdev->bandlist_memory, false); + } + + return code; +} + +static int +gx_output_saved_page(gx_device_printer *pdev, gx_saved_page *page) +{ + int code, ecode; + /* Note that banding_type is NOT a device parameter handled in the paramlist */ + gdev_banding_type save_banding_type = pdev->space_params.banding_type; + gx_device_clist_reader *crdev = (gx_device_clist_reader *)pdev; + + pdev->space_params.banding_type = BandingAlways; + + if ((code = gx_saved_page_load(pdev, page)) < 0) + goto out; + + /* don't want the band files touched after printing */ + crdev->do_not_open_or_close_bandfiles = true; + + /* load the color_usage_array */ + if ((code = clist_read_color_usage_array(crdev)) < 0) + goto out; + if ((code = clist_read_icctable(crdev)) < 0) + goto out; + code = (crdev->icc_cache_cl = gsicc_cache_new(crdev->memory)) == NULL ? + gs_error_VMerror : code; + if (code < 0) + goto out; + + /* After setting params, make sure bg_printing is off */ + pdev->bg_print_requested = false; + + /* Note: we never flush pages allowing for re-printing from the list */ + /* data (files) will be deleted when the list is flushed or freed. */ + code = (*dev_proc(pdev, output_page)) ((gx_device *) pdev, + (pdev->IgnoreNumCopies || pdev->NumCopies_set <= 0) ? 1 : pdev->NumCopies, false); + + clist_free_icc_table(crdev->icc_table, crdev->memory); + crdev->icc_table = NULL; + rc_decrement(crdev->icc_cache_cl,"clist_finish_page"); + crdev->icc_cache_cl = NULL; + + /* Close the clist files */ + ecode = crdev->page_info.io_procs->fclose(crdev->page_info.cfile, crdev->page_info.cfname, false); + if (ecode >= 0) { + crdev->page_info.cfile = NULL; + ecode = crdev->page_info.io_procs->fclose(crdev->page_info.bfile, crdev->page_info.bfname, false); + } + if (ecode < 0) { + code = ecode; + goto out; + } + crdev->page_info.bfile = NULL; + +out: + pdev->space_params.banding_type = save_banding_type; + return code; +} + +/* + * Print selected pages from the list to on the selected device. The + * saved_pages_list is NOT modified, allowing for reprint / recovery + * print. Each saved_page is printed on a separate page (unlike the + * gdev_prn_render_pages above which prints several saved_pages on + * a single "master" page, performing imposition). + * + * This is primarily intended to allow printing in non-standard order + * (reverse, odd, even) or producing collated copies for a job. + * + * On success return the number of bytes consumed or error code < 0. + * The printed_count will contain the number of pages printed. + * + * ------------------------------------------------------------------- + * + * The param string may begin with whitespace. The string is parsed + * and the selected pages are printed. There may be any number of ranges + * and or keywords separated by whitespace and/or comma ','. + * + * NB: The pdev printer device's PageCount is updated to reflect the + * total number of pages produced (per the spec for this parameter) + * since we may be producing multiple collated copies. + * Also the list PageCount is updated after printing since + * there may be a subsequent 'print' action. + * keywords: + * copies # Set the number of copies for subsequent printing actions + * "copies 1" resets to a single copy + * normal All pages are printed in normal order + * reverse All pages are printed in reverse order + * The following two options may be useful for duplexing. + * odd All odd pages are printed, e.g. 1, 3, 5, ... + * even All even pages are printed, e.g. 2, 4, 6, ... + * NB: an extra blank page will be printed if the list + * has an odd number of pages. + * even0pad All even pages, but no extra blank page if there are + * an odd number of pages on the list. + * range syntax: + * range range multiple ranges are separated by commas ',' + * and/or whitespace. + * # a specific page number is a valid range + * + * inclusive ranges below can have whitespace before + * or after the dash '-'. + * #-# a range consisting of all pages from the first + * page # up to (and including) the second page #. + * #-* all pages from # up through the last page + * "1-*" is equivalent to "normal" + * *-# all pages from the last up through # page. + * "reverse" is equivalent to "*-1" + */ +int +gx_saved_pages_list_print(gx_device_printer *pdev, gx_saved_pages_list *list, + byte *param, int param_size, int *printed_count) +{ + byte *param_scan = NULL; + int param_left; + int start_page = 0; /* 0 means start_page unknown */ + int end_page = 0; /* < 0 means waiting for the end of a # - # range */ + /* i.e, a '-' was scanned. 0 means unknown */ + int tmp_num; /* during token scanning loop */ + int code = 0, endcode = 0; + byte *token; + int copy, token_size; + gx_device_clist_reader *crdev = (gx_device_clist_reader *)pdev; + /* the following are used so we can go back to the original state */ + bool save_bg_print = false; /* arbitrary, silence warning */ + bool save_bandfile_open_close = false; /* arbitrary, silence warning */ + gx_saved_page saved_page; + clist_file_ptr saved_files[2]; + + /* save the current (empty) page while we print */ + if ((code = do_page_save(pdev, &saved_page, saved_files)) < 0) { + emprintf(pdev->memory, "gx_saved_pages_list_print: Error getting device params\n"); + goto out; + } + + /* save_page leaves the clist in writer mode, so prepare for reading clist */ + /* files. When we are done with printing, we'll go back to write mode. */ + if ((code = clist_close_writer_and_init_reader((gx_device_clist *)pdev)) < 0) + goto out; + + /* While printing, disable the saved_pages mode and bg_print */ + pdev->saved_pages_list = NULL; + save_bg_print = pdev->bg_print_requested; + + /* Inhibits modifying the clist at end of output_page */ + save_bandfile_open_close = crdev->do_not_open_or_close_bandfiles; + crdev->do_not_open_or_close_bandfiles = true; + + pdev->PageCount = list->PageCount; /* adjust to value last printed */ + + /* loop producing the number of copies */ + /* Note: list->collated_copies may change if 'copies' param follows the 'print' */ + for (copy = 1; copy <= list->collated_copies; copy++) { + int page_skip = 0; + bool do_blank_page_pad; + int page; + + /* Set to start of 'print' params to do collated copies */ + param_scan = param; + param_left = param_size; + while ((token = param_parse_token(param_scan, param_left, &token_size)) != NULL) { + saved_pages_key_enum key; + + page = 0; + do_blank_page_pad = false; /* only set for EVEN */ + key = param_find_key(token, token_size); + switch (key) { + case PARAM_DASH: + if (start_page == 0) { + emprintf(pdev->memory, "gx_saved_pages_list_print: '-' unexpected\n"); + code = gs_error_typecheck; + goto out; + } + end_page = -1; /* the next number will end a range */ + break; + + case PARAM_STAR: + page = list->count; /* last page */ + case PARAM_NUMBER: + if (page == 0) { + if (sscanf((const char *)token, "%d", &page) != 1) { + emprintf1(pdev->memory, "gx_saved_pages_list_print: Number format error '%s'\n", token); + code = gs_error_typecheck; + goto out; + } + } + if (start_page == 0) { + start_page = page; /* first number seen */ + } else { + /* a second number was seen after the start_page was set */ + if (end_page < 0) { + end_page = page; /* end of a '# - #' range */ + page_skip = (end_page >= start_page) ? 1 : -1; + } else { + /* 'page' was NOT part of a range after printing 'page' will start a new range */ + end_page = start_page; /* single page */ + page_skip = 1; + } + } + break; + + case PARAM_COPIES: /* copies requires a number next */ + /* Move to past 'copies' token */ + param_left -= token - param_scan + token_size; + param_scan = token + token_size; + + if ((token = param_parse_token(param_scan, param_left, &token_size)) == NULL || + param_find_key(token, token_size) != PARAM_NUMBER) { + emprintf(pdev->memory, "gx_saved_pages_list_print: copies not followed by number.\n"); + code = gs_error_typecheck; + goto out; + } + if (sscanf((const char *)token, "%d", &tmp_num) != 1) { + emprintf1(pdev->memory, "gx_saved_pages_list_print: Number format error '%s'\n", token); + code = gs_error_typecheck; + goto out; + } + list->collated_copies = tmp_num; /* save it for our loop */ + break; + + case PARAM_NORMAL: /* sets both start and end */ + start_page = 1; + end_page = list->count; + page_skip = 1; + break ; + + case PARAM_REVERSE: /* sets both start and end */ + start_page = list->count; + end_page = 1; + page_skip = -1; + break; + + case PARAM_EVEN: /* sets both start and end */ + do_blank_page_pad = (list->count & 1) != 0; /* pad if odd */ + case PARAM_EVEN0PAD: /* sets both start and end */ + start_page = 2; + end_page = list->count; + page_skip = 2; + break ; + + case PARAM_ODD: /* sets both start and end */ + start_page = 1; + end_page = list->count; + page_skip = 2; + break ; + + case PARAM_UNKNOWN: + case PARAM_BEGIN: + case PARAM_END: + case PARAM_FLUSH: + case PARAM_PRINT: + token_size = 0; /* non-print range token seen */ + } + if (end_page > 0) { + /* Here we have a range to print since start and end are known */ + int curr_page = start_page; + gx_saved_pages_list_element *curr_elem = NULL; + + /* get the start_page saved_page */ + if (start_page <= list->count) { + for (curr_elem = list->head; curr_elem->sequence_number != start_page; + curr_elem = curr_elem->next) { + if (curr_elem->next == NULL) { + emprintf1(pdev->memory, "gx_saved_pages_list_print: page %d not found.\n", start_page); + code = gs_error_rangecheck;; + goto out; + } + } + } + + for ( ; curr_elem != NULL; ) { + + /* print the saved page from the current curr_elem */ + + if ((code = gx_output_saved_page(pdev, curr_elem->page)) < 0) + goto out; + + curr_page += page_skip; + if (page_skip >= 0) { + if (curr_page > end_page) + break; + curr_elem = curr_elem->next; + if (page_skip > 1) + curr_elem = curr_elem->next; + } else { + /* reverse print order */ + if (curr_page < end_page) + break; + curr_elem = curr_elem->prev; + /* Below is not needed since we never print reverse even/odd */ + if (page_skip < -1) + curr_elem = curr_elem->prev; + } + if (curr_elem == NULL) { + emprintf1(pdev->memory, "gx_saved_pages_list_print: page %d not found.\n", curr_page); + code = gs_error_rangecheck;; + goto out; + } + } + + /* If we were printing EVEN, we may need to spit out a blank 'pad' page */ + if (do_blank_page_pad) { + /* print the empty page we had upon entry */ + /* FIXME: Note that the page size may not match the last odd page */ + if ((code = gx_output_saved_page(pdev, &saved_page)) < 0) + goto out; + } + + /* After printing, reset to handle next page range */ + start_page = (start_page == end_page) ? page : 0; /* if single page, set start_page */ + /* from the number scanned above */ + end_page = 0; + } + if (token_size == 0) + break; /* finished with print ranges */ + + /* Move to next token */ + param_left -= token - param_scan + token_size; + param_scan = token + token_size; + } + } +out: + /* restore the device parameters saved upon entry */ + *printed_count = pdev->PageCount - list->PageCount; + list->PageCount = pdev->PageCount; /* retain for subsequent print action */ + pdev->saved_pages_list = list; + pdev->bg_print_requested = save_bg_print; + crdev->do_not_open_or_close_bandfiles = save_bandfile_open_close; + + /* load must be after we've set saved_pages_list which forces clist mode. */ + do_page_load(pdev, &saved_page, saved_files); + + /* Finally, do the finish page which will reset the clist to empty and write mode */ + endcode = clist_finish_page((gx_device *)pdev, true); + return code < 0 ? code : endcode < 0 ? endcode : param_scan - param; +} + +/* + * Caller should make sure that this device supports saved_pages: + * dev_proc(dev, dev_spec_op)(dev, gxdso_supports_saved_pages, NULL, 0) == 1 + * + * Returns < 0 if error, 1 if erasepage needed, 0 if no action needed. + */ +int +gx_saved_pages_param_process(gx_device_printer *pdev, byte *param, int param_size) +{ + byte *param_scan = param; + int param_left = param_size; + byte *token; + int token_size, code, printed_count, collated_copies = 1; + int tmp_num; /* during token scanning loop */ + int erasepage_needed = 0; + + while (pdev->child) + pdev = (gx_device_printer *)pdev->child; + + while ((token = param_parse_token(param_scan, param_left, &token_size)) != NULL) { + + switch (param_find_key(token, token_size)) { + case PARAM_BEGIN: + if (pdev->saved_pages_list == NULL) { + if ((pdev->saved_pages_list = gx_saved_pages_list_new(pdev)) == NULL) + return_error(gs_error_VMerror); + pdev->finalize = gdev_prn_finalize; /* set to make sure the list gets freed */ + + /* We need to change to clist mode. Always uses clist when saving pages */ + pdev->saved_pages_list->save_banding_type = pdev->space_params.banding_type; + pdev->space_params.banding_type = BandingAlways; + if ((code = gdev_prn_reallocate_memory((gx_device *)pdev, &pdev->space_params, pdev->width, pdev->height)) < 0) + return code; + erasepage_needed |= 1; + } + break; + + case PARAM_END: + if (pdev->saved_pages_list != NULL) { + /* restore to what was set before the "begin" */ + pdev->space_params.banding_type = pdev->saved_pages_list->save_banding_type; + gx_saved_pages_list_free(pdev->saved_pages_list); + pdev->saved_pages_list = NULL; + /* We may need to change from clist mode since we forced clist when saving pages */ + code = gdev_prn_reallocate_memory((gx_device *)pdev, &pdev->space_params, pdev->width, pdev->height); + if (code < 0) + return code; + erasepage_needed |= 1; /* make sure next page is erased */ + } + break; + + case PARAM_FLUSH: + if (pdev->saved_pages_list != NULL) { + /* Save the collated copy count so the list we return will have it */ + collated_copies = pdev->saved_pages_list->collated_copies; + gx_saved_pages_list_free(pdev->saved_pages_list); + } + /* Always return with an empty list, even if we weren't saving previously */ + if ((pdev->saved_pages_list = gx_saved_pages_list_new(pdev)) == NULL) + return_error(gs_error_VMerror); + pdev->finalize = gdev_prn_finalize; /* set to make sure the list gets freed */ + /* restore the original count */ + pdev->saved_pages_list->collated_copies = collated_copies; + break; + + case PARAM_COPIES: /* copies requires a number next */ + /* make sure that we have a list */ + if (pdev->saved_pages_list == NULL) { + return_error(gs_error_rangecheck); /* copies not allowed before a 'begin' */ + } + /* Move to past 'copies' token */ + param_left -= token - param_scan + token_size; + param_scan = token + token_size; + + if ((token = param_parse_token(param_scan, param_left, &token_size)) == NULL || + param_find_key(token, token_size) != PARAM_NUMBER) { + emprintf(pdev->memory, "gx_saved_pages_param_process: copies not followed by number.\n"); + return_error(gs_error_typecheck); + } + if (sscanf((const char *)token, "%d", &tmp_num) != 1) { + emprintf1(pdev->memory, "gx_saved_pages_list_print: Number format error '%s'\n", token); + code = gs_error_typecheck; + return code; + } + pdev->saved_pages_list->collated_copies = tmp_num; /* save it for our loop */ + break; + + case PARAM_PRINT: + /* Move to past 'print' token */ + param_left -= token - param_scan + token_size; + param_scan = token + token_size; + + code = param_left; /* in case list is NULL, skip rest of string */ + if (pdev->saved_pages_list != NULL) { + if ((code = gx_saved_pages_list_print(pdev, pdev->saved_pages_list, + param_scan, param_left, &printed_count)) < 0) + return code; + erasepage_needed |= 1; /* make sure next page is erased */ + } + /* adjust for all of the print parameters */ + token_size += code; + break; + + /* We are expecting an action keyword, so other keywords and tokens */ + /* are not valid here (mostly the 'print' parameters). */ + default: + { + byte *bad_token = gs_alloc_string(pdev->memory, token_size+1, "saved_pages_param_process"); + byte *param_string = gs_alloc_string(pdev->memory, param_size+1, "saved_pages_param_process"); + if (bad_token != NULL && param_string != NULL) { + memcpy(bad_token, token, token_size); + bad_token[token_size] = 0; /* terminate string */ + memcpy(param_string, param, param_size); + param_string[param_size] = 0; /* terminate string */ + emprintf2(pdev->memory, "*** Invalid saved-pages token '%s'\n *** in param string '%s'\n", + bad_token, param_string); + gs_free_string(pdev->memory, bad_token, token_size+1, "saved_pages_param_process"); + gs_free_string(pdev->memory, param_string, param_size+1, "saved_pages_param_process"); + } + } + } + /* Move to next token */ + param_left -= token - param_scan + token_size; + param_scan = token + token_size; + } + return erasepage_needed; } diff -Nru ghostscript-9.10~dfsg/base/gxclpage.h ghostscript-9.25~dfsg+1/base/gxclpage.h --- ghostscript-9.10~dfsg/base/gxclpage.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclpage.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,7 +20,27 @@ #ifndef gxclpage_INCLUDED # define gxclpage_INCLUDED -#include "gxclio.h" +#include "gxclist.h" /* for gx_saved_page struct */ + +typedef struct gx_saved_pages_list_element_s gx_saved_pages_list_element; + +struct gx_saved_pages_list_element_s { + int sequence_number; /* to cross check position in list */ + gx_saved_pages_list_element *prev; + gx_saved_pages_list_element *next; + gx_saved_page *page; +}; + +typedef struct gx_saved_pages_list_s { + int PageCount; /* Page Count to start with on next 'print' action */ + int count; /* number of pages in the list */ + int collated_copies; /* how many copies of the job to print */ + int save_banding_type; /* to restore when we "end" */ + gx_saved_pages_list_element *head; + gx_saved_pages_list_element *tail; + gs_memory_t *mem; /* allocator used for this struct and list_elements */ +} gx_saved_pages_list; + /* ---------------- Procedures ---------------- */ @@ -31,8 +51,7 @@ * for later retrieval; in the latter case, the client should free the * in-memory structure. */ -int gdev_prn_save_page(gx_device_printer * pdev, gx_saved_page * page, - int num_copies); +int gdev_prn_save_page(gx_device_printer * pdev, gx_saved_page * page); /* * Render an array of saved pages by setting up a modified get_bits @@ -52,4 +71,45 @@ int gdev_prn_render_pages(gx_device_printer * pdev, const gx_placed_page * ppages, int count); +/* + * Allocate and initialize the list structure + */ +gx_saved_pages_list *gx_saved_pages_list_new(gx_device_printer *); + +/* + * Add a saved page to the end of an in memory list. This allocates + * a new gx_saved_page structure, saves the page to it and links it + * on to the end of the list. The list->mem is used as the allocator + * so that list_free can free the contents. This relies on save_page + * to use non_gc_memory for the stuff it allocates. + */ +int gx_saved_pages_list_add(gx_device_printer * pdev); + +/* Free the contents of all saved pages, unlink the files and free the + * saved_page structures and free the gx_saved_pages_list struct. + */ +void gx_saved_pages_list_free(gx_saved_pages_list *list); + +/* + * Process the param control string. + * Returns < 0 if an error, > 0 if OK, but erasepage is needed, otherwise 0. + */ +int gx_saved_pages_param_process(gx_device_printer *pdev, byte *param, int param_size); + +/* + * Print selected pages from the list to on the selected device. The + * saved_pages_list is NOT modified, allowing for reprint / recovery + * print. Each saved_page is printed on a separate page (unlike the + * gdev_prn_render_pages above which prints several saved_pages on + * a single "master" page, performing imposition). + * + * This is primarily intended to allow printing in non-standard order + * (reverse, odd then even) or producing collated copies for a job. + * + * On success return the number of bytes consumed or error code < 0. + * The printed_count will contain the number of pages printed. + * + */ +int gx_saved_pages_list_print(gx_device_printer *pdev, gx_saved_pages_list *list, + byte *control, int control_size, int *printed_count); #endif /* gxclpage_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxclpath.c ghostscript-9.25~dfsg+1/base/gxclpath.c --- ghostscript-9.10~dfsg/base/gxclpath.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclpath.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,6 +28,7 @@ #include "gxclpath.h" #include "gxcolor2.h" #include "gxdcolor.h" +#include "gxpcolor.h" #include "gxpaint.h" /* for gx_fill/stroke_params */ #include "gzpath.h" #include "gzcpath.h" @@ -134,7 +135,7 @@ * * The complete cmd_opv_ext_put_drawing_color consists of: * comand code (2 bytes) - * tile index value or non tile color (1) + * tile index value or non tile color (1) * device color type index (1) * length of serialized device color (enc_u_sizew(dc_size)) * the serialized device color itself (dc_size) @@ -152,7 +153,7 @@ return 0; else if (code < 0 && code != gs_error_rangecheck) return code; - if (!all_bands && dc_size * pre->nbands > 1024*1024 /* arbitrary */) + if (!all_bands && dc_size * pre->rect_nbands > 1024*1024 /* arbitrary */) all_bands = true; is_pattern = gx_dc_is_pattern1_color(pdcolor); if (is_pattern) @@ -204,9 +205,9 @@ if (req_size_final > buffer_space) return_error(gs_error_unregistered); /* Must not happen. */ if (all_bands) - code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, req_size_final); + code = set_cmd_put_all_op(&dp, cldev, cmd_opv_extend, req_size_final); else - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_extend, req_size_final); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_extend, req_size_final); if (code < 0) return code; dp0 = dp; @@ -243,12 +244,12 @@ left -= portion_size; } while (left); - /* should properly calculate color_usage, but for now just punt */ - pcls->color_usage.or = gx_color_usage_all(cldev); + /* attempt to properly calculate color_usage */ + pcls->color_usage.or |= cmd_drawing_color_usage(cldev, pdcolor); /* record the color we have just serialized color */ pdcolor->type->save_dc(pdcolor, &pcls->sdc); - if (pattern_id) { + if (pattern_id != gs_no_id) { /* Don't record empty tiles because they're not cached. */ pcls->pattern_id = pattern_id; } @@ -256,6 +257,23 @@ /* HACK: since gx_dc_pattern_write identifies pattern by tile id, replace the client's pattern id with tile id in the saved color. */ pcls->sdc.colors.pattern.id = pattern_id; + if (pattern_id && + (gx_pattern1_get_transptr(pdcolor) != NULL || + gx_pattern1_clist_has_trans(pdcolor))) { + /* update either this band or all bands with the trans_bbox */ + if (all_bands) { + pcls->color_usage.trans_bbox.p.x = 0; + pcls->color_usage.trans_bbox.q.x = cldev->width; /* no other information available */ + pcls->color_usage.trans_bbox.p.y = 0; + pcls->color_usage.trans_bbox.q.y = cldev->height; + clist_update_trans_bbox(cldev, &(pcls->color_usage.trans_bbox)); + } else { + pcls->color_usage.trans_bbox.p.x = 0; + pcls->color_usage.trans_bbox.q.x = cldev->width; /* no other information available */ + pcls->color_usage.trans_bbox.p.y = pre->y; + pcls->color_usage.trans_bbox.q.y = pre->yend; + } + } } if (is_pattern && all_bands) { /* Distribute the written pattern params to all bands. @@ -268,16 +286,26 @@ pcls1->pattern_id = pcls->pattern_id; pcls1->tile_phase.x = pcls->tile_phase.x; pcls1->tile_phase.y = pcls->tile_phase.y; + pcls1->color_usage.or = pcls->color_usage.or; } } return code; } /* Compute the colors used by a drawing color. */ -gx_color_index +/* If the device is using transparency, the pdf14 compositor may have */ +/* altered the colorspace. If so, just flag all components used. */ +gx_color_usage_bits cmd_drawing_color_usage(gx_device_clist_writer *cldev, const gx_drawing_color * pdcolor) { + if (cldev->page_uses_transparency && + (cldev->color_info.polarity != cldev->clist_color_info.polarity || + (cldev->color_info.num_components != cldev->clist_color_info.num_components))) { + /* we would have to transform the color which would impact performance */ + return gx_color_usage_all(cldev); + } + if (gx_dc_is_pure(pdcolor)) return gx_color_index2usage((gx_device *)cldev, gx_dc_pure_color(pdcolor)); else if (gx_dc_is_binary_halftone(pdcolor)) @@ -286,6 +314,12 @@ gx_color_index2usage((gx_device *)cldev, gx_dc_binary_color1(pdcolor))); else if (gx_dc_is_colored_halftone(pdcolor)) return gx_color_index2usage((gx_device *)cldev, colored_halftone_color_usage(cldev, pdcolor)); + else if (gx_dc_is_devn(pdcolor)) { + gx_color_usage_bits bits = 0; + + gx_dc_devn_get_nonzero_comps(pdcolor, (gx_device *)cldev, &bits); + return bits; + } else return gx_color_usage_all(cldev); } @@ -326,8 +360,8 @@ (cj_ac_sa_known | flatness_known | op_bm_tk_known | opacity_alpha_known |\ shape_alpha_known | fill_adjust_known | alpha_known | clip_path_known) static void -cmd_check_fill_known(gx_device_clist_writer *cdev, const gs_imager_state *pis, - floatp flatness, const gs_fixed_point *padjust, +cmd_check_fill_known(gx_device_clist_writer *cdev, const gs_gstate *pgs, + double flatness, const gs_fixed_point *padjust, const gx_clip_path *pcpath, uint *punknown) { /* @@ -342,9 +376,9 @@ state_update(accurate_curves); state_update(stroke_adjust); } - if (cdev->imager_state.flatness != flatness) { + if (cdev->gs_gstate.flatness != flatness) { *punknown |= flatness_known; - cdev->imager_state.flatness = flatness; + cdev->gs_gstate.flatness = flatness; } /* * Note: overprint and overprint_mode are implemented via a compositor @@ -370,13 +404,13 @@ *punknown |= shape_alpha_known; state_update(shape.alpha); } - if (cdev->imager_state.fill_adjust.x != padjust->x || - cdev->imager_state.fill_adjust.y != padjust->y + if (cdev->gs_gstate.fill_adjust.x != padjust->x || + cdev->gs_gstate.fill_adjust.y != padjust->y ) { *punknown |= fill_adjust_known; - cdev->imager_state.fill_adjust = *padjust; + cdev->gs_gstate.fill_adjust = *padjust; } - if (cdev->imager_state.alpha != pis->alpha) { + if (cdev->gs_gstate.alpha != pgs->alpha) { *punknown |= alpha_known; state_update(alpha); } @@ -432,105 +466,106 @@ if (misc2_unknown) { byte buf[ - 1 + /* cap_join */ + 1 + /* cap_join: start_cap|join */ + 1 + /* end_cap|dash_cap */ 1 + /* cj_ac_sa */ sizeof(float) + /* flatness */ sizeof(float) + /* line width */ sizeof(float) + /* miter limit */ 2 + /* op_bm_tk and rend intent */ sizeof(float) * 2 + /* opacity/shape alpha */ - sizeof(cldev->imager_state.alpha) + sizeof(cldev->gs_gstate.alpha) ]; byte *bp = buf; if (unknown & cap_join_known) { - *bp++ = (cldev->imager_state.line_params.start_cap << 3) + - cldev->imager_state.line_params.join; - *bp++ = (cldev->imager_state.line_params.end_cap << 3) + - cldev->imager_state.line_params.dash_cap; + *bp++ = (cldev->gs_gstate.line_params.start_cap << 3) + + cldev->gs_gstate.line_params.join; + *bp++ = (cldev->gs_gstate.line_params.end_cap << 3) + + cldev->gs_gstate.line_params.dash_cap; } if (unknown & cj_ac_sa_known) { *bp++ = - ((cldev->imager_state.line_params.curve_join + 1) << 2) + - (cldev->imager_state.accurate_curves ? 2 : 0) + - (cldev->imager_state.stroke_adjust ? 1 : 0); + ((cldev->gs_gstate.line_params.curve_join + 1) << 2) + + (cldev->gs_gstate.accurate_curves ? 2 : 0) + + (cldev->gs_gstate.stroke_adjust ? 1 : 0); } if (unknown & flatness_known) { - memcpy(bp, &cldev->imager_state.flatness, sizeof(float)); + memcpy(bp, &cldev->gs_gstate.flatness, sizeof(float)); bp += sizeof(float); } if (unknown & line_width_known) { float width = - gx_current_line_width(&cldev->imager_state.line_params); + gx_current_line_width(&cldev->gs_gstate.line_params); memcpy(bp, &width, sizeof(width)); bp += sizeof(width); } if (unknown & miter_limit_known) { - memcpy(bp, &cldev->imager_state.line_params.miter_limit, + memcpy(bp, &cldev->gs_gstate.line_params.miter_limit, sizeof(float)); bp += sizeof(float); } if (unknown & op_bm_tk_known) { *bp++ = - ((int)cldev->imager_state.blend_mode << 3) + - (cldev->imager_state.text_knockout << 2) + - (cldev->imager_state.overprint_mode << 1) + - cldev->imager_state.overprint; - *bp++ = cldev->imager_state.renderingintent; + ((int)cldev->gs_gstate.blend_mode << 3) + + (cldev->gs_gstate.text_knockout << 2) + + (cldev->gs_gstate.overprint_mode << 1) + + cldev->gs_gstate.overprint; + *bp++ = cldev->gs_gstate.renderingintent; } if (unknown & opacity_alpha_known) { - memcpy(bp, &cldev->imager_state.opacity.alpha, sizeof(float)); + memcpy(bp, &cldev->gs_gstate.opacity.alpha, sizeof(float)); bp += sizeof(float); } if (unknown & shape_alpha_known) { - memcpy(bp, &cldev->imager_state.shape.alpha, sizeof(float)); + memcpy(bp, &cldev->gs_gstate.shape.alpha, sizeof(float)); bp += sizeof(float); } if (unknown & alpha_known) { - memcpy(bp, &cldev->imager_state.alpha, - sizeof(cldev->imager_state.alpha)); - bp += sizeof(cldev->imager_state.alpha); + memcpy(bp, &cldev->gs_gstate.alpha, + sizeof(cldev->gs_gstate.alpha)); + bp += sizeof(cldev->gs_gstate.alpha); } - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_misc2, - 1 + cmd_sizew(misc2_unknown) + bp - buf); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_misc2, + 1 + cmd_sizew(misc2_unknown) + (bp - buf)); if (code < 0) return 0; memcpy(cmd_put_w(misc2_unknown, dp + 1), buf, bp - buf); pcls->known |= misc2_unknown; } if (unknown & fill_adjust_known) { - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_fill_adjust, + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_fill_adjust, 1 + sizeof(fixed) * 2); if (code < 0) return code; - memcpy(dp + 1, &cldev->imager_state.fill_adjust.x, sizeof(fixed)); - memcpy(dp + 1 + sizeof(fixed), &cldev->imager_state.fill_adjust.y, sizeof(fixed)); + memcpy(dp + 1, &cldev->gs_gstate.fill_adjust.x, sizeof(fixed)); + memcpy(dp + 1 + sizeof(fixed), &cldev->gs_gstate.fill_adjust.y, sizeof(fixed)); pcls->known |= fill_adjust_known; } if (unknown & ctm_known) { - int len = cmd_write_ctm_return_length(cldev, &ctm_only(&cldev->imager_state)); + int len = cmd_write_ctm_return_length(cldev, &ctm_only(&cldev->gs_gstate)); - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_ctm, len + 1); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_ctm, len + 1); if (code < 0) return code; - code = cmd_write_ctm(&ctm_only(&cldev->imager_state), dp, len); + code = cmd_write_ctm(&ctm_only(&cldev->gs_gstate), dp, len); if (code < 0) return code; pcls->known |= ctm_known; } if (unknown & dash_known) { - int n = cldev->imager_state.line_params.dash.pattern_size; + int n = cldev->gs_gstate.line_params.dash.pattern_size; - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_dash, + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_dash, 2 + (n + 2) * sizeof(float)); if (code < 0) return code; - dp[1] = n + (cldev->imager_state.line_params.dash.adapt ? 0x80 : 0) + - (cldev->imager_state.line_params.dot_length_absolute ? 0x40 : 0); - memcpy(dp + 2, &cldev->imager_state.line_params.dot_length, + dp[1] = n + (cldev->gs_gstate.line_params.dash.adapt ? 0x80 : 0) + + (cldev->gs_gstate.line_params.dot_length_absolute ? 0x40 : 0); + memcpy(dp + 2, &cldev->gs_gstate.line_params.dot_length, sizeof(float)); memcpy(dp + 2 + sizeof(float), - &cldev->imager_state.line_params.dash.offset, + &cldev->gs_gstate.line_params.dash.offset, sizeof(float)); if (n != 0) memcpy(dp + 2 + sizeof(float) * 2, @@ -550,7 +585,7 @@ bool punt_to_outer_box = false; int code; - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_begin_clip, 1); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_begin_clip, 1); if (code < 0) return code; if (pcpath->path_valid) { @@ -611,11 +646,11 @@ } { int end_code = - set_cmd_put_op(dp, cldev, pcls, cmd_opv_end_clip, 1); + set_cmd_put_op(&dp, cldev, pcls, cmd_opv_end_clip, 1); if (code >= 0) code = end_code; /* take the first failure seen */ - if (end_code < 0 && cldev->error_is_retryable) { + if (end_code < 0) { /* * end_clip has to work despite lo-mem to maintain consistency. * This isn't error recovery, but just to prevent dangling @@ -623,7 +658,7 @@ */ ++cldev->ignore_lo_mem_warnings; end_code = - set_cmd_put_op(dp, cldev, pcls, cmd_opv_end_clip, 1); + set_cmd_put_op(&dp, cldev, pcls, cmd_opv_end_clip, 1); --cldev->ignore_lo_mem_warnings; } } @@ -652,7 +687,7 @@ map_data = pcs->params.indexed.lookup.table.data; map_size = num_values; } - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_color_space, + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_color_space, 2 + cmd_sizew(hival) + map_size + sizeof(clist_icc_color_t)); if (code < 0) @@ -663,7 +698,7 @@ memcpy(cmd_put_w(hival, dp + 2 + sizeof(clist_icc_color_t)), map_data, map_size); } else { - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_color_space, + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_color_space, 2 + sizeof(clist_icc_color_t)); memcpy(dp + 2, &(cldev->color_space.icc_info), sizeof(clist_icc_color_t)); @@ -680,7 +715,7 @@ /* ------ Driver procedures ------ */ int -clist_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath, +clist_fill_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) { @@ -688,7 +723,7 @@ &((gx_device_clist *)dev)->writer; uint unknown = 0; int ry, rheight, rx, rwidth, y0, y1; - gs_logical_operation_t lop = pis->log_op; + gs_logical_operation_t lop = pgs->log_op; byte op = (byte) (params->rule == gx_rule_even_odd ? cmd_opv_eofill : cmd_opv_fill); @@ -720,7 +755,7 @@ gs_debug_c(',') ) { /* Disable path-based banding. */ - return gx_default_fill_path(dev, pis, ppath, params, pdcolor, + return gx_default_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); } if (pdcolor != NULL && gx_dc_is_pattern2_color(pdcolor)) { @@ -733,7 +768,7 @@ See comment below about pdcolor == NULL. */ cdev->cropping_saved = false; - code = gx_default_fill_path(dev, pis, ppath, params, pdcolor, pcpath); + code = gx_default_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); if (cdev->cropping_saved) { cdev->cropping_min = cdev->save_cropping_min; cdev->cropping_max = cdev->save_cropping_max; @@ -745,7 +780,7 @@ } y0 = ry; y1 = ry + rheight; - cmd_check_fill_known(cdev, pis, params->flatness, &adjust, pcpath, + cmd_check_fill_known(cdev, pgs, params->flatness, &adjust, pcpath, &unknown); if (unknown) cmd_clear_known(cdev, unknown); @@ -779,6 +814,10 @@ re.y += re.height; } while (re.y < re.yend); } else { + /* We should not reach here with ppath==NULL (pdcolor != NULL, so not a shading fill */ + if (ppath == NULL) + return_error(gs_error_unregistered); + /* If needed, update the trans_bbox */ if (cdev->pdf14_needed) { gs_int_rect bbox; @@ -801,13 +840,13 @@ (code = cmd_update_lop(cdev, re.pcls, lop)) < 0 ) return code; - code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, + code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, devn_not_tile); if (code == gs_error_unregistered) return code; if (code < 0) { /* Something went wrong, use the default implementation. */ - return gx_default_fill_path(dev, pis, ppath, params, pdcolor, + return gx_default_fill_path(dev, pgs, ppath, params, pdcolor, pcpath); } re.pcls->color_usage.slow_rop |= slow_rop; @@ -825,19 +864,19 @@ } int -clist_stroke_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath, +clist_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_stroke_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) { gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer; - int pattern_size = pis->line_params.dash.pattern_size; + int pattern_size = pgs->line_params.dash.pattern_size; uint unknown = 0; gs_fixed_rect bbox; gs_fixed_point expansion; int adjust_y, expansion_code; int ry, rheight; - gs_logical_operation_t lop = pis->log_op; + gs_logical_operation_t lop = pgs->log_op; bool slow_rop = cmd_slow_rop(dev, lop_know_S_0(lop), pdcolor); cmd_rects_enum_t re; @@ -845,13 +884,13 @@ gs_debug_c(',') ) { /* Disable path-based banding. */ - return gx_default_stroke_path(dev, pis, ppath, params, pdcolor, + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); } gx_path_bbox(ppath, &bbox); - /* We must use the supplied imager state, not our saved one, */ + /* We must use the supplied gs_gstate, not our saved one, */ /* for computing the stroke expansion. */ - expansion_code = gx_stroke_path_expansion(pis, ppath, &expansion); + expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion); if (expansion_code < 0) { /* Expansion is too large: use the entire page. */ adjust_y = 0; @@ -868,39 +907,39 @@ } /* Check the dash pattern, since we bail out if */ /* the pattern is too large. */ - if (cdev->imager_state.line_params.dash.pattern_size != pattern_size || + if (cdev->gs_gstate.line_params.dash.pattern_size != pattern_size || (pattern_size != 0 && - memcmp(cdev->dash_pattern, pis->line_params.dash.pattern, + memcmp(cdev->dash_pattern, pgs->line_params.dash.pattern, pattern_size * sizeof(float))) || - cdev->imager_state.line_params.dash.offset != - pis->line_params.dash.offset || - cdev->imager_state.line_params.dash.adapt != - pis->line_params.dash.adapt || - cdev->imager_state.line_params.dot_length != - pis->line_params.dot_length || - cdev->imager_state.line_params.dot_length_absolute != - pis->line_params.dot_length_absolute + cdev->gs_gstate.line_params.dash.offset != + pgs->line_params.dash.offset || + cdev->gs_gstate.line_params.dash.adapt != + pgs->line_params.dash.adapt || + cdev->gs_gstate.line_params.dot_length != + pgs->line_params.dot_length || + cdev->gs_gstate.line_params.dot_length_absolute != + pgs->line_params.dot_length_absolute ) { /* Bail out if the dash pattern is too long. */ if (pattern_size > cmd_max_dash) - return gx_default_stroke_path(dev, pis, ppath, params, + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); unknown |= dash_known; /* * Temporarily reset the dash pattern pointer for gx_set_dash, * but don't leave it set, since that would confuse the GC. */ - cdev->imager_state.line_params.dash.pattern = cdev->dash_pattern; - gx_set_dash(&cdev->imager_state.line_params.dash, - pis->line_params.dash.pattern, - pis->line_params.dash.pattern_size, - pis->line_params.dash.offset, NULL); - cdev->imager_state.line_params.dash.pattern = 0; - gx_set_dash_adapt(&cdev->imager_state.line_params.dash, - pis->line_params.dash.adapt); - gx_set_dot_length(&cdev->imager_state.line_params, - pis->line_params.dot_length, - pis->line_params.dot_length_absolute); + cdev->gs_gstate.line_params.dash.pattern = cdev->dash_pattern; + gx_set_dash(&cdev->gs_gstate.line_params.dash, + pgs->line_params.dash.pattern, + pgs->line_params.dash.pattern_size, + pgs->line_params.dash.offset, NULL); + cdev->gs_gstate.line_params.dash.pattern = 0; + gx_set_dash_adapt(&cdev->gs_gstate.line_params.dash, + pgs->line_params.dash.adapt); + gx_set_dot_length(&cdev->gs_gstate.line_params, + pgs->line_params.dot_length, + pgs->line_params.dot_length_absolute); } if (state_neq(line_params.start_cap) || state_neq(line_params.join) || @@ -911,7 +950,7 @@ state_update(line_params.dash_cap); state_update(line_params.join); } - cmd_check_fill_known(cdev, pis, params->flatness, &pis->fill_adjust, + cmd_check_fill_known(cdev, pgs, params->flatness, &pgs->fill_adjust, pcpath, &unknown); if (state_neq(line_params.half_width)) { unknown |= line_width_known; @@ -919,8 +958,8 @@ } if (state_neq(line_params.miter_limit)) { unknown |= miter_limit_known; - gx_set_miter_limit(&cdev->imager_state.line_params, - pis->line_params.miter_limit); + gx_set_miter_limit(&cdev->gs_gstate.line_params, + pgs->line_params.miter_limit); } if (state_neq(ctm.xx) || state_neq(ctm.xy) || state_neq(ctm.yx) || state_neq(ctm.yy) || @@ -964,7 +1003,7 @@ return code; if (code < 0) { /* Something went wrong, use the default implementation. */ - return gx_default_stroke_path(dev, pis, ppath, params, pdcolor, + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pcpath); } re.pcls->color_usage.slow_rop |= slow_rop; @@ -1236,7 +1275,7 @@ if (notes != psw->notes) { byte *dp; int code = - set_cmd_put_op(dp, psw->cldev, psw->pcls, cmd_opv_set_misc2, 3); + set_cmd_put_op(&dp, psw->cldev, psw->pcls, cmd_opv_set_misc2, 3); if (code < 0) return code; @@ -1246,7 +1285,7 @@ } { int len = q + 2 - psw->cmd; byte *dp; - int code = set_cmd_put_op(dp, psw->cldev, psw->pcls, op, len); + int code = set_cmd_put_op(&dp, psw->cldev, psw->pcls, op, len); if (code < 0) return code; @@ -1338,7 +1377,7 @@ /* Information about the last emitted operation: */ int open = 0; /* -1 if last was moveto, 1 if line/curveto, */ /* 0 if newpath/closepath */ - struct { fixed vs[6]; } prev; + struct { fixed vs[6]; } prev = { { 0 } }; first.x = first.y = out.x = out.y = start.x = start.y = 0; /* Quiet gcc warning. */ if_debug4m('p', cldev->memory, "[p]initial (%g,%g), clip [%g..%g)\n", @@ -1375,7 +1414,7 @@ pcls->rect.y = fixed2int_var(py); if_debug2m('p', cldev->memory, "[p]final (%d,%d)\n", pcls->rect.x, pcls->rect.y); - return set_cmd_put_op(dp, cldev, pcls, path_op, 1); + return set_cmd_put_op(&dp, cldev, pcls, path_op, 1); case gs_pe_moveto: /* If the path is open and needs an implicit close, */ /* do a closepath and then redo the moveto. */ @@ -1416,7 +1455,7 @@ continue; } /* If we skipped any segments, put out a moveto/lineto. */ - if (side && (px != out.x || py != out.y || first_point())) { + if (side && ((open < 0) || (px != out.x || py != out.y || first_point()))) { C = out.x - px, D = out.y - py; if (open < 0) { first = out; @@ -1458,7 +1497,7 @@ continue; } /* If we skipped any segments, put out a moveto/lineto. */ - if (side && (px != out.x || py != out.y || first_point())) { + if (side && ((open < 0) || (px != out.x || py != out.y || first_point()))) { C = out.x - px, D = out.y - py; if (open < 0) { first = out; @@ -1590,7 +1629,7 @@ } else out_side = which_side(F); /* If we skipped any segments, put out a moveto/lineto. */ - if (side && (px != out.x || py != out.y || first_point())) { + if (side && ((open < 0) || (px != out.x || py != out.y || first_point()))) { fixed diff[2]; diff[0] = out.x - px, diff[1] = out.y - py; @@ -1634,21 +1673,22 @@ B == prev.F && D == prev.D && F == prev.B)) ) op = cmd_opv_scurveto; - else if (B == 0 && E == 0) { - B = A, E = F, optr++, op = cmd_opv_hvcurveto; - if ((B ^ D) >= 0) { - if (C == D && E == B) - op = cmd_opv_hqcurveto; - } else if (C == -D && E == -B) - C = D, op = cmd_opv_hqcurveto; - } else if (A == 0 && F == 0) { + else if (A == 0 && F == 0) { optr++, op = cmd_opv_vhcurveto; if ((B ^ C) >= 0) { if (D == C && E == B) op = cmd_opv_vqcurveto; } else if (D == -C && E == -B) op = cmd_opv_vqcurveto; - } else if (A == 0 && B == 0) + } else if (B == 0 && E == 0) { + B = A, E = F, optr++, op = cmd_opv_hvcurveto; + if ((B ^ D) >= 0) { + if (C == D && E == B) + op = cmd_opv_hqcurveto; + } else if (C == -D && E == -B) + C = D, op = cmd_opv_hqcurveto; + } + else if (A == 0 && B == 0) optr += 2, op = cmd_opv_nrcurveto; else if (E == 0 && F == 0) op = cmd_opv_rncurveto; diff -Nru ghostscript-9.10~dfsg/base/gxclpath.h ghostscript-9.25~dfsg+1/base/gxclpath.h --- ghostscript-9.10~dfsg/base/gxclpath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclpath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -58,10 +58,6 @@ /* Extend the command set. See gxcldev.h for more information. */ typedef enum { cmd_op_misc2 = 0xd0, /* (see below) */ - /* obsolete */ - /* cmd_opv_set_color = 0xd0, */ /* Used if base values do not fit into 1 bit */ - /* #flags,#base[0],...#base[num_comp-1] if flags */ - /* colored halftone with base colors a,b,c,d */ cmd_op_fill_rect_hl = 0xd1, /* rect fill with devn color */ cmd_opv_set_fill_adjust = 0xd2, /* adjust_x/y(fixed) */ cmd_opv_set_ctm = 0xd3, /* [per sput/sget_matrix] */ @@ -80,7 +76,7 @@ /* op_bm_tk: blend mode(5)text knockout(1)o.p.mode(1)o.p.(1) */ /* segment notes: (byte) */ /* opacity/shape: alpha(float)mask(TBD) */ - /* alpha: <> */ + /* alpha: <> */ cmd_opv_set_misc2 = 0xd5, /* mask#, selected parameters */ cmd_opv_set_dash = 0xd6, /* adapt(1)abs.dot(1)n(6), dot */ /* length(float), offset(float), */ @@ -99,7 +95,16 @@ /* flags# (0 = same raster & data_x, */ /* 1 = new raster & data_x, lsb first), */ /* [raster#, [data_x#,]]* */ - cmd_opv_extend = 0xdf, /* command, varies */ + cmd_opv_extend = 0xdf, /* command, varies (see gx_cmd_ext_op below) */ + + +#define cmd_misc2_op_name_strings\ + "?d0?", "fill_hl_color", \ + "set_fill_adjust", "set_ctm",\ + "set_color_space", "set_misc2", "set_dash", "enable_clip",\ + "disable_clip", "begin_clip", "end_clip", "begin_image_rect",\ + "begin_image", "image_data", "image_plane_data", "extended" + cmd_op_segment = 0xe0, /* (see below) */ cmd_opv_rmoveto = 0xe0, /* dx%, dy% */ cmd_opv_rlineto = 0xe1, /* dx%, dy% */ @@ -110,7 +115,7 @@ cmd_opv_rm3lineto = 0xe6, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3%, */ /* [-dx2,-dy2 implicit] */ cmd_opv_rrcurveto = 0xe7, /* dx1%,dy1%, dx2%,dy2%, dx3%,dy3% */ - cmd_opv_min_curveto = cmd_opv_rrcurveto, + cmd_opv_min_curveto = cmd_opv_rrcurveto, cmd_opv_hvcurveto = 0xe8, /* dx1%, dx2%,dy2%, dy3% */ cmd_opv_vhcurveto = 0xe9, /* dy1%, dx2%,dy2%, dx3% */ cmd_opv_nrcurveto = 0xea, /* dx2%,dy2%, dx3%,dy3% */ @@ -124,21 +129,30 @@ /* *curveto with one or more of dx/y1/3 = 0. */ /* If h*: -dx3,dy3, -dx2,dy2, -dx1,dy1. */ /* If v*: dx3,-dy3, dx2,-dy2, dx1,-dy1. */ - cmd_opv_max_curveto = cmd_opv_scurveto, + cmd_opv_max_curveto = cmd_opv_scurveto, cmd_opv_closepath = 0xef, /* (nothing) */ + +#define cmd_segment_op_name_strings\ + "rmoveto", "rlineto", "hlineto", "vlineto",\ + "rmlineto", "rm2lineto", "rm3lineto", "rrcurveto",\ + "hvcurveto", "vhcurveto", "nrcurveto", "rncurveto",\ + "vqcurveto", "hqcurveto", "scurveto", "closepath" + cmd_op_path = 0xf0, /* (see below) */ cmd_opv_fill = 0xf0, - cmd_opv_rgapto = 0xf1, /* dx%, dy% */ /* was cmd_opv_htfill */ + cmd_opv_rgapto = 0xf1, /* dx%, dy% */ cmd_opv_eofill = 0xf3, - /* cmd_opv_hteofill = 0xf4, */ /* obsolete */ - /* cmd_opv_coloreofill = 0xf5, */ /* obsolete */ cmd_opv_stroke = 0xf6, - /* cmd_opv_htstroke = 0xf7, */ /* obsolete */ - /* cmd_opv_colorstroke = 0xf8, */ /* obsolete */ cmd_opv_polyfill = 0xf9, - /* cmd_opv_htpolyfill = 0xfa, */ /* obsolete */ - /* cmd_opv_colorpolyfill = 0xfb */ /* obsolete */ cmd_opv_fill_trapezoid = 0xfc + +#define cmd_path_op_name_strings\ + "fill", "rgapto", "?f2?", "eofill",\ + "?f4?", "?f5", "stroke", "?f7?",\ + "?f8?", "polyfill", "?fa?", "?fb?",\ + "fill_trapezoid", "?fd?", "?fe?", "?ff?" + +/* unused cmd_op values: 0xd0, 0xf2, 0xf4, 0xf5, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfd, 0xfe, 0xff */ } gx_cmd_xop; /* This is usd for cmd_opv_ext_put_drawing_color so that we know if it @@ -171,25 +185,6 @@ #define cmd_segment_op_num_operands_values\ 2, 2, 1, 1, 4, 6, 6, 6, 4, 4, 4, 4, 2, 2, 0, 0 -#define cmd_misc2_op_name_strings\ - "cmd_opv_set_color", "fill_hl_color", \ - "set_fill_adjust", "set_ctm",\ - "set_color_space", "set_misc2", "set_dash", "enable_clip",\ - "disable_clip", "begin_clip", "end_clip", "begin_image_rect",\ - "begin_image", "image_data", "image_plane_data", "put_params" - -#define cmd_segment_op_name_strings\ - "rmoveto", "rlineto", "hlineto", "vlineto",\ - "rmlineto", "rm2lineto", "rm3lineto", "rrcurveto",\ - "hvcurveto", "vhcurveto", "nrcurveto", "rncurveto",\ - "vqcurveto", "hqcurveto", "scurveto", "closepath" - -#define cmd_path_op_name_strings\ - "fill", "htfill", "colorfill", "eofill",\ - "hteofill", "coloreofill", "stroke", "htstroke",\ - "colorstroke", "polyfill", "htpolyfill", "colorpolyfill",\ - "fill_trapezoid", "?fd?", "?fe?", "?ff?" - /* * We represent path coordinates as 'fixed' values in a variable-length, * relative form (s/t = sign, x/y = integer, f/g = fraction): @@ -220,11 +215,11 @@ /* The procedures and macros defined here are used when writing */ /* (gxclimag.c, gxclpath.c). */ -/* Compare and update members of the imager state. */ +/* Compare and update members of the gs_gstate. */ #define state_neq(member)\ - (cdev->imager_state.member != pis->member) + (cdev->gs_gstate.member != pgs->member) #define state_update(member)\ - (cdev->imager_state.member = pis->member) + (cdev->gs_gstate.member = pgs->member) /* ------ Exported by gxclpath.c ------ */ diff -Nru ghostscript-9.10~dfsg/base/gxclrast.c ghostscript-9.25~dfsg+1/base/gxclrast.c --- ghostscript-9.10~dfsg/base/gxclrast.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclrast.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,7 +23,7 @@ #include "gscdefs.h" /* for image type table */ #include "gsbitops.h" #include "gsparams.h" -#include "gsstate.h" /* (should only be imager state) */ +#include "gsstate.h" /* (should only be gs_gstate) */ #include "gstrans.h" /* for gs_is_pdf14trans_compositor */ #include "gxdcolor.h" #include "gxdevice.h" @@ -247,22 +247,22 @@ int compress, gx_clist_state *pcls, gx_strip_bitmap *tile, tile_slot **pslot, gx_device_clist_reader *cdev, gs_memory_t *mem); -static int read_set_misc2(command_buf_t *pcb, gs_imager_state *pis, +static int read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes); -static int read_set_color_space(command_buf_t *pcb, gs_imager_state *pis, +static int read_set_color_space(command_buf_t *pcb, gs_gstate *pgs, gs_color_space **ppcs, gx_device_clist_reader *cdev, gs_memory_t *mem); static int read_begin_image(command_buf_t *pcb, gs_image_common_t *pic, gs_color_space *pcs); -static int read_put_params(command_buf_t *pcb, gs_imager_state *pis, +static int read_put_params(command_buf_t *pcb, gs_gstate *pgs, gx_device_clist_reader *cdev, gs_memory_t *mem); static int read_create_compositor(command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp); -static int apply_create_compositor(gx_device_clist_reader *cdev, gs_imager_state *pis, +static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs, gs_memory_t *mem, gs_composite_t *pcomp, int x0, int y0, gx_device **ptarget); static int read_alloc_ht_buff(ht_buff_t *, uint, gs_memory_t *); -static int read_ht_segment(ht_buff_t *, command_buf_t *, gs_imager_state *, +static int read_ht_segment(ht_buff_t *, command_buf_t *, gs_gstate *, gx_device *, gs_memory_t *); static const byte *cmd_read_rect(int, gx_cmd_rect *, const byte *); @@ -270,7 +270,7 @@ int width_bytes, int height, uint raster, const byte *cbp); static int cmd_select_map(cmd_map_index, cmd_map_contents, - gs_imager_state *, int **, + gs_gstate *, int **, frac **, uint *, gs_memory_t *); static int cmd_create_dev_ht(gx_device_halftone **, gs_memory_t *); static int cmd_resize_halftone(gx_device_halftone **, uint, @@ -370,7 +370,7 @@ } static int -execute_compositor_queue(gx_device_clist_reader *cdev, gx_device **target, gx_device **tdev, gs_imager_state *pis, +execute_compositor_queue(gx_device_clist_reader *cdev, gx_device **target, gx_device **tdev, gs_gstate *pgs, gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp_from, int x0, int y0, gs_memory_t *mem, bool idle) { @@ -383,7 +383,7 @@ if (code < 0) return code; pcomp->idle |= idle; - code = apply_create_compositor(cdev, pis, mem, pcomp, x0, y0, target); /* Releases the compositor. */ + code = apply_create_compositor(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */ if (code < 0) return code; *tdev = *target; @@ -407,7 +407,7 @@ static inline int drop_compositor_queue(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp_from, gs_memory_t *mem, int x0, int y0, - gs_imager_state *pis) + gs_gstate *pgs) { gs_composite_t *pcomp; @@ -418,7 +418,7 @@ if (pcomp == NULL) return 0; dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last); - code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pis); + code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs); if (code < 0) return code; free_compositor(pcomp, mem); @@ -427,18 +427,18 @@ } static int -read_set_misc_map(byte cb, command_buf_t *pcb, gs_imager_state *pis, gs_memory_t *mem) +read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem) { const byte *cbp = pcb->ptr; frac *mdata; int *pcomp_num; - uint count; + uint count = 0; /* quiet compiler */ cmd_map_contents cont = (cmd_map_contents)(cb & 0x30) >> 4; int code; code = cmd_select_map(cb & 0xf, cont, - pis, + pgs, &pcomp_num, &mdata, &count, mem); @@ -468,7 +468,7 @@ } /* Recompute the effective transfer, */ /* in case this was a transfer map. */ - gx_imager_set_effective_xfer(pis); + gx_gstate_set_effective_xfer(pgs); pcb->ptr = cbp; return 0; } @@ -509,12 +509,14 @@ gx_device_color dcolor; } clip_save; bool in_clip = false; - gs_imager_state imager_state; + gs_gstate gs_gstate; gx_device_color dev_color; float dash_pattern[cmd_max_dash]; gx_fill_params fill_params; gx_stroke_params stroke_params; +#ifdef DEBUG gs_halftone_type halftone_type; +#endif union im_ { gs_image_common_t c; gs_data_image_t d; @@ -606,12 +608,12 @@ } if (target != 0) (*dev_proc(target, get_clipping_box))(target, &target_box); - imager_state = clist_imager_state_initial; - code = gs_imager_state_initialize(&imager_state, mem); + GS_STATE_INIT_VALUES_CLIST((&gs_gstate)); + code = gs_gstate_initialize(&gs_gstate, mem); /* Remove the ICC link cache and replace with the device link cache so that we share the cache across bands */ - rc_decrement(imager_state.icc_link_cache,"clist_playback_band"); - imager_state.icc_link_cache = cdev->icc_cache_cl; + rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band"); + gs_gstate.icc_link_cache = cdev->icc_cache_cl; /* Need to lock during the increment of the link cache */ gx_monitor_enter(cdev->icc_cache_cl->lock); rc_increment(cdev->icc_cache_cl); @@ -619,16 +621,20 @@ if (code < 0) goto out; - imager_state.line_params.dash.pattern = dash_pattern; - if (tdev != 0) - gx_set_cmap_procs(&imager_state, tdev); - gx_imager_setscreenphase(&imager_state, -x0, -y0, gs_color_select_all); + gs_gstate.line_params.dash.pattern = dash_pattern; + if (tdev != 0) { + gx_set_cmap_procs(&gs_gstate, tdev); + } + gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all); +#ifdef DEBUG halftone_type = ht_type_none; +#endif pcs = gs_cspace_new_DeviceGray(mem); if (pcs == NULL) { code = gs_note_error(gs_error_VMerror); goto out; } + dev_color.ccolor_valid = false; color_unset(&dev_color); data_bits = gs_alloc_bytes(mem, data_bits_size, "clist_playback_band(data_bits)"); @@ -682,7 +688,7 @@ case cmd_opv_set_tile_size: cbuf.ptr = cbp; code = read_set_tile_size(&cbuf, &tile_bits, - IS_CLIST_FOR_PATTERN(cdev)); + gx_device_is_pattern_clist((gx_device *)cdev)); cbp = cbuf.ptr; if (code < 0) goto out; @@ -734,7 +740,7 @@ state.lop = (state.lop << 6) + (cb & 0x3f); if_debug1m('L', mem, " lop=0x%x\n", state.lop); if (state.lop_enabled) - imager_state.log_op = state.lop; + gs_gstate.log_op = state.lop; break; case cmd_set_misc_data_x >> 6: if (cb & 0x20) @@ -746,20 +752,23 @@ break; case cmd_set_misc_map >> 6: cbuf.ptr = cbp; - code = read_set_misc_map(cb, &cbuf, &imager_state, mem); + code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem); if (code < 0) goto out; cbp = cbuf.ptr; break; case cmd_set_misc_halftone >> 6: { uint num_comp; - +#ifdef DEBUG halftone_type = cb & 0x3f; +#endif cmd_getw(num_comp, cbp); +#ifdef DEBUG if_debug2m('L', mem, " halftone type=%d num_comp=%u\n", halftone_type, num_comp); +#endif code = cmd_resize_halftone( - &imager_state.dev_ht, + &gs_gstate.dev_ht, num_comp, mem); if (code < 0) goto out; @@ -772,12 +781,12 @@ continue; case cmd_opv_enable_lop: state.lop_enabled = true; - imager_state.log_op = state.lop; + gs_gstate.log_op = state.lop; if_debug0m('L', mem, "\n"); continue; case cmd_opv_disable_lop: state.lop_enabled = false; - imager_state.log_op = lop_default; + gs_gstate.log_op = lop_default; if_debug0m('L', mem, "\n"); continue; case cmd_opv_end_page: @@ -807,14 +816,17 @@ data = *cbp++; delta = (((gx_color_index) ((data & 0xf0) << 4) + (data & 0x0f)) << 24) << 24; + /* fall through */ case 6: data = *cbp++; delta |= (((gx_color_index) ((data & 0xf0) << 4) + (data & 0x0f)) << 16) << 16; + /* fall through */ case 4: data = *cbp++; delta |= ((gx_color_index) ((data & 0xf0) << 4) + (data & 0x0f)) << 16; + /* fall through */ case 2: data = *cbp++; delta |= ((gx_color_index) @@ -825,10 +837,12 @@ data = *cbp++; delta = ((gx_color_index) ((data & 0xf0) << 4) + (data & 0x0f)) << 16; + /* fall through */ case 5: data = *cbp++; delta |= ((gx_color_index) ((data & 0xf0) << 4) + (data & 0x0f)); + /* fall through */ case 3: data = *cbp++; odd_delta_shift = (dev_depth_bytes - 3) * 8; @@ -958,7 +972,7 @@ plane_height = 0; copy:cmd_getw(state.rect.x, cbp); cmd_getw(state.rect.y, cbp); - if (op & 8) { /* Use the current "tile". */ + if (op & cmd_copy_use_tile) { /* Use the current "tile". */ #ifdef DEBUG if (state_slot->index != state.tile_index) { mlprintf2(mem, "state_slot->index = %d, state.tile_index = %d!\n", @@ -971,13 +985,15 @@ depth = state_slot->cb_depth; state.rect.width = state_slot->width; state.rect.height = state_slot->height; + if (state.rect.y + state.rect.height > cdev->height) + state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */ raster = state_slot->cb_raster; source = (byte *) (state_slot + 1); } else { /* Read width, height, bits. */ /* depth was set already. */ uint width_bits, width_bytes; uint bytes; - uint planes = 1; + uchar planes = 1; uint plane_depth = depth; uint pln; byte compression = op & 3; @@ -1117,7 +1133,7 @@ state.tile_index = ((op & 0xf) << 8) + *cbp++; sti:state_slot = - (tile_slot *) (cdev->chunk.data + + (tile_slot *) (cdev->cache_chunk->data + cdev->tile_table[state.tile_index].offset); if_debug2m('L', mem, " index=%u offset=%lu\n", state.tile_index, @@ -1152,10 +1168,10 @@ if (state_tile.size.x) tile_phase.x = (state.tile_phase.x + x0) % state_tile.size.x; - if (imager_state.dev_ht && imager_state.dev_ht->lcm_width) + if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_width) color_phase.x = (state.tile_phase.x + x0) % - imager_state.dev_ht->lcm_width; + gs_gstate.dev_ht->lcm_width; /* * The true tile height for shifted tiles is not * size.y: see gxbitmap.h for the computation. @@ -1173,11 +1189,11 @@ tile_phase.y = (state.tile_phase.y + y0) % full_height; } - if (imager_state.dev_ht && imager_state.dev_ht->lcm_height) + if (gs_gstate.dev_ht && gs_gstate.dev_ht->lcm_height) color_phase.y = (state.tile_phase.y + y0) % - imager_state.dev_ht->lcm_height; - gx_imager_setscreenphase(&imager_state, + gs_gstate.dev_ht->lcm_height; + gx_gstate_setscreenphase(&gs_gstate, -(state.tile_phase.x + x0), -(state.tile_phase.y + y0), gs_color_select_all); @@ -1185,11 +1201,11 @@ case cmd_op_misc2 >> 4: switch (op) { case cmd_opv_set_fill_adjust: - cmd_get_value(imager_state.fill_adjust.x, cbp); - cmd_get_value(imager_state.fill_adjust.y, cbp); + cmd_get_value(gs_gstate.fill_adjust.x, cbp); + cmd_get_value(gs_gstate.fill_adjust.y, cbp); if_debug2m('L', mem, " (%g,%g)\n", - fixed2float(imager_state.fill_adjust.x), - fixed2float(imager_state.fill_adjust.y)); + fixed2float(gs_gstate.fill_adjust.x), + fixed2float(gs_gstate.fill_adjust.y)); continue; case cmd_opv_set_ctm: { @@ -1201,12 +1217,12 @@ mat.tx, mat.ty); mat.tx -= x0; mat.ty -= y0; - gs_imager_setmatrix(&imager_state, &mat); + gs_gstate_setmatrix(&gs_gstate, &mat); } continue; case cmd_opv_set_misc2: cbuf.ptr = cbp; - code = read_set_misc2(&cbuf, &imager_state, ¬es); + code = read_set_misc2(&cbuf, &gs_gstate, ¬es); cbp = cbuf.ptr; if (code < 0) goto out; @@ -1221,12 +1237,12 @@ cmd_get_value(offset, cbp); memcpy(dash_pattern, cbp, n * sizeof(float)); - gx_set_dash(&imager_state.line_params.dash, + gx_set_dash(&gs_gstate.line_params.dash, dash_pattern, n, offset, NULL); - gx_set_dash_adapt(&imager_state.line_params.dash, + gx_set_dash_adapt(&gs_gstate.line_params.dash, (nb & 0x80) != 0); - gx_set_dot_length(&imager_state.line_params, + gx_set_dot_length(&gs_gstate.line_params, dot_length, (nb & 0x40) != 0); #ifdef DEBUG @@ -1247,6 +1263,11 @@ break; case cmd_opv_enable_clip: pcpath = (use_clip ? &clip_path : NULL); + if (pcpath) { + code = gx_cpath_ensure_path_list(pcpath); + if (code < 0) + goto out; + } clipper_dev_open = false; if_debug0m('L', mem, "\n"); break; @@ -1263,7 +1284,7 @@ code = gx_cpath_reset(&clip_path); if (code < 0) goto out; - gx_cpath_accum_begin(&clip_accum, mem); + gx_cpath_accum_begin(&clip_accum, mem, false); gx_cpath_accum_set_cbox(&clip_accum, &target_box); tdev = (gx_device *)&clip_accum; @@ -1272,7 +1293,7 @@ /* temporarily set a solid color */ color_set_pure(&dev_color, (gx_color_index)1); state.lop_enabled = false; - imager_state.log_op = lop_default; + gs_gstate.log_op = lop_default; break; case cmd_opv_end_clip: if_debug0m('L', mem, "\n"); @@ -1293,9 +1314,14 @@ cbox.q.y >= target_box.q.y); } pcpath = (use_clip ? &clip_path : NULL); + if (pcpath) { + code = gx_cpath_ensure_path_list(pcpath); + if (code < 0) + goto out; + } clipper_dev_open = false; state.lop_enabled = clip_save.lop_enabled; - imager_state.log_op = + gs_gstate.log_op = (state.lop_enabled ? state.lop : lop_default); dev_color = clip_save.dcolor; @@ -1303,7 +1329,7 @@ break; case cmd_opv_set_color_space: cbuf.ptr = cbp; - code = read_set_color_space(&cbuf, &imager_state, + code = read_set_color_space(&cbuf, &gs_gstate, &pcs, cdev, mem); cbp = cbuf.ptr; if (code < 0) { @@ -1369,9 +1395,9 @@ ibegin: if_debug0m('L', mem, "\n"); { /* Processing an image operation */ - dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG); + dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */ code = (*dev_proc(tdev, begin_typed_image)) - (tdev, &imager_state, NULL, + (tdev, &gs_gstate, NULL, (const gs_image_common_t *)&image, &image_rect, &dev_color, pcpath, mem, &image_info); @@ -1396,15 +1422,15 @@ cmd_getw(flags, cbp); for (plane = 0; plane < image_info->num_planes; - ++plane, flags >>= 1 - ) { + ++plane, flags >>= 1) { if (flags & 1) { if (cbuf.end - cbp < - 2 * cmd_max_intsize(sizeof(uint))) + 2 * cmd_max_intsize(sizeof(uint))) { code = top_up_cbuf(&cbuf, &cbp); if (code < 0) return code; - cmd_getw(planes[plane].raster, cbp); + } + cmd_getw(planes[plane].raster, cbp) ; if ((raster1 = planes[plane].raster) != 0) cmd_getw(data_x, cbp); } else { @@ -1448,10 +1474,11 @@ } data_size *= data_height; data_on_heap = 0; - if (cbuf.end - cbp < data_size) + if (cbuf.end - cbp < data_size) { code = top_up_cbuf(&cbuf, &cbp); if (code < 0) return code; + } if (cbuf.end - cbp >= data_size) { planes[0].data = cbp; cbp += data_size; @@ -1525,8 +1552,9 @@ case cmd_opv_extend: switch (*cbp++) { case cmd_opv_ext_put_params: + if_debug0m('L', mem, "put_params\n"); cbuf.ptr = cbp; - code = read_put_params(&cbuf, &imager_state, + code = read_put_params(&cbuf, &gs_gstate, cdev, mem); cbp = cbuf.ptr; if (code > 0) @@ -1543,7 +1571,7 @@ * The screen phase may have been changed during * the processing of masked images. */ - gx_imager_setscreenphase(&imager_state, + gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all); cbp -= 2; /* Step back to simplify the cycle invariant below. */ for (;;) { @@ -1560,6 +1588,7 @@ } if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_create_compositor) { gs_composite_t *pcomp, *pcomp_opening; + gs_compositor_closing_state closing_state; cbuf.ptr = cbp += 2; code = read_create_compositor(&cbuf, mem, &pcomp); @@ -1576,60 +1605,68 @@ continue; } pcomp_opening = pcomp_last; - code = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev); - if (code < 0) + closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev); + switch(closing_state) + { + default: + code = (int)closing_state; + if (code >= 0) + code = gs_note_error(gs_error_unregistered); /* Must not happen. */ goto out; - else if (code == 0) { + case COMP_ENQUEUE: /* Enqueue. */ enqueue_compositor(&pcomp_first, &pcomp_last, pcomp); - } else if (code == 1) { + break; + case COMP_EXEC_IDLE: /* Execute idle. */ enqueue_compositor(&pcomp_first, &pcomp_last, pcomp); code = execute_compositor_queue(cdev, &target, &tdev, - &imager_state, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true); + &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true); if (code < 0) goto out; - } else if (code == 2) { + break; + case COMP_EXEC_QUEUE: /* The opening command was executed. Execute the queue. */ enqueue_compositor(&pcomp_first, &pcomp_last, pcomp); code = execute_compositor_queue(cdev, &target, &tdev, - &imager_state, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false); + &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false); if (code < 0) goto out; - } else if (code == 3) { + break; + case COMP_REPLACE_PREV: /* Replace last compositors. */ code = execute_compositor_queue(cdev, &target, &tdev, - &imager_state, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true); + &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true); if (code < 0) goto out; enqueue_compositor(&pcomp_first, &pcomp_last, pcomp); - } else if (code == 4) { + break; + case COMP_REPLACE_CURR: /* Replace specific compositor. */ code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening); if (code < 0) goto out; enqueue_compositor(&pcomp_first, &pcomp_last, pcomp); free_compositor(pcomp_opening, mem); - } else if (code == 5) { + break; + case COMP_DROP_QUEUE: /* Annihilate the last compositors. */ enqueue_compositor(&pcomp_first, &pcomp_last, pcomp); - code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &imager_state); + code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate); if (code < 0) goto out; - } else if (code == 6) { + break; + case COMP_MARK_IDLE: /* Mark as idle. */ enqueue_compositor(&pcomp_first, &pcomp_last, pcomp); mark_as_idle(pcomp_opening, pcomp); - } else { - code = gs_note_error(gs_error_unregistered); /* Must not happen. */ - goto out; } } else if (is_null_compositor_op(cbp, &len)) { cbuf.ptr = cbp += len; } else if (cbp[0] == cmd_opv_end_page) { /* End page, drop the queue. */ code = execute_compositor_queue(cdev, &target, &tdev, - &imager_state, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true); + &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true); if (code < 0) goto out; break; @@ -1660,7 +1697,7 @@ case cmd_opv_ext_put_ht_seg: cbuf.ptr = cbp; code = read_ht_segment(&ht_buff, &cbuf, - &imager_state, tdev, + &gs_gstate, tdev, mem); cbp = cbuf.ptr; if (code < 0) @@ -1676,7 +1713,7 @@ switch (cb >> 6) { case cmd_set_misc_map >> 6: cbuf.ptr = cbp; - code = read_set_misc_map(cb, &cbuf, &imager_state, mem); + code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem); if (code < 0) goto out; cbp = cbuf.ptr; @@ -1693,7 +1730,7 @@ } else { /* A drawing command, execute entire queue. */ code = execute_compositor_queue(cdev, &target, &tdev, - &imager_state, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false); + &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false); if (code < 0) goto out; break; @@ -1719,7 +1756,7 @@ if_debug0m('L', mem, " ext_put_ht_seg\n"); cbuf.ptr = cbp; code = read_ht_segment(&ht_buff, &cbuf, - &imager_state, tdev, + &gs_gstate, tdev, mem); cbp = cbuf.ptr; if (code < 0) @@ -1776,7 +1813,7 @@ if (!left) { /* We still need to call pdct->read because it may change dev_color.type - see gx_dc_null_read.*/ - code = pdct->read(pdcolor, &imager_state, + code = pdct->read(pdcolor, &gs_gstate, pdcolor, tdev, offset, cbp, 0, mem); if (code < 0) @@ -1789,7 +1826,7 @@ return code; } l = min(left, cbuf.end - cbp); - code = pdct->read(pdcolor, &imager_state, + code = pdct->read(pdcolor, &gs_gstate, pdcolor, tdev, offset, cbp, l, mem); if (code < 0) @@ -1799,7 +1836,7 @@ offset += l; left -= l; } - code = gx_color_load(pdcolor, &imager_state, + code = gx_color_load(pdcolor, &gs_gstate, tdev); if (code < 0) goto out; @@ -1899,8 +1936,8 @@ if (in_clip) { gx_path_init_local(&fpath, mem); code = gx_path_add_flattened_accurate(&path, &fpath, - gs_currentflat_inline(&imager_state), - imager_state.accurate_curves); + gs_currentflat_inline(&gs_gstate), + gs_gstate.accurate_curves); if (code < 0) goto out; ppath = &fpath; @@ -1912,24 +1949,24 @@ case cmd_opv_eofill: fill_params.rule = gx_rule_even_odd; fill: - fill_params.adjust = imager_state.fill_adjust; - fill_params.flatness = imager_state.flatness; + fill_params.adjust = gs_gstate.fill_adjust; + fill_params.flatness = gs_gstate.flatness; code = gx_fill_path_only(ppath, tdev, - &imager_state, + &gs_gstate, &fill_params, &dev_color, pcpath); break; case cmd_opv_stroke: - stroke_params.flatness = imager_state.flatness; + stroke_params.flatness = gs_gstate.flatness; stroke_params.traditional = false; code = (*dev_proc(tdev, stroke_path)) - (tdev, &imager_state, + (tdev, &gs_gstate, ppath, &stroke_params, &dev_color, pcpath); break; case cmd_opv_polyfill: code = clist_do_polyfill(tdev, ppath, &dev_color, - imager_state.log_op); + gs_gstate.log_op); break; case cmd_opv_fill_trapezoid: { @@ -1956,6 +1993,7 @@ the information that is used in the trap code */ ttdev->color_info.num_components = tdev->color_info.num_components; ttdev->color_info.depth = tdev->color_info.depth; + ttdev->color_info.polarity = tdev->color_info.polarity; memcpy(&(ttdev->color_info.comp_bits),&(tdev->color_info.comp_bits),GX_DEVICE_COLOR_MAX_COMPONENTS); memcpy(&(ttdev->color_info.comp_shift),&(tdev->color_info.comp_shift),GX_DEVICE_COLOR_MAX_COMPONENTS); } @@ -1986,7 +2024,7 @@ right.end.x -= x0f; right.end.y -= y0f; if (options & 2) { - int num_components = tdev->color_info.num_components; + uchar num_components = tdev->color_info.num_components; frac31 c[4][GX_DEVICE_COLOR_MAX_COMPONENTS], *cc[4]; byte colors_mask, i, j, m = 1; gs_fill_attributes fa; @@ -2013,7 +2051,7 @@ fa.clip = &clip; fa.swap_axes = swap_axes; fa.ht = NULL; - fa.lop = lop_default; /* fgixme: imager_state.log_op; */ + fa.lop = lop_default; /* fgixme: gs_gstate.log_op; */ fa.ystart = ybot - y0f; fa.yend = ytop - y0f; cmd_getw(colors_mask, cbp); @@ -2070,7 +2108,7 @@ code = gx_default_fill_trapezoid(ttdev, &left, &right, max(ybot - y0f, fixed_half), min(ytop - y0f, int2fixed(wh)), swap_axes, - &dev_color, imager_state.log_op); + &dev_color, gs_gstate.log_op); } break; default: @@ -2115,7 +2153,7 @@ /* FIXME: This test should be unnecessary. Bug 692076 * is open pending a proper fix. */ code = (dev_proc(tdev, fillpage) == NULL ? 0 : - (*dev_proc(tdev, fillpage))(tdev, &imager_state, + (*dev_proc(tdev, fillpage))(tdev, &gs_gstate, &dev_color)); break; } @@ -2162,7 +2200,7 @@ case cmd_op_tile_rect >> 4: if (state.rect.width == 0 && state.rect.height == 0 && state.rect.x == 0 && state.rect.y == 0) { - code = (*dev_proc(tdev, fillpage))(tdev, &imager_state, &dev_color); + code = (*dev_proc(tdev, fillpage))(tdev, &gs_gstate, &dev_color); break; } case cmd_op_tile_rect_short >> 4: @@ -2189,7 +2227,7 @@ (tdev, source, data_x, raster, gx_no_bitmap_id, state.rect.x - x0, state.rect.y - y0, state.rect.width - data_x, state.rect.height, - &dev_color, 1, imager_state.log_op, pcpath); + &dev_color, 1, gs_gstate.log_op, pcpath); } else { if (plane_height == 0) { code = (*dev_proc(tdev, copy_mono)) @@ -2211,7 +2249,8 @@ case cmd_op_copy_color_alpha >> 4: if (state.color_is_alpha) { /****** CAN'T DO ROP WITH ALPHA ******/ - if (state.color_is_devn) { + if (state.color_is_devn && + dev_proc(tdev, copy_alpha_hl_color) != gx_default_no_copy_alpha_hl_color) { /* FIXME */ code = (*dev_proc(tdev, copy_alpha_hl_color)) (tdev, source, data_x, raster, gx_no_bitmap_id, state.rect.x - x0, state.rect.y - y0, @@ -2252,7 +2291,7 @@ ht_buff.read_size = 0; if (pcomp_last != NULL) { - int code1 = drop_compositor_queue(&pcomp_first, &pcomp_last, NULL, mem, x0, y0, &imager_state); + int code1 = drop_compositor_queue(&pcomp_first, &pcomp_last, NULL, mem, x0, y0, &gs_gstate); if (code == 0) code = code1; @@ -2260,14 +2299,14 @@ rc_decrement_cs(pcs, "clist_playback_band"); gx_cpath_free(&clip_path, "clist_render_band exit"); gx_path_free(&path, "clist_render_band exit"); - if (imager_state.pattern_cache != NULL) { - gx_pattern_cache_free(imager_state.pattern_cache); - imager_state.pattern_cache = NULL; + if (gs_gstate.pattern_cache != NULL) { + gx_pattern_cache_free(gs_gstate.pattern_cache); + gs_gstate.pattern_cache = NULL; } /* The imager state release will decrement the icc link cache. To avoid race conditions lock the cache */ gx_monitor_enter(cdev->icc_cache_cl->lock); - gs_imager_state_release(&imager_state); + gs_gstate_release(&gs_gstate); gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */ gs_free_object(mem, data_bits, "clist_playback_band(data_bits)"); if (target != orig_target) { @@ -2281,7 +2320,8 @@ rc_decrement(target, "gxclrast(target compositor)"); } else { /* Ref count was 1. close the device and then free it */ - dev_proc(target, close_device)(target); + if (target->is_open) + dev_proc(target, close_device)(target); gs_free_object(target->memory, target, "gxclrast discard compositor"); } target = orig_target; @@ -2397,7 +2437,7 @@ if_debug2m('L', mem, " index=%d offset=%lu\n", pcls->tile_index, offset); pcls->tile_index = index; cdev->tile_table[pcls->tile_index].offset = offset; - slot = (tile_slot *)(cdev->chunk.data + offset); + slot = (tile_slot *)(cdev->cache_chunk->data + offset); *pslot = slot; *slot = *bits; tile->data = data = (byte *)(slot + 1); @@ -2526,7 +2566,7 @@ read_ht_segment( ht_buff_t * pht_buff, command_buf_t * pcb, - gs_imager_state * pis, + gs_gstate * pgs, gx_device * dev, gs_memory_t * mem ) { @@ -2563,7 +2603,7 @@ /* if everything has been read, convert back to a halftone */ if (pbuff != 0) { - code = gx_ht_read_and_install(pis, dev, pbuff, ht_size, mem); + code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem); /* release any buffered information */ if (pht_buff->pbuff != 0) { @@ -2582,7 +2622,7 @@ } static int -read_set_misc2(command_buf_t *pcb, gs_imager_state *pis, segment_notes *pnotes) +read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes) { const byte *cbp = pcb->ptr; uint mask, cb; @@ -2590,80 +2630,80 @@ cmd_getw(mask, cbp); if (mask & cap_join_known) { cb = *cbp++; - pis->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7); - pis->line_params.join = (gs_line_join)(cb & 7); - if_debug2m('L', pis->memory, " start_cap=%d join=%d\n", - pis->line_params.start_cap, pis->line_params.join); + pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7); + pgs->line_params.join = (gs_line_join)(cb & 7); + if_debug2m('L', pgs->memory, " start_cap=%d join=%d\n", + pgs->line_params.start_cap, pgs->line_params.join); cb = *cbp++; - pis->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7); - pis->line_params.dash_cap = (gs_line_cap)(cb & 7); - if_debug2m('L', pis->memory, "end_cap=%d dash_cap=%d\n", - pis->line_params.end_cap, pis->line_params.dash_cap); + pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7); + pgs->line_params.dash_cap = (gs_line_cap)(cb & 7); + if_debug2m('L', pgs->memory, "end_cap=%d dash_cap=%d\n", + pgs->line_params.end_cap, pgs->line_params.dash_cap); } if (mask & cj_ac_sa_known) { cb = *cbp++; - pis->line_params.curve_join = ((cb >> 2) & 7) - 1; - pis->accurate_curves = (cb & 2) != 0; - pis->stroke_adjust = cb & 1; - if_debug3m('L', pis->memory, " CJ=%d AC=%d SA=%d\n", - pis->line_params.curve_join, pis->accurate_curves, - pis->stroke_adjust); + pgs->line_params.curve_join = ((cb >> 2) & 7) - 1; + pgs->accurate_curves = (cb & 2) != 0; + pgs->stroke_adjust = cb & 1; + if_debug3m('L', pgs->memory, " CJ=%d AC=%d SA=%d\n", + pgs->line_params.curve_join, pgs->accurate_curves, + pgs->stroke_adjust); } if (mask & flatness_known) { - cmd_get_value(pis->flatness, cbp); - if_debug1m('L', pis->memory, " flatness=%g\n", pis->flatness); + cmd_get_value(pgs->flatness, cbp); + if_debug1m('L', pgs->memory, " flatness=%g\n", pgs->flatness); } if (mask & line_width_known) { float width; cmd_get_value(width, cbp); - if_debug1m('L', pis->memory, " line_width=%g\n", width); - gx_set_line_width(&pis->line_params, width); + if_debug1m('L', pgs->memory, " line_width=%g\n", width); + gx_set_line_width(&pgs->line_params, width); } if (mask & miter_limit_known) { float limit; cmd_get_value(limit, cbp); - if_debug1m('L', pis->memory, " miter_limit=%g\n", limit); - gx_set_miter_limit(&pis->line_params, limit); + if_debug1m('L', pgs->memory, " miter_limit=%g\n", limit); + gx_set_miter_limit(&pgs->line_params, limit); } if (mask & op_bm_tk_known) { cb = *cbp++; - pis->blend_mode = cb >> 3; - pis->text_knockout = (cb & 4) != 0; + pgs->blend_mode = cb >> 3; + pgs->text_knockout = (cb & 4) != 0; /* the following usually have no effect; see gxclpath.c */ - pis->overprint_mode = (cb >> 1) & 1; - pis->effective_overprint_mode = pis->overprint_mode; - pis->overprint = cb & 1; + pgs->overprint_mode = (cb >> 1) & 1; + pgs->effective_overprint_mode = pgs->overprint_mode; + pgs->overprint = cb & 1; cb = *cbp++; - pis->renderingintent = cb; - if_debug5m('L', pis->memory, " BM=%d TK=%d OPM=%d OP=%d RI=%d\n", - pis->blend_mode, pis->text_knockout, pis->overprint_mode, - pis->overprint, pis->renderingintent); + pgs->renderingintent = cb; + if_debug5m('L', pgs->memory, " BM=%d TK=%d OPM=%d OP=%d RI=%d\n", + pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode, + pgs->overprint, pgs->renderingintent); } if (mask & segment_notes_known) { cb = *cbp++; *pnotes = (segment_notes)(cb & 0x3f); - if_debug1m('L', pis->memory, " notes=%d\n", *pnotes); + if_debug1m('L', pgs->memory, " notes=%d\n", *pnotes); } if (mask & opacity_alpha_known) { - cmd_get_value(pis->opacity.alpha, cbp); - if_debug1m('L', pis->memory, " opacity.alpha=%g\n", pis->opacity.alpha); + cmd_get_value(pgs->opacity.alpha, cbp); + if_debug1m('L', pgs->memory, " opacity.alpha=%g\n", pgs->opacity.alpha); } if (mask & shape_alpha_known) { - cmd_get_value(pis->shape.alpha, cbp); - if_debug1m('L', pis->memory, " shape.alpha=%g\n", pis->shape.alpha); + cmd_get_value(pgs->shape.alpha, cbp); + if_debug1m('L', pgs->memory, " shape.alpha=%g\n", pgs->shape.alpha); } if (mask & alpha_known) { - cmd_get_value(pis->alpha, cbp); - if_debug1m('L', pis->memory, " alpha=%u\n", pis->alpha); + cmd_get_value(pgs->alpha, cbp); + if_debug1m('L', pgs->memory, " alpha=%u\n", pgs->alpha); } pcb->ptr = cbp; return 0; } static int -read_set_color_space(command_buf_t *pcb, gs_imager_state *pis, +read_set_color_space(command_buf_t *pcb, gs_gstate *pgs, gs_color_space **ppcs, gx_device_clist_reader *cdev, gs_memory_t *mem) { @@ -2705,6 +2745,7 @@ picc_profile->hashcode = icc_information.icc_hash; picc_profile->hash_is_valid = true; picc_profile->islab = icc_information.is_lab; + picc_profile->default_match = icc_information.default_match; picc_profile->data_cs = icc_information.data_cs; /* Store the clist reader address in the profile structure so that we can get to the buffer @@ -2714,13 +2755,18 @@ /* Assign it to the colorspace */ code = gsicc_set_gscs_profile(pcs, picc_profile, mem); /* And we no longer need our reference to the profile */ - rc_decrement(picc_profile, "read_set_color_space"); + gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space"); break; default: code = gs_note_error(gs_error_rangecheck); /* others are NYI */ goto out; } + if (pcs == NULL) { + code = gs_note_error(gs_error_VMerror); + goto out; + } + if (b & 8) { bool use_proc = (b & 4) != 0; int hival; @@ -2802,7 +2848,7 @@ } static int -read_put_params(command_buf_t *pcb, gs_imager_state *pis, +read_put_params(command_buf_t *pcb, gs_gstate *pgs, gx_device_clist_reader *cdev, gs_memory_t *mem) { const byte *cbp = pcb->ptr; @@ -2861,7 +2907,7 @@ code = gs_error_unknownerror; /* must match */ if (code >= 0) { gs_c_param_list_read(¶m_list); - code = gs_imager_putdeviceparams(pis, (gx_device *)cdev, + code = gs_gstate_putdeviceparams(pgs, (gx_device *)cdev, (gs_param_list *)¶m_list); } gs_c_param_list_release(¶m_list); @@ -2925,21 +2971,21 @@ return code; } -static int apply_create_compositor(gx_device_clist_reader *cdev, gs_imager_state *pis, +static int apply_create_compositor(gx_device_clist_reader *cdev, gs_gstate *pgs, gs_memory_t *mem, gs_composite_t *pcomp, int x0, int y0, gx_device **ptarget) { gx_device *tdev = *ptarget; int code; - code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pis); + code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs); if (code < 0) return code; /* * Apply the compositor to the target device; note that this may * change the target device. */ - code = dev_proc(tdev, create_compositor)(tdev, &tdev, pcomp, pis, mem, (gx_device*) cdev); + code = dev_proc(tdev, create_compositor)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev); if (code >= 0 && tdev != *ptarget) { /* If we created a new compositor here, then that new compositor should * become the device to which we send all future drawing requests. If @@ -2958,7 +3004,7 @@ /* Perform any updates for the clist device required */ code = pcomp->type->procs.clist_compositor_read_update(pcomp, - (gx_device *)cdev, tdev, pis, mem); + (gx_device *)cdev, tdev, pgs, mem); if (code < 0) return code; @@ -3048,7 +3094,7 @@ */ static int cmd_select_map(cmd_map_index map_index, cmd_map_contents cont, - gs_imager_state * pis, int ** pcomp_num, frac ** pmdata, + gs_gstate * pgs, int ** pcomp_num, frac ** pmdata, uint * pcount, gs_memory_t * mem) { gx_transfer_map *map; @@ -3059,36 +3105,36 @@ switch (map_index) { case cmd_map_transfer: if_debug0m('L', mem, " transfer"); - rc_unshare_struct(pis->set_transfer.gray, gx_transfer_map, + rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map, &st_transfer_map, mem, return_error(gs_error_VMerror), "cmd_select_map(default_transfer)"); - map = pis->set_transfer.gray; + map = pgs->set_transfer.gray; /* Release all current maps */ - rc_decrement(pis->set_transfer.red, "cmd_select_map(red)"); - pis->set_transfer.red = NULL; - pis->set_transfer.red_component_num = -1; - rc_decrement(pis->set_transfer.green, "cmd_select_map(green)"); - pis->set_transfer.green = NULL; - pis->set_transfer.green_component_num = -1; - rc_decrement(pis->set_transfer.blue, "cmd_select_map(blue)"); - pis->set_transfer.blue = NULL; - pis->set_transfer.blue_component_num = -1; + rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)"); + pgs->set_transfer.red = NULL; + pgs->set_transfer.red_component_num = -1; + rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)"); + pgs->set_transfer.green = NULL; + pgs->set_transfer.green_component_num = -1; + rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)"); + pgs->set_transfer.blue = NULL; + pgs->set_transfer.blue_component_num = -1; goto transfer2; case cmd_map_transfer_0: - pmap = &pis->set_transfer.red; - *pcomp_num = &pis->set_transfer.red_component_num; + pmap = &pgs->set_transfer.red; + *pcomp_num = &pgs->set_transfer.red_component_num; goto transfer1; case cmd_map_transfer_1: - pmap = &pis->set_transfer.green; - *pcomp_num = &pis->set_transfer.green_component_num; + pmap = &pgs->set_transfer.green; + *pcomp_num = &pgs->set_transfer.green_component_num; goto transfer1; case cmd_map_transfer_2: - pmap = &pis->set_transfer.blue; - *pcomp_num = &pis->set_transfer.blue_component_num; + pmap = &pgs->set_transfer.blue; + *pcomp_num = &pgs->set_transfer.blue_component_num; goto transfer1; case cmd_map_transfer_3: - pmap = &pis->set_transfer.gray; - *pcomp_num = &pis->set_transfer.gray_component_num; + pmap = &pgs->set_transfer.gray; + *pcomp_num = &pgs->set_transfer.gray_component_num; transfer1: if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0)); rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem, return_error(gs_error_VMerror), "cmd_select_map(transfer)"); @@ -3103,12 +3149,12 @@ break; case cmd_map_black_generation: if_debug0m('L', mem, " black generation"); - pmap = &pis->black_generation; + pmap = &pgs->black_generation; cname = "cmd_select_map(black generation)"; goto alloc; case cmd_map_undercolor_removal: if_debug0m('L', mem, " undercolor removal"); - pmap = &pis->undercolor_removal; + pmap = &pgs->undercolor_removal; cname = "cmd_select_map(undercolor removal)"; alloc: if (cont == cmd_map_none) { rc_decrement(*pmap, cname); @@ -3317,8 +3363,10 @@ } goto rrc; case cmd_opv_closepath: - code = gx_path_close_subpath(ppath); - gx_path_current_point(ppath, (gs_fixed_point *) vs); + if ((code = gx_path_close_subpath(ppath)) < 0) + return code;; + if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0) + return code;; px = A, py = B; break; default: diff -Nru ghostscript-9.10~dfsg/base/gxclread.c ghostscript-9.25~dfsg+1/base/gxclread.c --- ghostscript-9.10~dfsg/base/gxclread.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclread.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,9 +28,8 @@ #include "gxgetbit.h" #include "gxhttile.h" #include "gdevplnx.h" +#include "gdevp14.h" #include "gsmemory.h" -#include "gsmemlok.h" -#include "vdtrace.h" #include "gsicc_cache.h" /* * We really don't like the fact that gdevprn.h is included here, since @@ -228,7 +227,7 @@ return i; } } - gs_note_error(gs_error_unregistered); /* Must not happen. */ + (void)gs_note_error(gs_error_unregistered); /* Must not happen. */ return -1; } @@ -287,9 +286,7 @@ static int clist_plane_raster(const gx_device *dev, const gx_render_plane_t *render_plane) { - return bitmap_raster(dev->width * - (render_plane && render_plane->index >= 0 ? - render_plane->depth : dev->color_info.depth)); + return gx_device_raster_plane(dev, render_plane); } /* Select full-pixel rendering if required for RasterOp. */ @@ -368,8 +365,13 @@ return_error(gs_error_VMerror); } - code = (crdev->icc_cache_cl = gsicc_cache_new(base_mem)) == NULL ? gs_error_VMerror : code; + if (crdev->icc_cache_cl == NULL) { + code = (crdev->icc_cache_cl = gsicc_cache_new(base_mem)) == NULL ? gs_error_VMerror : code; + } } + + check_device_compatible_encoding((gx_device *)cldev); + return code; } @@ -383,25 +385,46 @@ clist_find_pseudoband(gx_device_clist_reader *crdev, int band, cmd_block *cb) { - clist_file_ptr bfile = crdev->page_info.bfile; - int64_t save_pos = crdev->page_info.bfile_end_pos; + gx_band_page_info_t *page_info = &(crdev->page_info); + clist_file_ptr bfile = page_info->bfile; + int64_t save_pos = page_info->bfile_end_pos; int64_t start_pos; + int code; + if (bfile == NULL) { + /* files haven't been opened yet. Do it now */ + char fmode[4]; + + strcpy(fmode, "r"); + strncat(fmode, gp_fmode_binary_suffix, 1); + if ((code=page_info->io_procs->fopen(page_info->cfname, fmode, + &page_info->cfile, + crdev->memory, crdev->memory, true)) < 0 || + (code=page_info->io_procs->fopen(page_info->bfname, fmode, + &page_info->bfile, + crdev->memory, crdev->memory, false)) < 0) { + return code; + } + bfile = page_info->bfile; + } /* Go to the start of the last command block */ - start_pos = crdev->page_info.bfile_end_pos - sizeof(cmd_block); - crdev->page_info.io_procs->fseek(bfile, start_pos, SEEK_SET, crdev->page_info.bfname); + start_pos = page_info->bfile_end_pos - sizeof(cmd_block); + page_info->io_procs->fseek(bfile, start_pos, SEEK_SET, page_info->bfname); while( 1 ) { - crdev->page_info.io_procs->fread_chars(cb, sizeof(cmd_block), bfile); + int read = page_info->io_procs->fread_chars(cb, sizeof(cmd_block), bfile); + + if (read < sizeof(cmd_block)) + return -1; if (cb->band_max == band && cb->band_min == band) { - crdev->page_info.io_procs->fseek(bfile, save_pos, SEEK_SET, crdev->page_info.bfname); + page_info->io_procs->fseek(bfile, save_pos, SEEK_SET, page_info->bfname); return(0); /* Found it */ } start_pos -= sizeof(cmd_block); if (start_pos < 0) { - crdev->page_info.io_procs->fseek(bfile, save_pos, SEEK_SET, crdev->page_info.bfname); + page_info->io_procs->fseek(bfile, save_pos, SEEK_SET, page_info->bfname); return(-1); /* Did not find it before getting into other stuff in normal bands */ } - crdev->page_info.io_procs->fseek(bfile, start_pos, SEEK_SET, crdev->page_info.bfname); + page_info->io_procs->fseek(bfile, start_pos, SEEK_SET, page_info->bfname); } } @@ -536,13 +559,12 @@ crdev->ymin = crdev->ymax = 0; crdev->yplane.index = -1; - /* For normal rasterizing, pages and num_pages are zero. */ + /* For normal rasterizing, pages and num_pages is 1. */ crdev->pages = 0; - crdev->num_pages = 0; + crdev->num_pages = 1; /* always at least one page */ crdev->offset_map = NULL; crdev->icc_table = NULL; crdev->color_usage_array = NULL; - crdev->icc_cache_cl = NULL; crdev->render_threads = NULL; return 0; @@ -563,7 +585,7 @@ gs_int_rect band_rect; int lines_rasterized; gx_device *bdev; - int num_planes = + uint num_planes = (options & GB_PACKING_CHUNKY ? 1 : options & GB_PACKING_PLANAR ? dev->color_info.num_components : options & GB_PACKING_BIT_PLANAR ? dev->color_info.depth : @@ -609,15 +631,15 @@ if (code < 0) return code; code = clist_rasterize_lines(dev, y, line_count, bdev, &render_plane, &my); - if (code < 0) - return code; - lines_rasterized = min(code, line_count); - /* Return as much of the rectangle as falls within the rasterized lines. */ - band_rect = *prect; - band_rect.p.y = my; - band_rect.q.y = my + lines_rasterized; - code = dev_proc(bdev, get_bits_rectangle) - (bdev, &band_rect, params, unread); + if (code >= 0) { + lines_rasterized = min(code, line_count); + /* Return as much of the rectangle as falls within the rasterized lines. */ + band_rect = *prect; + band_rect.p.y = my; + band_rect.q.y = my + lines_rasterized; + code = dev_proc(bdev, get_bits_rectangle) + (bdev, &band_rect, params, unread); + } cdev->buf_procs.destroy_buf_device(bdev); if (code < 0 || lines_rasterized == line_count) return code; @@ -688,6 +710,7 @@ gx_device *target = crdev->target; uint raster = clist_plane_raster(target, render_plane); byte *mdata = crdev->data + crdev->page_tile_cache_size; + byte *mlines = (crdev->page_line_ptrs_offset == 0 ? NULL : mdata + crdev->page_line_ptrs_offset); int plane_index = (render_plane ? render_plane->index : -1); int code; @@ -712,7 +735,7 @@ if (y < 0 || y > dev->height) return_error(gs_error_rangecheck); code = crdev->buf_procs.setup_buf_device - (bdev, mdata, raster, NULL, 0, band_num_lines, band_num_lines); + (bdev, mdata, raster, (byte **)mlines, 0, band_num_lines, band_num_lines); band_rect.p.x = 0; band_rect.p.y = band_begin_line; band_rect.q.x = dev->width; @@ -732,7 +755,7 @@ if (line_count > crdev->ymax - y) line_count = crdev->ymax - y; code = crdev->buf_procs.setup_buf_device - (bdev, mdata, raster, NULL, y - crdev->ymin, line_count, + (bdev, mdata, raster, (byte **)mlines, y - crdev->ymin, line_count, crdev->ymax - crdev->ymin); if (code < 0) return code; @@ -756,8 +779,8 @@ int band_height = crdev->page_band_height; int band_first = prect->p.y / band_height; int band_last = (prect->q.y - 1) / band_height; - gx_saved_page current_page; - gx_placed_page placed_page; + gx_band_page_info_t *pinfo; + gx_band_page_info_t page_info; int code = 0; int i; bool save_pageneutralcolor; @@ -768,49 +791,72 @@ crdev->yplane.index = -1; if_debug2m('l', bdev->memory, "[l]rendering bands (%d,%d)\n", band_first, band_last); - /* - * If we aren't rendering saved pages, do the current one. - * Note that this is the only case in which we may encounter - * a gx_saved_page with non-zero cfile or bfile. - */ ppages = crdev->pages; - if (ppages == 0) { - current_page.info = crdev->page_info; - placed_page.page = ¤t_page; - placed_page.offset.x = placed_page.offset.y = 0; - ppages = &placed_page; - num_pages = 1; - } + /* Before playing back the clist, make sure that the gray detection is disabled */ /* so we don't slow down the rendering (primarily high level images). */ save_pageneutralcolor = crdev->icc_struct->pageneutralcolor; crdev->icc_struct->pageneutralcolor = false; for (i = 0; i < num_pages && code >= 0; ++i) { - const gx_placed_page *ppage = &ppages[i]; + bool pdf14_needed = false; + int band; - /* - * Set the band_offset_? values in case the buffer device - * needs this. Example, a device may need to adjust the - * phase of the dithering based on the page position, NOT - * the position within the band buffer to avoid band stitch - * lines in the dither pattern. The old wtsimdi device did this - * - * The band_offset_x is not important for placed pages that - * are nested on a 'master' page (imposition) since each - * page expects to be dithered independently, but setting - * this allows pages to be contiguous without a dithering - * shift. - * - * The following sets the band_offset_? relative to the - * master page. - */ - bdev->band_offset_x = ppage->offset.x; - bdev->band_offset_y = ppage->offset.y + (band_first * band_height); - code = clist_playback_file_bands(playback_action_render, - crdev, &ppage->page->info, + if (ppages == NULL) { + /* + * If we aren't rendering saved pages, do the current one. + * Note that this is the only case in which we may encounter + * a gx_saved_page with non-zero cfile or bfile. + */ + bdev->band_offset_x = 0; + bdev->band_offset_y = band_first * band_height; + pinfo = &(crdev->page_info); + } else { + const gx_placed_page *ppage = &ppages[i]; + + /* Store the page information. */ + page_info.cfile = page_info.bfile = NULL; + strncpy(page_info.cfname, ppage->page->cfname, sizeof(page_info.cfname)-1); + strncpy(page_info.bfname, ppage->page->bfname, sizeof(page_info.bfname)-1); + page_info.io_procs = ppage->page->io_procs; + page_info.tile_cache_size = ppage->page->tile_cache_size; + page_info.bfile_end_pos = ppage->page->bfile_end_pos; + page_info.band_params = ppage->page->band_params; + pinfo = &page_info; + + /* + * Set the band_offset_? values in case the buffer device + * needs this. Example, a device may need to adjust the + * phase of the dithering based on the page position, NOT + * the position within the band buffer to avoid band stitch + * lines in the dither pattern. The old wtsimdi device did this + * + * The band_offset_x is not important for placed pages that + * are nested on a 'master' page (imposition) since each + * page expects to be dithered independently, but setting + * this allows pages to be contiguous without a dithering + * shift. + * + * The following sets the band_offset_? relative to the + * master page. + */ + bdev->band_offset_x = ppage->offset.x; + bdev->band_offset_y = ppage->offset.y + (band_first * band_height); + } + /* if any of the requested bands need transparency, use it for all of them */ + /* The pdf14_ok_to_optimize checks if the target device (bdev) is compatible */ + /* with the pdf14 compositor info that was written to the clist: colorspace, */ + /* colorspace, etc. */ + pdf14_needed = !pdf14_ok_to_optimize(bdev); + for (band=band_first; !pdf14_needed && band <= band_last; band++) + pdf14_needed |= (crdev->color_usage_array[band].trans_bbox.p.y <= + crdev->color_usage_array[band].trans_bbox.q.y) ? true : false; + + code = clist_playback_file_bands(pdf14_needed ? + playback_action_render : playback_action_render_no_pdf14, + crdev, pinfo, bdev, band_first, band_last, - prect->p.x - ppage->offset.x, + prect->p.x - bdev->band_offset_x, prect->p.y); } crdev->icc_struct->pageneutralcolor = save_pageneutralcolor; /* restore it */ @@ -872,16 +918,7 @@ s.foreign = 1; s.state = (stream_state *)&rs; - if (vd_allowed('s')) { - vd_get_dc('s'); - } else if (vd_allowed('i')) { - vd_get_dc('i'); - } - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); code = clist_playback_band(action, crdev, &s, target, x0, y0, mem); - vd_release_dc; # ifdef DEBUG s_band_read_dnit_offset_map(crdev, (stream_state *)&rs); # endif diff -Nru ghostscript-9.10~dfsg/base/gxclrect.c ghostscript-9.25~dfsg+1/base/gxclrect.c --- ghostscript-9.10~dfsg/base/gxclrect.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclrect.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,6 +24,8 @@ #include "gxclpath.h" #include "gxdevsop.h" +extern dev_proc_dev_spec_op(gdev_prn_forwarding_dev_spec_op); + /* ---------------- Writing utilities ---------------- */ #define cmd_set_rect(rect)\ @@ -38,13 +40,13 @@ cmd_sizew(prect->x) + cmd_sizew(prect->y) + cmd_sizew(prect->width) + cmd_sizew(prect->height); } -static byte * -cmd_put_rect(register const gx_cmd_rect * prect, register byte * dp) +static inline byte * +cmd_put_rect(const gx_cmd_rect * prect, byte * dp) { - cmd_putw(prect->x, dp); - cmd_putw(prect->y, dp); - cmd_putw(prect->width, dp); - cmd_putw(prect->height, dp); + cmd_putw(prect->x, &dp); + cmd_putw(prect->y, &dp); + cmd_putw(prect->width, &dp); + cmd_putw(prect->height, &dp); return dp; } @@ -60,12 +62,12 @@ cmd_set_rect(pcls->rect); if (extended_command) { rcsize = 2 + cmd_size_rect(&pcls->rect); - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_extend, rcsize); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_extend, rcsize); dp[1] = op; dp += 2; } else { rcsize = 1 + cmd_size_rect(&pcls->rect); - code = set_cmd_put_op(dp, cldev, pcls, op, rcsize); + code = set_cmd_put_op(&dp, cldev, pcls, op, rcsize); dp += 1; } if (code < 0) @@ -103,11 +105,11 @@ byte op_tiny = op + 0x20 + dwidth - cmd_min_dw_tiny; if (dx == width - dwidth && dy == 0) { - code = set_cmd_put_op(dp, cldev, pcls, op_tiny + 8, 1); + code = set_cmd_put_op(&dp, cldev, pcls, op_tiny + 8, 1); if (code < 0) return code; } else { - code = set_cmd_put_op(dp, cldev, pcls, op_tiny, 2); + code = set_cmd_put_op(&dp, cldev, pcls, op_tiny, 2); if (code < 0) return code; dp[1] = (dx << 4) + dy - (cmd_min_dxy_tiny * 0x11); @@ -122,13 +124,13 @@ dh != 0 && dy == 0 ) { op += dh; - code = set_cmd_put_op(dp, cldev, pcls, op + 0x10, 3); + code = set_cmd_put_op(&dp, cldev, pcls, op + 0x10, 3); if (code < 0) return code; if_debug3m('L', cldev->memory, " rs2:%d,%d,0,%d\n", dx, dwidth, dheight); } else { - code = set_cmd_put_op(dp, cldev, pcls, op + 0x10, 5); + code = set_cmd_put_op(&dp, cldev, pcls, op + 0x10, 5); if (code < 0) return code; if_debug4m('L', cldev->memory, " rs4:%d,%d,%d,%d\n", @@ -146,16 +148,16 @@ ) { int rcsize = 1 + cmd_sizew(x) + cmd_sizew(width); - code = set_cmd_put_op(dp, cldev, pcls, + code = set_cmd_put_op(&dp, cldev, pcls, op + ((dy + 2) << 2) + dheight + 2, rcsize); if (code < 0) return code; ++dp; - cmd_put2w(x, width, dp); + cmd_put2w(x, width, &dp); } else { int rcsize = 1 + cmd_size_rect(&pcls->rect); - code = set_cmd_put_op(dp, cldev, pcls, op, rcsize); + code = set_cmd_put_op(&dp, cldev, pcls, op, rcsize); if (code < 0) return code; if_debug5m('L', cldev->memory, " r%d:%d,%d,%d,%d\n", @@ -180,16 +182,16 @@ int code; if_debug0m('L', cldev->memory, "[L]fillpage beg\n"); - code = set_cmd_put_all_op(dp, cldev, op, rcsize); + code = set_cmd_put_all_op(&dp, cldev, op, rcsize); if (code < 0) return code; for (pcls1 = cldev->states; pcls1 < cldev->states + cldev->nbands; pcls1++) cmd_set_rect(pcls1->rect); ++dp; - cmd_putw(0, dp); - cmd_putw(0, dp); - cmd_putw(0, dp); - cmd_putw(0, dp); + cmd_putw(0, &dp); + cmd_putw(0, &dp); + cmd_putw(0, &dp); + cmd_putw(0, &dp); if_debug0m('L', cldev->memory, "[L]fillpage end\n"); return 0; } @@ -197,8 +199,8 @@ static inline byte * cmd_put_frac31_color(gx_device_clist_writer * cldev, const frac31 *c, byte *dp) { - int num_components = cldev->clist_color_info.num_components; - int j; + uchar num_components = cldev->clist_color_info.num_components; + uchar j; for (j = 0; j < num_components; j++) dp = cmd_put_frac31(c[j], dp); @@ -208,8 +210,9 @@ static inline int cmd_size_frac31_color(gx_device_clist_writer * cldev, const frac31 *c) { - int j, s = 0; - int num_components = cldev->clist_color_info.num_components; + uchar j; + int s = 0; + uchar num_components = cldev->clist_color_info.num_components; for (j = 0; j < num_components; j++) s += cmd_size_frac31(c[j]); @@ -258,33 +261,36 @@ } rcsize += cmd_sizew(colors_mask); } - code = set_cmd_put_op(dp, cldev, pcls, op, rcsize); + code = set_cmd_put_op(&dp, cldev, pcls, op, rcsize); if (code < 0) return code; dp++; - cmd_putw(left->start.x, dp); - cmd_putw(left->start.y, dp); - cmd_putw(left->end.x, dp); - cmd_putw(left->end.y, dp); - cmd_putw(right->start.x, dp); - cmd_putw(right->start.y, dp); - cmd_putw(right->end.x, dp); - cmd_putw(right->end.y, dp); - cmd_putw(options, dp); + cmd_putw(left->start.x, &dp); + cmd_putw(left->start.y, &dp); + cmd_putw(left->end.x, &dp); + cmd_putw(left->end.y, &dp); + cmd_putw(right->start.x, &dp); + cmd_putw(right->start.y, &dp); + cmd_putw(right->end.x, &dp); + cmd_putw(right->end.y, &dp); + cmd_putw(options, &dp); if (!(options & 4)) { - cmd_putw(ybot, dp); - cmd_putw(ytop, dp); + cmd_putw(ybot, &dp); + cmd_putw(ytop, &dp); } if_debug6m('L', cldev->memory, " t%d:%ld,%ld,%ld,%ld %ld\n", - rcsize - 1, left->start.x, left->start.y, left->end.x, left->end.y, ybot); + rcsize - 1, (long int)left->start.x, (long int)left->start.y, + (long int)left->end.x, (long int)left->end.y, (long int)ybot); if_debug6m('L', cldev->memory, " t%ld,%ld,%ld,%ld %ld o=%d\n", - right->start.x, right->start.y, right->end.x, right->end.y, ytop, options); + (long int)right->start.x, (long int)right->start.y, + (long int)right->end.x, (long int)right->end.y, (long int)ytop, + options); if (options & 2) { - cmd_putw(fa->clip->p.x, dp); - cmd_putw(fa->clip->p.y, dp); - cmd_putw(fa->clip->q.x, dp); - cmd_putw(fa->clip->q.y, dp); - cmd_putw(colors_mask, dp); + cmd_putw(fa->clip->p.x, &dp); + cmd_putw(fa->clip->p.y, &dp); + cmd_putw(fa->clip->q.x, &dp); + cmd_putw(fa->clip->q.y, &dp); + cmd_putw(colors_mask, &dp); if (c0 != NULL) dp = cmd_put_frac31_color(cldev, c0, dp); if (c1 != NULL) @@ -300,7 +306,7 @@ /* ---------------- Driver procedures ---------------- */ int -clist_fillpage(gx_device * dev, gs_imager_state *pis, gx_drawing_color *pdcolor) +clist_fillpage(gx_device * dev, gs_gstate *pgs, gx_drawing_color *pdcolor) { gx_device_clist * const cldev = (gx_device_clist *)dev; gx_device_clist_writer * const cdev = &(cldev->writer); @@ -314,11 +320,9 @@ pcls = cdev->states; /* Use any. */ - do { - code = cmd_put_drawing_color(cdev, pcls, pdcolor, NULL, devn_not_tile); - if (code >= 0) - code = cmd_write_page_rect_cmd(cdev, cmd_op_fill_rect); - } while (RECT_RECOVER(code)); + code = cmd_put_drawing_color(cdev, pcls, pdcolor, NULL, devn_not_tile); + if (code >= 0) + code = cmd_write_page_rect_cmd(cdev, cmd_op_fill_rect); return code; } @@ -353,25 +357,18 @@ do { RECT_STEP_INIT(re); re.pcls->color_usage.or |= color_usage; - do { - code = cmd_disable_lop(cdev, re.pcls); - if (code >= 0 && color != re.pcls->colors[1]) { - code = cmd_put_color(cdev, re.pcls, &clist_select_color1, - color, &re.pcls->colors[1]); - } - if (code >= 0) { - code = cmd_write_rect_cmd(cdev, re.pcls, cmd_op_fill_rect, rx, re.y, - rwidth, re.height); - } - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_disable_lop(cdev, re.pcls); + if (code >= 0 && color != re.pcls->colors[1]) { + code = cmd_put_color(cdev, re.pcls, &clist_select_color1, + color, &re.pcls->colors[1]); + } + if (code >= 0) { + code = cmd_write_rect_cmd(cdev, re.pcls, cmd_op_fill_rect, rx, re.y, + rwidth, re.height); + } + if (code < 0) + return code; re.y += re.height; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; } while (re.y < re.yend); return 0; } @@ -379,7 +376,7 @@ /* This is used in fills from devn color types */ int clist_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, const gx_drawing_color *pdcolor, + const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_clist_writer * const cdev = @@ -387,6 +384,7 @@ int code; int rx, ry, rwidth, rheight; cmd_rects_enum_t re; + gx_color_usage_bits color_usage = cmd_drawing_color_usage(cdev, pdcolor); rx = fixed2int(rect->p.x); ry = fixed2int(rect->p.y); @@ -412,28 +410,36 @@ RECT_ENUM_INIT(re, ry, rheight); do { RECT_STEP_INIT(re); - re.pcls->color_usage.or = gx_color_usage_all(cdev); - do { - code = cmd_disable_lop(cdev, re.pcls); - code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, - devn_not_tile); - if (code >= 0) { - code = cmd_write_rect_hl_cmd(cdev, re.pcls, cmd_op_fill_rect_hl, - rx, re.y, rwidth, re.height, false); - } - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + re.pcls->color_usage.or |= color_usage; + code = cmd_disable_lop(cdev, re.pcls); + code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, + devn_not_tile); + if (code >= 0) { + code = cmd_write_rect_hl_cmd(cdev, re.pcls, cmd_op_fill_rect_hl, + rx, re.y, rwidth, re.height, false); + } + if (code < 0) + return code; re.y += re.height; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; } while (re.y < re.yend); return 0; } +static void update_color_use_frac_array(uchar num_colors, const frac31 *color, + cmd_rects_enum_t *re) +{ + uchar k; + + if (color == NULL) + return; + + for (k = 0; k < num_colors; k++){ + if (color[k] != 0) { + re->pcls->color_usage.or |= (1<= 0) { - /* Dont't want to shorten the trapezoid by the band boundary, - keeping in mind a further optimization with writing same data to all bands. */ - code = cmd_write_trapezoid_cmd(cdev, re.pcls, cmd_opv_fill_trapezoid, left, right, - ybot, ytop, options, fa, c0, c1, c2, c3); + if (pdcolor != NULL) { + code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, + devn_not_tile); + if (code == gs_error_unregistered) + return code; + if (code < 0) { + /* Something went wrong, use the default implementation. */ + return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); } - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_update_lop(cdev, re.pcls, lop); + } else { + /* Even with pdcolor NULL, we may still have colors packed in + c0, c1, c2 or c3 */ + update_color_use_frac_array(dev->color_info.num_components, c0, &re); + update_color_use_frac_array(dev->color_info.num_components, c1, &re); + update_color_use_frac_array(dev->color_info.num_components, c2, &re); + update_color_use_frac_array(dev->color_info.num_components, c3, &re); + code = 0; + } + if (code >= 0) { + /* Dont't want to shorten the trapezoid by the band boundary, + keeping in mind a further optimization with writing same data to all bands. */ + code = cmd_write_trapezoid_cmd(cdev, re.pcls, cmd_opv_fill_trapezoid, left, right, + ybot, ytop, options, fa, c0, c1, c2, c3); + } + if (code < 0) + return code; re.y += re.height; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; } while (re.y < re.yend); return 0; } @@ -598,19 +604,18 @@ return 1; } +extern dev_proc_open_device(pattern_clist_open_device); +extern dev_proc_dev_spec_op(pattern_accum_dev_spec_op); + int clist_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) { - gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)data; - gx_bitmap_id id = (gx_bitmap_id)size; gx_device_clist_common * const cdev = &((gx_device_clist *)pdev)->common; if (dev_spec_op == gxdso_pattern_handles_clip_path) return 1; if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path) return 1; - if (dev_spec_op == gxdso_is_native_planar) - return cdev->is_planar; if (dev_spec_op == gxdso_supports_devn) { cmm_dev_profile_t *dev_profile; int code; @@ -621,12 +626,23 @@ return 0; } } - return gx_default_dev_spec_op(pdev, dev_spec_op, pinst, id); + if (dev_spec_op == gxdso_restrict_bbox) { + gx_device_clist_writer *cwdev = &((gx_device_clist *)pdev)->writer; + gs_int_rect *ibox = (gs_int_rect *)data; + if (ibox->p.y < cwdev->cropping_min) + ibox->p.y = cwdev->cropping_min; + if (ibox->q.y > cwdev->cropping_max) + ibox->q.y = cwdev->cropping_max; + return 0; + } + /* forward to the appropriate super class */ + if (cdev->is_printer) + return gdev_prn_forwarding_dev_spec_op(pdev, dev_spec_op, data, size); + if (dev_proc(cdev, open_device) == pattern_clist_open_device) + return pattern_accum_dev_spec_op(pdev, dev_spec_op, data, size); + return gx_default_dev_spec_op(pdev, dev_spec_op, data, size); } -#define dev_proc_pattern_manage(proc)\ - dev_t_proc_pattern_manage(proc, gx_device) - /* Based heavily off of clist_strip_tile_rectangle */ int clist_strip_tile_rect_devn(gx_device * dev, const gx_strip_bitmap * tile, @@ -639,6 +655,7 @@ int depth = 1; int code; cmd_rects_enum_t re; + gx_color_usage_bits color_usage = cmd_drawing_color_usage(cdev, pdcolor0); crop_fill(cdev, rx, ry, rwidth, rheight); if (rwidth <= 0 || rheight <= 0) @@ -656,58 +673,46 @@ clist_update_trans_bbox(cdev, &bbox); } + color_usage |= cmd_drawing_color_usage(cdev, pdcolor1); RECT_ENUM_INIT(re, ry, rheight); do { ulong offset_temp; RECT_STEP_INIT(re); - re.pcls->color_usage.or = gx_color_usage_all(cdev); - do { - code = cmd_disable_lop(cdev, re.pcls); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + re.pcls->color_usage.or |= color_usage; + code = cmd_disable_lop(cdev, re.pcls); + if (code < 0) + return code; /* Change the tile if needed */ if (!cls_has_tile_id(cdev, re.pcls, tile->id, offset_temp)) { if (tile->id != gx_no_bitmap_id) { - do { - code = clist_change_tile(cdev, re.pcls, tile, depth); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code != gs_error_VMerror || !cdev->error_is_retryable) && SET_BAND_CODE(code)) - goto error_in_rect; - } else - code = -1; - if (code < 0) { + code = clist_change_tile(cdev, re.pcls, tile, depth); + if (code < 0) + return code; + } else { return_error(gs_error_unregistered); } } - do { - code = 0; - /* Write out the devn colors */ - code = cmd_put_drawing_color(cdev, re.pcls, pdcolor0, &re, - devn_tile0); - code = cmd_put_drawing_color(cdev, re.pcls, pdcolor1, &re, - devn_tile1); - /* Set the tile phase */ - if (px != re.pcls->tile_phase.x || py != re.pcls->tile_phase.y) { - if (code >= 0) - code = cmd_set_tile_phase(cdev, re.pcls, px, py); - } - /* Write out the actually command to fill with the devn colors */ - if (code >= 0) { - code = cmd_write_rect_hl_cmd(cdev, re.pcls, - cmd_opv_ext_tile_rect_hl, rx, re.y, - rwidth, re.height, true); - } - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = 0; + /* Write out the devn colors */ + code = cmd_put_drawing_color(cdev, re.pcls, pdcolor0, &re, + devn_tile0); + code = cmd_put_drawing_color(cdev, re.pcls, pdcolor1, &re, + devn_tile1); + /* Set the tile phase */ + if (px != re.pcls->tile_phase.x || py != re.pcls->tile_phase.y) { + if (code >= 0) + code = cmd_set_tile_phase(cdev, re.pcls, px, py); + } + /* Write out the actually command to fill with the devn colors */ + if (code >= 0) { + code = cmd_write_rect_hl_cmd(cdev, re.pcls, + cmd_opv_ext_tile_rect_hl, rx, re.y, + rwidth, re.height, true); + } + if (code < 0) + return code; re.y += re.height; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; } while (re.y < re.yend); return 0; } @@ -753,18 +758,12 @@ RECT_STEP_INIT(re); re.pcls->color_usage.or |= color_usage; - do { - code = cmd_disable_lop(cdev, re.pcls); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_disable_lop(cdev, re.pcls); + if (code < 0) + return code; if (!cls_has_tile_id(cdev, re.pcls, tile->id, offset_temp)) { if (tile->id != gx_no_bitmap_id) { - do { - code = clist_change_tile(cdev, re.pcls, tile, depth); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code != gs_error_VMerror || !cdev->error_is_retryable) && SET_BAND_CODE(code)) - goto error_in_rect; + code = clist_change_tile(cdev, re.pcls, tile, depth); } else code = -1; /* Force the default implementation. Should never happen. */ if (code < 0) { @@ -774,32 +773,25 @@ rx, re.y, rwidth, re.height, color0, color1, px, py); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + if (code < 0) + return code; goto endr; } } - do { - code = 0; - if (color0 != re.pcls->tile_colors[0] || color1 != re.pcls->tile_colors[1]) - code = cmd_set_tile_colors(cdev, re.pcls, color0, color1); - if (px != re.pcls->tile_phase.x || py != re.pcls->tile_phase.y) { - if (code >= 0) - code = cmd_set_tile_phase(cdev, re.pcls, px, py); - } + code = 0; + if (color0 != re.pcls->tile_colors[0] || color1 != re.pcls->tile_colors[1]) + code = cmd_set_tile_colors(cdev, re.pcls, color0, color1); + if (px != re.pcls->tile_phase.x || py != re.pcls->tile_phase.y) { if (code >= 0) - code = cmd_write_rect_cmd(cdev, re.pcls, cmd_op_tile_rect, rx, re.y, - rwidth, re.height); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_set_tile_phase(cdev, re.pcls, px, py); + } + if (code >= 0) + code = cmd_write_rect_cmd(cdev, re.pcls, cmd_op_tile_rect, rx, re.y, + rwidth, re.height); + if (code < 0) + return code; endr:; re.y += re.height; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; } while (re.y < re.yend); return 0; } @@ -843,17 +835,15 @@ RECT_STEP_INIT(re); re.pcls->color_usage.or |= color_usage; - do { - code = cmd_disable_lop(cdev, re.pcls); - if (code >= 0) - code = cmd_disable_clip(cdev, re.pcls); - if (color0 != re.pcls->colors[0] && code >= 0) - code = cmd_set_color0(cdev, re.pcls, color0); - if (color1 != re.pcls->colors[1] && code >= 0) - code = cmd_set_color1(cdev, re.pcls, color1); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_disable_lop(cdev, re.pcls); + if (code >= 0) + code = cmd_disable_clip(cdev, re.pcls); + if (color0 != re.pcls->colors[0] && code >= 0) + code = cmd_set_color0(cdev, re.pcls, color0); + if (color1 != re.pcls->colors[1] && code >= 0) + code = cmd_set_color1(cdev, re.pcls, color1); + if (code < 0) + return code; /* Don't bother to check for a possible cache hit: */ /* tile_rectangle and fill_mask handle those cases. */ copy:{ @@ -868,15 +858,13 @@ rect.x = rx, rect.y = re.y; rect.width = w1, rect.height = re.height; rsize = (dx ? 3 : 1) + cmd_size_rect(&rect) + cmd_sizew(0); /* planar_height 0 */ - do { - code = cmd_put_bits(cdev, re.pcls, row, w1, re.height, raster, - rsize, (orig_id == gx_no_bitmap_id ? - 1 << cmd_compress_rle : - cmd_mask_compress_any), - &dp, &csize); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code == gs_error_limitcheck) && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_put_bits(cdev, re.pcls, row, w1, re.height, raster, + rsize, (orig_id == gx_no_bitmap_id ? + 1 << cmd_compress_rle : + cmd_mask_compress_any), + &dp, &csize); + if (code < 0 && !(code == gs_error_limitcheck)) + return code; compress = (uint)code; if (code < 0) { /* The bitmap was too large; split up the transfer. */ @@ -891,20 +879,16 @@ /* Split a single (very long) row. */ int w2 = w1 >> 1; - ++cdev->driver_call_nesting; - { - code = clist_copy_mono(dev, row, dx, - raster, gx_no_bitmap_id, rx, re.y, - w2, 1, color0, color1); - if (code >= 0) - code = clist_copy_mono(dev, row, dx + w2, - raster, gx_no_bitmap_id, - rx + w2, re.y, - w1 - w2, 1, color0, color1); - } - --cdev->driver_call_nesting; - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = clist_copy_mono(dev, row, dx, + raster, gx_no_bitmap_id, rx, re.y, + w2, 1, color0, color1); + if (code >= 0) + code = clist_copy_mono(dev, row, dx + w2, + raster, gx_no_bitmap_id, + rx + w2, re.y, + w1 - w2, 1, color0, color1); + if (code < 0) + return code; continue; } } @@ -915,17 +899,11 @@ } *dp++ = cmd_count_op(op, csize, dev->memory); /* Store the plane_height */ - cmd_putw(0, dp); - cmd_put2w(rx, re.y, dp); - cmd_put2w(w1, re.height, dp); + cmd_putw(0, &dp); + cmd_put2w(rx, re.y, &dp); + cmd_put2w(w1, re.height, &dp); re.pcls->rect = rect; } - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - re.y -= re.height; } while ((re.y += re.height) < re.yend); return 0; } @@ -983,15 +961,14 @@ const byte *row = data + (re.y - y0) * raster + (data_x / (8/bpc)); int bytes_row = ((w1*bpc+7)/8 + 7) & ~7; int maxheight = data_bits_size / bytes_row / cdev->color_info.num_components; + int plane; RECT_STEP_INIT(re); - do { - code = cmd_disable_lop(cdev, re.pcls); - if (code >= 0) - code = cmd_disable_clip(cdev, re.pcls); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_disable_lop(cdev, re.pcls); + if (code >= 0) + code = cmd_disable_clip(cdev, re.pcls); + if (code < 0) + return code; /* Don't bother to check for a possible cache hit: */ /* tile_rectangle and fill_mask handle those cases. */ @@ -1005,7 +982,6 @@ int w2 = w1 >> 1; re.height = 1; - ++cdev->driver_call_nesting; code = clist_copy_planes(dev, row, dx, raster, gx_no_bitmap_id, rx, re.y, w2, 1, plane_height); @@ -1014,70 +990,60 @@ raster, gx_no_bitmap_id, rx + w2, re.y, w1 - w2, 1, plane_height); - --cdev->driver_call_nesting; - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + if (code < 0) + return code; continue; } /* 0x100 fudge is arbitrary, but the BufferSpace is large w.r.t. cbuf size so it doesn't matter */ - if ((cdev->cend - cdev->cnext) < 0x100 + (re.height * bytes_row * cdev->color_info.num_components)) + if ((cdev->cend - cdev->cnext) < 0x100 + (re.height * bytes_row * (long)cdev->color_info.num_components)) cmd_write_buffer(cdev, cmd_opv_end_run); /* Insure that all planes fit in the bufferspace */ rect.x = rx, rect.y = re.y; rect.width = w1, rect.height = re.height; rsize = (dx ? 3 : 1) + cmd_size_rect(&rect) + cmd_sizew(plane_height); - do { - int plane; - /* Copy the 0th plane - this is the one the op goes in. */ - code = cmd_put_bits(cdev, re.pcls, row, w1*bpc, re.height, raster, - rsize, (bpc == 1 ? (orig_id == gx_no_bitmap_id ? - 1 << cmd_compress_rle : - cmd_mask_compress_any) : 0), - &dp, &csize); - if (code < 0) - continue; - /* Write the command header out now, in case the following - * cmd_put_bits fill the buffer up. */ - dp2 = dp; - if (dx) { - *dp2++ = cmd_count_op(cmd_opv_set_misc, 2, cdev->memory); - *dp2++ = cmd_set_misc_data_x + dx; - } - *dp2++ = cmd_count_op(op + code, csize, cdev->memory); - cmd_putw(plane_height, dp2); - cmd_put2w(rx, re.y, dp2); - cmd_put2w(w1, re.height, dp2); - for (plane = 1; plane < cdev->color_info.num_components && (code >= 0); plane++) - { - byte *dummy_dp; - uint csize2; - /* Copy subsequent planes - 1 byte header used to send the - * compression type. */ - code = cmd_put_bits(cdev, re.pcls, - row + plane_height * raster * plane, - w1*bpc, re.height, raster, 1, - (bpc == 1 ? - (orig_id == gx_no_bitmap_id ? - 1 << cmd_compress_rle : - cmd_mask_compress_any) : 0), - &dummy_dp, &csize2); - if (code >= 0) - *dummy_dp = code; + /* Copy the 0th plane - this is the one the op goes in. */ + code = cmd_put_bits(cdev, re.pcls, row, w1*bpc, re.height, raster, + rsize, (bpc == 1 ? (orig_id == gx_no_bitmap_id ? + 1 << cmd_compress_rle : + cmd_mask_compress_any) : 0), + &dp, &csize); + if (code < 0) + continue; + /* Write the command header out now, in case the following + * cmd_put_bits fill the buffer up. */ + dp2 = dp; + if (dx) { + *dp2++ = cmd_count_op(cmd_opv_set_misc, 2, cdev->memory); + *dp2++ = cmd_set_misc_data_x + dx; + } + *dp2++ = cmd_count_op(op + code, csize, cdev->memory); + cmd_putw(plane_height, &dp2); + cmd_put2w(rx, re.y, &dp2); + cmd_put2w(w1, re.height, &dp2); + for (plane = 1; plane < cdev->color_info.num_components && (code >= 0); plane++) + { + byte *dummy_dp; + uint csize2; + /* Copy subsequent planes - 1 byte header used to send the + * compression type. */ + code = cmd_put_bits(cdev, re.pcls, + row + plane_height * raster * plane, + w1*bpc, re.height, raster, 1, + (bpc == 1 ? + (orig_id == gx_no_bitmap_id ? + 1 << cmd_compress_rle : + cmd_mask_compress_any) : 0), + &dummy_dp, &csize2); + if (code >= 0) + *dummy_dp = code; - csize += csize2; - } - } while (RECT_RECOVER(code)); - if (code < 0 && !(code == gs_error_limitcheck) && SET_BAND_CODE(code)) - goto error_in_rect; + csize += csize2; + } + if (code < 0 && !(code == gs_error_limitcheck)) + return code; re.pcls->rect = rect; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - re.y -= re.height; } while ((re.y += re.height) < re.yend); return 0; } @@ -1123,22 +1089,18 @@ RECT_STEP_INIT(re); re.pcls->color_usage.or |= all; - do { - code = cmd_disable_lop(cdev, re.pcls); - if (code >= 0) - code = cmd_disable_clip(cdev, re.pcls); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_disable_lop(cdev, re.pcls); + if (code >= 0) + code = cmd_disable_clip(cdev, re.pcls); + if (code < 0) + return code; if (re.pcls->color_is_alpha) { byte *dp; - do { - code = - set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_set_copy_color, 1); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = + set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_set_copy_color, 1); + if (code < 0) + return code; re.pcls->color_is_alpha = 0; } copy:{ @@ -1152,13 +1114,11 @@ rect.x = rx, rect.y = re.y; rect.width = w1, rect.height = re.height; rsize = (dx ? 3 : 1) + cmd_size_rect(&rect); - do { - code = cmd_put_bits(cdev, re.pcls, row, w1 * depth, - re.height, raster, rsize, - 1 << cmd_compress_rle, &dp, &csize); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code == gs_error_limitcheck) && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_put_bits(cdev, re.pcls, row, w1 * depth, + re.height, raster, rsize, + 1 << cmd_compress_rle, &dp, &csize); + if (code < 0 && !(code == gs_error_limitcheck)) + return code; compress = (uint)code; if (code < 0) { /* The bitmap was too large; split up the transfer. */ @@ -1172,19 +1132,15 @@ /* Split a single (very long) row. */ int w2 = w1 >> 1; - ++cdev->driver_call_nesting; - { - code = clist_copy_color(dev, row, dx, + code = clist_copy_color(dev, row, dx, + raster, gx_no_bitmap_id, + rx, re.y, w2, 1); + if (code >= 0) + code = clist_copy_color(dev, row, dx + w2, raster, gx_no_bitmap_id, - rx, re.y, w2, 1); - if (code >= 0) - code = clist_copy_color(dev, row, dx + w2, - raster, gx_no_bitmap_id, - rx + w2, re.y, w1 - w2, 1); - } - --cdev->driver_call_nesting; - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + rx + w2, re.y, w1 - w2, 1); + if (code < 0) + return code; continue; } } @@ -1194,16 +1150,10 @@ *dp++ = cmd_set_misc_data_x + dx; } *dp++ = cmd_count_op(op, csize, dev->memory); - cmd_put2w(rx, re.y, dp); - cmd_put2w(w1, re.height, dp); + cmd_put2w(rx, re.y, &dp); + cmd_put2w(w1, re.height, &dp); re.pcls->rect = rect; } - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - re.y -= re.height; } while ((re.y += re.height) < re.yend); return 0; } @@ -1256,42 +1206,32 @@ RECT_STEP_INIT(re); re.pcls->color_usage.or = all; - do { - code = cmd_disable_lop(cdev, re.pcls); - if (code >= 0) - code = cmd_disable_clip(cdev, re.pcls); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_disable_lop(cdev, re.pcls); + if (code >= 0) + code = cmd_disable_clip(cdev, re.pcls); + if (code < 0) + return code; if (!re.pcls->color_is_alpha) { byte *dp; - do { - code = - set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_set_copy_alpha, 1); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_set_copy_alpha, 1); + if (code < 0) + return code; re.pcls->color_is_alpha = 1; } /* Set extended command for overload of copy_color_alpha with devn type */ if (!re.pcls->color_is_devn) { byte *dp; - do { - code = set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_extend, 2); - dp[1] = cmd_opv_ext_set_color_is_devn; - dp += 2; - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_extend, 2); + dp[1] = cmd_opv_ext_set_color_is_devn; + dp += 2; + if (code < 0) + return code; re.pcls->color_is_alpha = 1; } /* Set the color */ - do { - code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, - devn_not_tile); - } while (RECT_RECOVER(code)); + code = cmd_put_drawing_color(cdev, re.pcls, pdcolor, &re, devn_not_tile); copy:{ gx_cmd_rect rect; int rsize; @@ -1303,13 +1243,11 @@ rect.x = rx, rect.y = re.y; rect.width = w1, rect.height = re.height; rsize = (dx ? 4 : 2) + cmd_size_rect(&rect); - do { - code = cmd_put_bits(cdev, re.pcls, row, w1 << log2_depth, - re.height, raster, rsize, - 1 << cmd_compress_rle, &dp, &csize); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code == gs_error_limitcheck) && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_put_bits(cdev, re.pcls, row, w1 << log2_depth, + re.height, raster, rsize, + 1 << cmd_compress_rle, &dp, &csize); + if (code < 0 && !(code == gs_error_limitcheck)) + return code; compress = (uint)code; if (code < 0) { /* The bitmap was too large; split up the transfer. */ @@ -1323,20 +1261,16 @@ /* Split a single (very long) row. */ int w2 = w1 >> 1; - ++cdev->driver_call_nesting; - { - code = clist_copy_alpha_hl_color(dev, row, dx, - raster, gx_no_bitmap_id, rx, re.y, - w2, 1, pdcolor, depth); - if (code >= 0) + code = clist_copy_alpha_hl_color(dev, row, dx, + raster, gx_no_bitmap_id, rx, re.y, + w2, 1, pdcolor, depth); + if (code >= 0) code = clist_copy_alpha_hl_color(dev, row, dx + w2, raster, gx_no_bitmap_id, rx + w2, re.y, w1 - w2, 1, pdcolor, depth); - } - --cdev->driver_call_nesting; - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + if (code < 0) + return code; continue; } } @@ -1347,16 +1281,10 @@ } *dp++ = cmd_count_op(op, csize, dev->memory); *dp++ = depth; - cmd_put2w(rx, re.y, dp); - cmd_put2w(w1, re.height, dp); + cmd_put2w(rx, re.y, &dp); + cmd_put2w(w1, re.height, &dp); re.pcls->rect = rect; } - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - re.y -= re.height; } while ((re.y += re.height) < re.yend); return 0; } @@ -1407,50 +1335,34 @@ RECT_STEP_INIT(re); re.pcls->color_usage.or |= color_usage; - do { - code = cmd_disable_lop(cdev, re.pcls); - if (code >= 0) - code = cmd_disable_clip(cdev, re.pcls); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_disable_lop(cdev, re.pcls); + if (code >= 0) + code = cmd_disable_clip(cdev, re.pcls); + if (code < 0) + return code; if (!re.pcls->color_is_alpha) { byte *dp; - do { - code = - set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_set_copy_alpha, 1); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_set_copy_alpha, 1); + if (code < 0) + return code; re.pcls->color_is_alpha = 1; } if (re.pcls->color_is_devn) { byte *dp; - do { - code = set_cmd_put_op(dp, cdev, re.pcls, cmd_opv_extend, 1); - code = set_cmd_put_op(dp, cdev, re.pcls, + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_extend, 1); + if (code >= 0) + code = set_cmd_put_op(&dp, cdev, re.pcls, cmd_opv_ext_unset_color_is_devn, 1); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + if (code < 0) + return code; re.pcls->color_is_alpha = 1; } - - - - - - - - if (color != re.pcls->colors[1]) { - do { - code = cmd_set_color1(cdev, re.pcls, color); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_set_color1(cdev, re.pcls, color); + if (code < 0) + return code; } copy:{ gx_cmd_rect rect; @@ -1463,13 +1375,11 @@ rect.x = rx, rect.y = re.y; rect.width = w1, rect.height = re.height; rsize = (dx ? 4 : 2) + cmd_size_rect(&rect); - do { - code = cmd_put_bits(cdev, re.pcls, row, w1 << log2_depth, - re.height, raster, rsize, - 1 << cmd_compress_rle, &dp, &csize); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code == gs_error_limitcheck) && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_put_bits(cdev, re.pcls, row, w1 << log2_depth, + re.height, raster, rsize, + 1 << cmd_compress_rle, &dp, &csize); + if (code < 0 && !(code == gs_error_limitcheck)) + return code; compress = (uint)code; if (code < 0) { /* The bitmap was too large; split up the transfer. */ @@ -1483,20 +1393,16 @@ /* Split a single (very long) row. */ int w2 = w1 >> 1; - ++cdev->driver_call_nesting; - { - code = clist_copy_alpha(dev, row, dx, - raster, gx_no_bitmap_id, rx, re.y, - w2, 1, color, depth); - if (code >= 0) - code = clist_copy_alpha(dev, row, dx + w2, - raster, gx_no_bitmap_id, - rx + w2, re.y, w1 - w2, 1, - color, depth); - } - --cdev->driver_call_nesting; - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = clist_copy_alpha(dev, row, dx, + raster, gx_no_bitmap_id, rx, re.y, + w2, 1, color, depth); + if (code >= 0) + code = clist_copy_alpha(dev, row, dx + w2, + raster, gx_no_bitmap_id, + rx + w2, re.y, w1 - w2, 1, + color, depth); + if (code < 0) + return code; continue; } } @@ -1507,16 +1413,10 @@ } *dp++ = cmd_count_op(op, csize, dev->memory); *dp++ = depth; - cmd_put2w(rx, re.y, dp); - cmd_put2w(w1, re.height, dp); + cmd_put2w(rx, re.y, &dp); + cmd_put2w(w1, re.height, &dp); re.pcls->rect = rect; } - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - re.y -= re.height; } while ((re.y += re.height) < re.yend); return 0; } @@ -1657,13 +1557,11 @@ tile_with_id.id = gs_next_ids(dev->memory, 1); tiles = &tile_with_id; } - do { - code = clist_change_tile(cdev, re.pcls, tiles, - (tcolors != 0 ? 1 : - cdev->clist_color_info.depth)); - } while (RECT_RECOVER(code)); - if (code < 0 && !(code == gs_error_limitcheck) && SET_BAND_CODE(code)) - goto error_in_rect; + code = clist_change_tile(cdev, re.pcls, tiles, + (tcolors != 0 ? 1 : + cdev->clist_color_info.depth)); + if (code < 0 && !(code == gs_error_limitcheck)) + return code; if (code < 0) { /* * The error is a limitcheck: we have a tile that @@ -1738,85 +1636,65 @@ line_tile.data = tiles->data + raster * ((re.y + iy + phase_y) % rep_height) + data_shift; line_tile.id = ids + (iy % rep_height); - ++cdev->driver_call_nesting; - { - code = clist_strip_copy_rop2(dev, - (sdata == 0 ? 0 : row + iy * sraster), - sourcex, sraster, - gx_no_bitmap_id, scolors, - &line_tile, tcolors, - rx, re.y + iy, rwidth, 1, - new_phase, 0, lop, planar_height); - } - --cdev->driver_call_nesting; - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = clist_strip_copy_rop2(dev, + (sdata == 0 ? 0 : row + iy * sraster), + sourcex, sraster, + gx_no_bitmap_id, scolors, + &line_tile, tcolors, + rx, re.y + iy, rwidth, 1, + new_phase, 0, lop, planar_height); + if (code < 0) + return code; } continue; } if (((phase_x != re.pcls->tile_phase.x) && (tiles->rep_width > 1)) || ((phase_y != re.pcls->tile_phase.y) && (tiles->rep_height > 1))) { - do { - code = cmd_set_tile_phase(cdev, re.pcls, phase_x, - phase_y); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = cmd_set_tile_phase(cdev, re.pcls, phase_x, + phase_y); + if (code < 0) + return code; } } } /* Set the tile colors. */ - do { - code = - (tcolors != 0 ? - cmd_set_tile_colors(cdev, re.pcls, tcolors[0], tcolors[1]) : - cmd_set_tile_colors(cdev, re.pcls, gx_no_color_index, - gx_no_color_index)); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = + (tcolors != 0 ? + cmd_set_tile_colors(cdev, re.pcls, tcolors[0], tcolors[1]) : + cmd_set_tile_colors(cdev, re.pcls, gx_no_color_index, + gx_no_color_index)); + if (code < 0) + return code; } - do { - code = 0; - if (lop != re.pcls->lop) - code = cmd_set_lop(cdev, re.pcls, lop); - if (code >= 0) - code = cmd_enable_lop(cdev, re.pcls); - } while (RECT_RECOVER(code)); - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; + code = 0; + if (lop != re.pcls->lop) + code = cmd_set_lop(cdev, re.pcls, lop); + if (code >= 0) + code = cmd_enable_lop(cdev, re.pcls); + if (code < 0) + return code; /* Set lop_enabled to -1 so that fill_rectangle / copy_* */ /* won't attempt to set it to 0. */ re.pcls->lop_enabled = -1; - ++cdev->driver_call_nesting; - { - if (scolors != NULL) { - if (scolors[0] == scolors[1]) - code = clist_fill_rectangle(dev, rx, re.y, rwidth, re.height, - scolors[1]); - else - code = clist_copy_mono(dev, row, sourcex, sraster, id, - rx, re.y, rwidth, re.height, - scolors[0], scolors[1]); - } else if (planar_height) { - code = clist_copy_planes(dev, row, sourcex, sraster, id, - rx, re.y, rwidth, re.height, - planar_height); - } else { - code = clist_copy_color(dev, row, sourcex, sraster, id, - rx, re.y, rwidth, re.height); - } + if (scolors != NULL) { + if (scolors[0] == scolors[1]) + code = clist_fill_rectangle(dev, rx, re.y, rwidth, re.height, + scolors[1]); + else + code = clist_copy_mono(dev, row, sourcex, sraster, id, + rx, re.y, rwidth, re.height, + scolors[0], scolors[1]); + } else if (planar_height) { + code = clist_copy_planes(dev, row, sourcex, sraster, id, + rx, re.y, rwidth, re.height, + planar_height); + } else { + code = clist_copy_color(dev, row, sourcex, sraster, id, + rx, re.y, rwidth, re.height); } - --cdev->driver_call_nesting; re.pcls->lop_enabled = 1; - if (code < 0 && SET_BAND_CODE(code)) - goto error_in_rect; - continue; -error_in_rect: - if (!(cdev->error_is_retryable && cdev->driver_call_nesting == 0 && - SET_BAND_CODE(clist_VMerror_recover_flush(cdev, re.band_code)) >= 0)) - return re.band_code; - re.y -= re.height; + if (code < 0) + return code; } while ((re.y += re.height) < re.yend); return 0; } diff -Nru ghostscript-9.10~dfsg/base/gxclthrd.c ghostscript-9.25~dfsg+1/base/gxclthrd.c --- ghostscript-9.10~dfsg/base/gxclthrd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclthrd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,10 +31,12 @@ #include "gdevppla.h" #include "gsmemory.h" #include "gsmchunk.h" -#include "gsmemlok.h" #include "gxclthrd.h" #include "gdevdevn.h" #include "gsicc_cache.h" +#include "gsicc_manage.h" +#include "gstrans.h" +#include "gzht.h" /* for gx_ht_cache_default_bits_size */ /* Forward reference prototypes */ static int clist_start_render_thread(gx_device *dev, int thread_index, int band); @@ -46,7 +48,7 @@ /* to the chunk allocator. */ /* Exported for use by background printing. */ gx_device * -setup_device_and_mem_for_thread(gs_memory_t *chunk_base_mem, gx_device *dev, bool bg_print) +setup_device_and_mem_for_thread(gs_memory_t *chunk_base_mem, gx_device *dev, bool bg_print, gsicc_link_cache_t **cachep) { int i, code; char fmode[4]; @@ -61,6 +63,9 @@ gx_device *protodev; gs_c_param_list paramlist; gs_devn_params *pclist_devn_params; + gx_device_buf_space_t buf_space; + ulong state_size; + /* Every thread will have a 'chunk allocator' to reduce the interaction * with the 'base' allocator which has 'mutex' (locking) protection. @@ -77,7 +82,8 @@ /* Clone the device from the prototype device */ if (protodev == NULL || - (code = gs_copydevice((gx_device **) &ndev, protodev, thread_mem)) < 0) { + (code = gs_copydevice((gx_device **) &ndev, protodev, thread_mem)) < 0 || + ndev == NULL) { /* should only happen if copydevice failed */ gs_memory_chunk_release(thread_mem); return NULL; } @@ -93,12 +99,16 @@ npdev->file = pdev->file; /* For background printing when doing N copies with %d */ strcpy((npdev->fname), (pdev->fname)); ndev->color_info = dev->color_info; /* copy before putdeviceparams */ -#if CMM_THREAD_SAFE + ndev->pad = dev->pad; + ndev->log2_align_mod = dev->log2_align_mod; + ndev->is_planar = dev->is_planar; + if (gscms_is_threadsafe()) { + /* safe to share the icc_struct among threads */ ndev->icc_struct = dev->icc_struct; /* Set before put params */ rc_increment(ndev->icc_struct); -#endif + } /* get the current device parameters to put into the cloned device */ - gs_c_param_list_write(¶mlist, dev->memory); + gs_c_param_list_write(¶mlist, thread_mem); if ((code = gs_getdeviceparams(dev, (gs_param_list *)¶mlist)) < 0) { emprintf1(dev->memory, "Error getting device params, code=%d. Rendering threads not started.\n", @@ -110,6 +120,29 @@ goto out_cleanup; gs_c_param_list_release(¶mlist); + /* If the device ICC profile (or proof) is OI_PROFILE, then that was not handled + * by put/get params. In this case we need to clone the profiles. The clone + * operation also initializes some of the required data */ + if (dev->icc_struct != NULL && dev->icc_struct->device_profile[0] != NULL && + strncmp(dev->icc_struct->device_profile[0]->name, OI_PROFILE, strlen(OI_PROFILE)) == 0) { + if ((code = gsicc_clone_profile(dev->icc_struct->device_profile[0], + &(ndev->icc_struct->device_profile[0]), ndev->memory)) < 0) { + emprintf1(dev->memory, + "Error setting up device profile, code=%d. Rendering threads not started.\n", + code); + goto out_cleanup; + } + } + if (dev->icc_struct != NULL && dev->icc_struct->proof_profile != NULL && + strncmp(dev->icc_struct->proof_profile->name, OI_PROFILE, strlen(OI_PROFILE)) == 0) { + if ((code = gsicc_clone_profile(dev->icc_struct->proof_profile, + &ndev->icc_struct->proof_profile, ndev->memory)) < 0) { + emprintf1(dev->memory, + "Error setting up proof profile, code=%d. Rendering threads not started.\n", + code); + goto out_cleanup; + } + } /* In the case of a separation device, we need to make sure we get the devn params copied over */ pclist_devn_params = dev_proc(dev, ret_devn_params)(dev); @@ -117,7 +150,7 @@ code = devn_copy_params(dev, ndev); if (code < 0) { #ifdef DEBUG /* suppress a warning on a release build */ - gs_note_error(gs_error_VMerror); + (void)gs_note_error(gs_error_VMerror); #endif goto out_cleanup; } @@ -134,6 +167,22 @@ if ((ncdev->is_planar = cdev->is_planar)) gdev_prn_set_procs_planar(ndev); + /* Make sure that the ncdev BandHeight matches what we used when writing the clist, but + * re-calculate the BandBufferSpace so we don't over-allocate (in case the page uses + * transparency so that the BandHeight was reduced.) + */ + ncdev->space_params.band = cdev->page_info.band_params; + ncdev->space_params.banding_type = BandingAlways; + code = npdev->printer_procs.buf_procs.size_buf_device + (&buf_space, (gx_device *)ncdev, NULL, ncdev->space_params.band.BandHeight, false); + /* The 100 is bogus, we are just matching what is in clist_init_states */ + state_size = cdev->nbands * (ulong) sizeof(gx_clist_state) + sizeof(cmd_prefix) + cmd_largest_size + 100; + ncdev->space_params.band.BandBufferSpace = buf_space.bits + buf_space.line_ptrs; + if (state_size > ncdev->space_params.band.BandBufferSpace) + ncdev->space_params.band.BandBufferSpace = state_size; + ncdev->space_params.band.tile_cache_size = cdev->page_info.tile_cache_size; /* must be the same */ + ncdev->space_params.band.BandBufferSpace += cdev->page_info.tile_cache_size; + /* gdev_prn_allocate_memory sets the clist for writing, creating new files. * We need to unlink those files and open the main thread's files, then * reset the clist state for reading/rendering @@ -141,6 +190,13 @@ if ((code = gdev_prn_allocate_memory(ndev, NULL, ndev->width, ndev->height)) < 0) goto out_cleanup; + if (ncdev->page_info.tile_cache_size != cdev->page_info.tile_cache_size) { + emprintf2(thread_mem, + "clist_setup_render_threads: tile_cache_size mismatch. New size=%d, should be %d\n", + ncdev->page_info.tile_cache_size, cdev->page_info.tile_cache_size); + goto out_cleanup; + } + /* close and unlink the temp files just created */ ncdev->page_info.io_procs->fclose(ncdev->page_info.cfile, ncdev->page_info.cfname, true); ncdev->page_info.io_procs->fclose(ncdev->page_info.bfile, ncdev->page_info.bfname, true); @@ -163,27 +219,45 @@ /* The threads are maintained until clist_finish_page. At which point, the threads are torn down, the master clist reader device is changed to writer, and the icc_table and the icc_cache_cl freed */ -#if CMM_THREAD_SAFE + if (gscms_is_threadsafe()) { /* safe to share the link cache */ - ncdev->icc_cache_cl = cdev->icc_cache_cl; - rc_increment(cdev->icc_cache_cl, "setup_render_thread"); -#else - /* each thread needs its own link cache */ - if ((ncdev->icc_cache_cl = gsicc_cache_new(thread_mem)) == NULL) - goto out_cleanup; -#endif - if (bg_print && cdev->icc_table != NULL) { - /* This is a background printing thread, so it cannot share the icc_table */ - /* since this probably was created with a GC'ed allocator and the bg_print */ - /* thread can't deal with the relocation. Free the cdev->icc_table and get */ - /* a new one from the clist. */ - clist_icc_freetable(cdev->icc_table, cdev->memory); - cdev->icc_table = NULL; - if ((code = clist_read_icctable((gx_device_clist_reader *)ncdev)) < 0) + ncdev->icc_cache_cl = cdev->icc_cache_cl; + rc_increment(cdev->icc_cache_cl); /* FIXME: needs to be incdemented safely */ + } else { + /* each thread needs its own link cache */ + if (cachep != NULL) { + if (*cachep == NULL) { + /* We don't have one cached that we can reuse, so make one. */ + if ((*cachep = gsicc_cache_new(thread_mem->thread_safe_memory)) == NULL) + goto out_cleanup; + } + rc_increment(*cachep); + ncdev->icc_cache_cl = *cachep; + } else if ((ncdev->icc_cache_cl = gsicc_cache_new(thread_mem)) == NULL) + goto out_cleanup; + } + if (bg_print) { + gx_device_clist_reader *ncrdev = (gx_device_clist_reader *)ncdev; + + if (cdev->icc_table != NULL) { + /* This is a background printing thread, so it cannot share the icc_table */ + /* since this probably was created with a GC'ed allocator and the bg_print */ + /* thread can't deal with the relocation. Free the cdev->icc_table and get */ + /* a new one from the clist. */ + clist_free_icc_table(cdev->icc_table, cdev->memory); + cdev->icc_table = NULL; + if ((code = clist_read_icctable((gx_device_clist_reader *)ncdev)) < 0) + goto out_cleanup; + } + /* Similarly for the color_usage_array, when the foreground device switches to */ + /* writer mode, the foreground's array will be freed. */ + if ((code = clist_read_color_usage_array(ncrdev)) < 0) goto out_cleanup; } else { - /* Use the same profile table in each thread */ + /* Use the same profile table and color usage array in each thread */ ncdev->icc_table = cdev->icc_table; /* OK for multiple rendering threads */ + ((gx_device_clist_reader *)ncdev)->color_usage_array = + ((gx_device_clist_reader *)cdev)->color_usage_array; } /* Needed for case when the target has cielab profile and pdf14 device has a RGB profile stored in the profile list of the clist */ @@ -200,17 +274,16 @@ ncdev->page_info.io_procs->fclose(ncdev->page_info.cfile, ncdev->page_info.cfname, false); ncdev->do_not_open_or_close_bandfiles = true; /* we already closed the files */ - if (ndev != NULL) { - gdev_prn_free_memory(ndev); - gs_free_object(thread_mem, ndev, "setup_device_and_mem_for_thread"); - } + /* we can't get here with ndev == NULL */ + gdev_prn_free_memory(ndev); + gs_free_object(thread_mem, ndev, "setup_device_and_mem_for_thread"); gs_memory_chunk_release(thread_mem); return NULL; } /* Set up and start the render threads */ static int -clist_setup_render_threads(gx_device *dev, int y) +clist_setup_render_threads(gx_device *dev, int y, gx_process_page_options_t *options) { gx_device_printer *pdev = (gx_device_printer *)dev; gx_device_clist *cldev = (gx_device_clist *)dev; @@ -219,33 +292,66 @@ gs_memory_t *mem = cdev->bandlist_memory; gs_memory_t *chunk_base_mem = mem->thread_safe_memory; gs_memory_status_t mem_status; - int i, code, band; + int i, j, band; + int code = 0; int band_count = cdev->nbands; + int band_height = crdev->page_info.band_params.BandHeight; + byte **reserve_memory_array = NULL; + int reserve_pdf14_memory_size = 0; + /* space for the halftone cache plus 2Mb for other allocations during rendering (paths, etc.) */ + /* this will be increased by the measured profile storage and icclinks (estimated). */ + int reserve_size = 2 * 1024 * 1024 + (gx_ht_cache_default_bits_size() * dev->color_info.num_components); + clist_icctable_entry_t *curr_entry; + crdev->num_render_threads = pdev->num_render_threads_requested; if(gs_debug[':'] != 0) dmprintf1(mem, "%% %d rendering threads requested.\n", pdev->num_render_threads_requested); + if (crdev->page_uses_transparency) { + reserve_pdf14_memory_size = (ESTIMATED_PDF14_ROW_SPACE(max(1, crdev->width), crdev->color_info.num_components) >> 3); + reserve_pdf14_memory_size *= crdev->page_info.band_params.BandHeight; /* BandHeight set by writer */ + } + /* scan the profile table sizes to get the total each thread will need */ + if (crdev->icc_table != NULL) { + for (curr_entry = crdev->icc_table->head; curr_entry != NULL; curr_entry = curr_entry->next) { + reserve_size += curr_entry->serial_data.size; + /* FIXME: Should actually measure the icclink size to device (or pdf14 blend space) */ + reserve_size += 2 * 1024 * 1024; /* a worst case estimate */ + } + } if (crdev->num_render_threads > band_count) crdev->num_render_threads = band_count; /* don't bother starting more threads than bands */ /* Allocate and initialize an array of thread control structures */ crdev->render_threads = (clist_render_thread_control_t *) gs_alloc_byte_array(mem, crdev->num_render_threads, - sizeof(clist_render_thread_control_t), "clist_setup_render_threads" ); + sizeof(clist_render_thread_control_t), + "clist_setup_render_threads"); /* fallback to non-threaded if allocation fails */ if (crdev->render_threads == NULL) { emprintf(mem, " VMerror prevented threads from starting.\n"); return_error(gs_error_VMerror); } - + reserve_memory_array = (byte **)gs_alloc_byte_array(mem, + crdev->num_render_threads, + sizeof(void *), + "clist_setup_render_threads"); + if (reserve_memory_array == NULL) { + gs_free_object(mem, crdev->render_threads, "clist_setup_render_threads"); + crdev->render_threads = NULL; + emprintf(mem, " VMerror prevented threads from starting.\n"); + return_error(gs_error_VMerror); + } + memset(reserve_memory_array, 0, crdev->num_render_threads * sizeof(void *)); memset(crdev->render_threads, 0, crdev->num_render_threads * sizeof(clist_render_thread_control_t)); + crdev->main_thread_data = cdev->data; /* save data area */ /* Based on the line number requested, decide the order of band rendering */ /* Almost all devices go in increasing line order (except the bmp* devices ) */ crdev->thread_lookahead_direction = (y < (cdev->height - 1)) ? 1 : -1; - band = y / crdev->page_info.band_params.BandHeight; + band = y / band_height; /* If the 'mem' is not thread safe, we need to wrap it in a locking memory */ gs_memory_status(chunk_base_mem, &mem_status); @@ -253,13 +359,39 @@ return_error(gs_error_VMerror); } + /* If we don't have one large enough already, create an icc cache list */ + if (crdev->num_render_threads > crdev->icc_cache_list_len) { + gsicc_link_cache_t **old = crdev->icc_cache_list; + crdev->icc_cache_list = (gsicc_link_cache_t **)gs_alloc_byte_array(mem->thread_safe_memory, + crdev->num_render_threads, + sizeof(void*), "clist_render_setup_threads"); + if (crdev->icc_cache_list == NULL) { + crdev->icc_cache_list = NULL; + return_error(gs_error_VMerror); + } + if (crdev->icc_cache_list_len > 0) + memcpy(crdev->icc_cache_list, old, crdev->icc_cache_list_len * sizeof(gsicc_link_cache_t *)); + memset(&(crdev->icc_cache_list[crdev->icc_cache_list_len]), 0, + (crdev->num_render_threads - crdev->icc_cache_list_len) * sizeof(void *)); + crdev->icc_cache_list_len = crdev->num_render_threads; + gs_free_object(mem, old, "clist_render_setup_threads"); + } + /* Loop creating the devices and semaphores for each thread, then start them */ for (i=0; (i < crdev->num_render_threads) && (band >= 0) && (band < band_count); i++, band += crdev->thread_lookahead_direction) { gx_device *ndev; clist_render_thread_control_t *thread = &(crdev->render_threads[i]); - ndev = setup_device_and_mem_for_thread(chunk_base_mem, dev, false); + /* arbitrary extra reserve for other allocation by threads (paths, etc.) */ + /* plus the amount estimated for the pdf14 buffers */ + reserve_memory_array[i] = (byte *)gs_alloc_bytes(mem, reserve_size + reserve_pdf14_memory_size, + "clist_render_setup_threads"); + if (reserve_memory_array[i] == NULL) { + code = gs_error_VMerror; /* set code to an error for cleanup after the loop */ + break; + } + ndev = setup_device_and_mem_for_thread(chunk_base_mem, dev, false, &crdev->icc_cache_list[i]); if (ndev == NULL) { code = gs_error_VMerror; /* set code to an error for cleanup after the loop */ break; @@ -268,6 +400,13 @@ thread->cdev = ndev; thread->memory = ndev->memory; thread->band = -1; /* a value that won't match any valid band */ + thread->options = options; + thread->buffer = NULL; + if (options && options->init_buffer_fn) { + code = options->init_buffer_fn(options->arg, dev, thread->memory, dev->width, band_height, &thread->buffer); + if (code < 0) + break; + } /* create the buf device for this thread, and allocate the semaphores */ if ((code = gdev_create_buf_device(cdev->buf_procs.create_buf_device, @@ -275,18 +414,18 @@ band*crdev->page_band_height, NULL, thread->memory, &(crdev->color_usage_array[0])) < 0)) break; - if ((thread->sema_this = gx_semaphore_alloc(thread->memory)) == NULL || - (thread->sema_group = gx_semaphore_alloc(thread->memory)) == NULL) { + if ((thread->sema_this = gx_semaphore_label(gx_semaphore_alloc(thread->memory), "Band")) == NULL || + (thread->sema_group = gx_semaphore_label(gx_semaphore_alloc(thread->memory), "Group")) == NULL) { code = gs_error_VMerror; break; } - /* Start thread 'i' to do band */ - if ((code = clist_start_render_thread(dev, i, band)) < 0) - break; + /* We don't start the threads yet until we free up the */ + /* reserve memory we have allocated for that band. */ + thread->band = band; } /* If the code < 0, the last thread creation failed -- clean it up */ if (code < 0) { - band -= crdev->thread_lookahead_direction; /* update for 'next_band' usage */ + /* NB: 'band' will be the one that failed, so will be the next_band needed to start */ /* the following relies on 'free' ignoring NULL pointers */ gx_semaphore_free(crdev->render_threads[i].sema_group); gx_semaphore_free(crdev->render_threads[i].sema_this); @@ -304,6 +443,10 @@ gs_free_object(crdev->render_threads[i].memory, thread_cdev, "clist_setup_render_threads"); } + if (crdev->render_threads[i].buffer != NULL && options && options->free_buffer_fn != NULL) { + options->free_buffer_fn(options->arg, dev, crdev->render_threads[i].memory, crdev->render_threads[i].buffer); + crdev->render_threads[i].buffer = NULL; + } if (crdev->render_threads[i].memory != NULL) { gs_memory_chunk_release(crdev->render_threads[i].memory); crdev->render_threads[i].memory = NULL; @@ -315,9 +458,7 @@ if (i == 0) { if (crdev->render_threads[0].memory != NULL) { gs_memory_chunk_release(crdev->render_threads[0].memory); - /* free up the locking wrapper if we allocated one */ if (chunk_base_mem != mem) { - gs_memory_locked_release((gs_memory_locked_t *)chunk_base_mem); gs_free_object(mem, chunk_base_mem, "clist_setup_render_threads(locked allocator)"); } } @@ -339,14 +480,24 @@ emprintf1(mem, "Rendering threads not started, code=%d.\n", code); return_error(code); } + /* Free up any "reserve" memory we may have allocated, and start the + * threads since we deferred that in the thread setup loop above. + * We know if we get here we can start at least 1 thread. + */ + for (j=0, code = 0; jnum_render_threads; j++) { + gs_free_object(mem, reserve_memory_array[j], "clist_setup_render_threads"); + if (code == 0 && j < i) + code = clist_start_render_thread(dev, j, crdev->render_threads[j].band); + } + gs_free_object(mem, reserve_memory_array, "clist_setup_render_threads"); crdev->num_render_threads = i; crdev->curr_render_thread = 0; - crdev->next_band = band; + crdev->next_band = band; if(gs_debug[':'] != 0) dmprintf1(mem, "%% Using %d rendering threads\n", i); - return 0; + return code; } /* This is also exported for teardown after background printing */ @@ -363,25 +514,40 @@ if (bg_print) { /* we are cleaning up a background printing thread, so we clean up similarly to */ /* what is done by clist_finish_page, but without re-opening the clist files. */ - gs_free_object(thread_cdev->memory, thread_crdev->color_usage_array, "clist_color_usage_array"); - thread_crdev->color_usage_array = NULL; clist_teardown_render_threads(dev); /* we may have used multiple threads */ /* free the thread's icc_table since this was not done by clist_finish_page */ - clist_icc_freetable(thread_crdev->icc_table, thread_memory); - rc_decrement(thread_crdev->icc_cache_cl, "teardown_render_thread"); - } - /* - * Free the BufferSpace, close the band files, optionally unlinking them. - * We unlink the files if this call is cleaning up from bg printing. + clist_free_icc_table(thread_crdev->icc_table, thread_memory); + thread_crdev->icc_table = NULL; + /* NB: gdev_prn_free_memory below will free the color_usage_array */ + } else { + /* make sure this doesn't get freed by gdev_prn_free_memory below */ + ((gx_device_clist_reader *)thread_cdev)->color_usage_array = NULL; + + /* For non-bg_print cases the icc_table is shared between devices, but + * is not reference counted or anything. We rely on it being shared with + * and owned by the "parent" device in the interpreter thread, hence + * null it here to avoid it being freed as we cleanup the thread device. + */ + thread_crdev->icc_table = NULL; + } + rc_decrement(thread_crdev->icc_cache_cl, "teardown_render_thread"); + thread_crdev->icc_cache_cl = NULL; + /* + * Free the BufferSpace, close the band files, optionally unlinking them. + * We unlink the files if this call is cleaning up from bg printing. * Note that the BufferSpace is freed using 'ppdev->buf' so the 'data' * pointer doesn't need to be the one that the thread started with */ /* If this thread was being used for background printing and NumRenderingThreads > 0 */ /* the clist_setup_render_threads may have already closed these files */ - if (thread_cdev->page_info.cfile != NULL) - thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.bfile, thread_cdev->page_info.bfname, bg_print); + /* Note that in the case of back ground printing, we only want to close the instance */ + /* of the files for the reader (hence the final parameter being false). We'll clean */ + /* the original instance of the files in prn_finish_bg_print() */ if (thread_cdev->page_info.bfile != NULL) - thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.cfile, thread_cdev->page_info.cfname, bg_print); + thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.bfile, thread_cdev->page_info.bfname, false); + if (thread_cdev->page_info.cfile != NULL) + thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.cfile, thread_cdev->page_info.cfname, false); + thread_cdev->page_info.bfile = thread_cdev->page_info.cfile = NULL; thread_cdev->do_not_open_or_close_bandfiles = true; /* we already closed the files */ gdev_prn_free_memory((gx_device *)thread_cdev); @@ -403,11 +569,10 @@ gx_device_clist *cldev = (gx_device_clist *)dev; gx_device_clist_common *cdev = (gx_device_clist_common *)dev; gx_device_clist_reader *crdev = &cldev->reader; - gs_memory_t *mem = cdev->bandlist_memory, *chunk_base_mem; + gs_memory_t *mem = cdev->bandlist_memory; int i; if (crdev->render_threads != NULL) { - chunk_base_mem = gs_memory_chunk_target(crdev->render_threads[0].memory); /* Wait for each thread to finish then free its memory */ for (i = (crdev->num_render_threads - 1); i >= 0; i--) { clist_render_thread_control_t *thread = &(crdev->render_threads[i]); @@ -421,6 +586,14 @@ /* destroy the thread's buffer device */ thread_cdev->buf_procs.destroy_buf_device(thread->bdev); + if (thread->options) { + if (thread->options->free_buffer_fn && thread->buffer) { + thread->options->free_buffer_fn(thread->options->arg, dev, thread->memory, thread->buffer); + thread->buffer = NULL; + } + thread->options = NULL; + } + /* before freeing this device's memory, swap with cdev if it was the main_thread_data */ if (thread_cdev->data == crdev->main_thread_data) { thread_cdev->data = cdev->data; @@ -466,6 +639,7 @@ code = gp_thread_start(clist_render_thread, &(crdev->render_threads[thread_index]), &(crdev->render_threads[thread_index].thread)); + gp_thread_label(crdev->render_threads[thread_index].thread, "Band"); return code; } @@ -480,7 +654,8 @@ gx_device *bdev = thread->bdev; gs_int_rect band_rect; byte *mdata = crdev->data + crdev->page_tile_cache_size; - uint raster = bitmap_raster(dev->width * dev->color_info.depth); + byte *mlines = (crdev->page_line_ptrs_offset == 0 ? NULL : mdata + crdev->page_line_ptrs_offset); + uint raster = gx_device_raster_plane(dev, NULL); int code; int band_height = crdev->page_band_height; int band = thread->band; @@ -497,13 +672,17 @@ band_num_lines = band_end_line - band_begin_line; code = crdev->buf_procs.setup_buf_device - (bdev, mdata, raster, NULL, 0, band_num_lines, band_num_lines); + (bdev, mdata, raster, (byte **)mlines, 0, band_num_lines, band_num_lines); band_rect.p.x = 0; band_rect.p.y = band_begin_line; band_rect.q.x = dev->width; band_rect.q.y = band_end_line; if (code >= 0) code = clist_render_rectangle(cldev, &band_rect, bdev, NULL, true); + + if (code >= 0 && thread->options && thread->options->process_fn) + code = thread->options->process_fn(thread->options->arg, dev, bdev, &band_rect, thread->buffer); + /* Reset the band boundaries now */ crdev->ymin = band_begin_line; crdev->ymax = band_end_line; @@ -536,7 +715,7 @@ * next band remaining to do (if any) */ static int -clist_get_band_from_thread(gx_device *dev, int band_needed) +clist_get_band_from_thread(gx_device *dev, int band_needed, gx_process_page_options_t *options) { gx_device_clist *cldev = (gx_device_clist *)dev; gx_device_clist_common *cdev = (gx_device_clist_common *)dev; @@ -553,6 +732,10 @@ if (thread->band != band_needed) { int band = band_needed; + emprintf3(thread->memory, + "thread->band = %d, band_needed = %d, direction = %d, ", + thread->band, band_needed, crdev->thread_lookahead_direction); + /* Probably we went in the wrong direction, so let the threads */ /* all complete, then restart them in the opposite direction */ /* If the caller is 'bouncing around' we may end up back here, */ @@ -568,7 +751,10 @@ crdev->thread_lookahead_direction = -1; /* assume backwards if we are asking for the last band */ if (band_needed == 0) crdev->thread_lookahead_direction = 1; /* force forward if we are looking for band 0 */ - /* Loop creating the devices and semaphores for each thread, then start them */ + + dmprintf1(thread->memory, "new_direction = %d\n", crdev->thread_lookahead_direction); + + /* Loop starting the threads in the new lookahead_direction */ for (i=0; (i < crdev->num_render_threads) && (band >= 0) && (band < band_count); i++, band += crdev->thread_lookahead_direction) { thread = &(crdev->render_threads[i]); @@ -587,7 +773,13 @@ gp_thread_finish(thread->thread); thread->thread = NULL; if (thread->status == THREAD_ERROR) - return gs_error_unknownerror; /* FAIL */ + return_error(gs_error_unknownerror); /* FAIL */ + + if (options && options->output_fn) { + code = options->output_fn(options->arg, dev, thread->buffer); + if (code < 0) + return code; + } /* Swap the data areas to avoid the copy */ tmp = cdev->data; @@ -634,7 +826,7 @@ int lines_rasterized; gx_device *bdev; byte *mdata; - uint raster = bitmap_raster(dev->width * dev->color_info.depth); + uint raster = gx_device_raster(dev, 1); int my; int code = 0; @@ -656,7 +848,7 @@ if (crdev->ymin == 0 && crdev->ymax == 0 && crdev->render_threads == NULL) { /* Haven't done any rendering yet, try to set up the threads */ - if (clist_setup_render_threads(dev, y) < 0) + if (clist_setup_render_threads(dev, y, NULL) < 0) /* problem setting up the threads, revert to single threaded */ return clist_get_bits_rectangle(dev, prect, params, unread); } else { @@ -668,7 +860,7 @@ } /* If we already have the band's data, just return it */ if (y < crdev->ymin || end_y > crdev->ymax) - code = clist_get_band_from_thread(dev, band); + code = clist_get_band_from_thread(dev, band, NULL); if (code < 0) goto free_thread_out; mdata = crdev->data + crdev->page_tile_cache_size; @@ -708,8 +900,7 @@ options = params->options; if (!(options & GB_RETURN_COPY)) { /* Redo the first piece with copying. */ - params->options = options = - (params->options & ~GB_RETURN_ALL) | GB_RETURN_COPY; + params->options = (params->options & ~GB_RETURN_ALL) | GB_RETURN_COPY; lines_rasterized = 0; } { @@ -736,7 +927,7 @@ (bdev, &band_rect, &band_params, unread); if (code < 0) break; - params->options = options = band_params.options; + params->options = band_params.options; if (lines_rasterized == line_count) break; } @@ -750,6 +941,121 @@ return code; } +int +clist_process_page(gx_device *dev, gx_process_page_options_t *options) +{ + gx_device_clist *cldev = (gx_device_clist *)dev; + gx_device_clist_reader *crdev = &cldev->reader; + gx_device_clist_common *cdev = (gx_device_clist_common *)dev; + int y; + int line_count; + int band_height = crdev->page_band_height; + gs_int_rect band_rect; + int lines_rasterized; + gx_device *bdev; + gx_render_plane_t render_plane; + int my; + int code; + void *buffer = NULL; + + if (0 > (code = clist_close_writer_and_init_reader(cldev))) + return code; + + if (options->init_buffer_fn) { + code = options->init_buffer_fn(options->arg, dev, dev->memory, dev->width, band_height, &buffer); + if (code < 0) + return code; + } + + render_plane.index = -1; + for (y = 0; y < dev->height; y += lines_rasterized) + { + line_count = band_height; + if (line_count > dev->height - y) + line_count = dev->height - y; + code = gdev_create_buf_device(cdev->buf_procs.create_buf_device, + &bdev, cdev->target, y, &render_plane, + dev->memory, + &(crdev->color_usage_array[y/band_height])); + if (code < 0) + return code; + code = clist_rasterize_lines(dev, y, line_count, bdev, &render_plane, &my); + if (code >= 0) + { + lines_rasterized = min(code, line_count); + + /* Return as much of the rectangle as falls within the rasterized lines. */ + band_rect.p.x = 0; + band_rect.p.y = y; + band_rect.q.x = dev->width; + band_rect.q.y = y + lines_rasterized; + if (options->process_fn) + code = options->process_fn(options->arg, dev, bdev, &band_rect, buffer); + } + if (code >= 0 && options->output_fn) + code = options->output_fn(options->arg, dev, buffer); + cdev->buf_procs.destroy_buf_device(bdev); + if (code < 0) + break; + } + + if (options->free_buffer_fn) { + options->free_buffer_fn(options->arg, dev, dev->memory, buffer); + } + + return code; +} + +static int +clist_process_page_mt(gx_device *dev, gx_process_page_options_t *options) +{ + gx_device_printer *pdev = (gx_device_printer *)dev; + gx_device_clist *cldev = (gx_device_clist *)dev; + gx_device_clist_reader *crdev = &cldev->reader; + int band_height = crdev->page_info.band_params.BandHeight; + int band; + int num_bands = (dev->height + band_height-1)/band_height; + int code; + int reverse = !!(options->options & GX_PROCPAGE_BOTTOM_UP); + + /* This page might not want multiple threads */ + /* Also we don't support plane extraction using multiple threads */ + if (pdev->num_render_threads_requested < 1) + return clist_process_page(dev, options); + + if ((code = clist_close_writer_and_init_reader(cldev)) < 0) + return code; /* can't recover from this */ + + /* Haven't done any rendering yet, try to set up the threads */ + if (clist_setup_render_threads(dev, reverse ? dev->height-1 : 0, options) < 0) + /* problem setting up the threads, revert to single threaded */ + return clist_process_page(dev, options); + + if (reverse) + { + for (band = num_bands-1; band > 0; band--) + { + code = clist_get_band_from_thread(dev, band, options); + if (code < 0) + goto free_thread_out; + } + } + else + { + for (band = 0; band < num_bands; band++) + { + code = clist_get_band_from_thread(dev, band, options); + if (code < 0) + goto free_thread_out; + } + } + + /* Always free up thread stuff before exiting*/ +free_thread_out: + clist_teardown_render_threads(dev); + return code; +} + static void test_threads(void *dummy) { @@ -769,8 +1075,10 @@ if ((code = gp_thread_start(test_threads, NULL, &thread)) < 0 ) { return code; /* Threads don't work */ } + gp_thread_label(thread, "test_thread"); gp_thread_finish(thread); set_dev_proc(dev, get_bits_rectangle, clist_get_bits_rect_mt); + set_dev_proc(dev, process_page, clist_process_page_mt); return 1; } diff -Nru ghostscript-9.10~dfsg/base/gxclthrd.h ghostscript-9.25~dfsg+1/base/gxclthrd.h --- ghostscript-9.10~dfsg/base/gxclthrd.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclthrd.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,7 +28,7 @@ /* to the chunk allocator. */ /* Exported for use by background printing. */ /* When called to setup for background printing, bg_print is true */ -gx_device * setup_device_and_mem_for_thread(gs_memory_t *chunk_base_mem, gx_device *dev, bool bg_print); +gx_device * setup_device_and_mem_for_thread(gs_memory_t *chunk_base_mem, gx_device *dev, bool bg_print, gsicc_link_cache_t **cachep); /* Close and free the thread's device, finish the thread, free up the */ /* thread's memory and its chunk allocator and close the clist files */ @@ -59,6 +59,10 @@ gx_device *bdev; /* this thread's buffer device */ int band; gp_thread_id thread; + + /* For process_page mode */ + gx_process_page_options_t *options; + void *buffer; #ifdef DEBUG ulong cputime; #endif diff -Nru ghostscript-9.10~dfsg/base/gxclutil.c ghostscript-9.25~dfsg+1/base/gxclutil.c --- ghostscript-9.10~dfsg/base/gxclutil.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclutil.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -178,7 +178,7 @@ cb.band_min = band_min; cb.band_max = band_max; cb.pos = cldev->page_info.io_procs->ftell(cfile); - if_debug3m('l', cldev->memory, "[l]writing for bands (%d,%d) at %ld K %d \n", + if_debug3m('l', cldev->memory, "[l]writing for bands (%d,%d) at %ld\n", band_min, band_max, (long)cb.pos); cldev->page_info.io_procs->fwrite_chars(&cb, sizeof(cb), bfile); if (cp != 0) { @@ -304,14 +304,6 @@ if ((cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run)) != 0 || (size + cmd_headroom > cldev->cend - cldev->cnext)) { - if (cldev->error_code < 0) - cldev->error_is_retryable = 0; /* hard error */ - else { - /* upgrade lo-mem warning into an error */ - if (!cldev->ignore_lo_mem_warnings) - cldev->error_code = gs_note_error(gs_error_VMerror); - cldev->error_is_retryable = 1; - } return 0; } else @@ -368,7 +360,6 @@ if (size + cmd_headroom > cldev->cend - cldev->cnext) { cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run); if (cldev->error_code < 0) { - cldev->error_is_retryable = 0; /* hard error */ return cldev->error_code; } } @@ -399,13 +390,6 @@ band_max != cldev->band_range_max) ) { if ((cldev->error_code = cmd_write_buffer(cldev, cmd_opv_end_run)) != 0) { - if (cldev->error_code < 0) - cldev->error_is_retryable = 0; /* hard error */ - else { - /* upgrade lo-mem warning into an error */ - cldev->error_code = gs_error_VMerror; - cldev->error_is_retryable = 1; - } return 0; } cldev->band_range_min = band_min; @@ -567,7 +551,7 @@ /* If this is a tile color then send tile color type */ if (select->tile_color) { - code = set_cmd_put_op(dp, cldev, pcls, cmd_opv_set_tile_color, 1); + code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_tile_color, 1); if (code < 0) return code; } @@ -578,7 +562,7 @@ * We must handle this specially, because it may take more * bytes than the color depth. */ - code = set_cmd_put_op(dp, cldev, pcls, op + cmd_no_color_index, 1); + code = set_cmd_put_op(&dp, cldev, pcls, op + cmd_no_color_index, 1); if (code < 0) return code; } else { @@ -611,7 +595,7 @@ } /* Now send one of the two command forms */ if (use_delta && delta_bytes < (num_bytes - bytes_dropped)) { - code = set_cmd_put_op(dp, cldev, pcls, + code = set_cmd_put_op(&dp, cldev, pcls, op_delta, delta_bytes + 1); if (code < 0) return code; @@ -631,7 +615,7 @@ } else { num_bytes -= bytes_dropped; - code = set_cmd_put_op(dp, cldev, pcls, + code = set_cmd_put_op(&dp, cldev, pcls, (byte)(op + bytes_dropped), num_bytes + 1); if (code < 0) return code; @@ -677,15 +661,15 @@ pcsize = 1 + cmd_size2w(px, py); if (all_bands) - code = set_cmd_put_all_op(dp, cldev, (byte)cmd_opv_set_tile_phase, pcsize); + code = set_cmd_put_all_op(&dp, cldev, (byte)cmd_opv_set_tile_phase, pcsize); else - code = set_cmd_put_op(dp, cldev, pcls, (byte)cmd_opv_set_tile_phase, pcsize); + code = set_cmd_put_op(&dp, cldev, pcls, (byte)cmd_opv_set_tile_phase, pcsize); if (code < 0) return code; ++dp; pcls->tile_phase.x = px; pcls->tile_phase.y = py; - cmd_putxy(pcls->tile_phase, dp); + cmd_putxy(pcls->tile_phase, &dp); return 0; } @@ -702,7 +686,7 @@ int enable) { byte *dp; - int code = set_cmd_put_op(dp, cldev, pcls, + int code = set_cmd_put_op(&dp, cldev, pcls, (byte)(enable ? cmd_opv_enable_lop : cmd_opv_disable_lop), 1); @@ -720,7 +704,7 @@ int enable) { byte *dp; - int code = set_cmd_put_op(dp, cldev, pcls, + int code = set_cmd_put_op(&dp, cldev, pcls, (byte)(enable ? cmd_opv_enable_clip : cmd_opv_disable_clip), 1); @@ -738,7 +722,7 @@ { byte *dp; uint lop_msb = lop >> 6; - int code = set_cmd_put_op(dp, cldev, pcls, + int code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_misc, 2 + cmd_size_w(lop_msb)); if (code < 0) @@ -780,7 +764,7 @@ gs_param_list_serialize(param_list, local_buf, sizeof(local_buf)); if (param_length > 0) { /* Get cmd buffer space for serialized */ - code = set_cmd_put_all_op(dp, cldev, cmd_opv_extend, + code = set_cmd_put_all_op(&dp, cldev, cmd_opv_extend, 2 + sizeof(unsigned) + param_length); if (code < 0) return code; diff -Nru ghostscript-9.10~dfsg/base/gxclzlib.c ghostscript-9.25~dfsg+1/base/gxclzlib.c --- ghostscript-9.10~dfsg/base/gxclzlib.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxclzlib.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxcmap.c ghostscript-9.25~dfsg+1/base/gxcmap.c --- ghostscript-9.10~dfsg/base/gxcmap.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcmap.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -54,14 +54,14 @@ gx_color_index gx_default_encode_color(gx_device * dev, const gx_color_value cv[]) { - int ncomps = dev->color_info.num_components; - int i; + uchar ncomps = dev->color_info.num_components; + uchar i; const byte * comp_shift = dev->color_info.comp_shift; const byte * comp_bits = dev->color_info.comp_bits; gx_color_index color = 0; #ifdef DEBUG - if ( dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN ) { + if (!colors_are_separable_and_linear(&dev->color_info)) { dmprintf(dev->memory, "gx_default_encode_color() requires separable and linear\n" ); return gx_no_color_index; } @@ -82,17 +82,17 @@ int gx_default_decode_color(gx_device * dev, gx_color_index color, gx_color_value cv[]) { - int ncomps = dev->color_info.num_components; - int i; + uchar ncomps = dev->color_info.num_components; + uchar i; const byte * comp_shift = dev->color_info.comp_shift; const byte * comp_bits = dev->color_info.comp_bits; const gx_color_index * comp_mask = dev->color_info.comp_mask; uint shift, ivalue, nbits, scale; #ifdef DEBUG - if ( dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN ) { + if (!colors_are_separable_and_linear(&dev->color_info)) { dmprintf(dev->memory, "gx_default_decode_color() requires separable and linear\n" ); - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } #endif @@ -139,7 +139,7 @@ #endif for(; i>=0; i--) colors[i] = 0; - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } /* @@ -175,7 +175,7 @@ gx_color_index gx_default_gray_encode(gx_device * dev, const gx_color_value cv[]) { - return cv[0] * (dev->color_info.max_gray + 1) / (gx_max_color_value + 1); + return (gx_color_index)(cv[0]) * (dev->color_info.max_gray + 1) / (gx_max_color_value + 1); } /** @@ -206,7 +206,7 @@ } static void -rgb_cs_to_gray_cm(gx_device * dev, const gs_imager_state *pis, +rgb_cs_to_gray_cm(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { out[0] = color_rgb_to_gray(r, g, b, NULL); @@ -225,7 +225,7 @@ } void -rgb_cs_to_rgb_cm(gx_device * dev, const gs_imager_state *pis, +rgb_cs_to_rgb_cm(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { out[0] = r; @@ -247,7 +247,7 @@ } static void -rgb_cs_to_rgbk_cm(gx_device * dev, const gs_imager_state *pis, +rgb_cs_to_rgbk_cm(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { if ((r == g) && (g == b)) { @@ -289,7 +289,7 @@ * it is unlikely that any device with a DeviceCMYK color model * would define this mapping on its own. * - * If the imager state is not available, map as though the black + * If the gs_gstate is not available, map as though the black * generation and undercolor removal functions are identity * transformations. This mode is used primarily to support the * raster operation (rop) feature of PCL, which requires that @@ -299,11 +299,11 @@ * often they are { pop 0 }. */ static void -rgb_cs_to_cmyk_cm(gx_device * dev, const gs_imager_state *pis, +rgb_cs_to_cmyk_cm(gx_device * dev, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) { - if (pis != 0) - color_rgb_to_cmyk(r, g, b, pis, out, dev->memory); + if (pgs != 0) + color_rgb_to_cmyk(r, g, b, pgs, out, dev->memory); else { frac c = frac_1 - r, m = frac_1 - g, y = frac_1 - b; frac k = min(c, min(m, y)); @@ -526,55 +526,57 @@ const gx_color_map_procs *const cmap_procs_default = &cmap_many; /* Determine the color mapping procedures for a device. */ -/* Note that the default procedure doesn't consult the imager state. */ +/* Note that the default procedure doesn't consult the gs_gstate. */ const gx_color_map_procs * -gx_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev) +gx_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev) { - return (pis->get_cmap_procs)(pis, dev); + return (pgs->get_cmap_procs)(pgs, dev); } const gx_color_map_procs * -gx_default_get_cmap_procs(const gs_imager_state *pis, const gx_device * dev) +gx_default_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev) { return (gx_device_must_halftone(dev) ? &cmap_few : &cmap_many); } /* Set the color mapping procedures in the graphics state. */ void -gx_set_cmap_procs(gs_imager_state * pis, const gx_device * dev) +gx_set_cmap_procs(gs_gstate * pgs, const gx_device * dev) { - pis->cmap_procs = gx_get_cmap_procs(pis, dev); + pgs->cmap_procs = gx_get_cmap_procs(pgs, dev); } /* Remap the color in the graphics state. */ int -gx_remap_color(gs_state * pgs) +gx_remap_color(gs_gstate * pgs) { const gs_color_space *pcs = gs_currentcolorspace_inline(pgs); - int code; + int code = 0; /* The current color in the graphics state is always used for */ /* the texture, never for the source. */ - code = (*pcs->type->remap_color) (gs_currentcolor_inline(pgs), - pcs, gs_currentdevicecolor_inline(pgs), - (gs_imager_state *) pgs, pgs->device, - gs_color_select_texture); + /* skip remap if the dev_color is already set and is type "pure" (a common case) */ + if (!gx_dc_is_pure(gs_currentdevicecolor_inline(pgs))) + code = (*pcs->type->remap_color) (gs_currentcolor_inline(pgs), + pcs, gs_currentdevicecolor_inline(pgs), + (gs_gstate *) pgs, pgs->device, + gs_color_select_texture); /* if overprint mode is in effect, update the overprint information */ - if (code >= 0 && pgs->effective_overprint_mode == 1) + if (code >= 0 && pgs->overprint) code = gs_do_set_overprint(pgs); return code; } /* Indicate that a color space has no underlying concrete space. */ const gs_color_space * -gx_no_concrete_space(const gs_color_space * pcs, const gs_imager_state * pis) +gx_no_concrete_space(const gs_color_space * pcs, const gs_gstate * pgs) { return NULL; } /* Indicate that a color space is concrete. */ const gs_color_space * -gx_same_concrete_space(const gs_color_space * pcs, const gs_imager_state * pis) +gx_same_concrete_space(const gs_color_space * pcs, const gs_gstate * pgs) { return pcs; } @@ -582,27 +584,161 @@ /* Indicate that a color cannot be concretized. */ int gx_no_concretize_color(const gs_client_color * pcc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { return_error(gs_error_rangecheck); } -/* By default, remap a color by concretizing it and then */ -/* remapping the concrete color. */ +/* If someone has specified a table for handling named spot colors then we will + be attempting to do the special handling to go directly to the device colors + here */ +bool +gx_remap_named_color(const gs_client_color * pcc, const gs_color_space * pcs, +gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, +gs_color_select_t select) +{ + gx_color_value device_values[GX_DEVICE_COLOR_MAX_COMPONENTS]; + const gs_separation_name name = pcs->params.separation.sep_name; + byte *pname; + uint name_size; + gsicc_rendering_param_t rendering_params; + int code; + gsicc_namedcolor_t named_color_sep; + gsicc_namedcolor_t *named_color_devn = NULL; + gsicc_namedcolor_t *named_color_ptr = NULL; + uchar num_des_comps = dev->color_info.num_components; + uchar k; + frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS]; + int i = pcs->type->num_components(pcs); + cmm_dev_profile_t *dev_profile = NULL; + gs_color_space_index type = gs_color_space_get_index(pcs); + int num_src_comps = 1; + + /* Define the rendering intents. */ + rendering_params.black_point_comp = pgs->blackptcomp; + rendering_params.graphics_type_tag = dev->graphics_type_tag; + rendering_params.override_icc = false; + rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; + rendering_params.rendering_intent = pgs->renderingintent; + rendering_params.cmm = gsCMM_DEFAULT; + + if (type == gs_color_space_index_Separation) { + pcs->params.separation.get_colorname_string(pgs->memory, name, + &pname, &name_size); + named_color_sep.colorant_name = (char*)pname; + named_color_sep.name_size = name_size; + named_color_ptr = &named_color_sep; + } else if (type == gs_color_space_index_DeviceN) { + const gs_separation_name *names = pcs->params.device_n.names; + num_src_comps = pcs->params.device_n.num_components; + /* Allocate and initialize name structure */ + named_color_devn = + (gsicc_namedcolor_t*)gs_alloc_bytes(dev->memory->non_gc_memory, + num_src_comps * sizeof(gsicc_namedcolor_t), + "gx_remap_named_color"); + if (named_color_devn == NULL) + return false; /* Clearly a bigger issue. But lets not end here */ + for (k = 0; k < num_src_comps; k++) { + pcs->params.device_n.get_colorname_string(dev->memory, names[k], + &pname, &name_size); + named_color_devn[k].colorant_name = (char*)pname; + named_color_devn[k].name_size = name_size; + } + named_color_ptr = named_color_devn; + } else + return false; /* Only sep and deviceN for named color replacement */ + + code = gsicc_transform_named_color(pcc->paint.values, named_color_ptr, + num_src_comps, device_values, pgs, dev, NULL, &rendering_params); + if (named_color_devn != NULL) + gs_free_object(dev->memory->non_gc_memory, named_color_devn, + "gx_remap_named_color"); + + if (code == 0) { + /* Named color was found and set. Note that gsicc_transform_named_color + MUST set ALL the colorant values AND they must be in the proper + order already. If we have specified the colorants with + -sICCOutputColors (i.e. if you are using an NCLR output profile) then + we should be good. If not or if instead one used SeparationColorNames and + SeparationOrder to set up the device, then we need to make a copy + of the gs_gstate and make sure that we set color_component_map is + properly set up for the gx_remap_concrete_devicen proc. */ + for (k = 0; k < num_des_comps; k++) + conc[k] = float2frac(((float)device_values[k]) / 65535.0); + + /* If we are looking to create the equivalent CMYK value then no need + to worry about NCLR profiles or about altering the colorant map */ + if (!named_color_equivalent_cmyk_colors(pgs)) { + /* We need to apply transfer functions, possibily halftone and + encode the color for the device. To get proper mapping of the + colors to the device positions, you MUST specify -sICCOutputColors + which will enumerate the positions of the colorants and enable + proper color management for the CMYK portions IF you are using + an NCLR output profile. */ + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return false; + + /* Check if the profile is DeviceN (NCLR) */ + if (dev_profile->device_profile[0]->data_cs == gsNCHANNEL) { + if (dev_profile->spotnames == NULL) + return false; + if (!dev_profile->spotnames->equiv_cmyk_set) { + /* Note that if the improper NCLR profile is used, then the + composite preview will be wrong. */ + code = gsicc_set_devicen_equiv_colors(dev, pgs, dev_profile->device_profile[0]); + if (code < 0) + return false; + dev_profile->spotnames->equiv_cmyk_set = true; + } + gx_remap_concrete_devicen(conc, pdc, pgs, dev, select); + } else { + gs_gstate temp_state = *((const gs_gstate *)pgs); + + /* No NCLR profile with spot names. So set up the + color_component_map in the gs_gstate. Again, note that + gsicc_transform_named_color must have set ALL the device + colors */ + for (k = 0; k < dev->color_info.num_components; k++) + temp_state.color_component_map.color_map[k] = k; + temp_state.color_component_map.num_components = dev->color_info.num_components; + gx_remap_concrete_devicen(conc, pdc, &temp_state, dev, select); + } + } else { + gx_remap_concrete_devicen(conc, pdc, pgs, dev, select); + } + /* Save original color space and color info into dev color */ + i = any_abs(i); + for (i--; i >= 0; i--) + pdc->ccolor.paint.values[i] = pcc->paint.values[i]; + pdc->ccolor_valid = true; + return true; + } + return false; +} + +/* By default, remap a color by concretizing it and then remapping the concrete + color. */ int gx_default_remap_color(const gs_client_color * pcc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { frac conc[GS_CLIENT_COLOR_MAX_COMPONENTS]; const gs_color_space *pconcs; int i = pcs->type->num_components(pcs); - int code = (*pcs->type->concretize_color)(pcc, pcs, conc, pis, dev); + int code = (*pcs->type->concretize_color)(pcc, pcs, conc, pgs, dev); + cmm_dev_profile_t *dev_profile; if (code < 0) return code; - pconcs = cs_concrete_space(pcs, pis); - code = (*pconcs->type->remap_concrete_color)(conc, pconcs, pdc, pis, dev, select); + pconcs = cs_concrete_space(pcs, pgs); + if (!pconcs) + return gs_note_error(gs_error_undefined); + code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + code = (*pconcs->type->remap_concrete_color)(pconcs, conc, pdc, pgs, dev, select, dev_profile); /* Save original color space and color info into dev color */ i = any_abs(i); @@ -619,69 +755,69 @@ /* DeviceGray */ int gx_concretize_DeviceGray(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { pconc[0] = gx_unit_frac(pc->paint.values[0]); return 0; } int -gx_remap_concrete_DGray(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) -{ - if (pis->alpha == gx_max_color_value) - (*pis->cmap_procs->map_gray) - (pconc[0], pdc, pis, dev, select); +gx_remap_concrete_DGray(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select, + const cmm_dev_profile_t *dev_profile) +{ + if (pgs->alpha == gx_max_color_value) + (*pgs->cmap_procs->map_gray) + (pconc[0], pdc, pgs, dev, select); else - (*pis->cmap_procs->map_rgb_alpha) - (pconc[0], pconc[0], pconc[0], cv2frac(pis->alpha), - pdc, pis, dev, select); + (*pgs->cmap_procs->map_rgb_alpha) + (pconc[0], pconc[0], pconc[0], cv2frac(pgs->alpha), + pdc, pgs, dev, select); return 0; } int gx_remap_DeviceGray(const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select) { frac fgray = gx_unit_frac(pc->paint.values[0]); int code; /* We are in here due to the fact that we are using a color space that - was set in the graphic state before the ICC manager was intitialized + was set in the graphic state before the ICC manager was intitialized and the color space was never actually "installed" and hence set - over to a proper ICC color space. We will "install" this color space + over to a proper ICC color space. We will "install" this color space at this time */ - if (pis->icc_manager->default_gray != NULL) { + if (pgs->icc_manager->default_gray != NULL) { gs_color_space *pcs_notconst = (gs_color_space*) pcs; - gs_state *pgs = (gs_state*) pis; - pcs_notconst->cmm_icc_profile_data = pis->icc_manager->default_gray; - rc_increment(pis->icc_manager->default_gray); + pcs_notconst->cmm_icc_profile_data = pgs->icc_manager->default_gray; + gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "gx_remap_DeviceGray"); pcs_notconst->type = &gs_color_space_type_ICC; - code = + code = (*pcs_notconst->type->remap_color)(gs_currentcolor_inline(pgs), - pcs_notconst, + pcs_notconst, gs_currentdevicecolor_inline(pgs), - pis, pgs->device, + pgs, pgs->device, gs_color_select_texture); return code; } - /* Save orgxiginal color space and color info into dev color */ + /* Save original color space and color info into dev color */ pdc->ccolor.paint.values[0] = pc->paint.values[0]; pdc->ccolor_valid = true; - if (pis->alpha == gx_max_color_value) - (*pis->cmap_procs->map_gray) - (fgray, pdc, pis, dev, select); + if (pgs->alpha == gx_max_color_value) + (*pgs->cmap_procs->map_gray) + (fgray, pdc, pgs, dev, select); else - (*pis->cmap_procs->map_rgb_alpha) - (fgray, fgray, fgray, cv2frac(pis->alpha), pdc, pis, dev, select); + (*pgs->cmap_procs->map_rgb_alpha) + (fgray, fgray, fgray, cv2frac(pgs->alpha), pdc, pgs, dev, select); return 0; } /* DeviceRGB */ int gx_concretize_DeviceRGB(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { pconc[0] = gx_unit_frac(pc->paint.values[0]); pconc[1] = gx_unit_frac(pc->paint.values[1]); @@ -689,22 +825,23 @@ return 0; } int -gx_remap_concrete_DRGB(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) +gx_remap_concrete_DRGB(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select, + const cmm_dev_profile_t *dev_profile) { - if (pis->alpha == gx_max_color_value) + if (pgs->alpha == gx_max_color_value) gx_remap_concrete_rgb(pconc[0], pconc[1], pconc[2], - pdc, pis, dev, select); + pdc, pgs, dev, select); else gx_remap_concrete_rgb_alpha(pconc[0], pconc[1], pconc[2], - cv2frac(pis->alpha), - pdc, pis, dev, select); + cv2frac(pgs->alpha), + pdc, pgs, dev, select); return 0; } int gx_remap_DeviceRGB(const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { frac fred = gx_unit_frac(pc->paint.values[0]), fgreen = gx_unit_frac(pc->paint.values[1]), @@ -715,19 +852,19 @@ pdc->ccolor.paint.values[1] = pc->paint.values[1]; pdc->ccolor.paint.values[2] = pc->paint.values[2]; pdc->ccolor_valid = true; - if (pis->alpha == gx_max_color_value) + if (pgs->alpha == gx_max_color_value) gx_remap_concrete_rgb(fred, fgreen, fblue, - pdc, pis, dev, select); + pdc, pgs, dev, select); else - gx_remap_concrete_rgb_alpha(fred, fgreen, fblue, cv2frac(pis->alpha), - pdc, pis, dev, select); + gx_remap_concrete_rgb_alpha(fred, fgreen, fblue, cv2frac(pgs->alpha), + pdc, pgs, dev, select); return 0; } /* DeviceCMYK */ int gx_concretize_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs, - frac * pconc, const gs_imager_state * pis, gx_device *dev) + frac * pconc, const gs_gstate * pgs, gx_device *dev) { pconc[0] = gx_unit_frac(pc->paint.values[0]); pconc[1] = gx_unit_frac(pc->paint.values[1]); @@ -736,18 +873,19 @@ return 0; } int -gx_remap_concrete_DCMYK(const frac * pconc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, - gs_color_select_t select) +gx_remap_concrete_DCMYK(const gs_color_space * pcs, const frac * pconc, + gx_device_color * pdc, const gs_gstate * pgs, + gx_device * dev, gs_color_select_t select, + const cmm_dev_profile_t *dev_profile) { /****** IGNORE alpha ******/ gx_remap_concrete_cmyk(pconc[0], pconc[1], pconc[2], pconc[3], pdc, - pis, dev, select, pcs); + pgs, dev, select, pcs); return 0; } int gx_remap_DeviceCMYK(const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { /****** IGNORE alpha ******/ @@ -761,7 +899,7 @@ gx_unit_frac(pc->paint.values[1]), gx_unit_frac(pc->paint.values[2]), gx_unit_frac(pc->paint.values[3]), - pdc, pis, dev, select, pcs); + pdc, pgs, dev, select, pcs); return 0; } @@ -769,188 +907,207 @@ static void cmap_gray_halftoned(frac gray, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; + subclass_color_mappings scm; /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - dev_proc(dev, get_color_mapping_procs)(dev)->map_gray(dev, gray, cm_comps); + scm = get_color_mapping_procs_subclass(dev); + map_gray_subclass(scm, gray, cm_comps); /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + if (pgs->effective_transfer_non_identity_count == 0) { + if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) + check_cmyk_color_model_comps(dev); + } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pis, + cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); else { if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) check_cmyk_color_model_comps(dev); if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ - int k = dev->color_info.black_component; - - for (i = 0; i < ncomps; i++) { - if (i == k) - cm_comps[i] = frac_1 - gx_map_color_frac(pis, + i = dev->color_info.black_component; + if (i < ncomps) + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); - else - cm_comps[i] = cm_comps[i]; /* Ignore transfer, see PLRM3 p. 494 */ - } } else { for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pis, + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); } } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht, - &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } static void -cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_imager_state * pis, +cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; + subclass_color_mappings scm; /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - dev_proc(dev, get_color_mapping_procs)(dev)->map_gray(dev, gray, cm_comps); + scm = get_color_mapping_procs_subclass(dev); + map_gray_subclass(scm, gray, cm_comps); /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + if (pgs->effective_transfer_non_identity_count == 0) { + if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) + check_cmyk_color_model_comps(dev); for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pis, - cm_comps[i], effective_transfer[i])); + cv[i] = frac2cv(cm_comps[i]); + } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + for (i = 0; i < ncomps; i++) { + cm_comps[i] = gx_map_color_frac(pgs, + cm_comps[i], effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); + } else { if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) check_cmyk_color_model_comps(dev); if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ - int k = dev->color_info.black_component; - + i = dev->color_info.black_component; + if (i < ncomps) + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(cm_comps[i]); + } else { for (i = 0; i < ncomps; i++) { - if (i == k) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); - else - cv[i] = frac2cv(cm_comps[i]); /* Ignore transfer, see PLRM3 p. 494 */ + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); } - } else { - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); } } /* encode as a color index */ color = dev_proc(dev, encode_color)(dev, cv); /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) + if (color != gx_no_color_index) { color_set_pure(pdc, color); - else - cmap_gray_halftoned(gray, pdc, pis, dev, select); + return; + } + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } /* ------ Render RGB color. ------ */ static void cmap_rgb_halftoned(frac r, frac g, frac b, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; + subclass_color_mappings scm; /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps); + scm = get_color_mapping_procs_subclass(dev); + map_rgb_subclass(scm, pgs, r, g, b, cm_comps); /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pis, + if (pgs->effective_transfer_non_identity_count != 0) { + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + for (i = 0; i < ncomps; i++) + cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); - else - for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pis, + else + for (i = 0; i < ncomps; i++) + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht, - &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } static void cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; + subclass_color_mappings scm; /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps); + scm = get_color_mapping_procs_subclass(dev); + map_rgb_subclass(scm, pgs, r, g, b, cm_comps); /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + if (pgs->effective_transfer_non_identity_count == 0) { for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pis, - cm_comps[i], effective_transfer[i])); + cv[i] = frac2cv(cm_comps[i]); + } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + for (i = 0; i < ncomps; i++) { + cm_comps[i] = gx_map_color_frac(pgs, + cm_comps[i], effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); + } else - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); + for (i = 0; i < ncomps; i++) { + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); + } /* encode as a color index */ color = dev_proc(dev, encode_color)(dev, cv); /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) + if (color != gx_no_color_index) { color_set_pure(pdc, color); - else - cmap_rgb_halftoned(r, g, b, pdc, pis, dev, select); + return; + } + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } /* ------ Render CMYK color. ------ */ static void cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select, + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select, const gs_color_space *source_pcs) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; - int black_index; + uint black_index; cmm_dev_profile_t *dev_profile; gsicc_colorbuffer_t src_space = gsUNDEFINED; - int code; bool gray_to_k; + subclass_color_mappings scm; /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - dev_proc(dev, get_color_mapping_procs)(dev)->map_cmyk(dev, c, m, y, k, cm_comps); + scm = get_color_mapping_procs_subclass(dev); + map_cmyk_subclass(scm, c, m, y, k, cm_comps); /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pis, + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { + if (pgs->effective_transfer_non_identity_count != 0) + for (i = 0; i < ncomps; i++) + cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); - else { + } else { /* Check if source space is gray. In this case we are to use only the transfer function on the K channel. Do this only if gray to K is also set */ - code = dev_proc(dev, get_profile)(dev, &dev_profile); + dev_proc(dev, get_profile)(dev, &dev_profile); gray_to_k = dev_profile->devicegraytok; if (source_pcs != NULL && source_pcs->cmm_icc_profile_data != NULL) { src_space = source_pcs->cmm_icc_profile_data->data_cs; @@ -961,21 +1118,20 @@ /* Find the black channel location */ black_index = dev_proc(dev, get_color_comp_index)(dev, "Black", strlen("Black"), SEPARATION_NAME); - cm_comps[black_index] = frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[black_index]), + cm_comps[black_index] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cm_comps[black_index]), effective_transfer[black_index]); - } else { + } else if (pgs->effective_transfer_non_identity_count != 0) for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pis, + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); - } } /* We make a test for direct vs. halftoned, rather than */ /* duplicating most of the code of this procedure. */ if (gx_device_must_halftone(dev)) { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pis->dev_ht, &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); return; } /* if output device supports devn, we need to make sure we send it the @@ -994,8 +1150,8 @@ color_set_pure(pdc, color); else { if (gx_render_device_DeviceN(cm_comps, pdc, dev, - pis->dev_ht, &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } } return; @@ -1003,16 +1159,16 @@ static void cmap_rgb_alpha_halftoned(frac r, frac g, frac b, frac alpha, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; + subclass_color_mappings scm; /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps); + scm = get_color_mapping_procs_subclass(dev); + map_rgb_subclass(scm, pgs, r, g, b, cm_comps); /* pre-multiply to account for the alpha weighting */ if (alpha != frac_1) { @@ -1027,33 +1183,35 @@ } /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pis, + if (pgs->effective_transfer_non_identity_count != 0) { + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + for (i = 0; i < ncomps; i++) + cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); - else - for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pis, + else + for (i = 0; i < ncomps; i++) + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht, - &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } static void cmap_rgb_alpha_direct(frac r, frac g, frac b, frac alpha, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv_alpha, cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; + subclass_color_mappings scm; /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - dev_proc(dev, get_color_mapping_procs)(dev)->map_rgb(dev, pis, r, g, b, cm_comps); + scm = get_color_mapping_procs_subclass(dev); + map_rgb_subclass(scm, pgs, r, g, b, cm_comps); /* pre-multiply to account for the alpha weighting */ if (alpha != frac_1) { @@ -1068,13 +1226,16 @@ } /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + if (pgs->effective_transfer_non_identity_count == 0) + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(cm_comps[i]); + else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pis, + cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); else for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, + cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); /* encode as a color index */ @@ -1085,10 +1246,13 @@ color = dev_proc(dev, encode_color)(dev, cv); /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) + if (color != gx_no_color_index) { color_set_pure(pdc, color); - else - cmap_rgb_alpha_halftoned(r, g, b, alpha, pdc, pis, dev, select); + return; + } + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } /* ------ Render Separation All color. ------ */ @@ -1128,16 +1292,14 @@ static void cmap_separation_halftoned(frac all, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, gs_color_select_t select) + const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE; frac comp_value = all; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - if (pis->color_component_map.sep_type == SEP_ALL) { + if (pgs->color_component_map.sep_type == SEP_ALL) { /* * Invert the photometric interpretation for additive * color spaces because separations are always subtractive. @@ -1146,52 +1308,50 @@ comp_value = frac_1 - comp_value; /* Use the "all" value for all components */ - i = pis->color_component_map.num_colorants - 1; - for (; i >= 0; i--) + for (i = 0; i < pgs->color_component_map.num_colorants; i++) cm_comps[i] = comp_value; } else { /* map to the color model */ - map_components_to_colorants(&all, &(pis->color_component_map), cm_comps); + map_components_to_colorants(&all, &(pgs->color_component_map), cm_comps); } /* apply the transfer function(s); convert to color values */ - if (additive) - for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pis, + if (pgs->effective_transfer_non_identity_count != 0) { + if (additive) + for (i = 0; i < ncomps; i++) + cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); - else - for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pis, + else + for (i = 0; i < ncomps; i++) + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + } - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht, - &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } static void -cmap_separation_direct(frac all, gx_device_color * pdc, const gs_imager_state * pis, +cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE; frac comp_value = all; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; bool use_rgb2dev_icc = false; - gsicc_rendering_param_t render_cond; - int code; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile = NULL; cmm_profile_t *des_profile = NULL; - code = dev_proc(dev, get_profile)(dev, &dev_profile); + dev_proc(dev, get_profile)(dev, &dev_profile); gsicc_extract_profile(dev->graphics_type_tag, - dev_profile, &des_profile, &render_cond); - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - if (pis->color_component_map.sep_type == SEP_ALL) { + dev_profile, &des_profile, &render_cond); + if (pgs->color_component_map.sep_type == SEP_ALL) { /* * Invert the photometric interpretation for additive * color spaces because separations are always subtractive. @@ -1200,8 +1360,7 @@ comp_value = frac_1 - comp_value; /* Use the "all" value for all components */ - i = pis->color_component_map.num_colorants - 1; - for (; i >= 0; i--) + for (i = 0; i < pgs->color_component_map.num_colorants; i++) cm_comps[i] = comp_value; /* If our device space is CIELAB then we really want to treat this as RGB during the fill up here of the separation value and then @@ -1215,36 +1374,43 @@ } else { /* map to the color model */ - map_components_to_colorants(&comp_value, &(pis->color_component_map), cm_comps); + map_components_to_colorants(&comp_value, &(pgs->color_component_map), cm_comps); } /* apply the transfer function(s); convert to color values */ - if (additive) + if (pgs->effective_transfer_non_identity_count == 0) for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pis, - cm_comps[i], effective_transfer[i])); + cv[i] = frac2cv(cm_comps[i]); + else if (additive) + for (i = 0; i < ncomps; i++) { + cm_comps[i] = gx_map_color_frac(pgs, + cm_comps[i], effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); + } else - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); + for (i = 0; i < ncomps; i++) { + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); + } - if (use_rgb2dev_icc && pis->icc_manager->default_rgb != NULL) { + if (use_rgb2dev_icc && pgs->icc_manager->default_rgb != NULL) { /* After the transfer function go ahead and do the mapping from RGB to the device profile. */ gsicc_link_t *icc_link; gsicc_rendering_param_t rendering_params; unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS], psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS]; - rendering_params.black_point_comp = pis->blackptcomp; + rendering_params.black_point_comp = pgs->blackptcomp; rendering_params.graphics_type_tag = dev->graphics_type_tag; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; + rendering_params.rendering_intent = pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; - icc_link = gsicc_get_link_profile(pis, dev, pis->icc_manager->default_rgb, + icc_link = gsicc_get_link_profile(pgs, dev, pgs->icc_manager->default_rgb, des_profile, &rendering_params, - pis->memory, dev_profile->devicegraytok); + pgs->memory, dev_profile->devicegraytok); /* Transform the color */ for (i = 0; i < ncomps; i++) { psrc[i] = cv[i]; @@ -1261,17 +1427,21 @@ for (i = 0; i < ncomps; i++) pdc->colors.devn.values[i] = cv[i]; pdc->type = gx_dc_type_devn; - } else { - /* encode as a color index */ - color = dev_proc(dev, encode_color)(dev, cv); + return; + } - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); - else - cmap_separation_halftoned(all, pdc, pis, dev, select); + /* encode as a color index */ + color = dev_proc(dev, encode_color)(dev, cv); + + /* check if the encoding was successful; we presume failure is rare */ + if (color != gx_no_color_index) { + color_set_pure(pdc, color); + return; } - return; + + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } /* Routines for handling CM of CMYK components of a DeviceN color space */ @@ -1280,12 +1450,7 @@ { gs_devn_params *devn_params; - /* Device may not have ret_devn_params! */ - if (dev->procs.ret_devn_params != NULL) { - devn_params = dev_proc(dev, ret_devn_params)(dev); - } else { - return false; - } + devn_params = dev_proc(dev, ret_devn_params)(dev); if (devn_params == NULL) { return false; } @@ -1293,35 +1458,37 @@ } static int -devicen_icc_cmyk(frac cm_comps[], const gs_imager_state * pis, gx_device *dev) +devicen_icc_cmyk(frac cm_comps[], const gs_gstate * pgs, gx_device *dev) { gsicc_link_t *icc_link; gsicc_rendering_param_t rendering_params; unsigned short psrc[GS_CLIENT_COLOR_MAX_COMPONENTS]; unsigned short psrc_cm[GS_CLIENT_COLOR_MAX_COMPONENTS]; - int k; + int k, code; unsigned short *psrc_temp; - gsicc_rendering_param_t render_cond; - int code; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile = NULL; cmm_profile_t *des_profile = NULL; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code < 0) + return code; + gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &des_profile, &render_cond); /* Define the rendering intents. */ - rendering_params.black_point_comp = pis->blackptcomp; + rendering_params.black_point_comp = pgs->blackptcomp; rendering_params.graphics_type_tag = dev->graphics_type_tag; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; + rendering_params.rendering_intent = pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; /* Sigh, frac to full 16 bit. Need to clean this up */ for (k = 0; k < 4; k++){ psrc[k] = frac2cv(cm_comps[k]); } - icc_link = gsicc_get_link_profile(pis, dev, pis->icc_manager->default_cmyk, - des_profile, &rendering_params, pis->memory, + icc_link = gsicc_get_link_profile(pgs, dev, pgs->icc_manager->default_cmyk, + des_profile, &rendering_params, pgs->memory, dev_profile->devicegraytok); /* Transform the color */ if (icc_link->is_identity) { @@ -1348,42 +1515,41 @@ */ static void cmap_devicen_halftoned(const frac * pcc, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int code; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile = NULL; cmm_profile_t *des_profile = NULL; - code = dev_proc(dev, get_profile)(dev, &dev_profile); + dev_proc(dev, get_profile)(dev, &dev_profile); gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &des_profile, &render_cond); /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; - map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps); + map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps); /* See comments in cmap_devicen_direct for details on below operations */ if (devicen_has_cmyk(dev) && des_profile->data_cs == gsCMYK) { - code = devicen_icc_cmyk(cm_comps, pis, dev); + devicen_icc_cmyk(cm_comps, pgs, dev); } /* apply the transfer function(s); convert to color values */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cm_comps[i] = gx_map_color_frac(pis, + if (pgs->effective_transfer_non_identity_count != 0) { + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + for (i = 0; i < ncomps; i++) + cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]); - else - for (i = 0; i < ncomps; i++) - cm_comps[i] = frac_1 - gx_map_color_frac(pis, + else + for (i = 0; i < ncomps; i++) + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + } /* We need to finish halftoning */ - if (gx_render_device_DeviceN(cm_comps, pdc, dev, pis->dev_ht, - &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } /* @@ -1392,30 +1558,27 @@ */ static void cmap_devicen_direct(const frac * pcc, - gx_device_color * pdc, const gs_imager_state * pis, gx_device * dev, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; - int code; - gsicc_rendering_param_t render_cond; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile = NULL; cmm_profile_t *des_profile = NULL; - code = dev_proc(dev, get_profile)(dev, &dev_profile); + dev_proc(dev, get_profile)(dev, &dev_profile); gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &des_profile, &render_cond); /* See the comment below */ /* map to the color model */ - for (i=0; i < ncomps; i++) - cm_comps[i] = 0; if (dev_profile->spotnames != NULL && dev_profile->spotnames->equiv_cmyk_set) { - map_components_to_colorants(pcc, dev_profile->spotnames->color_map, + map_components_to_colorants(pcc, dev_profile->spotnames->color_map, cm_comps); } else { - map_components_to_colorants(pcc, &(pis->color_component_map), cm_comps); + map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps); } /* Check if we have the standard colorants. If yes, then we will apply ICC color management to those colorants. To understand why, consider @@ -1435,49 +1598,63 @@ and possibly permute the colorants, much as is done on the input side for the case when we add DeviceN icc source profiles for use in PDF and PS data. */ - code = devicen_icc_cmyk(cm_comps, pis, dev); + devicen_icc_cmyk(cm_comps, pgs, dev); } - /* apply the transfer function(s); convert to color values. + /* apply the transfer function(s); convert to color values. assign directly if output device supports devn */ if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) { - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + if (pgs->effective_transfer_non_identity_count == 0) for (i = 0; i < ncomps; i++) - pdc->colors.devn.values[i] = frac2cv(gx_map_color_frac(pis, - cm_comps[i], effective_transfer[i])); - else + pdc->colors.devn.values[i] = frac2cv(cm_comps[i]); + else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) for (i = 0; i < ncomps; i++) - pdc->colors.devn.values[i] = frac2cv(frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); - pdc->type = gx_dc_type_devn; - } else { - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) - for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(gx_map_color_frac(pis, + pdc->colors.devn.values[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i])); else for (i = 0; i < ncomps; i++) - cv[i] = frac2cv(frac_1 - gx_map_color_frac(pis, + pdc->colors.devn.values[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i])); - /* encode as a color index */ - color = dev_proc(dev, encode_color)(dev, cv); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdc, color); - else - cmap_devicen_halftoned(pcc, pdc, pis, dev, select); + pdc->type = gx_dc_type_devn; + return; + } + + if (pgs->effective_transfer_non_identity_count == 0) + for (i = 0; i < ncomps; i++) + cv[i] = frac2cv(cm_comps[i]); + else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + for (i = 0; i < ncomps; i++) { + cm_comps[i] = gx_map_color_frac(pgs, + cm_comps[i], effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); + } + else + for (i = 0; i < ncomps; i++) { + cm_comps[i] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cm_comps[i]), effective_transfer[i]); + cv[i] = frac2cv(cm_comps[i]); + } + /* encode as a color index */ + color = dev_proc(dev, encode_color)(dev, cv); + /* check if the encoding was successful; we presume failure is rare */ + if (color != gx_no_color_index) { + color_set_pure(pdc, color); + return; } + if (gx_render_device_DeviceN(cm_comps, pdc, dev, pgs->dev_ht, + &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } /* ------ Halftoning check ----- */ static bool -cmap_halftoned_is_halftoned(const gs_imager_state * pis, gx_device * dev) +cmap_halftoned_is_halftoned(const gs_gstate * pgs, gx_device * dev) { return true; } static bool -cmap_direct_is_halftoned(const gs_imager_state * pis, gx_device * dev) +cmap_direct_is_halftoned(const gs_gstate * pgs, gx_device * dev) { return false; } @@ -1486,7 +1663,7 @@ /* Define an identity transfer function. */ float -gs_identity_transfer(floatp value, const gx_transfer_map * pmap) +gs_identity_transfer(double value, const gx_transfer_map * pmap) { return (float) value; } @@ -1494,7 +1671,7 @@ /* Define the generic transfer function for the library layer. */ /* This just returns what's already in the map. */ float -gs_mapped_transfer(floatp value, const gx_transfer_map * pmap) +gs_mapped_transfer(double value, const gx_transfer_map * pmap) { return gx_map_color_float(pmap, value); } @@ -1530,7 +1707,7 @@ mdv = values[cmi + 1] - mv; #if ARCH_INTS_ARE_SHORT /* Only use long multiplication if necessary. */ - if (mdv < -1 << (16 - cp_frac_bits) || + if (mdv < -(1 << (16 - cp_frac_bits)) || mdv > 1 << (16 - cp_frac_bits) ) return mv + (uint) (((ulong) rem * mdv) >> cp_frac_bits); @@ -1546,7 +1723,7 @@ gx_color_index gx_default_w_b_map_rgb_color(gx_device * dev, const gx_color_value cv[]) { /* Map values >= 1/2 to 1, < 1/2 to 0. */ - int i, ncomps = dev->color_info.num_components; + int i, ncomps = dev->color_info.num_components; gx_color_value cv_all = 0; for (i = 0; i < ncomps; i++) @@ -1568,7 +1745,7 @@ gx_color_index gx_default_b_w_map_rgb_color(gx_device * dev, const gx_color_value cv[]) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; gx_color_value cv_all = 0; for (i = 0; i < ncomps; i++) @@ -1820,28 +1997,262 @@ return f; } +static void +cmapper_transfer_halftone_add(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + const gs_gstate * pgs = data->pgs; + gx_device * dev = data->dev; + gs_color_select_t select = data->select; + uchar ncomps = dev->color_info.num_components; + frac frac_value; + uchar i; + frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS]; + + /* apply the transfer function(s) */ + for (i = 0; i < ncomps; i++) { + frac_value = cv2frac(pconc[i]); + cv_frac[i] = gx_map_color_frac(pgs, frac_value, effective_transfer[i]); + } + /* Halftoning */ + if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, + pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_color_load_select(&data->devc, pgs, dev, select); +} + +static void +cmapper_transfer_halftone_op(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + const gs_gstate * pgs = data->pgs; + gx_device * dev = data->dev; + gs_color_select_t select = data->select; + uchar ncomps = dev->color_info.num_components; + frac frac_value; + uchar i; + frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS]; + + /* apply the transfer function(s) */ + uint k = dev->color_info.black_component; + for (i = 0; i < ncomps; i++) { + frac_value = cv2frac(pconc[i]); + if (i == k) { + cv_frac[i] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - frac_value), effective_transfer[i]); + } else { + cv_frac[i] = frac_value; /* Ignore transfer, see PLRM3 p. 494 */ + } + } + /* Halftoning */ + if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, + pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_color_load_select(&data->devc, pgs, dev, select); +} + +static void +cmapper_transfer_halftone_sub(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + const gs_gstate * pgs = data->pgs; + gx_device * dev = data->dev; + gs_color_select_t select = data->select; + uchar ncomps = dev->color_info.num_components; + frac frac_value; + uchar i; + frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS]; + + /* apply the transfer function(s) */ + for (i = 0; i < ncomps; i++) { + frac_value = cv2frac(pconc[i]); + cv_frac[i] = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - frac_value), effective_transfer[i]); + } + /* Halftoning */ + if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, + pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_color_load_select(&data->devc, pgs, dev, select); +} + +static void +cmapper_transfer_add(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + const gs_gstate * pgs = data->pgs; + gx_device * dev = data->dev; + uchar ncomps = dev->color_info.num_components; + frac frac_value; + uchar i; + gx_color_index color; + + /* apply the transfer function(s) */ + for (i = 0; i < ncomps; i++) { + frac_value = cv2frac(pconc[i]); + frac_value = gx_map_color_frac(pgs, + frac_value, effective_transfer[i]); + pconc[i] = frac2cv(frac_value); + } + /* Halftoning */ + color = dev_proc(dev, encode_color)(dev, &(pconc[0])); + /* check if the encoding was successful; we presume failure is rare */ + if (color != gx_no_color_index) + color_set_pure(&data->devc, color); +} + +static void +cmapper_transfer_op(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + const gs_gstate * pgs = data->pgs; + gx_device * dev = data->dev; + frac frac_value; + gx_color_index color; + + uint k = dev->color_info.black_component; + /* Ignore transfer for non blacks, see PLRM3 p. 494 */ + frac_value = cv2frac(pconc[k]); + frac_value = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - frac_value), effective_transfer[k]); + pconc[k] = frac2cv(frac_value); + /* Halftoning */ + color = dev_proc(dev, encode_color)(dev, &(pconc[0])); + /* check if the encoding was successful; we presume failure is rare */ + if (color != gx_no_color_index) + color_set_pure(&data->devc, color); +} + +static void +cmapper_transfer_sub(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + const gs_gstate * pgs = data->pgs; + gx_device * dev = data->dev; + uchar ncomps = dev->color_info.num_components; + frac frac_value; + uchar i; + gx_color_index color; + + /* apply the transfer function(s) */ + for (i = 0; i < ncomps; i++) { + frac_value = cv2frac(pconc[i]); + frac_value = frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - frac_value), effective_transfer[i]); + pconc[i] = frac2cv(frac_value); + } + /* Halftoning */ + color = dev_proc(dev, encode_color)(dev, &(pconc[0])); + /* check if the encoding was successful; we presume failure is rare */ + if (color != gx_no_color_index) + color_set_pure(&data->devc, color); +} + +/* This is used by image color render to handle the cases where we need to + perform either a transfer function or halftoning on the color values + during an ICC color flow. In this case, the color is already in the + device color space but in 16bpp color values. */ +static void +cmapper_halftone(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + const gs_gstate * pgs = data->pgs; + gx_device * dev = data->dev; + gs_color_select_t select = data->select; + uchar ncomps = dev->color_info.num_components; + uchar i; + frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS]; + + /* We need this to be in frac form */ + for (i = 0; i < ncomps; i++) { + cv_frac[i] = cv2frac(pconc[i]); + } + if (gx_render_device_DeviceN(&(cv_frac[0]), &data->devc, dev, + pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_color_load_select(&data->devc, pgs, dev, select); +} + +/* This is used by image color render to handle the cases where we need to + perform either a transfer function or halftoning on the color values + during an ICC color flow. In this case, the color is already in the + device color space but in 16bpp color values. */ +static void +cmapper_vanilla(gx_cmapper_data *data) +{ + gx_color_value *pconc = &data->conc[0]; + gx_device * dev = data->dev; + gx_color_index color; + + color = dev_proc(dev, encode_color)(dev, &(pconc[0])); + /* check if the encoding was successful; we presume failure is rare */ + if (color != gx_no_color_index) + color_set_pure(&data->devc, color); +} + +gx_cmapper_fn * +gx_get_cmapper(gx_cmapper_data *data, const gs_gstate *pgs, + gx_device *dev, bool has_transfer, bool has_halftone, + gs_color_select_t select) +{ + memset(&(data->conc[0]), 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS])); + data->pgs = pgs; + data->dev = dev; + data->select = select; + data->devc.type = gx_dc_type_none; + if (has_transfer && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) + check_cmyk_color_model_comps(dev); + if (pgs->effective_transfer_non_identity_count == 0) + has_transfer = 0; + if (has_transfer) { + if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { + if (has_halftone) + data->set_color = cmapper_transfer_halftone_add; + else + data->set_color = cmapper_transfer_add; + } else if (dev->color_info.opmode == GX_CINFO_OPMODE) { + if (has_halftone) + data->set_color = cmapper_transfer_halftone_op; + else + data->set_color = cmapper_transfer_op; + } else { + if (has_halftone) + data->set_color = cmapper_transfer_halftone_sub; + else + data->set_color = cmapper_transfer_sub; + } + } else { + if (has_halftone) + data->set_color = cmapper_halftone; + else + data->set_color = cmapper_vanilla; + } + return data->set_color; +} + /* This is used by image color render to handle the cases where we need to perform either a transfer function or halftoning on the color values during an ICC color flow. In this case, the color is already in the device color space but in 16bpp color values. */ void cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, bool has_transfer, + const gs_gstate * pgs, gx_device * dev, bool has_transfer, bool has_halftone, gs_color_select_t select) { - int ncomps = dev->color_info.num_components; + uchar ncomps = dev->color_info.num_components; frac frac_value; - int i; + uchar i; frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_index color; gx_color_value color_val[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* apply the transfer function(s) */ if (has_transfer) { - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { + if (pgs->effective_transfer_non_identity_count == 0) { + if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) + check_cmyk_color_model_comps(dev); + for (i = 0; i < ncomps; i++) + cv_frac[i] = cv2frac(pconc[i]); + } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { for (i = 0; i < ncomps; i++) { frac_value = cv2frac(pconc[i]); - cv_frac[i] = gx_map_color_frac(pis, + cv_frac[i] = gx_map_color_frac(pgs, frac_value, effective_transfer[i]); } } else { @@ -1849,11 +2260,11 @@ check_cmyk_color_model_comps(dev); } if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ - int k = dev->color_info.black_component; + uint k = dev->color_info.black_component; for (i = 0; i < ncomps; i++) { frac_value = cv2frac(pconc[i]); if (i == k) { - cv_frac[i] = frac_1 - gx_map_color_frac(pis, + cv_frac[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - frac_value), effective_transfer[i]); } else { cv_frac[i] = cv2frac(pconc[i]); /* Ignore transfer, see PLRM3 p. 494 */ @@ -1862,7 +2273,7 @@ } else { for (i = 0; i < ncomps; i++) { frac_value = cv2frac(pconc[i]); - cv_frac[i] = frac_1 - gx_map_color_frac(pis, + cv_frac[i] = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - frac_value), effective_transfer[i]); } } @@ -1878,8 +2289,8 @@ /* Halftoning */ if (has_halftone) { if (gx_render_device_DeviceN(&(cv_frac[0]), pdc, dev, - pis->dev_ht, &pis->screen_phase[select]) == 1) - gx_color_load_select(pdc, pis, dev, select); + pgs->dev_ht, &pgs->screen_phase[select]) == 1) + gx_color_load_select(pdc, pgs, dev, select); } else { /* We have a frac value from the transfer function. Do the encode. which does not take a frac value... */ @@ -1890,58 +2301,45 @@ /* check if the encoding was successful; we presume failure is rare */ if (color != gx_no_color_index) color_set_pure(pdc, color); - } } /* This is used by image color render to apply only the transfer function. We follow this up with threshold rendering. */ void -cmap_transfer(gx_color_value *pconc, const gs_imager_state * pis, gx_device * dev) +cmap_transfer(gx_color_value *pconc, const gs_gstate * pgs, gx_device * dev) { - int ncomps = dev->color_info.num_components; - frac frac_value; - int i; - frac cv_frac[GX_DEVICE_COLOR_MAX_COMPONENTS]; + uchar ncomps = dev->color_info.num_components; + uchar i; /* apply the transfer function(s) */ - if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { - for (i = 0; i < ncomps; i++) { - frac_value = cv2frac(pconc[i]); - cv_frac[i] = gx_map_color_frac(pis, - frac_value, effective_transfer[i]); - pconc[i] = frac2cv(cv_frac[i]); - } - } else { + if (pgs->effective_transfer_non_identity_count == 0) { + if (dev->color_info.polarity != GX_CINFO_POLARITY_ADDITIVE && dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) + check_cmyk_color_model_comps(dev); + } else if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) + for (i = 0; i < ncomps; i++) + pconc[i] = frac2cv(gx_map_color_frac(pgs, + cv2frac(pconc[i]), effective_transfer[i])); + else { if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { check_cmyk_color_model_comps(dev); } if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ - int k = dev->color_info.black_component; - for (i = 0; i < ncomps; i++) { - frac_value = cv2frac(pconc[i]); - if (i == k) { - cv_frac[i] = frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - frac_value), effective_transfer[i]); - } else { - cv_frac[i] = cv2frac(pconc[i]); /* Ignore transfer, see PLRM3 p. 494 */ - } - pconc[i] = frac2cv(cv_frac[i]); - } + i = dev->color_info.black_component; + if (i < ncomps) + pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cv2frac(pconc[i])), effective_transfer[i])); } else { - for (i = 0; i < ncomps; i++) { - frac_value = cv2frac(pconc[i]); - cv_frac[i] = frac_1 - gx_map_color_frac(pis, - (frac)(frac_1 - frac_value), effective_transfer[i]); - pconc[i] = frac2cv(cv_frac[i]); - } + for (i = 0; i < ncomps; i++) + pconc[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, + (frac)(frac_1 - cv2frac(pconc[i])), effective_transfer[i])); } } } /* A planar version which applies only one transfer function */ void -cmap_transfer_plane(gx_color_value *pconc, const gs_imager_state *pis, +cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs, gx_device *dev, int plane) { frac frac_value; @@ -1950,25 +2348,23 @@ /* apply the transfer function(s) */ if (dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) { frac_value = cv2frac(pconc[0]); - cv_frac = gx_map_color_frac(pis, frac_value, effective_transfer[plane]); + cv_frac = gx_map_color_frac(pgs, frac_value, effective_transfer[plane]); pconc[0] = frac2cv(cv_frac); } else { if (dev->color_info.opmode == GX_CINFO_OPMODE_UNKNOWN) { check_cmyk_color_model_comps(dev); } if (dev->color_info.opmode == GX_CINFO_OPMODE) { /* CMYK-like color space */ - int k = dev->color_info.black_component; - frac_value = cv2frac(pconc[0]); + uint k = dev->color_info.black_component; if (plane == k) { - cv_frac = frac_1 - gx_map_color_frac(pis, + frac_value = cv2frac(pconc[0]); + cv_frac = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - frac_value), effective_transfer[plane]); - } else { - cv_frac = cv2frac(pconc[0]); /* Ignore transfer, see PLRM3 p. 494 */ + pconc[0] = frac2cv(cv_frac); } - pconc[0] = frac2cv(cv_frac); } else { frac_value = cv2frac(pconc[0]); - cv_frac = frac_1 - gx_map_color_frac(pis, + cv_frac = frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - frac_value), effective_transfer[plane]); pconc[0] = frac2cv(cv_frac); } @@ -1977,20 +2373,25 @@ bool -gx_device_uses_std_cmap_procs(gx_device * dev, const gs_imager_state * pis) +gx_device_uses_std_cmap_procs(gx_device * dev, const gs_gstate * pgs) { + subclass_color_mappings scm; const gx_cm_color_map_procs *pprocs; - gsicc_rendering_param_t render_cond; - int code; + gsicc_rendering_param_t render_cond; cmm_dev_profile_t *dev_profile = NULL; cmm_profile_t *des_profile = NULL; - code = dev_proc(dev, get_profile)(dev, &dev_profile); + dev_proc(dev, get_profile)(dev, &dev_profile); gsicc_extract_profile(dev->graphics_type_tag, dev_profile, &des_profile, &render_cond); if (des_profile != NULL) { - pprocs = dev_proc(dev, get_color_mapping_procs)(dev); + scm = get_color_mapping_procs_subclass(dev); + pprocs = scm.procs; + /* FIXME: This looks wrong to me. Presumably we should be finding + * the parentmost device, looking at the procs for that, and if + * they are forwarding ones, getting the procs for the forwarded + * device. This is NOT what this code does. */ /* Check if they are forwarding procs */ if (fwd_uses_fwd_cmap_procs(dev)) { pprocs = fwd_get_target_cmap_procs(dev); diff -Nru ghostscript-9.10~dfsg/base/gxcmap.h ghostscript-9.25~dfsg+1/base/gxcmap.h --- ghostscript-9.10~dfsg/base/gxcmap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcmap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,6 +23,7 @@ #include "gscsel.h" #include "gxfmap.h" #include "gscspace.h" +#include "gsdcolor.h" #ifndef gx_device_DEFINED # define gx_device_DEFINED @@ -32,30 +33,34 @@ # define gx_device_color_DEFINED typedef struct gx_device_color_s gx_device_color; #endif +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; +#endif /* Procedures for rendering colors specified by fractions. */ #define cmap_proc_gray(proc)\ - void proc(frac, gx_device_color *, const gs_imager_state *,\ + void proc(frac, gx_device_color *, const gs_gstate *,\ gx_device *, gs_color_select_t) #define cmap_proc_rgb(proc)\ - void proc(frac, frac, frac, gx_device_color *, const gs_imager_state *,\ + void proc(frac, frac, frac, gx_device_color *, const gs_gstate *,\ gx_device *, gs_color_select_t) #define cmap_proc_cmyk(proc)\ void proc(frac, frac, frac, frac, gx_device_color *,\ - const gs_imager_state *, gx_device *, gs_color_select_t,\ + const gs_gstate *, gx_device *, gs_color_select_t,\ const gs_color_space *) #define cmap_proc_rgb_alpha(proc)\ void proc(frac, frac, frac, frac, gx_device_color *,\ - const gs_imager_state *, gx_device *, gs_color_select_t) + const gs_gstate *, gx_device *, gs_color_select_t) #define cmap_proc_separation(proc)\ - void proc(frac, gx_device_color *, const gs_imager_state *,\ + void proc(frac, gx_device_color *, const gs_gstate *,\ gx_device *, gs_color_select_t) #define cmap_proc_devicen(proc)\ - void proc(const frac *, gx_device_color *, const gs_imager_state *, \ + void proc(const frac *, gx_device_color *, const gs_gstate *, \ gx_device *, gs_color_select_t) #define cmap_proc_is_halftoned(proc)\ - bool proc(const gs_imager_state *, gx_device *) + bool proc(const gs_gstate *, gx_device *) /* * List of mapping functions from the standard color spaces to the @@ -67,7 +72,7 @@ #define cm_map_proc_rgb(proc) \ void proc (gx_device * dev, \ - const gs_imager_state *pis, \ + const gs_gstate *pgs, \ frac r, frac g, frac b, \ frac * out) @@ -107,7 +112,7 @@ * applying the current transfer function or halftone. * * The routine pointed to by get_cmap_procs (a field in the image - * state; see gxistate.h) should initialize the cm_color_map_procs + * state; see gxgstate.h) should initialize the cm_color_map_procs * pointer, using the get_color_mapping_procs method of the device. * * Because of a bug in the Watcom C compiler, we have to split the @@ -126,65 +131,41 @@ /* * Determine the color mapping procedures for a device. Even though this - * does not currently use information from the imager state, it must be + * does not currently use information from the gs_gstate, it must be * a virtual procedure of the state for internal reasons. */ const gx_color_map_procs * - gx_get_cmap_procs(const gs_imager_state *, const gx_device *); + gx_get_cmap_procs(const gs_gstate *, const gx_device *); const gx_color_map_procs * - gx_default_get_cmap_procs(const gs_imager_state *, const gx_device *); + gx_default_get_cmap_procs(const gs_gstate *, const gx_device *); /* * Set the color mapping procedures in the graphics state. This is * currently only needed when switching devices, but might be used more * often in the future. */ -void gx_set_cmap_procs(gs_imager_state *, const gx_device *); +void gx_set_cmap_procs(gs_gstate *, const gx_device *); /* Remap a concrete (frac) gray, RGB or CMYK color. */ /* These cannot fail, and do not return a value. */ -#define gx_remap_concrete_gray(cgray, pdc, pis, dev, select)\ - ((pis)->cmap_procs->map_gray)(cgray, pdc, pis, dev, select) -#define gx_remap_concrete_rgb(cr, cg, cb, pdc, pis, dev, select)\ - ((pis)->cmap_procs->map_rgb)(cr, cg, cb, pdc, pis, dev, select) -#define gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pis, dev, select, pcs)\ - ((pis)->cmap_procs->map_cmyk)(cc, cm, cy, ck, pdc, pis, dev, select, pcs) -#define gx_remap_concrete_rgb_alpha(cr, cg, cb, ca, pdc, pis, dev, select)\ - ((pis)->cmap_procs->map_rgb_alpha)(cr, cg, cb, ca, pdc, pis, dev, select) -#define gx_remap_concrete_separation(pcc, pdc, pis, dev, select)\ - ((pis)->cmap_procs->map_separation)(pcc, pdc, pis, dev, select) -#define gx_remap_concrete_devicen(pcc, pdc, pis, dev, select)\ - ((pis)->cmap_procs->map_devicen)(pcc, pdc, pis, dev, select) +#define gx_remap_concrete_gray(cgray, pdc, pgs, dev, select)\ + ((pgs)->cmap_procs->map_gray)(cgray, pdc, pgs, dev, select) +#define gx_remap_concrete_rgb(cr, cg, cb, pdc, pgs, dev, select)\ + ((pgs)->cmap_procs->map_rgb)(cr, cg, cb, pdc, pgs, dev, select) +#define gx_remap_concrete_cmyk(cc, cm, cy, ck, pdc, pgs, dev, select, pcs)\ + ((pgs)->cmap_procs->map_cmyk)(cc, cm, cy, ck, pdc, pgs, dev, select, pcs) +#define gx_remap_concrete_rgb_alpha(cr, cg, cb, ca, pdc, pgs, dev, select)\ + ((pgs)->cmap_procs->map_rgb_alpha)(cr, cg, cb, ca, pdc, pgs, dev, select) +#define gx_remap_concrete_separation(pcc, pdc, pgs, dev, select)\ + ((pgs)->cmap_procs->map_separation)(pcc, pdc, pgs, dev, select) +#define gx_remap_concrete_devicen(pcc, pdc, pgs, dev, select)\ + ((pgs)->cmap_procs->map_devicen)(pcc, pdc, pgs, dev, select) /* Map a color */ #include "gxcindex.h" #include "gxcvalue.h" /* - * These are the default routines for converting a color space into - * a list of device colorants. - */ -extern cm_map_proc_gray(gx_default_gray_cs_to_gray_cm); -extern cm_map_proc_rgb(gx_default_rgb_cs_to_gray_cm); -extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_gray_cm); - -extern cm_map_proc_gray(gx_default_gray_cs_to_rgb_cm); -extern cm_map_proc_rgb(gx_default_rgb_cs_to_rgb_cm); -extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_rgb_cm); - -extern cm_map_proc_gray(gx_default_gray_cs_to_cmyk_cm); -extern cm_map_proc_rgb(gx_default_rgb_cs_to_cmyk_cm); -extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_cmyk_cm); - -extern cm_map_proc_gray(gx_default_gray_cs_to_cmyk_cm); -extern cm_map_proc_rgb(gx_default_rgb_cs_to_cmyk_cm); -extern cm_map_proc_cmyk(gx_default_cmyk_cs_to_cmyk_cm); - -extern cm_map_proc_gray(gx_error_gray_cs_to_cmyk_cm); -extern cm_map_proc_rgb(gx_error_rgb_cs_to_cmyk_cm); -extern cm_map_proc_cmyk(gx_error_cmyk_cs_to_cmyk_cm); - -/* Get the mapping procedures appropriate for the currently set color model. */ @@ -288,15 +269,33 @@ /* Determine if the device is using the standard color mapping procs. In such a case, we can make use of the faster icc color conversions for images */ -bool gx_device_uses_std_cmap_procs(gx_device * dev, - const gs_imager_state * pis); +bool gx_device_uses_std_cmap_procs(gx_device * dev, + const gs_gstate * pgs); bool fwd_uses_fwd_cmap_procs(gx_device * dev); const gx_cm_color_map_procs* fwd_get_target_cmap_procs(gx_device * dev); void cmap_transfer_halftone(gx_color_value *pconc, gx_device_color * pdc, - const gs_imager_state * pis, gx_device * dev, bool has_transfer, + const gs_gstate * pgs, gx_device * dev, bool has_transfer, bool has_halftone, gs_color_select_t select); -void cmap_transfer(gx_color_value *pconc, const gs_imager_state * pis, +void cmap_transfer(gx_color_value *pconc, const gs_gstate * pgs, gx_device * dev); -void cmap_transfer_plane(gx_color_value *pconc, const gs_imager_state *pis, +void cmap_transfer_plane(gx_color_value *pconc, const gs_gstate *pgs, gx_device *dev, int plane); + +typedef struct gx_cmapper_data_s gx_cmapper_data; + +typedef void (gx_cmapper_fn)(gx_cmapper_data *data); + +struct gx_cmapper_data_s { + gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS]; + const gs_gstate *pgs; + gx_device *dev; + gs_color_select_t select; + gx_device_color devc; + gx_cmapper_fn *set_color; +}; + +gx_cmapper_fn *gx_get_cmapper(gx_cmapper_data *data, const gs_gstate *pgs, + gx_device *dev, bool has_transfer, bool has_halftone, + gs_color_select_t select); + #endif /* gxcmap_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxcolor2.h ghostscript-9.25~dfsg+1/base/gxcolor2.h --- ghostscript-9.10~dfsg/base/gxcolor2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcolor2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,7 +30,7 @@ rc_header rc; union { int (*lookup_index)(const gs_color_space *, int, float *); - int (*tint_transform)(const gs_separation_params *, floatp, float *); + int (*tint_transform)(const gs_separation_params *, double, float *); } proc; void *proc_data; uint num_values; /* base_space->type->num_components * (hival + 1) */ diff -Nru ghostscript-9.10~dfsg/base/gxcomp.h ghostscript-9.25~dfsg+1/base/gxcomp.h --- ghostscript-9.10~dfsg/base/gxcomp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcomp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -53,9 +53,9 @@ */ /*typedef struct gs_composite_s gs_composite_t; *//* in gscompt.h */ -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_device_DEFINED @@ -75,7 +75,7 @@ */ #define composite_create_default_compositor_proc(proc)\ int proc(const gs_composite_t *pcte, gx_device **pcdev,\ - gx_device *dev, gs_imager_state *pis, gs_memory_t *mem) + gx_device *dev, gs_gstate *pgs, gs_memory_t *mem) composite_create_default_compositor_proc((*create_default_compositor)); /* @@ -112,7 +112,7 @@ * Adjust CTM before applying the compositor. Used with banding. */ #define composite_adjust_ctm_proc(proc)\ - int proc(gs_composite_t *pcte, int x0, int y0, gs_imager_state *pis) + int proc(gs_composite_t *pcte, int x0, int y0, gs_gstate *pgs) composite_adjust_ctm_proc((*adjust_ctm)); /* @@ -123,7 +123,7 @@ * 3 - closing and replacing, 4 - replace one, 5 - drop queue. */ #define composite_is_closing_proc(proc)\ - int proc(const gs_composite_t *this, gs_composite_t **pcte, gx_device *dev) + gs_compositor_closing_state proc(const gs_composite_t *this, gs_composite_t **pcte, gx_device *dev) composite_is_closing_proc((*is_closing)); /* @@ -139,7 +139,7 @@ */ #define composite_clist_write_update(proc)\ int proc(const gs_composite_t * pcte, gx_device * dev, gx_device ** pcdev,\ - gs_imager_state * pis, gs_memory_t * mem) + gs_gstate * pgs, gs_memory_t * mem) composite_clist_write_update((*clist_compositor_write_update)); /* @@ -147,7 +147,7 @@ */ #define composite_clist_read_update(proc)\ int proc(gs_composite_t * pcte, gx_device * cdev, gx_device * tdev,\ - gs_imager_state * pis, gs_memory_t * mem) + gs_gstate * pgs, gs_memory_t * mem) composite_clist_read_update((*clist_compositor_read_update)); /* diff -Nru ghostscript-9.10~dfsg/base/gxcoord.h ghostscript-9.25~dfsg+1/base/gxcoord.h --- ghostscript-9.10~dfsg/base/gxcoord.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcoord.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,10 +24,10 @@ /* Set the translation to a fixed value, and translate any existing path. */ /* Used by gschar.c to prepare for a BuildChar or BuildGlyph procedure. */ -int gx_translate_to_fixed(gs_state *, fixed, fixed); +int gx_translate_to_fixed(gs_gstate *, fixed, fixed); /* Scale the CTM and character matrix for oversampling. */ -int gx_scale_char_matrix(gs_state *, int, int); +int gx_scale_char_matrix(gs_gstate *, int, int); /* Compute the coefficients for fast fixed-point distance transformations */ /* from a transformation matrix. */ diff -Nru ghostscript-9.10~dfsg/base/gxcpath.c ghostscript-9.25~dfsg+1/base/gxcpath.c --- ghostscript-9.10~dfsg/base/gxcpath.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcpath.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,13 +9,14 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Implementation of clipping paths, other than actual clipping */ #include "gx.h" +#include "string_.h" #include "gserrors.h" #include "gsstruct.h" #include "gsutil.h" @@ -24,7 +25,7 @@ #include "gxfixed.h" #include "gxpaint.h" #include "gscoord.h" /* needs gsmatrix.h */ -#include "gxistate.h" +#include "gxgstate.h" #include "gzpath.h" #include "gzcpath.h" #include "gzacpath.h" @@ -38,18 +39,20 @@ public_st_clip_path(); private_st_clip_rect_list(); public_st_device_clip(); -private_st_cpath_enum(); private_st_cpath_path_list(); /* GC procedures for gx_clip_path */ static -ENUM_PTRS_WITH(clip_path_enum_ptrs, gx_clip_path *cptr) return ENUM_USING(st_path, &cptr->path, sizeof(cptr->path), index - 2); +ENUM_PTRS_WITH(clip_path_enum_ptrs, gx_clip_path *cptr) return ENUM_USING(st_path, &cptr->path, sizeof(cptr->path), index - 3); case 0: return ENUM_OBJ((cptr->rect_list == &cptr->local_list ? 0 : cptr->rect_list)); case 1: return ENUM_OBJ(cptr->path_list); +case 2: +return ENUM_OBJ((cptr->cached == &cptr->rect_list->list.single ? 0 : + cptr->cached)); ENUM_PTRS_END static RELOC_PTRS_WITH(clip_path_reloc_ptrs, gx_clip_path *cptr) @@ -57,6 +60,8 @@ if (cptr->rect_list != &cptr->local_list) RELOC_VAR(cptr->rect_list); RELOC_VAR(cptr->path_list); + if (cptr->cached != &cptr->rect_list->list.single) + RELOC_VAR(cptr->cached); RELOC_USING(st_path, &cptr->path, sizeof(gx_path)); } RELOC_PTRS_END @@ -65,16 +70,18 @@ static ENUM_PTRS_WITH(device_clip_enum_ptrs, gx_device_clip *cptr) { - if (index < st_clip_list_max_ptrs + 1) + if (index < st_clip_list_max_ptrs + 2) return ENUM_USING(st_clip_list, &cptr->list, - sizeof(gx_clip_list), index - 1); + sizeof(gx_clip_list), index - 2); return ENUM_USING(st_device_forward, vptr, sizeof(gx_device_forward), - index - (st_clip_list_max_ptrs + 1)); + index - (st_clip_list_max_ptrs + 2)); } case 0: ENUM_RETURN((cptr->current == &cptr->list.single ? NULL : (void *)cptr->current)); +case 1: +ENUM_RETURN((cptr->cpath)); ENUM_PTRS_END static RELOC_PTRS_WITH(device_clip_reloc_ptrs, gx_device_clip *cptr) @@ -83,6 +90,7 @@ cptr->current = &((gx_device_clip *)RELOC_OBJ(vptr))->list.single; else RELOC_PTR(gx_device_clip, current); + RELOC_PTR(gx_device_clip, cpath); RELOC_USING(st_clip_list, &cptr->list, sizeof(gx_clip_list)); RELOC_USING(st_device_forward, vptr, sizeof(gx_device_forward)); } @@ -104,7 +112,8 @@ 0, /* insert */ 0, /* xmin */ 0, /* xmax */ - 0 /* count */ + 0, /* count */ + 0 /* transpose = false */ }; /* ------ Clipping path memory management ------ */ @@ -126,6 +135,7 @@ pcpath->path.bbox = *pbox; gx_cpath_set_outer_box(pcpath); pcpath->id = gs_next_ids(pcpath->path.memory, 1); /* path changed => change id */ + pcpath->cached = NULL; } static void cpath_init_own_contents(gx_clip_path * pcpath) @@ -143,6 +153,7 @@ pcpath->path_valid = shared->path_valid; pcpath->outer_box = shared->outer_box; pcpath->id = shared->id; + pcpath->cached = NULL; } /* Allocate only the segments of a clipping path on the heap. */ @@ -265,6 +276,8 @@ return code; /* Copy the rectangle list. */ /**************** NYI ****************/ + /* Until/Unless we implement this, NULL out the list */ + memset(&pcpath->rect_list->list, 0x00, sizeof(gx_clip_list)); rc_decrement(rlist, "gx_cpath_unshare"); } return code; @@ -538,9 +551,9 @@ int code = cpath_alloc_list(&pcpath->rect_list, pcpath->path.memory, "gx_cpath_from_rectangle"); + rc_decrement(rlist, "gx_cpath_from_rectangle"); if (code < 0) return code; - rc_decrement(rlist, "gx_cpath_from_rectangle"); rlist = pcpath->rect_list; } cpath_init_rectangle(pcpath, pbox); @@ -561,6 +574,7 @@ gs_fixed_rect null_rect; null_rect.p.x = null_rect.p.y = null_rect.q.x = null_rect.q.y = 0; + rc_decrement(pcpath->path_list, "gx_cpath_reset"); return gx_cpath_from_rectangle(pcpath, &null_rect); } @@ -587,34 +601,45 @@ /* Intersect a new clipping path with an old one. */ /* Flatten the new path first (in a copy) if necessary. */ int -gx_cpath_clip(gs_state *pgs, gx_clip_path *pcpath, +gx_cpath_clip(gs_gstate *pgs, gx_clip_path *pcpath, /*const*/ gx_path *ppath_orig, int rule) { - return gx_cpath_intersect(pcpath, ppath_orig, rule, - (gs_imager_state *)pgs); + return gx_cpath_intersect(pcpath, ppath_orig, rule, pgs); +} + +int +gx_cpath_ensure_path_list(gx_clip_path *pcpath) +{ + if (pcpath == NULL || pcpath->path_list) + return 0; + return gx_cpath_path_list_new(pcpath->path.memory, pcpath, pcpath->rule, + &pcpath->path, NULL, &pcpath->path_list); } int gx_cpath_intersect_with_params(gx_clip_path *pcpath, /*const*/ gx_path *ppath_orig, - int rule, gs_imager_state *pis, const gx_fill_params * params) + int rule, gs_gstate *pgs, const gx_fill_params * params) { gx_path fpath; /*const*/ gx_path *ppath = ppath_orig; gs_fixed_rect old_box, new_box; int code; + int pcpath_is_rect; + pcpath->cached = NULL; /* Flatten the path if necessary. */ if (gx_path_has_curves_inline(ppath)) { - gx_path_init_local(&fpath, pis->memory); + gx_path_init_local(&fpath, pgs->memory); code = gx_path_add_flattened_accurate(ppath, &fpath, - gs_currentflat_inline(pis), - pis->accurate_curves); + gs_currentflat_inline(pgs), + pgs->accurate_curves); if (code < 0) return code; ppath = &fpath; } - if (gx_cpath_inner_box(pcpath, &old_box) && + pcpath_is_rect = gx_cpath_inner_box(pcpath, &old_box); + if (pcpath_is_rect && ((code = gx_path_is_rectangle(ppath, &new_box)) || gx_path_is_void(ppath)) ) { @@ -624,14 +649,14 @@ /* The new path is void. */ if (gx_path_current_point(ppath, &new_box.p) < 0) { /* Use the user space origin (arbitrarily). */ - new_box.p.x = float2fixed(pis->ctm.tx); - new_box.p.y = float2fixed(pis->ctm.ty); + new_box.p.x = float2fixed(pgs->ctm.tx); + new_box.p.y = float2fixed(pgs->ctm.ty); } new_box.q = new_box.p; changed = 1; } else { { /* Apply same adjustment as for filling the path. */ - gs_fixed_point adjust = params != NULL ? params->adjust : pis->fill_adjust; + gs_fixed_point adjust = params != NULL ? params->adjust : pgs->fill_adjust; fixed adjust_xl, adjust_xu, adjust_yl, adjust_yu; if (adjust.x == -1) @@ -677,22 +702,27 @@ } } else { /* New clip path is nontrivial. Intersect the slow way. */ - gx_cpath_path_list *next = pcpath->path_list; + gx_cpath_path_list *next = NULL; bool path_valid = - gx_cpath_inner_box(pcpath, &old_box) && + pcpath_is_rect && gx_path_bbox(ppath, &new_box) >= 0 && gx_cpath_includes_rectangle(pcpath, new_box.p.x, new_box.p.y, new_box.q.x, new_box.q.y); if (!path_valid && next == NULL) { - code = gx_cpath_path_list_new(pcpath->path.memory, pcpath, pcpath->rule, - &pcpath->path, NULL, &next); + /* gx_cpaths should generally have a path_list set within + * them. In some cases (filled images), they may not. Ensure + * that they do, and remember the path_list */ + code = gx_cpath_ensure_path_list(pcpath); if (code < 0) goto ex; + /* gx_cpath_intersect_path_slow NULLs pcpath->path_list, so + * remember it here. */ + next = pcpath->path_list; } code = gx_cpath_intersect_path_slow(pcpath, (params != NULL ? ppath_orig : ppath), - rule, pis, params); + rule, pgs, params); if (code < 0) goto ex; if (path_valid) { @@ -701,7 +731,7 @@ pcpath->rule = rule; } else { code = gx_cpath_path_list_new(pcpath->path.memory, NULL, rule, - ppath_orig, next, &pcpath->path_list); + ppath_orig, next, &pcpath->path_list); } } ex: @@ -711,10 +741,10 @@ } int gx_cpath_intersect(gx_clip_path *pcpath, /*const*/ gx_path *ppath_orig, - int rule, gs_imager_state *pis) + int rule, gs_gstate *pgs) { return gx_cpath_intersect_with_params(pcpath, ppath_orig, - rule, pis, NULL); + rule, pgs, NULL); } /* Scale a clipping path by a power of 2. */ @@ -1079,6 +1109,7 @@ pcpath->rule = from->rule; pcpath->outer_box = from->outer_box; pcpath->inner_box = from->inner_box; + pcpath->cached = NULL; l->single = from->rect_list->list.single; for (r = from->rect_list->list.head; r != NULL; r = r->next) { s = gs_alloc_struct(from->rect_list->rc.memory, gx_clip_rect, &st_clip_rect, "gx_cpath_copy"); diff -Nru ghostscript-9.10~dfsg/base/gxcpath.h ghostscript-9.25~dfsg+1/base/gxcpath.h --- ghostscript-9.10~dfsg/base/gxcpath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcpath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -75,6 +75,7 @@ int xmin, xmax; /* min and max X over all but head/tail */ int count; /* # of rectangles not counting */ /* head or tail */ + bool transpose; /* Transpose x / y */ }; #define public_st_clip_list() /* in gxcpath.c */\ @@ -104,6 +105,7 @@ gs_int_point translation; gs_fixed_rect clipping_box; bool clipping_box_set; + const gx_clip_path *cpath; }; extern_st(st_device_clip); @@ -112,6 +114,7 @@ "gx_device_clip", device_clip_enum_ptrs, device_clip_reloc_ptrs,\ gx_device_finalize) void gx_make_clip_device_on_stack(gx_device_clip * dev, const gx_clip_path *pcpath, gx_device *target); +void gx_destroy_clip_device_on_stack(gx_device_clip * dev); gx_device *gx_make_clip_device_on_stack_if_needed(gx_device_clip * dev, const gx_clip_path *pcpath, gx_device *target, gs_fixed_rect *rect); void gx_make_clip_device_in_heap(gx_device_clip * dev, const gx_clip_path *pcpath, gx_device *target, gs_memory_t *mem); diff -Nru ghostscript-9.10~dfsg/base/gxcspace.h ghostscript-9.25~dfsg+1/base/gxcspace.h --- ghostscript-9.10~dfsg/base/gxcspace.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcspace.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -104,9 +104,9 @@ #define cs_proc_concrete_space(proc)\ const gs_color_space *proc(const gs_color_space *,\ - const gs_imager_state *) -#define cs_concrete_space(pcs, pis)\ - (*(pcs)->type->concrete_space)(pcs, pis) + const gs_gstate *) +#define cs_concrete_space(pcs, pgs)\ + (*(pcs)->type->concrete_space)(pcs, pgs) cs_proc_concrete_space((*concrete_space)); /* @@ -119,31 +119,32 @@ #define cs_proc_concretize_color(proc)\ int proc(const gs_client_color *, const gs_color_space *,\ - frac *, const gs_imager_state *, gx_device *) -#define cs_concretize_color(pcc, pcs, values, pis, dev)\ - (*(pcs)->type->concretize_color)(pcc, pcs, values, pis, dev) + frac *, const gs_gstate *, gx_device *) +#define cs_concretize_color(pcc, pcs, values, pgs, dev)\ + (*(pcs)->type->concretize_color)(pcc, pcs, values, pgs, dev) cs_proc_concretize_color((*concretize_color)); /* Map a concrete color to a device color. */ /* (Only defined for concrete color spaces.) */ #define cs_proc_remap_concrete_color(proc)\ - int proc(const frac *, const gs_color_space * pcs, gx_device_color *,\ - const gs_imager_state *, gx_device *, gs_color_select_t) + int proc(const gs_color_space * pcs, const frac *, gx_device_color *,\ + const gs_gstate *, gx_device *, gs_color_select_t,\ + const cmm_dev_profile_t *dev_profile) cs_proc_remap_concrete_color((*remap_concrete_color)); /* Map a color directly to a device color. */ #define cs_proc_remap_color(proc)\ int proc(const gs_client_color *, const gs_color_space *,\ - gx_device_color *, const gs_imager_state *, gx_device *,\ + gx_device_color *, const gs_gstate *, gx_device *,\ gs_color_select_t) cs_proc_remap_color((*remap_color)); /* Install the color space in a graphics state. */ #define cs_proc_install_cspace(proc)\ - int proc(gs_color_space *, gs_state *) + int proc(gs_color_space *, gs_gstate *) cs_proc_install_cspace((*install_cspace)); /* @@ -159,7 +160,7 @@ */ #define cs_proc_set_overprint(proc)\ - int proc(const gs_color_space *, gs_state *) + int proc(const gs_color_space *, gs_gstate *) cs_proc_set_overprint((*set_overprint)); /* Free contents of composite colorspace objects. */ @@ -203,14 +204,23 @@ /* A color mapping linearity check. */ #define cs_proc_is_linear(proc)\ - int proc(const gs_color_space *cs, const gs_imager_state * pis,\ + int proc(const gs_color_space *cs, const gs_gstate * pgs,\ gx_device *dev,\ const gs_client_color *c0, const gs_client_color *c1,\ const gs_client_color *c2, const gs_client_color *c3,\ float smoothness, gsicc_link_t *icclink) -#define cs_is_linear(pcs, pis, dev, c0, c1, c2, c3, smoothness, icclink)\ - (*(pcs)->type->is_linear)(pcs, pis, dev, c0, c1, c2, c3, smoothness, icclink) +#define cs_is_linear(pcs, pgs, dev, c0, c1, c2, c3, smoothness, icclink)\ + (*(pcs)->type->is_linear)(pcs, pgs, dev, c0, c1, c2, c3, smoothness, icclink) cs_proc_is_linear((*is_linear)); + + /* Define the polarity of a color space. We will use gx_color_polarity_t + with spaces such as patterns returning GX_CINFO_POLARITY_UNKNOWN */ + +#define cs_proc_polarity(proc)\ + gx_color_polarity_t proc(const gs_color_space *) +#define cs_polarity(pcs)\ + (*(pcs)->type->polarity)(pcs) + cs_proc_polarity((*polarity)); }; extern_st(st_base_color_space); @@ -222,6 +232,9 @@ cs_proc_num_components(gx_num_components_1); cs_proc_num_components(gx_num_components_3); cs_proc_num_components(gx_num_components_4); +cs_proc_polarity(gx_polarity_subtractive); +cs_proc_polarity(gx_polarity_additive); +cs_proc_polarity(gx_polarity_unknown); cs_proc_init_color(gx_init_paint_1); cs_proc_init_color(gx_init_paint_3); cs_proc_init_color(gx_init_paint_4); @@ -232,9 +245,9 @@ cs_proc_concrete_space(gx_same_concrete_space); cs_proc_concretize_color(gx_no_concretize_color); cs_proc_remap_color(gx_default_remap_color); +cs_proc_remap_color(gx_remap_named_color); cs_proc_install_cspace(gx_no_install_cspace); cs_proc_set_overprint(gx_spot_colors_set_overprint); -cs_proc_set_overprint(gx_simulated_set_overprint); cs_proc_adjust_color_count(gx_no_adjust_color_count); cs_proc_serialize(gx_serialize_cspace_type); cs_proc_is_linear(gx_cspace_no_linear); @@ -262,13 +275,10 @@ gs_cspace_alloc(gs_memory_t *mem, const gs_color_space_type *pcstype); /* Determine if the current color model is a "DeviceCMYK" color model, and */ -/* if so what are its process color components. Also the same for the RGB */ -/* device that simulates CMYK overprinting */ +/* if so what are its process color components. */ gx_color_index check_cmyk_color_model_comps(gx_device * dev); -gx_color_index check_rgb_color_model_comps(gx_device * dev); /* Shared code with ICC overprint */ -int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_state * pgs); -int gx_set_overprint_rgb(const gs_color_space * pcs, gs_state * pgs); +int gx_set_overprint_cmyk(const gs_color_space * pcs, gs_gstate * pgs); #endif /* gxcspace_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxctable.c ghostscript-9.25~dfsg+1/base/gxctable.c --- ghostscript-9.10~dfsg/base/gxctable.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxctable.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxctable.h ghostscript-9.25~dfsg+1/base/gxctable.h --- ghostscript-9.10~dfsg/base/gxctable.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxctable.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxcvalue.h ghostscript-9.25~dfsg+1/base/gxcvalue.h --- ghostscript-9.10~dfsg/base/gxcvalue.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxcvalue.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,7 +22,6 @@ /* Define the type for gray or RGB values at the driver interface. */ typedef unsigned short gx_color_value; -#define arch_sizeof_gx_color_value arch_sizeof_short /* We might use less than the full range someday. */ /* ...bits must lie between 8 and 16. */ #define gx_color_value_bits (sizeof(gx_color_value) * 8) @@ -38,6 +37,10 @@ #define frac2cv(fr) frac2ushort(fr) #define cv2frac(cv) ushort2frac(cv) +/* Convert between gx_color_values and frac31s. */ +#define frac312cv(fr) frac312ushort(fr) +#define cv2frac31(cv) ushort2frac31(cv) + /* At various points in the code (particularly inside encode_color and * decode_color functions), we need to convert colour values between * different bitdepths. diff -Nru ghostscript-9.10~dfsg/base/gxdcconv.c ghostscript-9.25~dfsg+1/base/gxdcconv.c --- ghostscript-9.10~dfsg/base/gxdcconv.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdcconv.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,7 +22,7 @@ #include "gxcmap.h" #include "gxfarith.h" #include "gxlum.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gsstate.h" /* for gs_currentcpsimode */ /* @@ -44,7 +44,7 @@ /* Convert RGB to Gray. */ frac -color_rgb_to_gray(frac r, frac g, frac b, const gs_imager_state * pis) +color_rgb_to_gray(frac r, frac g, frac b, const gs_gstate * pgs) { return (r * (unsigned long)lum_red_weight + g * (unsigned long)lum_green_weight + @@ -56,7 +56,7 @@ /* Convert RGB to CMYK. */ /* Note that this involves black generation and undercolor removal. */ void -color_rgb_to_cmyk(frac r, frac g, frac b, const gs_imager_state * pis, +color_rgb_to_cmyk(frac r, frac g, frac b, const gs_gstate * pgs, frac cmyk[4], gs_memory_t *mem) { frac c = frac_1 - r, m = frac_1 - g, y = frac_1 - b; @@ -67,11 +67,11 @@ * but they must agree with the ones in gs_init.ps. */ frac bg = - (pis == NULL ? k : pis->black_generation == NULL ? frac_0 : - gx_map_color_frac(pis, k, black_generation)); + (pgs == NULL ? k : pgs->black_generation == NULL ? frac_0 : + gx_map_color_frac(pgs, k, black_generation)); signed_frac ucr = - (pis == NULL ? k : pis->undercolor_removal == NULL ? frac_0 : - gx_map_color_frac(pis, k, undercolor_removal)); + (pgs == NULL ? k : pgs->undercolor_removal == NULL ? frac_0 : + gx_map_color_frac(pgs, k, undercolor_removal)); if (ucr == frac_1) cmyk[0] = cmyk[1] = cmyk[2] = 0; @@ -109,9 +109,9 @@ /* Convert CMYK to Gray. */ frac -color_cmyk_to_gray(frac c, frac m, frac y, frac k, const gs_imager_state * pis) +color_cmyk_to_gray(frac c, frac m, frac y, frac k, const gs_gstate * pgs) { - frac not_gray = color_rgb_to_gray(c, m, y, pis); + frac not_gray = color_rgb_to_gray(c, m, y, pgs); return (not_gray > frac_1 - k ? /* gray + k > 1.0 */ frac_0 : frac_1 - (not_gray + k)); @@ -119,7 +119,7 @@ /* Convert CMYK to RGB. */ void -color_cmyk_to_rgb(frac c, frac m, frac y, frac k, const gs_imager_state * pis, +color_cmyk_to_rgb(frac c, frac m, frac y, frac k, const gs_gstate * pgs, frac rgb[3], gs_memory_t *mem) { switch (k) { diff -Nru ghostscript-9.10~dfsg/base/gxdcconv.h ghostscript-9.25~dfsg+1/base/gxdcconv.h --- ghostscript-9.10~dfsg/base/gxdcconv.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdcconv.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,14 +23,14 @@ /* Color space conversion routines */ frac color_rgb_to_gray(frac r, frac g, frac b, - const gs_imager_state * pis); + const gs_gstate * pgs); void color_rgb_to_cmyk(frac r, frac g, frac b, - const gs_imager_state * pis, frac cmyk[4], + const gs_gstate * pgs, frac cmyk[4], gs_memory_t * mem); frac color_cmyk_to_gray(frac c, frac m, frac y, frac k, - const gs_imager_state * pis); + const gs_gstate * pgs); void color_cmyk_to_rgb(frac c, frac m, frac y, frac k, - const gs_imager_state * pis, frac rgb[3], + const gs_gstate * pgs, frac rgb[3], gs_memory_t * mem); #endif /* gxdcconv_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxdcolor.c ghostscript-9.25~dfsg+1/base/gxdcolor.c --- ghostscript-9.10~dfsg/base/gxdcolor.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdcolor.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,6 +23,7 @@ #include "gxpcolor.h" #include "gxdevice.h" #include "gxdevcli.h" +#include "gxclist.h" /* Define the standard device color types. */ @@ -106,13 +107,14 @@ gx_device_black(gx_device *dev) { if (dev->cached_colors.black == gx_no_color_index) { - const gx_cm_color_map_procs * cm_procs = dev_proc(dev, get_color_mapping_procs)(dev); - int i, ncomps = dev->color_info.num_components; + subclass_color_mappings scm; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; + scm = get_color_mapping_procs_subclass(dev); /* Get color components for black (gray = 0) */ - cm_procs->map_gray(dev, frac_0, cm_comps); + map_gray_subclass(scm, frac_0, cm_comps); for (i = 0; i < ncomps; i++) cv[i] = frac2cv(cm_comps[i]); @@ -125,13 +127,14 @@ gx_device_white(gx_device *dev) { if (dev->cached_colors.white == gx_no_color_index) { - const gx_cm_color_map_procs * cm_procs = dev_proc(dev, get_color_mapping_procs)(dev); - int i, ncomps = dev->color_info.num_components; + subclass_color_mappings scm; + uchar i, ncomps = dev->color_info.num_components; frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS]; gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS]; + scm = get_color_mapping_procs_subclass(dev); /* Get color components for white (gray = 1) */ - cm_procs->map_gray(dev, frac_1, cm_comps); + map_gray_subclass(scm, frac_1, cm_comps); for (i = 0; i < ncomps; i++) cv[i] = frac2cv(cm_comps[i]); @@ -258,7 +261,7 @@ } static int -gx_dc_no_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis, +gx_dc_no_load(gx_device_color *pdevc, const gs_gstate *ignore_pgs, gx_device *ignore_dev, gs_color_select_t ignore_select) { return 0; @@ -313,7 +316,7 @@ static int gx_dc_no_read( gx_device_color * pdevc, - const gs_imager_state * pis, /* ignored */ + const gs_gstate * pgs, /* ignored */ const gx_device_color * prior_devc, /* ignored */ const gx_device * dev, /* ignored */ int64_t offset, /* ignored */ @@ -340,7 +343,7 @@ int gx_dc_cannot_read( gx_device_color * pdevc, - const gs_imager_state * pis, /* ignored */ + const gs_gstate * pgs, /* ignored */ const gx_device_color * prior_devc, /* ignored */ const gx_device * dev, /* ignored */ int64_t offset, /* ignored */ @@ -363,7 +366,7 @@ /* ------ Null color ------ */ static int -gx_dc_null_load(gx_device_color *pdevc, const gs_imager_state *ignore_pis, +gx_dc_null_load(gx_device_color *pdevc, const gs_gstate *ignore_pgs, gx_device *ignore_dev, gs_color_select_t ignore_select) { return 0; @@ -396,7 +399,7 @@ static int gx_dc_null_read( gx_device_color * pdevc, - const gs_imager_state * pis, /* ignored */ + const gs_gstate * pgs, /* ignored */ const gx_device_color * prior_devc, /* ignored */ const gx_device * dev, /* ignored */ int64_t offset, /* ignored */ @@ -415,12 +418,12 @@ gx_dc_devn_save_dc(const gx_device_color * pdevc, gx_device_color_saved * psdc) { psdc->type = pdevc->type; - memcpy(&(psdc->colors.devn.values[0]), &(pdevc->colors.devn.values[0]), + memcpy(&(psdc->colors.devn.values[0]), &(pdevc->colors.devn.values[0]), GX_DEVICE_COLOR_MAX_COMPONENTS*sizeof(ushort)); } static int -gx_dc_devn_load(gx_device_color * pdevc, const gs_imager_state * ignore_pis, +gx_dc_devn_load(gx_device_color * pdevc, const gs_gstate * ignore_pgs, gx_device * ignore_dev, gs_color_select_t ignore_select) { return 0; @@ -429,8 +432,8 @@ /* Fill a rectangle with a devicen color. */ static int gx_dc_devn_fill_rectangle(const gx_device_color * pdevc, int x, int y, - int w, int h, gx_device * dev, - gs_logical_operation_t lop, + int w, int h, gx_device * dev, + gs_logical_operation_t lop, const gx_rop_source_t * source) { gs_fixed_rect rect; @@ -443,8 +446,8 @@ } /* Fill a mask with a DeviceN color. */ -/* Note that there is no source in this case: the mask is the source. - I would like to add a device proc that was fill_masked_hl for +/* Note that there is no source in this case: the mask is the source. + I would like to add a device proc that was fill_masked_hl for handling this instead of breaking this down to hl rect fills */ int gx_dc_devn_fill_masked(const gx_device_color * pdevc, const byte * data, @@ -536,8 +539,8 @@ /* * Utility to write a devn color into the clist. We should only be here - * if the device can handle these colors (e.g. a separation device like - * tiffsep). TODO: Reduce the size of this by removing leading zeros in + * if the device can handle these colors (e.g. a separation device like + * tiffsep). TODO: Reduce the size of this by removing leading zeros in * the mask. * */ @@ -549,12 +552,22 @@ uint * psize ) { int num_bytes1, num_bytes_temp, num_bytes; - gx_color_index mask, mask_temp; - int count; - int i, ncomps = dev->color_info.num_components; + gx_color_index mask_temp; + int count = 0; + uchar i; + gx_device_clist_writer* const cdev = &((gx_device_clist *)dev)->writer; + uchar ncomps = cdev->clist_color_info.num_components; /* Could be different than target if 1.4 device */ + gx_color_index mask = 0x1, comp_bits = 0; + + /* First find the number of non zero values */ + for (i = 0; i < ncomps; i++, mask <<= 1) { + if (pdevc->colors.devn.values[i] != 0) { + comp_bits |= mask; + count++; + } + } + mask = comp_bits; - /* Figure out the size needed. First find the number of non zero values */ - count = gx_dc_devn_get_nonzero_comps(pdevc, dev, &mask); num_bytes1 = sizeof(gx_color_index); num_bytes = num_bytes1 + count * 2; num_bytes_temp = num_bytes1; @@ -624,8 +637,6 @@ byte * pdata, uint * psize ) { - int k; - /* Due to the fact that the devn color type can vary being cmd_opv_ext_put_drawing_color, cmd_opv_ext_put_tile_devn_color0, cmd_opv_ext_put_tile_devn_color1, or cmd_opv_ext_put_drawing_color @@ -662,8 +673,8 @@ int size ) { gx_color_index mask = 0; - int i; - int ncomps = dev->color_info.num_components; + uchar i; + uchar ncomps = dev->color_info.num_components; int pos; int num_bytes; @@ -688,7 +699,7 @@ values[i] = 0; } mask >>= 1; - } + } return num_bytes; } @@ -700,11 +711,11 @@ * pdevc pointer to the location in which to write the * reconstructed device color * - * pis pointer to the current imager state (ignored here) + * pgs pointer to the current gs_gstate (ignored here) * * prior_devc pointer to the current device color (this is provided * separately because the device color is not part of the - * imager state; it is ignored here) + * gs_gstate; it is ignored here) * * dev pointer to the current device, used to retrieve process * color model information @@ -724,7 +735,7 @@ static int gx_dc_devn_read( gx_device_color * pdevc, - const gs_imager_state * pis, /* ignored */ + const gs_gstate * pgs, /* ignored */ const gx_device_color * prior_devc, /* ignored */ const gx_device * dev, int64_t offset, /* ignored */ @@ -736,22 +747,23 @@ return gx_devn_read_color(&(pdevc->colors.devn.values[0]), dev, pdata, size); } -/* Remember these are 16 bit values. Also here we return the number of +/* Remember these are 16 bit values. Also here we return the number of nonzero entries so we can figure out the size for the clist more easily. Hopefully that does not cause any confusion in overprint - situations where is where this operation is also used. */ + situations where this operation is also used. */ int gx_dc_devn_get_nonzero_comps( const gx_device_color * pdevc, const gx_device * dev, gx_color_index * pcomp_bits ) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; gx_color_index mask = 0x1, comp_bits = 0; int count = 0; + ushort white_value = (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) ? 0 : 1; for (i = 0; i < ncomps; i++, mask <<= 1) { - if (pdevc->colors.devn.values[i] != 0) { + if (pdevc->colors.devn.values[i] != white_value) { comp_bits |= mask; count++; } @@ -771,7 +783,7 @@ } static int -gx_dc_pure_load(gx_device_color * pdevc, const gs_imager_state * ignore_pis, +gx_dc_pure_load(gx_device_color * pdevc, const gs_gstate * ignore_pgs, gx_device * ignore_dev, gs_color_select_t ignore_select) { return 0; @@ -835,10 +847,17 @@ scolors[1] = gx_device_white(dev); } tcolors[0] = tcolors[1] = pdevc->colors.pure; + + if (invert) + lop = rop3_invert_S(lop); + + if (!rop3_uses_S(lop)) + lop |= rop3_S; + return (*dev_proc(dev, strip_copy_rop)) (dev, data, data_x, raster, id, scolors, NULL, tcolors, x, y, w, h, 0, 0, - (invert ? rop3_invert_S(lop) : lop) | (rop3_S | lop_S_transparent)); + lop | lop_S_transparent); } } @@ -906,11 +925,11 @@ * pdevc pointer to the location in which to write the * reconstructed device color * - * pis pointer to the current imager state (ignored here) + * pgs pointer to the current gs_gstate (ignored here) * * prior_devc pointer to the current device color (this is provided * separately because the device color is not part of the - * imager state; it is ignored here) + * gs_gstate; it is ignored here) * * dev pointer to the current device, used to retrieve process * color model information @@ -930,7 +949,7 @@ static int gx_dc_pure_read( gx_device_color * pdevc, - const gs_imager_state * pis, /* ignored */ + const gs_gstate * pgs, /* ignored */ const gx_device_color * prior_devc, /* ignored */ const gx_device * dev, int64_t offset, /* ignored */ @@ -955,7 +974,7 @@ pdevc->colors.pure, cvals ); if (code >= 0) { - int i, ncomps = dev->color_info.num_components; + uchar i, ncomps = dev->color_info.num_components; gx_color_index mask = 0x1, comp_bits = 0; for (i = 0; i < ncomps; i++, mask <<= 1) { @@ -1166,7 +1185,7 @@ num_bytes = sizeof(gx_color_index) + 1; } - /* num_bytes > arch_sizeof_color_index, discard first byte */ + /* num_bytes > ARCH_SIZEOF_COLOR_INDEX, discard first byte */ for (i = 0; i < num_bytes; i++) color = (color << 8) | pdata[i]; *pcolor = color; diff -Nru ghostscript-9.10~dfsg/base/gxdcolor.h ghostscript-9.25~dfsg+1/base/gxdcolor.h --- ghostscript-9.10~dfsg/base/gxdcolor.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdcolor.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,9 +32,9 @@ typedef struct gx_device_s gx_device; #endif -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif /* @@ -114,7 +114,7 @@ */ #define dev_color_proc_load(proc)\ - int proc(gx_device_color *pdevc, const gs_imager_state *pis,\ + int proc(gx_device_color *pdevc, const gs_gstate *pgs,\ gx_device *dev, gs_color_select_t select) dev_color_proc_load((*load)); @@ -202,10 +202,10 @@ * changed, so informaition from the prior device color will no * longer be available. * - * For the read method, the imager state is passed as an operand, + * For the read method, the gs_gstate is passed as an operand, * which allows the routine to access the current device halftone * (always required). Also passed in a pointer to the existing device - * color, as this is not part of the imager state. If the writer was + * color, as this is not part of the gs_gstate. If the writer was * passed a non-null psdc operand, *prior_devc must reflect the * information contained in *psdc. * @@ -223,7 +223,7 @@ dev_color_proc_write((*write)); #define dev_color_proc_read(proc)\ - int proc(gx_device_color *pdevc, const gs_imager_state * pis,\ + int proc(gx_device_color *pdevc, const gs_gstate * pgs,\ const gx_device_color *prior_devc, const gx_device * dev, int64_t offset,\ const byte *data, uint size, gs_memory_t *mem) dev_color_proc_read((*read)); @@ -300,10 +300,10 @@ /* Set up device color 1 for writing into a mask cache */ /* (e.g., the character cache). */ -int gx_set_device_color_1(gs_state * pgs); +int gx_set_device_color_1(gs_gstate * pgs); /* Remap the color if necessary. */ -int gx_remap_color(gs_state *); +int gx_remap_color(gs_gstate *); #define gx_set_dev_color(pgs)\ color_is_set(gs_currentdevicecolor_inline(pgs)) ? 0 :\ @@ -314,14 +314,17 @@ color_unset(gs_currentdevicecolor_inline(pgs)) #define gx_unset_alt_dev_color(pgs)\ color_unset(gs_altdevicecolor_inline(pgs)) +#define gx_unset_both_dev_colors(pgs)\ + (color_unset(gs_currentdevicecolor_inline(pgs)),\ + color_unset(gs_altdevicecolor_inline(pgs))) /* Load the halftone cache in preparation for drawing. */ -#define gx_color_load_select(pdevc, pis, dev, select)\ - (*(pdevc)->type->load)(pdevc, pis, dev, select) -#define gx_color_load(pdevc, pis, dev)\ - gx_color_load_select(pdevc, pis, dev, gs_color_select_texture) -#define gs_state_color_load(pgs)\ - gx_color_load(gs_currentdevicecolor_inline(pgs), (const gs_imager_state *)(pgs),\ +#define gx_color_load_select(pdevc, pgs, dev, select)\ + (*(pdevc)->type->load)(pdevc, pgs, dev, select) +#define gx_color_load(pdevc, pgs, dev)\ + gx_color_load_select(pdevc, pgs, dev, gs_color_select_texture) +#define gs_gstate_color_load(pgs)\ + gx_color_load(gs_currentdevicecolor_inline(pgs), (const gs_gstate *)(pgs),\ (pgs)->device) /* Fill a rectangle with a color. */ diff -Nru ghostscript-9.10~dfsg/base/gxdda.h ghostscript-9.25~dfsg+1/base/gxdda.h --- ghostscript-9.10~dfsg/base/gxdda.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdda.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxdevbuf.h ghostscript-9.25~dfsg+1/base/gxdevbuf.h --- ghostscript-9.10~dfsg/base/gxdevbuf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevbuf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxdevcli.h ghostscript-9.25~dfsg+1/base/gxdevcli.h --- ghostscript-9.10~dfsg/base/gxdevcli.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevcli.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -39,6 +39,7 @@ #include "gsnamecl.h" #include "gp.h" #include "gscms.h" +#include "gxrplane.h" /* See Drivers.htm for documentation of the driver interface. */ @@ -118,9 +119,9 @@ /* We need at least an abstract type for a graphics state, */ /* which is passed to the page device procedures. */ -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif /* We need abstract types for paths and fill/stroke parameters, */ @@ -141,9 +142,9 @@ # define gx_stroke_params_DEFINED typedef struct gx_stroke_params_s gx_stroke_params; #endif -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef patch_fill_state_t_DEFINED # define patch_fill_state_t_DEFINED @@ -227,26 +228,49 @@ * by the comp_shift array. Hence, there is no need to provide * an encode_color procedure for such devices, though the device * creator may choose to do so for performance reasons (e.g.: when - * each color component is assigned a byte). + * each color component is assigned a byte). + * + * Note that if the device encodes tags, the comp_shift array must + * provide a shift (and mask) for the tag component in the num_components + * element of the array. Used in gx_default_fill_linear_color_scanline. + * + * GX_CINFO_SEP_LIN_NON_STANDARD + * A separable and linear encoding has the separability and + * linearity properties. In addition, we know that this encoding + * is NOT the 'standard' one. (i.e. it is not compatible with the + * encoding used by the pdf14 compositor). + * + * Encodings with this property are completely characterized + * by the comp_shift array. Hence, there is no need to provide + * an encode_color procedure for such devices, though the device + * creator may choose to do so for performance reasons (e.g.: when + * each color component is assigned a byte). + * + * GX_CINFO_SEP_LIN_STANDARD + * A separable and linear encoding has the separability and + * linearity properties. In addition, we know that this encoding + * is the 'standard' one. (i.e. it is compatible with the encoding + * used by the pd14 compositor). + * + * Encodings with this property are completely characterized + * by the comp_shift array. Hence, there is no need to provide + * an encode_color procedure for such devices, though the device + * creator may choose to do so for performance reasons (e.g.: when + * each color component is assigned a byte). */ +/* Note: The arithmetic ordering for these values is relied upon + * in tests (see colors_are_separable_and_linear below) for + * separability and linearity. Change them with care! */ typedef enum { GX_CINFO_UNKNOWN_SEP_LIN = -1, GX_CINFO_SEP_LIN_NONE = 0, - GX_CINFO_SEP_LIN + GX_CINFO_SEP_LIN = 1, + GX_CINFO_SEP_LIN_NON_STANDARD = 2, + GX_CINFO_SEP_LIN_STANDARD = 3 } gx_color_enc_sep_lin_t; /* - * Color model component polarity. An "unknown" value has been added to - * this enumeration. - */ -typedef enum { - GX_CINFO_POLARITY_UNKNOWN = -1, - GX_CINFO_POLARITY_SUBTRACTIVE = 0, - GX_CINFO_POLARITY_ADDITIVE -} gx_color_polarity_t; - -/* * Enumerator to indicate if a color model will support overprint mode. * * Only "DeviceCMYK" color space support this option, but we interpret @@ -264,16 +288,11 @@ * information is required, hence the use of an enumeration with an * "unknown" setting. * - * GX_CINFO_OPMODE_RGB is an odd case where by the device is RGB based - * but we attempt to simulate CMY overprinting. GC_CINFO_OPMODE_RGB_SET - * is the value after we verify the color model and the colorant positions */ typedef enum { GX_CINFO_OPMODE_UNKNOWN = -1, GX_CINFO_OPMODE_NOT = 0, - GX_CINFO_OPMODE = 1, - GX_CINFO_OPMODE_RGB, - GC_CINFO_OPMODE_RGB_SET + GX_CINFO_OPMODE = 1 } gx_cm_opmode_t; /* component index value used to indicate no color component. */ @@ -310,7 +329,7 @@ * color models supported by this device. This does not include * any alpha components. */ - int max_components; + uchar max_components; /* * The number of color components. This does not include any @@ -318,7 +337,7 @@ * the gx_color_index but is otherwise passed as a separate * component. */ - int num_components; + uchar num_components; /* * Polarity of the components of the color space, either @@ -330,7 +349,7 @@ /* * The number of bits of gx_color_index actually used. - * This must be <= arch_sizeof_color_index, which is usually 64. + * This must be <= ARCH_SIZEOF_COLOR_INDEX, which is usually 64. * Note that we now have planar devices which can support much more. * Changing this to a ushort to reflect this. */ @@ -460,9 +479,17 @@ */ gx_cm_opmode_t opmode; gx_color_index process_comps; - int black_component;\ + uint black_component; + bool use_antidropout_downscaler; } gx_device_color_info; +/* Test to see if colors are separable and linear */ +static inline int colors_are_separable_and_linear(gx_device_color_info *info) +{ + return (info->separable_and_linear >= GX_CINFO_SEP_LIN); +} + + /* NB encoding flag ignored */ #define dci_extended_alpha_values(mcmp, nc, p, d, gi, mg, \ mc, dg, dc, ta, ga, sl, cn) \ @@ -629,15 +656,15 @@ typedef struct gx_page_device_procs_s { #define dev_page_proc_install(proc)\ - int proc(gx_device *dev, gs_state *pgs) + int proc(gx_device *dev, gs_gstate *pgs) dev_page_proc_install((*install)); #define dev_page_proc_begin_page(proc)\ - int proc(gx_device *dev, gs_state *pgs) + int proc(gx_device *dev, gs_gstate *pgs) dev_page_proc_begin_page((*begin_page)); #define dev_page_proc_end_page(proc)\ - int proc(gx_device *dev, int reason, gs_state *pgs) + int proc(gx_device *dev, int reason, gs_gstate *pgs) dev_page_proc_end_page((*end_page)); } gx_page_device_procs; @@ -692,6 +719,45 @@ typedef struct gx_device_cached_colors_s { gx_color_index black, white; } gx_device_cached_colors_t; + +/* + * Define the parameters controlling banding. + */ +/* if you make any additions/changes to this structure you need to make + the appropriate additions/changes to the compare_gdev_prn_space_params() + function in gdevprn.c */ +typedef struct gx_band_params_s { + int BandWidth; /* (optional) band width in pixels */ + int BandHeight; /* (optional) */ + long BandBufferSpace; /* (optional) */ + long tile_cache_size; /* (optional) */ +} gx_band_params_t; + +#define BAND_PARAMS_INITIAL_VALUES 0, 0, 0, 0 + +typedef enum { + BandingAuto = 0, + BandingAlways, + BandingNever +} gdev_banding_type; + +/* if you make any additions/changes to this structure you need to make + the appropriate additions/changes to the compare_gdev_prn_space_params() + function in gdevprn.c */ +typedef struct gdev_space_params_s { + long MaxBitmap; /* max size of non-buffered bitmap */ + long BufferSpace; /* space to use for buffer */ + gx_band_params_t band; /* see gxband.h */ + bool params_are_read_only; /* true if put_params may not modify this struct */ + gdev_banding_type banding_type; /* used to force banding or bitmap */ +} gdev_space_params; + +typedef struct gdev_pagelist_s { + rc_header rc; + char *Pages; + int PagesSize; +} gdev_pagelist; + #define gx_device_common\ int params_size; /* OBSOLETE if stype != 0: */\ /* size of this structure */\ @@ -708,6 +774,10 @@ rc_header rc; /* reference count from gstates */\ /* and targets, +1 if retained */\ bool retained; /* true if retained */\ + gx_device *parent;\ + gx_device *child;\ + void *subclass_data; /* Must be immovable, non-GC memory, used to store subclass data */\ + gdev_pagelist *PageList;\ bool is_open; /* true if device has been opened */\ int max_fill_band; /* limit on band size for fill, */\ /* must be 0 or a power of 2 */\ @@ -716,17 +786,25 @@ gx_device_cached_colors_t cached_colors;\ int width; /* width in pixels */\ int height; /* height in pixels */\ + int pad; /* pad to use for buffers; 0 for default */\ + int log2_align_mod; /* align to use for buffers; 0 for default */\ + int is_planar; /* 1 planar, 0 for chunky */\ int LeadingEdge; /* see below */\ float MediaSize[2]; /* media dimensions in points */\ float ImagingBBox[4]; /* imageable region in points */\ - bool ImagingBBox_set;\ + bool ImagingBBox_set;\ float HWResolution[2]; /* resolution, dots per inch */\ - float MarginsHWResolution[2]; /* resolution for Margins */\ float Margins[2]; /* offset of physical page corner */\ /* from device coordinate (0,0), */\ - /* in units given by MarginsHWResolution */\ + /* in units given by HWResolution */\ float HWMargins[4]; /* margins around imageable area, */\ /* in default user units ("points") */\ + int FirstPage;\ + int LastPage;\ + bool PageHandlerPushed; /* Handles FirstPage and LastPage operations */\ + bool DisablePageHandler; /* Can be set by the interpreter if it will process FirstPage and LastPage itself */\ + int ObjectFilter; /* Bit field for which object filters to apply */\ + bool ObjectHandlerPushed; /* Handles filtering of objects to devices */\ long PageCount; /* number of pages written */\ long ShowpageCount; /* number of calls on showpage */\ int NumCopies;\ @@ -736,10 +814,15 @@ bool LockSafetyParams; /* If true, prevent unsafe changes */\ long band_offset_x; /* offsets of clist band base to (mem device) buffer */\ long band_offset_y; /* for rendering that is phase sensitive (old wtsimdi) */\ + bool BLS_force_memory;\ gx_stroked_gradient_recognizer_t sgr;\ int MaxPatternBitmap; /* Threshold for switching to pattern_clist mode */\ + bool page_uses_transparency; /* PDF 1.4 transparency is used. */\ + gdev_space_params space_params;\ cmm_dev_profile_t *icc_struct; /* object dependent profiles */\ gs_graphics_type_tag_t graphics_type_tag; /* e.g. vector, image or text */\ + int interpolate_control; /* default 1 (use image /Interpolate value), 0 is NOINTERPOLATE. */\ + /* > 1 limits interpolation, < 0 forces interpolation */\ gx_page_device_procs page_procs; /* must be last */\ /* end of std_device_body */\ gx_device_procs procs /* object procedures */ @@ -773,8 +856,8 @@ #define no_margins margin_values(0, 0, 0, 0) #define no_margins_() no_margins /* Define macros that give the page offset ("Margins") in inches. */ -#define dev_x_offset(dev) ((dev)->Margins[0] / (dev)->MarginsHWResolution[0]) -#define dev_y_offset(dev) ((dev)->Margins[1] / (dev)->MarginsHWResolution[1]) +#define dev_x_offset(dev) ((dev)->Margins[0] / (dev)->HWResolution[0]) +#define dev_y_offset(dev) ((dev)->Margins[1] / (dev)->HWResolution[1]) #define dev_y_offset_points(dev) (dev_y_offset(dev) * 72.0) /* Note that left/right/top/bottom are defined relative to */ /* the physical paper, not the coordinate system. */ @@ -797,6 +880,15 @@ #define assign_dev_procs(todev, fromdev)\ ((todev)->procs = (fromdev)->procs) +/* The bit fields used to filter objects out. If any bit field is set + * then objects of that type will not be rendered/output. + */ +typedef enum FILTER_FLAGS { + FILTERIMAGE = 1, + FILTERTEXT = 2, + FILTERVECTOR = 4 +} OBJECT_FILTER_FLAGS; + /* ---------------- Device procedures ---------------- */ /* Define an opaque type for parameter lists. */ @@ -984,7 +1076,7 @@ #define dev_t_proc_fill_path(proc, dev_t)\ int proc(dev_t *dev,\ - const gs_imager_state *pis, gx_path *ppath,\ + const gs_gstate *pgs, gx_path *ppath,\ const gx_fill_params *params,\ const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) #define dev_proc_fill_path(proc)\ @@ -992,7 +1084,7 @@ #define dev_t_proc_stroke_path(proc, dev_t)\ int proc(dev_t *dev,\ - const gs_imager_state *pis, gx_path *ppath,\ + const gs_gstate *pgs, gx_path *ppath,\ const gx_stroke_params *params,\ const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) #define dev_proc_stroke_path(proc)\ @@ -1053,7 +1145,7 @@ #define dev_t_proc_begin_image(proc, dev_t)\ int proc(dev_t *dev,\ - const gs_imager_state *pis, const gs_image_t *pim,\ + const gs_gstate *pgs, const gs_image_t *pim,\ gs_image_format_t format, const gs_int_rect *prect,\ const gx_drawing_color *pdcolor, const gx_clip_path *pcpath,\ gs_memory_t *memory, gx_image_enum_common_t **pinfo) @@ -1108,7 +1200,7 @@ #define dev_t_proc_begin_typed_image(proc, dev_t)\ int proc(dev_t *dev,\ - const gs_imager_state *pis, const gs_matrix *pmat,\ + const gs_gstate *pgs, const gs_matrix *pmat,\ const gs_image_common_t *pim, const gs_int_rect *prect,\ const gx_drawing_color *pdcolor, const gx_clip_path *pcpath,\ gs_memory_t *memory, gx_image_enum_common_t **pinfo) @@ -1132,7 +1224,7 @@ #define dev_t_proc_create_compositor(proc, dev_t)\ int proc(dev_t *dev,\ gx_device **pcdev, const gs_composite_t *pcte,\ - gs_imager_state *pis, gs_memory_t *memory, gx_device *cdev) + gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) #define dev_proc_create_compositor(proc)\ dev_t_proc_create_compositor(proc, gx_device)\ @@ -1145,7 +1237,7 @@ /* Added in release 5.24 */ - /* ... text_begin ... see gxtext.h for definition */ + /* ... text_begin ... see gstext.h for definition */ /* Added in release 6.23 */ @@ -1164,7 +1256,7 @@ /* Push the current transparency state (*ppts) onto the associated stack, and set *ppts to a new transparency state of the given dimension. The - transparency state may copy some or all of the imager state, such as the + transparency state may copy some or all of the gs_gstate, such as the current alpha and/or transparency mask values, and definitely copies the parameters. */ @@ -1172,7 +1264,7 @@ int proc(gx_device *dev,\ const gs_transparency_group_params_t *ptgp,\ const gs_rect *pbbox,\ - gs_imager_state *pis,\ + gs_gstate *pgs,\ gs_memory_t *mem) #define dev_proc_begin_transparency_group(proc)\ dev_t_proc_begin_transparency_group(proc, gx_device) @@ -1186,7 +1278,7 @@ */ #define dev_t_proc_end_transparency_group(proc, dev_t)\ int proc(gx_device *dev,\ - gs_imager_state *pis) + gs_gstate *pgs) #define dev_proc_end_transparency_group(proc)\ dev_t_proc_end_transparency_group(proc, gx_device) @@ -1199,7 +1291,7 @@ int proc(gx_device *dev,\ const gx_transparency_mask_params_t *ptmp,\ const gs_rect *pbbox,\ - gs_imager_state *pis,\ + gs_gstate *pgs,\ gs_memory_t *mem) #define dev_proc_begin_transparency_mask(proc)\ dev_t_proc_begin_transparency_mask(proc, gx_device) @@ -1207,21 +1299,23 @@ /* Store a pointer to the rendered transparency mask into *pptm, popping the stack like end_group. Normally, the client will follow this by using - rc_assign to store the rendered mask into pis->{opacity,shape}.mask. If + rc_assign to store the rendered mask into pgs->{opacity,shape}.mask. If end_mask fails, the stack is *not* popped. */ #define dev_t_proc_end_transparency_mask(proc, dev_t)\ int proc(gx_device *dev,\ - gs_imager_state *pis) + gs_gstate *pgs) #define dev_proc_end_transparency_mask(proc)\ dev_t_proc_end_transparency_mask(proc, gx_device) /* - Pop the transparency stack, discarding the top element, which may be - either a group or a mask. Set *ppts to 0 iff the stack is now empty. + This will clean up the entire device allocations as something went + wrong in the middle of reading in the source content while we are dealing with + a transparency device. */ #define dev_t_proc_discard_transparency_layer(proc, dev_t)\ - int proc(gx_device *dev) + int proc(gx_device *dev,\ + gs_gstate *pgs) #define dev_proc_discard_transparency_layer(proc)\ dev_t_proc_discard_transparency_layer(proc, gx_device) @@ -1284,14 +1378,14 @@ a proper code. Currently this function is used with gs_rectfill and gs_fillpage. It is - also used for the handling of the devn color type for supporting - large number of spot colorants to planar separation devices. - + also used for the handling of the devn color type for supporting + large number of spot colorants to planar separation devices. + */ #define dev_t_proc_fill_rectangle_hl_color(proc, dev_t)\ int proc(dev_t *dev, const gs_fixed_rect *rect, \ - const gs_imager_state *pis, const gx_drawing_color *pdcolor, \ + const gs_gstate *pgs, const gx_drawing_color *pdcolor, \ const gx_clip_path *pcpath) #define dev_proc_fill_rectangle_hl_color(proc)\ dev_t_proc_fill_rectangle_hl_color(proc, gx_device) @@ -1380,7 +1474,7 @@ * start of src/gsequivc.c. */ #define dev_t_proc_update_spot_equivalent_colors(proc, dev_t)\ - int proc(dev_t *dev, const gs_state * pgs) + int proc(dev_t *dev, const gs_gstate * pgs) #define dev_proc_update_spot_equivalent_colors(proc)\ dev_t_proc_update_spot_equivalent_colors(proc, gx_device) @@ -1403,25 +1497,25 @@ */ #define dev_t_proc_fillpage(proc, dev_t)\ - int proc(gx_device *dev, gs_imager_state * pis, gx_device_color *pdevc) + int proc(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) #define dev_proc_fillpage(proc)\ dev_t_proc_fillpage(proc, gx_device) #define dev_t_proc_push_transparency_state(proc, dev_t)\ int proc(gx_device *dev,\ - gs_imager_state *pis) + gs_gstate *pgs) #define dev_proc_push_transparency_state(proc)\ dev_t_proc_push_transparency_state(proc, gx_device) #define dev_t_proc_pop_transparency_state(proc, dev_t)\ int proc(gx_device *dev,\ - gs_imager_state *pis) + gs_gstate *pgs) #define dev_proc_pop_transparency_state(proc)\ dev_t_proc_pop_transparency_state(proc, gx_device) #define dev_t_proc_put_image(proc, dev_t)\ - int proc(gx_device *dev, const byte *buffer, int num_chan, int x, int y,\ - int width, int height, int row_stride, int plane_stride,\ + int proc(gx_device *dev, const byte **buffers, int num_chan, int x, int y,\ + int width, int height, int row_stride,\ int alpha_plane_index, int tag_plane_index) #define dev_proc_put_image(proc)\ dev_t_proc_put_image(proc, gx_device) @@ -1474,6 +1568,27 @@ #define dev_proc_copy_alpha_hl_color(proc)\ dev_t_proc_copy_alpha_hl_color(proc, gx_device) +typedef struct gx_process_page_options_s gx_process_page_options_t; + +struct gx_process_page_options_s +{ + int (*init_buffer_fn)(void *arg, gx_device *dev, gs_memory_t *memory, int w, int h, void **buffer); + void (*free_buffer_fn)(void *arg, gx_device *dev, gs_memory_t *memory, void *buffer); + int (*process_fn)(void *arg, gx_device *dev, gx_device *bdev, const gs_int_rect *rect, void *buffer); + int (*output_fn)(void *arg, gx_device *dev, void *buffer); + void *arg; + int options; /* A mask of GX_PROCPAGE_... options bits */ +}; + +/* If GX_PROCPAGE_BOTTOM_UP, then we run from band n-1 to band 0, rather than + * 0 to n-1. */ +#define GX_PROCPAGE_BOTTOM_UP 1 + +#define dev_t_proc_process_page(proc, dev_t)\ + int proc(dev_t *dev, gx_process_page_options_t *options) +#define dev_proc_process_page(proc)\ + dev_t_proc_process_page(proc, gx_device) + /* Define the device procedure vector template proper. */ #define gx_device_proc_struct(dev_t)\ @@ -1549,6 +1664,7 @@ dev_t_proc_strip_copy_rop2((*strip_copy_rop2), dev_t);\ dev_t_proc_strip_tile_rect_devn((*strip_tile_rect_devn), dev_t);\ dev_t_proc_copy_alpha_hl_color((*copy_alpha_hl_color), dev_t);\ + dev_t_proc_process_page((*process_page), dev_t);\ } /* @@ -1564,12 +1680,12 @@ uint raster; } gx_image_plane_t; -#define gx_device_begin_image(dev, pis, pim, format, prect, pdcolor, pcpath, memory, pinfo)\ +#define gx_device_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo)\ ((*dev_proc(dev, begin_image))\ - (dev, pis, pim, format, prect, pdcolor, pcpath, memory, pinfo)) -#define gx_device_begin_typed_image(dev, pis, pmat, pim, prect, pdcolor, pcpath, memory, pinfo)\ + (dev, pgs, pim, format, prect, pdcolor, pcpath, memory, pinfo)) +#define gx_device_begin_typed_image(dev, pgs, pmat, pim, prect, pdcolor, pcpath, memory, pinfo)\ ((*dev_proc(dev, begin_typed_image))\ - (dev, pis, pmat, pim, prect, pdcolor, pcpath, memory, pinfo)) + (dev, pgs, pmat, pim, prect, pdcolor, pcpath, memory, pinfo)) /* * The driver-like procedures gx_device_{image_data, image_plane_data, @@ -1637,8 +1753,8 @@ /* gx_device can have subclasses. */ #define public_st_device() /* in gsdevice.c */\ gs_public_st_complex_only(st_device, gx_device, "gx_device",\ - 0, gs_no_struct_enum_ptrs, gs_no_struct_reloc_ptrs, gx_device_finalize) -#define st_device_max_ptrs 0 + 0, device_enum_ptrs, device_reloc_ptrs, gx_device_finalize) +#define st_device_max_ptrs 2 /* Enumerate or relocate a pointer to a device. */ /* These take the containing space into account properly. */ @@ -1672,6 +1788,76 @@ device_forward_reloc_ptrs, gx_device_finalize) #define st_device_forward_max_ptrs (st_device_max_ptrs + 1) +/* The color mapping procs were used in a way which defeats a 'pipeline' + * approach to devices. Certain graphics library routines (eg images) + * called the color mapping procs *directly* from the device procs of the + * current (ie terminal) device. This prevented any pipeline approach from + * working as earlier devices in the chain wouldn't see the call. In particular + * this prevented the use of such a device to do 'monochrome mode' in PCL + * (see pcpalet.c, pcl_update_mono). This macro walks back up the pipeline + * and retrieves the uppermost device color_mapping procs. + */ +typedef struct { + gx_cm_color_map_procs *procs; + gx_device *dev; +} subclass_color_mappings; + +static inline gx_device * +subclass_parentmost_device(gx_device *dev) +{ + while (dev->parent) + dev = dev->parent; + return dev; +} + +extern const gx_cm_color_map_procs *default_subclass_get_color_mapping_procs(const gx_device *dev); + +static inline +subclass_color_mappings get_color_mapping_procs_subclass(gx_device *dev) +{ + subclass_color_mappings sc; + gx_device *d; + sc.dev = NULL; + + d = subclass_parentmost_device(dev); + while (d->procs.get_color_mapping_procs == default_subclass_get_color_mapping_procs) { + if (d->child) + d = d->child; + else { + break; + } + } + sc.dev = d; + + sc.procs = (gx_cm_color_map_procs *)(dev_proc(sc.dev, get_color_mapping_procs) == NULL ? + NULL : dev_proc(sc.dev, get_color_mapping_procs)(sc.dev)); + return sc; +} + +static inline +void map_rgb_subclass(const subclass_color_mappings scm, const gs_gstate *pgs, frac r, frac g, frac b, frac out[]) +{ + scm.procs->map_rgb(scm.dev, pgs, r, g, b, out); +} + +static inline +void map_gray_subclass(const subclass_color_mappings scm, frac gray, frac out[]) +{ + scm.procs->map_gray(scm.dev, gray, out); +} + +static inline +void map_cmyk_subclass(const subclass_color_mappings scm, frac c, frac m, frac y, frac k, frac out[]) +{ + scm.procs->map_cmyk(scm.dev, c, m, y, k, out); +} + +/* Test to see if the device wants to use tags */ +static inline bool device_encodes_tags(gx_device *dev) +{ + return (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0; +} + /* A null device. This is used to temporarily disable output. */ #ifndef gx_device_null_DEFINED # define gx_device_null_DEFINED @@ -1724,9 +1910,17 @@ void gx_device_retain(gx_device *dev, bool retained); /* Calculate the raster (number of bytes in a scan line), */ -/* with byte or word padding. */ +/* with byte or device padding. */ uint gx_device_raster(const gx_device * dev, bool pad_to_word); +/* Calculate the raster (number of bytes in a scan line), */ +/* with byte or device padding forcing chunky format. */ +uint gx_device_raster_chunky(const gx_device * dev, bool pad); + +/* Calculate the raster (with device padding) optionally for a given + * render_plane (may be NULL). */ +uint gx_device_raster_plane(const gx_device * dev, const gx_render_plane_t *render_plane); + /* Adjust the resolution for devices that only have a fixed set of */ /* geometries, so that the apparent size in inches remains constant. */ /* If fit=1, the resolution is adjusted so that the entire image fits; */ @@ -1742,10 +1936,10 @@ void gx_device_set_width_height(gx_device * dev, int width, int height); /* Set the resolution (in pixels per inch), updating width and height. */ -void gx_device_set_resolution(gx_device * dev, floatp x_dpi, floatp y_dpi); +void gx_device_set_resolution(gx_device * dev, double x_dpi, double y_dpi); /* Set the MediaSize (in 1/72" units), updating width and height. */ -void gx_device_set_media_size(gx_device * dev, floatp media_width, floatp media_height); +void gx_device_set_media_size(gx_device * dev, double media_width, double media_height); /****** BACKWARD COMPATIBILITY ******/ #define gx_device_set_page_size(dev, w, h)\ @@ -1755,7 +1949,7 @@ * Temporarily install a null device, or a special device such as * a clipping or cache device. */ -void gx_set_device_only(gs_state *, gx_device *); +void gx_set_device_only(gs_gstate *, gx_device *); /* Close a device. */ int gs_closedevice(gx_device *); @@ -1783,4 +1977,7 @@ void gx_device_dump(gx_device *dev, const char *text); #endif +/* Compare color information structures */ +bool gx_color_info_equal(const gx_device_color_info *p1, const gx_device_color_info *p2); + #endif /* gxdevcli_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxdevice.h ghostscript-9.25~dfsg+1/base/gxdevice.h --- ghostscript-9.10~dfsg/base/gxdevice.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevice.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -63,6 +63,22 @@ # define DEFAULT_HEIGHT_10THS DEFAULT_HEIGHT_10THS_US_LETTER #endif +/* Define parameters for machines with little dinky RAMs.... */ +#if ARCH_SMALL_MEMORY +# define MAX_BITMAP 32000 +# define BUFFER_SPACE 25000 +# define MIN_MEMORY_LEFT 32000 +#else +# define MAX_BITMAP 10000000L /* reasonable on most modern hosts */ +# define BUFFER_SPACE 4000000L +# define MIN_MEMORY_LEFT 500000L +#endif +#define MIN_BUFFER_SPACE 10000 /* give up if less than this */ + +#ifndef MaxPatternBitmap_DEFAULT +# define MaxPatternBitmap_DEFAULT MAX_BITMAP +#endif + /* ---------------- Device structure ---------------- */ /* @@ -82,10 +98,11 @@ * Note also that the macro does not initialize procs, which is * the next element of the structure. */ -#define std_device_part1_(devtype, ptr_procs, dev_name, stype, open_init)\ + #define std_device_part1_(devtype, ptr_procs, dev_name, stype, open_init)\ sizeof(devtype), ptr_procs, dev_name,\ 0 /*memory*/, stype, 0 /*stype_is_dynamic*/, 0 /*finalize*/,\ - { 0 } /*rc*/, 0 /*retained*/, open_init() /*is_open, max_fill_band*/ + { 0 } /*rc*/, 0 /*retained*/, 0 /* parent */, 0 /* child */, 0 /* subclass_data */, 0, /* PageList */\ + open_init() /*is_open, max_fill_band*/ /* color_info goes here */ /* * The MetroWerks compiler has some bizarre bug that produces a spurious @@ -94,19 +111,28 @@ */ #define std_device_part2_(width, height, x_dpi, y_dpi)\ { gx_no_color_index, gx_no_color_index },\ - width, height, 0/*TrayOrientation*/,\ + width, height, 0/*Pad*/, 0/*align*/, 0/*Num planes*/, 0/*TrayOrientation*/,\ { (float)((((width) * 72.0 + 0.5) - 0.5) / (x_dpi))/*MediaSize[0]*/,\ (float)((((height) * 72.0 + 0.5) - 0.5) / (y_dpi))/*MediaSize[1]*/},\ { 0, 0, 0, 0 }/*ImagingBBox*/, 0/*ImagingBBox_set*/,\ - { x_dpi, y_dpi }/*HWResolution*/, { x_dpi, y_dpi }/*MarginsHWResolution*/ + { x_dpi, y_dpi }/*HWResolution*/ /* offsets and margins go here */ #define std_device_part3_()\ + 0/*FirstPage*/, 0/*LastPage*/, 0/*PageHandlerPushed*/, 0/*DisablePageHandler*/, 0/* Object Filter*/, 0/*ObjectHandlerPushed*/,\ 0/*PageCount*/, 0/*ShowpageCount*/, 1/*NumCopies*/, 0/*NumCopies_set*/,\ 0/*IgnoreNumCopies*/, 0/*UseCIEColor*/, 0/*LockSafetyParams*/,\ - 0/*band_offset_x*/, 0/*band_offset_y*/, {false}/* sgr */, 0/* MaxPatternBitmap */,\ + 0/*band_offset_x*/, 0/*band_offset_y*/, false /*BLS_force_memory*/, \ + {false}/* sgr */,\ + 0/* MaxPatternBitmap */, 0/*page_uses_transparency*/,\ + { MAX_BITMAP, BUFFER_SPACE,\ + { BAND_PARAMS_INITIAL_VALUES },\ + 0/*false*/, /* params_are_read_only */\ + BandingAuto /* banding_type */\ + }, /*space_params*/\ 0/*Profile Array*/,\ - 0/* graphics_type_tag default GS_UNKNOWN_TAG */,\ + 0/* graphics_type_tag default GS_UNTOUCHED_TAG */,\ + 1/* interpolate_control default 1, uses image /Interpolate flag, full device resolution */,\ { gx_default_install, gx_default_begin_page, gx_default_end_page } /* * We need a number of different variants of the std_device_ macro simply @@ -286,6 +312,19 @@ dev_proc_strip_copy_rop2(gx_default_strip_copy_rop2); dev_proc_strip_tile_rect_devn(gx_default_strip_tile_rect_devn); dev_proc_copy_alpha_hl_color(gx_default_copy_alpha_hl_color); +dev_proc_process_page(gx_default_process_page); +dev_proc_begin_transparency_group(gx_default_begin_transparency_group); +dev_proc_end_transparency_group(gx_default_end_transparency_group); +dev_proc_begin_transparency_mask(gx_default_begin_transparency_mask); +dev_proc_end_transparency_mask(gx_default_end_transparency_mask); +dev_proc_discard_transparency_layer(gx_default_discard_transparency_layer); +dev_proc_pattern_manage(gx_default_pattern_manage); +dev_proc_push_transparency_state(gx_default_push_transparency_state); +dev_proc_pop_transparency_state(gx_default_pop_transparency_state); +dev_proc_put_image(gx_default_put_image); +dev_proc_copy_alpha_hl_color(gx_default_no_copy_alpha_hl_color); +dev_proc_copy_planes(gx_default_copy_planes); + /* BACKWARD COMPATIBILITY */ #define gx_non_imaging_create_compositor gx_null_create_compositor @@ -378,6 +417,7 @@ dev_proc_copy_alpha_hl_color(gx_forward_copy_alpha_hl_color); /* ---------------- Implementation utilities ---------------- */ +int gx_default_get_param(gx_device *dev, char *Param, void *list); /* Convert the device procedures to the proper form (see above). */ void gx_device_set_procs(gx_device *); @@ -395,6 +435,11 @@ */ void check_device_separable(gx_device * dev); /* + * Check if the device's encode_color routine uses a pdf14 compatible + * encoding. For more info see the routine's header. + */ +void check_device_compatible_encoding(gx_device * dev); +/* * If a device has a linear and separable encode color function then * set up the comp_bits, comp_mask, and comp_shift fields. */ @@ -459,6 +504,9 @@ int gx_device_close_output_file(const gx_device * dev, const char *fname, FILE *file); +/* Delete the current output file for a device (file must be closed first) */ +int gx_device_delete_output_file(const gx_device * dev, const char *fname); + /* * Define the number of levels for a colorant above which we do not halftone. */ @@ -466,7 +514,7 @@ /* * Determine whether a given device needs to halftone. Eventually this - * should take an imager state as an additional argument. + * should take a gs_gstate as an additional argument. */ #define gx_device_must_halftone(dev)\ ((gx_device_has_color(dev) ? (dev)->color_info.max_color :\ @@ -583,7 +631,7 @@ int count); int gdev_write_input_page_size(int index, gs_param_dict * pdict, - floatp width_points, floatp height_points); + double width_points, double height_points); int gdev_write_input_media(int index, gs_param_dict * pdict, const gdev_input_media_t * pim); @@ -610,4 +658,27 @@ void gx_device_request_leadingedge(gx_device *dev, int le_req); +/* ---------------- Device subclassing procedures ---------------- */ +int gs_is_pdf14trans_compositor(const gs_composite_t * pct); + +#define subclass_common\ + t_dev_proc_create_compositor *saved_compositor_method;\ + gx_device_forward *forwarding_dev + +typedef int (t_dev_proc_create_compositor) (gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev); + +typedef struct { + t_dev_proc_create_compositor *saved_compositor_method; + gx_device_forward *forwarding_dev; +} generic_subclass_data; + + +int gx_copy_device_procs(gx_device *dest, gx_device *src, gx_device *prototype); +int gx_device_subclass(gx_device *dev_to_subclass, gx_device *new_prototype, unsigned int private_data_size); +int gx_device_unsubclass(gx_device *dev); +int gx_update_from_subclass(gx_device *dev); +int gx_subclass_create_compositor(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, + gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev); + + #endif /* gxdevice_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxdevmem.h ghostscript-9.25~dfsg+1/base/gxdevmem.h --- ghostscript-9.10~dfsg/base/gxdevmem.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevmem.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -96,7 +96,6 @@ * means this is a chunky device. Note that for planar devices, we * require color_info.depth = the sum of the individual plane depths. */ - int num_planes; gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* * End of client-initializable fields. @@ -161,7 +160,6 @@ true, /* foreign_bits (default) */\ 0, /* line_pointer_memory */\ true, /* foreign_line_pointers (default) */\ - 0, /* num_planes (default) */\ { { 0 } }, /* planes (only used for planar) */\ { identity_matrix_body }, /* initial matrix (filled in) */\ (byte **)0, /* line_ptrs (filled in by mem_open) */\ @@ -291,6 +289,6 @@ bool gs_device_is_abuf(const gx_device *); /* Check for getting the antialiasing bit depth */ -int alpha_buffer_bits(gs_state * pgs); +int alpha_buffer_bits(gs_gstate * pgs); #endif /* gxdevmem_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxdevndi.c ghostscript-9.25~dfsg+1/base/gxdevndi.c --- ghostscript-9.10~dfsg/base/gxdevndi.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevndi.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -107,7 +107,7 @@ } for (i = 0; i < num_colors; i++) { - unsigned long hsize = pdht ? + unsigned long hsize = pdht && i <= pdht->num_comp ? (unsigned) pdht->components[i].corder.num_levels : 1; unsigned long nshades = hsize * max_value[i] + 1; @@ -144,7 +144,8 @@ _color_set_c(pdevc, i, int_color[i], l_color[i]); gx_complete_halftone(pdevc, num_colors, pdht); - color_set_phase_mod(pdevc, ht_phase->x, ht_phase->y, + if (pdht) + color_set_phase_mod(pdevc, ht_phase->x, ht_phase->y, pdht->lcm_width, pdht->lcm_height); /* Determine if we are using only one component */ diff -Nru ghostscript-9.10~dfsg/base/gxdevndi.h ghostscript-9.25~dfsg+1/base/gxdevndi.h --- ghostscript-9.10~dfsg/base/gxdevndi.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevndi.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxdevrop.h ghostscript-9.25~dfsg+1/base/gxdevrop.h --- ghostscript-9.10~dfsg/base/gxdevrop.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevrop.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxdevsop.h ghostscript-9.25~dfsg+1/base/gxdevsop.h --- ghostscript-9.10~dfsg/base/gxdevsop.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdevsop.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -116,6 +116,22 @@ int n; } gxdso_device_child_request; +/* structure used to request a specific device parameter + * be returned by a device. + */ +typedef struct dev_param_req_s { + char *Param; + void *list; +}dev_param_req_t; + +/* structure used to pass the parameters for pattern handling */ +typedef struct pattern_accum_param_t { + void *pinst; + gs_memory_t *interpreter_memory; + void *graphics_state; + int pinst_id; +}pattern_accum_param_s; + enum { /* All gxdso_ keys must be defined in this structure. * Do NOT rely on your particular gxdso_ having a particular value. @@ -197,19 +213,18 @@ gxdso_is_std_cmyk_1bit, /* gxdso_is_pdf14_device: + * Either: * data = NULL * size = 0 - * Returns 1 if the device is a pdf14 device . + * Returns 1 if the device is a pdf14 device . + * Or: + * data = pointer to a place to store a pdf14_device * + * size = sizeof(pdf14_device *). + * Returns 1 if the device is a pdf14 device, and fills data with the + * pointer to the pdf14 device (may be a child of the original device) */ gxdso_is_pdf14_device, - /* gxdso_is_native_planar: - * data = NULL - * size = 0 - * Returns the number of bits per plane if the device's native format is planar - */ - gxdso_is_native_planar, - /* gxdso_device_child: * data = pointer to gxdso_device_child_request struct * size = sizeof(gxdso_device_child_request) @@ -233,7 +248,7 @@ * data = NULL * size = 0 * Returns 1 if the device supports devicen colors. example tiffsep. - */ + */ gxdso_supports_devn, /* gxdso_supports_hlcolor: * for devices that can handle pattern and other high level structures @@ -260,7 +275,58 @@ * (eg pdfwrite) we can't deal with this. return '0' if the device * doesn't care if the palette changes, and 1 if it does. */ - gxdso_needs_invariant_palette, + gxdso_needs_invariant_palette, + /* gxdso_supports_saved_pages: + * gx_device_printer devices can support this saving pages as clist + */ + gxdso_supports_saved_pages, + /* Form handling, we need one to start and one to stop a form + */ + gxdso_form_begin, + gxdso_form_end, + /* These next two relate to high level form handling. After executing a form the + * PostScript will request an ID for the form. If it gets one, it stores it in the + * /Implementation in the Form dictioanry. Next time it encoutners 'execform' for that + * form it will not call gxdso_form_begin and gxdso_form_end, instead it will simply call + * gxdso_repeat_form with the ID presented earlier. You should not return anything in response + * to the gxdso_form_ID unless the device is capable of storing the form and repeating it + * without running the PaintProc again. + */ + gxdso_get_form_ID, + gxdso_repeat_form, + /* gxdso_adjust_bandheight: + * Adjust the bandheight given in 'size' (normally downwards). Typically + * to round it to a multiple of a given number. + */ + gxdso_adjust_bandheight, + /* Retrieve a *single* device parameter */ + gxdso_get_dev_param, + /* gxdso_in_pattern_accumulator: + * data = NULL + * size = 0 + * Returns +ve value if we are rendering into a pattern accumulator + * device. + */ + gxdso_in_pattern_accumulator, + /* Determine if we are in a PDF14 device and the target is a separation + * device. In this case, we may want to not use the alternate tint + * tranform even if the blending color space is RGB or Gray. */ + gxdso_pdf14_sep_device, + /* Used only by pdfwrite to paa a Form Appearance Name, so that + * we can use the name in a pdfmark. + */ + gxdso_pdf_form_name, + gxdso_pdf_last_form_ID, + /* Restrict the supplied bbox to that actually used by the underlying device. + * Used to restrict alphabits drawing to the area defined by compositors etc.*/ + gxdso_restrict_bbox, + /* JPEG passthrough requests/control. Currently used for the pdfwrite family only. + */ + gxdso_JPEG_passthrough_query, + gxdso_JPEG_passthrough_begin, + gxdso_JPEG_passthrough_data, + gxdso_JPEG_passthrough_end, + gxdso_supports_iccpostrender, /* Add new gxdso_ keys above this. */ gxdso_pattern__LAST }; diff -Nru ghostscript-9.10~dfsg/base/gxdht.h ghostscript-9.25~dfsg+1/base/gxdht.h --- ghostscript-9.10~dfsg/base/gxdht.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdht.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -222,7 +222,7 @@ gx_transfer_map *transfer; /* TransferFunction or 0 */ gx_ht_order_screen_params_t screen_params; byte *threshold; - bool threshold_inverts; + bool threshold_inverted; }; #define ht_order_is_complete(porder)\ @@ -283,7 +283,7 @@ /* * Device Halftone Structure definition. See comments before - * gx_imager_dev_ht_install() for more information on this structure and its + * gx_gstate_dev_ht_install() for more information on this structure and its * fields. */ struct gx_device_halftone_s { @@ -292,7 +292,7 @@ gs_id id; /* the id changes whenever the data change */ /* * We have to keep the halftone type so that we can pass it - * through the band list for gx_imager_dev_ht_install. + * through the band list for gx_gstate_dev_ht_install. */ gs_halftone_type type; gx_ht_order_component *components; diff -Nru ghostscript-9.10~dfsg/base/gxdhtres.h ghostscript-9.25~dfsg+1/base/gxdhtres.h --- ghostscript-9.10~dfsg/base/gxdhtres.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdhtres.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxdhtserial.c ghostscript-9.25~dfsg+1/base/gxdhtserial.c --- ghostscript-9.10~dfsg/base/gxdhtserial.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdhtserial.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -73,7 +73,7 @@ req_size += sizeof(pmap->values); if (req_size > *psize) { *psize = req_size; - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } if (req_size == 1) @@ -221,7 +221,7 @@ req_size += tmp_size; if (req_size > *psize) { *psize = req_size; - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } /* write out the dimensional data */ @@ -297,6 +297,7 @@ if (data >= data_lim) return_error(gs_error_rangecheck); new_order.procs = &ht_order_procs_table[*data++]; + new_order.threshold_inverted = 0; /* calculate the space required for levels and bit data */ levels_size = new_order.num_levels * sizeof(new_order.levels[0]); @@ -537,7 +538,7 @@ */ int gx_ht_read_and_install( - gs_imager_state * pis, + gs_gstate * pgs, const gx_device * dev, const byte * data, uint size, @@ -583,9 +584,11 @@ /* save since the 'install' copies the order, but then clears the source order */ for (i = 0; i < num_dev_comps; i++) components_save[i] = components[i]; - code = gx_imager_dev_ht_install(pis, &dht, dht.type, dev); - for (i = 0; i < num_dev_comps; i++) - gx_ht_order_release(&components_save[i].corder, mem, false); + code = gx_gstate_dev_ht_install(pgs, &dht, dht.type, dev); + if (code >= 0) { + for (i = 0; i < num_dev_comps; i++) + gx_ht_order_release(&components_save[i].corder, mem, false); + } } /* diff -Nru ghostscript-9.10~dfsg/base/gxdhtserial.h ghostscript-9.25~dfsg+1/base/gxdhtserial.h --- ghostscript-9.10~dfsg/base/gxdhtserial.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdhtserial.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -34,9 +34,9 @@ typedef struct gx_device_halftone_s gx_device_halftone; #endif -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif /* @@ -70,7 +70,7 @@ * * Returns the number of bytes read, or < 0 in the event of an error. */ -extern int gx_ht_read_and_install( gs_imager_state * pis, +extern int gx_ht_read_and_install( gs_gstate * pgs, const gx_device * dev, const byte * data, uint size, diff -Nru ghostscript-9.10~dfsg/base/gxdither.h ghostscript-9.25~dfsg+1/base/gxdither.h --- ghostscript-9.10~dfsg/base/gxdither.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdither.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxdownscale.c ghostscript-9.25~dfsg+1/base/gxdownscale.c --- ghostscript-9.10~dfsg/base/gxdownscale.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdownscale.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,22 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ #include "gxdownscale.h" #include "gserrors.h" +#include "string_.h" #include "gdevprn.h" +#include "assert_.h" +#include "ets.h" + +enum +{ + MAX_ETS_PLANES = 8 +}; /* Error diffusion data is stored in errors block. * We have 1 empty entry at each end to avoid overflow. When @@ -171,6 +179,42 @@ pack_8to1(out_buffer, outp, awidth); } +static void down_core_ets_1(gx_downscaler_t *ds, + byte *out_buffer, + byte *in_buffer, + int row, + int plane, + int span) +{ + unsigned char *dest[MAX_ETS_PLANES]; + ETS_SrcPixel *src[MAX_ETS_PLANES]; + int pad_white, y; + int factor = ds->factor; + + pad_white = (ds->awidth - ds->width) * factor * 4; + if (pad_white < 0) + pad_white = 0; + + if (pad_white) + { + unsigned char *inp = in_buffer + ds->width * factor * 4; + for (y = factor; y > 0; y--) + { + memset(inp, 0xFF, pad_white); + inp += span; + } + } + + if (ds->ets_downscale) + ds->ets_downscale(ds, in_buffer, in_buffer, row, plane, span); + + src[0] = in_buffer; + dest[0] = in_buffer; + ets_line((ETS_Ctx *)ds->ets_config, dest, (const ETS_SrcPixel * const *)src); + + pack_8to1(out_buffer, in_buffer, ds->awidth); +} + static void down_core_1(gx_downscaler_t *ds, byte *out_buffer, byte *in_buffer, @@ -653,7 +697,7 @@ mfs_data += awidth; inp += awidth*factor-1; outp = inp; - *mfs_data-- = 0; + *mfs_data-- = mfs_clear; for (x = awidth; x > 0; x--) { value = e_forward + *errors; @@ -830,6 +874,48 @@ pack_8to1(out_buffer, outp, awidth*4); } +static void down_core4_ets(gx_downscaler_t *ds, + byte *out_buffer, + byte *in_buffer, + int row, + int plane /* unused */, + int span) +{ + unsigned char *dest[MAX_ETS_PLANES]; + ETS_SrcPixel *src[MAX_ETS_PLANES]; + int pad_white, y; + int factor = ds->factor; + + pad_white = (ds->awidth - ds->width) * factor * 4; + if (pad_white < 0) + pad_white = 0; + + if (pad_white) + { + unsigned char *inp = in_buffer + ds->width * factor * 4; + for (y = factor; y > 0; y--) + { + memset(inp, 0xFF, pad_white); + inp += span; + } + } + + if (ds->ets_downscale) + ds->ets_downscale(ds, in_buffer, in_buffer, row, plane, span); + + src[0] = in_buffer+3; + dest[0] = in_buffer+3; + src[1] = in_buffer+1; + dest[1] = in_buffer+1; + src[2] = in_buffer+0; + dest[2] = in_buffer+0; + src[3] = in_buffer+2; + dest[3] = in_buffer+2; + ets_line((ETS_Ctx *)ds->ets_config, dest, (const ETS_SrcPixel * const *)src); + + pack_8to1(out_buffer, in_buffer, ds->awidth * 4); +} + static void down_core4_mfs(gx_downscaler_t *ds, byte *out_buffer, byte *in_buffer, @@ -845,9 +931,9 @@ int awidth = ds->awidth; int factor = ds->factor; int *errors; - byte *mfs_data; const int threshold = factor*factor*128; const int max_value = factor*factor*255; + byte *mfs_data; pad_white = (awidth - width) * factor * 4; if (pad_white < 0) @@ -863,18 +949,16 @@ } } - inp = in_buffer; if ((row & 1) == 0) { /* Left to Right pass (with min feature size = 2) */ const int back = span * factor - 4; - byte *outp_base = inp; for (comp = 0; comp < 4; comp++) { byte mfs, force_forward = 0; errors = ds->errors + (awidth+3)*comp + 2; - inp = outp_base; - outp = outp_base++; + inp = in_buffer + comp; + outp = inp; mfs_data = ds->mfs_data + (awidth+1)*comp; *mfs_data++ = mfs_clear; for (x = awidth; x > 0; x--) @@ -894,13 +978,15 @@ if ((mfs & mfs_force_off) || force_forward) { /* We are being forced to be 0 */ - *outp = 0; outp += 4; + *outp = 1; outp += 4; + value -= max_value; force_forward = 0; } - else if (value < threshold) + else if (value >= threshold) { - /* We want to be 0 anyway */ - *outp = 0; outp += 4; + /* We want to be 1 anyway */ + *outp = 1; outp += 4; + value -= max_value; if ((mfs & (mfs_above_is_0 | mfs_above_left_is_0)) != (mfs_above_is_0 | mfs_above_left_is_0)) { @@ -913,15 +999,14 @@ else { /* No forcing, but we need to tell other pixels that - * we were 0. */ + * we were 1. */ mfs_data[-2] |= mfs_above_is_0; mfs_data[-1] |= mfs_above_left_is_0; } } else { - *outp = 1; outp += 4; - value -= max_value; + *outp = 0; outp += 4; } e_forward = value * 7/16; e_downleft = value * 3/16; @@ -932,21 +1017,20 @@ *errors++ = value; } } - outp = outp_base-4; + outp = in_buffer; } else { /* Right to Left pass (with min feature size = 2) */ const int back = span * factor + 4; - byte *outp_base = inp + awidth*factor - 4; for (comp = 0; comp < 4; comp++) { byte mfs, force_forward = 0; errors = ds->errors + (awidth+3)*comp + awidth; + inp = in_buffer + awidth*factor*4 - 4 + comp; + outp = inp; mfs_data = ds->mfs_data + (awidth+1)*comp + awidth; - inp = outp_base; - outp = outp_base++; - *mfs_data-- = 0; + *mfs_data-- = mfs_clear; for (x = awidth; x > 0; x--) { value = e_forward + *errors; @@ -964,12 +1048,14 @@ if ((mfs & mfs_force_off) || force_forward) { /* We are being forced to be 0 */ - *outp = 0; outp -= 4; + *outp = 1; outp -= 4; + value -= max_value; force_forward = 0; } - else if (value < threshold) + else if (value >= threshold) { - *outp = 0; outp -= 4; + *outp = 1; outp -= 4; + value -= max_value; if ((mfs & (mfs_above_is_0 | mfs_above_left_is_0)) != (mfs_above_is_0 | mfs_above_left_is_0)) { @@ -982,15 +1068,14 @@ else { /* No forcing, but we need to tell other pixels that - * we were 0. */ + * we were 1. */ mfs_data[1] |= mfs_above_is_0; mfs_data[2] |= mfs_above_left_is_0; } } else { - *outp = 1; outp -= 4; - value -= max_value; + *outp = 0; outp -= 4; } e_forward = value * 7/16; e_downleft = value * 3/16; @@ -1001,7 +1086,7 @@ *errors-- = value; } } - outp = outp_base - awidth*factor; + outp = in_buffer + awidth*factor*4 - (awidth*4); } pack_8to1(out_buffer, outp, awidth*4); } @@ -1536,6 +1621,172 @@ return (width*up)/down; } +int gx_downscaler_adjust_bandheight(int factor, int band_height) +{ + int up, down; + + decode_factor(factor, &up, &down); + return (band_height/down)*down; +} + +int +gx_downscaler_scale_rounded(int width, int factor) +{ + int up, down; + + decode_factor(factor, &up, &down); + return (width*up + down-1)/down; +} + +static int get_planar_line_for_trap(void *arg, unsigned char *buf) +{ + gx_downscaler_t *ds = (gx_downscaler_t *)arg; + gs_int_rect rect; + gs_get_bits_params_t params; /* params (if trapping) */ + int nc = ds->num_planes; + int i, code; + unsigned char *buf2; + + rect.p.x = 0; + rect.p.y = ds->claptrap_y++; + rect.q.x = ds->dev->width; + rect.q.y = rect.p.y+1; + /* Allow for devices (like psdcmyk) that make several passes through + * the image. */ + if (ds->claptrap_y == ds->dev->height) + ds->claptrap_y = 0; + + params = *ds->claptrap_params; + buf2 = buf; + for (i = 0; i < nc; i++) + { + params.data[i] = buf2; + buf2 += ds->width; + } + + code = (*dev_proc(ds->dev, get_bits_rectangle))(ds->dev, &rect, ¶ms, NULL); + if (code < 0) + return code; + + /* Now cope with the fact we might have been returned pointers */ + for (i = 0; i < nc; i++) + { + if (params.data[i] != buf) + memcpy(buf, params.data[i], ds->width); + buf += ds->width; + } + + return code; +} + +static int check_trapping(gs_memory_t *memory, int trap_w, int trap_h, + int num_comps, const int *comp_order) +{ +#ifndef ENABLE_TRAPPING + if (trap_w > 0 || trap_h > 0) + { + dmprintf(memory, + "Trapping is disabled in this build. To enable trapping,\n" + "follow the instructions in the documentation. Please note\n" + "that if you do this, you are responsible for ensuring that\n" + "you have any and all patent licenses that may be required.\n"); + return_error(gs_error_rangecheck); + } +#endif + + if (trap_w < 0 || trap_h < 0) + { + dmprintf(memory, "Trapping range must be >= 0"); + return_error(gs_error_rangecheck); + } + + if (trap_w > 0 || trap_h > 0) + { + if (comp_order == NULL) + { + emprintf(memory, "Trapping cannot be used without comp_order being defined"); + return_error(gs_error_rangecheck); + } + + /* Check that the comp_order we have been passed is sane */ + { + char comps[GS_CLIENT_COLOR_MAX_COMPONENTS] = { 0 }; + int i; + + for (i = 0; i < num_comps; i++) + { + int n = comp_order[i]; + if (n < 0 || n >= num_comps || comps[n] != 0) + break; + comps[n] = 1; + } + if (i != num_comps) + { + emprintf(memory, "Illegal component order passed to trapping"); + return_error(gs_error_rangecheck); + } + } + } + return 0; +} + +static int init_ets(gx_downscaler_t *ds, int num_planes, gx_downscale_core *downscale_core) +{ + ETS_Params params = { 0 }; + int strengths[MAX_ETS_PLANES] = { 128, 51, 51, 13, 13, 13, 13, 13 }; + int lut[ETS_SRC_MAX+1]; + int *luts[MAX_ETS_PLANES]; + int rs_lut[ETS_SRC_MAX+1]; + int *rs_luts[MAX_ETS_PLANES]; + int i; + int c1_scale[MAX_ETS_PLANES] = { 1, 1, 1, 1, 1, 1, 1, 1 }; + ETS_POLARITY polarity = ETS_BLACK_IS_ONE; + + polarity = ETS_BLACK_IS_ONE; + + if (num_planes > MAX_ETS_PLANES) + return gs_error_rangecheck; + + ds->ets_downscale = downscale_core; + + /* Setup a simple gamma scale */ + { + double scale = ETS_SRC_MAX; + for (i = 0; i < (ETS_SRC_MAX+1); i++) + lut[i] = (int)((1 << 24) * (pow (i / scale, 1.0))); + } + for (i = 0; i < (ETS_SRC_MAX+1); i++) + rs_lut[i] = 2 << 16; + for (i = 0; i < num_planes; i++) + luts[i] = lut; + for (i = 0; i < num_planes; i++) + rs_luts[i] = rs_lut; + + params.width = ds->width; + params.n_planes = num_planes; + params.levels = 2; + params.luts = luts; + params.distscale = 0; + params.aspect_x = 1; + params.aspect_y = 1; + params.strengths = strengths; + params.rand_scale = 0; + params.c1_scale = c1_scale; + params.ets_bias = ETS_BIAS_REDUCE_POSITIVE; + params.r_style = ETS_RSTYLE_THRESHOLD; + params.dump_file = NULL; + params.dump_level = 0; + params.rand_scale_luts = rs_luts; + params.polarity = polarity; + + ds->ets_config = ets_create(ds->dev->memory, ¶ms); + if (ds->ets_config == NULL) + return gs_error_VMerror; + + return 0; +} + + int gx_downscaler_init_planar(gx_downscaler_t *ds, gx_device *dev, gs_get_bits_params_t *params, @@ -1545,7 +1796,45 @@ int src_bpc, int dst_bpc) { + return gx_downscaler_init_planar_trapped_cm(ds, dev, params, num_comps, + factor, mfs, src_bpc, dst_bpc, 0, 0, NULL, NULL, NULL, num_comps); +} + +int gx_downscaler_init_planar_trapped(gx_downscaler_t *ds, + gx_device *dev, + gs_get_bits_params_t *params, + int num_comps, + int factor, + int mfs, + int src_bpc, + int dst_bpc, + int trap_w, + int trap_h, + const int *comp_order) +{ + return gx_downscaler_init_planar_trapped_cm(ds, dev, params, num_comps, + factor, mfs, src_bpc, dst_bpc, + trap_w, trap_h, comp_order, + NULL, NULL, num_comps); +} + +int gx_downscaler_init_planar_trapped_cm(gx_downscaler_t *ds, + gx_device *dev, + gs_get_bits_params_t *params, + int num_comps, + int factor, + int mfs, + int src_bpc, + int dst_bpc, + int trap_w, + int trap_h, + const int *comp_order, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps) +{ int span = bitmap_raster(dev->width * src_bpc); + int post_span = bitmap_raster(dev->width * src_bpc); int width; int code; gx_downscale_core *core; @@ -1557,48 +1846,73 @@ /* width = scaled width */ width = (dev->width*upfactor)/downfactor; memset(ds, 0, sizeof(*ds)); - ds->dev = dev; - ds->width = width; - ds->awidth = width; - ds->span = span; - ds->factor = factor; - ds->num_planes = num_comps; - ds->src_bpc = src_bpc; - ds->scaled_data = NULL; - ds->scaled_span = bitmap_raster((dst_bpc*dev->width*upfactor + downfactor-1)/downfactor); + ds->dev = dev; + ds->width = width; + ds->awidth = width; + ds->span = span; + ds->factor = factor; + ds->num_planes = num_comps; + ds->src_bpc = src_bpc; + ds->scaled_data = NULL; + ds->scaled_span = bitmap_raster((dst_bpc*dev->width*upfactor + downfactor-1)/downfactor); + ds->apply_cm = apply_cm; + ds->apply_cm_arg = apply_cm_arg; + ds->early_cm = dst_bpc < src_bpc; + ds->post_cm_num_comps = post_cm_num_comps; + + if (apply_cm) { + for (i = 0; i < post_cm_num_comps; i++) { + ds->post_cm[i] = gs_alloc_bytes(dev->memory, post_span * downfactor, + "gx_downscaler(planar_data)"); + if (ds->post_cm[i] == NULL) { + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } + } + } + + code = check_trapping(dev->memory, trap_w, trap_h, num_comps, comp_order); + if (code < 0) + return code; + + if (trap_w > 0 || trap_h > 0) { + ds->claptrap = ClapTrap_Init(dev->memory, width, dev->height, num_comps, comp_order, trap_w, trap_h, get_planar_line_for_trap, ds); + if (ds->claptrap == NULL) { + emprintf(dev->memory, "Trapping initialisation failed"); + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } + } + else + ds->claptrap = NULL; memcpy(&ds->params, params, sizeof(*params)); ds->params.raster = span; - for (i = 0; i < num_comps; i++) - { - ds->params.data[i] = gs_alloc_bytes(dev->memory, span * downfactor, + for (i = 0; i < num_comps; i++) { + ds->pre_cm[i] = gs_alloc_bytes(dev->memory, span * downfactor, "gx_downscaler(planar_data)"); - if (ds->params.data[i] == NULL) + if (ds->pre_cm[i] == NULL) { + code = gs_note_error(gs_error_VMerror); goto cleanup; + } } - if (upfactor) - { + if (upfactor > 1) { ds->scaled_data = gs_alloc_bytes(dev->memory, ds->scaled_span * upfactor * num_comps, "gx_downscaler(scaled_data)"); - if (ds->scaled_data == NULL) + if (ds->scaled_data == NULL) { + code = gs_note_error(gs_error_VMerror); goto cleanup; + } } - if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 32)) - { + if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 32)) { core = &down_core8_3_2; - } - else if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 34)) - { + } else if ((src_bpc == 8) && (dst_bpc == 8) && (factor == 34)) { core = &down_core8_3_4; - } - else if (factor > 8) - { + } else if (factor > 8) { code = gs_note_error(gs_error_rangecheck); goto cleanup; - } - else if (dst_bpc == 1) - { + } else if (dst_bpc == 1) { if (mfs > 1) core = &down_core_mfs; else if (factor == 4) @@ -1611,8 +1925,7 @@ core = &down_core_1; else core = &down_core; - } - else if (factor == 1) + } else if (factor == 1) core = NULL; else if (src_bpc == 16) core = &down_core16; @@ -1636,13 +1949,11 @@ } memset(ds->mfs_data, 0, (width+1) * num_comps); } - if (dst_bpc == 1) - { + if (dst_bpc == 1) { ds->errors = (int *)gs_alloc_bytes(dev->memory, num_comps*(width+3)*sizeof(int), "gx_downscaler(errors)"); - if (ds->errors == NULL) - { + if (ds->errors == NULL) { code = gs_note_error(gs_error_VMerror); goto cleanup; } @@ -1656,6 +1967,18 @@ return code; } +static int get_line_for_trap(void *arg, unsigned char *buf) +{ + gx_downscaler_t *ds = (gx_downscaler_t *)arg; + + /* Allow for devices (like psdcmyk) that make several passes through + * the image. */ + if (ds->claptrap_y == ds->dev->height) + ds->claptrap_y = 0; + + return (*dev_proc(ds->dev, get_bits))(ds->dev, ds->claptrap_y++, buf, NULL); +} + int gx_downscaler_init(gx_downscaler_t *ds, gx_device *dev, int src_bpc, @@ -1666,7 +1989,150 @@ int (*adjust_width_proc)(int, int), int adjust_width) { - int size = gdev_mem_bytes_per_scan_line((gx_device *)dev); + return gx_downscaler_init_trapped_cm_ets(ds, dev, src_bpc, dst_bpc, num_comps, + factor, mfs, adjust_width_proc, adjust_width, 0, 0, NULL, NULL, NULL, 0, 0); +} + + +int gx_downscaler_init_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int ets) +{ + return gx_downscaler_init_trapped_cm_ets(ds, dev, src_bpc, dst_bpc, num_comps, + factor, mfs, adjust_width_proc, adjust_width, 0, 0, NULL, NULL, NULL, 0, ets); +} + +int gx_downscaler_init_trapped(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order) +{ + return gx_downscaler_init_trapped_cm_ets(ds, dev, src_bpc, dst_bpc, + num_comps, factor, mfs, + adjust_width_proc, adjust_width, + trap_w, trap_h, comp_order, + NULL, NULL, 0, 0); +} + +int gx_downscaler_init_trapped_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order, + int ets) +{ + return gx_downscaler_init_trapped_cm_ets(ds, dev, src_bpc, dst_bpc, + num_comps, factor, mfs, + adjust_width_proc, adjust_width, + trap_w, trap_h, comp_order, + NULL, NULL, 0, ets); +} +int gx_downscaler_init_cm(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps) +{ + return gx_downscaler_init_trapped_cm_ets(ds, dev, src_bpc, dst_bpc, + num_comps, factor, mfs, + adjust_width_proc, adjust_width, + 0, 0, NULL, + apply_cm, apply_cm_arg, post_cm_num_comps, 0); +} + +int gx_downscaler_init_cm_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps, + int ets) +{ + return gx_downscaler_init_trapped_cm_ets(ds, dev, src_bpc, dst_bpc, + num_comps, factor, mfs, + adjust_width_proc, adjust_width, + 0, 0, NULL, + apply_cm, apply_cm_arg, post_cm_num_comps, ets); +} + +int gx_downscaler_init_trapped_cm(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps) +{ + return gx_downscaler_init_trapped_cm_ets(ds, dev, src_bpc, dst_bpc, + num_comps, factor, mfs, + adjust_width_proc, adjust_width, + trap_w, trap_h, comp_order, + apply_cm, apply_cm_arg, post_cm_num_comps, + 0); +} + +int gx_downscaler_init_trapped_cm_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps, + int ets) +{ + int size; + int post_size; int span; int width; int awidth; @@ -1675,11 +2141,15 @@ gx_downscale_core *core; int upfactor; int downfactor; - + int nc; + + size = gdev_mem_bytes_per_scan_line((gx_device *)dev); + post_size = bitmap_raster(dev->width * src_bpc * post_cm_num_comps); + decode_factor(factor, &upfactor, &downfactor); /* width = scaled width */ - width = (dev->width*upfactor)/downfactor; + width = (dev->width * upfactor)/downfactor; awidth = width; if (adjust_width_proc != NULL) awidth = (*adjust_width_proc)(width, adjust_width); @@ -1690,100 +2160,158 @@ /* size = unscaled size. span = unscaled size + padding */ span = size + pad_white*downfactor*num_comps/upfactor + downfactor-1; memset(ds, 0, sizeof(*ds)); - ds->dev = dev; - ds->width = width; - ds->awidth = awidth; - ds->span = span; - ds->factor = factor; - ds->num_planes = 0; - ds->src_bpc = src_bpc; - - /* Choose an appropriate core */ - if (factor > 8) + ds->dev = dev; + ds->width = width; + ds->awidth = awidth; + ds->span = span; + ds->factor = factor; + ds->num_planes = 0; + ds->src_bpc = src_bpc; + ds->apply_cm = apply_cm; + ds->apply_cm_arg = apply_cm_arg; + ds->early_cm = dst_bpc < src_bpc; + ds->post_cm_num_comps = post_cm_num_comps; + + code = check_trapping(dev->memory, trap_w, trap_h, num_comps, comp_order); + if (code < 0) + return code; + + if (trap_w > 0 || trap_h > 0) { + ds->claptrap = ClapTrap_Init(dev->memory, width, dev->height, num_comps, comp_order, trap_w, trap_h, get_line_for_trap, ds); + if (ds->claptrap == NULL) { + emprintf(dev->memory, "Trapping initialisation failed"); + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } + } else + ds->claptrap = NULL; + + /* Choose an appropriate core. Try to honour our early_cm + * choice, and fallback to late cm if we can't. */ + core = NULL; + while (1) { + nc = ds->early_cm ? post_cm_num_comps : num_comps; + + if (factor > 8) { + code = gs_note_error(gs_error_rangecheck); + goto cleanup; + } + else if ((src_bpc == 16) && (dst_bpc == 16) && (nc == 1)) + { + core = &down_core16; + } + else if ((src_bpc == 8) && (dst_bpc == 1) && (nc == 4)) + { + if (mfs > 1) + core = &down_core4_mfs; + else if (ets) + { + code = init_ets(ds, 4, core); + if (code) + goto cleanup; + core = &down_core4_ets; + } + else + core = &down_core4; + } + else if ((src_bpc == 8) && (dst_bpc == 1) && (nc == 1)) + { + if (mfs > 1) + core = &down_core_mfs; + else if (ets) + { + code = init_ets(ds, 1, core); + if (code) + goto cleanup; + core = &down_core_ets_1; + } + else if (factor == 4) + core = &down_core_4; + else if (factor == 3) + core = &down_core_3; + else if (factor == 2) + core = &down_core_2; + else if (factor == 1) + core = &down_core_1; + else + core = &down_core; + } + else if ((factor == 1) && (src_bpc == dst_bpc)) + break; + else if ((src_bpc == 8) && (dst_bpc == 8) && (nc == 1)) + { + if (factor == 4) + core = &down_core8_4; + else if (factor == 3) + core = &down_core8_3; + else if (factor == 2) + core = &down_core8_2; + else + core = &down_core8; + } + else if ((src_bpc == 8) && (dst_bpc == 8) && (nc == 3)) + core = &down_core24; + else if ((src_bpc == 8) && (dst_bpc == 8) && (nc == 4)) + core = &down_core32; + + /* If we found one, or we have nothing to fallback to, exit */ + if (core || !ds->early_cm) + break; + + /* Fallback */ + ds->early_cm = false; + } + if (factor == 1 && src_bpc == dst_bpc) { + /* core can permissibly be NULL */ + } else if (core == NULL) { code = gs_note_error(gs_error_rangecheck); goto cleanup; } - else if ((src_bpc == 16) && (dst_bpc == 16) && (num_comps == 1)) - { - core = &down_core16; - } - else if ((src_bpc == 8) && (dst_bpc == 1) && (num_comps == 4)) - { - if (mfs > 1) - core = &down_core4_mfs; - else - core = &down_core4; - } - else if ((src_bpc == 8) && (dst_bpc == 1) && (num_comps == 1)) - { - if (mfs > 1) - core = &down_core_mfs; - else if (factor == 4) - core = &down_core_4; - else if (factor == 3) - core = &down_core_3; - else if (factor == 2) - core = &down_core_2; - else if (factor == 1) - core = &down_core_1; - else - core = &down_core; - } - else if ((factor == 1) && (src_bpc == dst_bpc)) - core = NULL; - else if ((src_bpc == 8) && (dst_bpc == 8) && (num_comps == 1)) - { - if (factor == 4) - core = &down_core8_4; - else if (factor == 3) - core = &down_core8_3; - else if (factor == 2) - core = &down_core8_2; - else - core = &down_core8; + ds->down_core = core; + + if (apply_cm) { + ds->post_cm[0] = gs_alloc_bytes(dev->memory, + post_size * downfactor, + "gx_downscaler(data)"); + if (ds->post_cm[0] == NULL) { + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } } - else if ((src_bpc == 8) && (dst_bpc == 8) && (num_comps == 3)) - core = &down_core24; - else if ((src_bpc == 8) && (dst_bpc == 8) && (num_comps == 4)) - core = &down_core32; - else { - code = gs_note_error(gs_error_rangecheck); - goto cleanup; + + if (core != NULL || apply_cm) { + ds->pre_cm[0] = gs_alloc_bytes(dev->memory, + span * downfactor, + "gx_downscaler(data)"); + if (ds->pre_cm[0] == NULL) { + code = gs_note_error(gs_error_VMerror); + goto cleanup; + } } - ds->down_core = core; - if (core != NULL) { - ds->data = gs_alloc_bytes(dev->memory, - span * downfactor, - "gx_downscaler(data)"); - if (ds->data == NULL) - return_error(gs_error_VMerror); - if (mfs > 1) { ds->mfs_data = (byte *)gs_alloc_bytes(dev->memory, - awidth+1, + (awidth+1)*nc, "gx_downscaler(mfs)"); if (ds->mfs_data == NULL) { code = gs_note_error(gs_error_VMerror); goto cleanup; } - memset(ds->mfs_data, 0, awidth+1); + memset(ds->mfs_data, 0, (awidth+1)*nc); } - if (dst_bpc == 1) - { + if (dst_bpc == 1) { ds->errors = (int *)gs_alloc_bytes(dev->memory, num_comps*(awidth+3)*sizeof(int), "gx_downscaler(errors)"); - if (ds->errors == NULL) - { + if (ds->errors == NULL) { code = gs_note_error(gs_error_VMerror); goto cleanup; } memset(ds->errors, 0, num_comps * (awidth+3) * sizeof(int)); } } - + return 0; cleanup: @@ -1794,9 +2322,10 @@ void gx_downscaler_fin(gx_downscaler_t *ds) { int plane; - for (plane=0; plane < ds->num_planes; plane++) - { - gs_free_object(ds->dev->memory, ds->params.data[plane], + for (plane=0; plane < GS_CLIENT_COLOR_MAX_COMPONENTS; plane++) { + gs_free_object(ds->dev->memory, ds->pre_cm[plane], + "gx_downscaler(planar_data)"); + gs_free_object(ds->dev->memory, ds->post_cm[plane], "gx_downscaler(planar_data)"); } ds->num_planes = 0; @@ -1805,12 +2334,17 @@ ds->mfs_data = NULL; gs_free_object(ds->dev->memory, ds->errors, "gx_downscaler(errors)"); ds->errors = NULL; - gs_free_object(ds->dev->memory, ds->data, "gx_downscaler(data)"); - ds->data = NULL; gs_free_object(ds->dev->memory, ds->scaled_data, "gx_downscaler(scaled_data)"); ds->scaled_data = NULL; + + if (ds->claptrap) + ClapTrap_Fin(ds->dev->memory, ds->claptrap); + + if (ds->ets_config) + ets_destroy(ds->dev->memory, ds->ets_config); } +/* Chunky case */ int gx_downscaler_getbits(gx_downscaler_t *ds, byte *out_data, int row) @@ -1818,29 +2352,67 @@ int code = 0; int y, y_end; byte *data_ptr; + int upfactor, downfactor; + + decode_factor(ds->factor, &upfactor, &downfactor); /* Check for the simple case */ if (ds->down_core == NULL) { - return (*dev_proc(ds->dev, get_bits))(ds->dev, row, out_data, NULL); + if (ds->claptrap) + code = ClapTrap_GetLine(ds->claptrap, ds->apply_cm ? ds->pre_cm[0] : out_data); + else + code = (*dev_proc(ds->dev, get_bits))(ds->dev, row, ds->apply_cm ? ds->pre_cm[0] : out_data, NULL); + if (code < 0) + return code; + if (ds->apply_cm) { + data_ptr = out_data; + return ds->apply_cm(ds->apply_cm_arg, &data_ptr, ds->pre_cm, ds->width, 1, 0); + } + return 0; } /* Get factor rows worth of data */ - y = row * ds->factor; - y_end = y + ds->factor; - data_ptr = ds->data; - do { - code = (*dev_proc(ds->dev, get_bits))(ds->dev, y, data_ptr, NULL); - if (code < 0) - return code; - data_ptr += ds->span; - y++; - } while (y < y_end); - - (ds->down_core)(ds, out_data, ds->data, row, 0, ds->span); + y = row * downfactor; + y_end = y + downfactor; + data_ptr = ds->pre_cm[0]; + if (ds->claptrap) { + do { + code = ClapTrap_GetLine(ds->claptrap, data_ptr); + if (code < 0) + return code; + data_ptr += ds->span; + y++; + } while (y < y_end); + } else { + do { + code = (*dev_proc(ds->dev, get_bits))(ds->dev, y, data_ptr, NULL); + if (code < 0) + return code; + data_ptr += ds->span; + y++; + } while (y < y_end); + } + + if (ds->apply_cm) { + if (ds->early_cm) { + code = ds->apply_cm(ds->apply_cm_arg, ds->post_cm, ds->pre_cm, ds->dev->width, 1, 0); + if (code < 0) + return code; + (ds->down_core)(ds, out_data, ds->post_cm[0], row, 0, ds->span); + } else { + data_ptr = out_data; + (ds->down_core)(ds, ds->post_cm[0], ds->pre_cm[0], row, 0, ds->span); + code = ds->apply_cm(ds->apply_cm_arg, &out_data, ds->post_cm, ds->width, 1, 0); + if (code < 0) + return code; + } + } else + (ds->down_core)(ds, out_data, ds->pre_cm[0], row, 0, ds->span); return code; } +/* Planar case */ int gx_downscaler_get_bits_rectangle(gx_downscaler_t *ds, gs_get_bits_params_t *params, int row) @@ -1853,17 +2425,15 @@ int upfactor, downfactor; int subrow; int copy = (ds->dev->width * ds->src_bpc + 7)>>3; + int i, j; decode_factor(factor, &upfactor, &downfactor); subrow = row % upfactor; - if (subrow) - { + if (subrow) { /* Just copy a previous row from our stored buffer */ for (plane=0; plane < ds->num_planes; plane++) - { params->data[plane] = ds->scaled_data + (upfactor * plane + subrow) * ds->scaled_span; - } return 0; } @@ -1873,18 +2443,47 @@ rect.q.y = ((row/upfactor) + 1) * downfactor; /* Check for the simple case */ - if (ds->down_core == NULL) { - return (*dev_proc(ds->dev, get_bits_rectangle))(ds->dev, &rect, params, NULL); + if (ds->down_core == NULL && ds->claptrap == NULL) { + gs_get_bits_params_t saved; + if (ds->apply_cm) { + /* Always do the request giving our own workspace, + * and be prepared to accept a pointer */ + saved = *params; + for (i = 0; i < ds->num_planes; i++) + params->data[i] = ds->pre_cm[i]; + params->options |= GB_RETURN_POINTER; + } + code = (*dev_proc(ds->dev, get_bits_rectangle))(ds->dev, &rect, params, NULL); + if (code < 0) + return code; + if (ds->apply_cm) { + byte **buffer; + if (saved.options & GB_RETURN_COPY) { + /* They will accept a copy. Let's use the buffer they supplied */ + params->options &= ~GB_RETURN_POINTER; + buffer = saved.data; + } else + buffer = ds->pre_cm; + code = ds->apply_cm(ds->apply_cm_arg, params->data, buffer, ds->dev->width, rect.q.y - rect.p.y, params->raster); + if ((saved.options & GB_RETURN_COPY) == 0) + for (i = 0; i < ds->num_planes; i++) + params->data[i] = buffer[i]; + } + return code; } /* Copy the params, because get_bits_rectangle can helpfully overwrite * them. */ memcpy(¶ms2, &ds->params, sizeof(params2)); + for (i = 0; i < ds->num_planes; i++) + params2.data[i] = ds->pre_cm[i]; + /* Get downfactor rows worth of data */ - code = (*dev_proc(ds->dev, get_bits_rectangle))(ds->dev, &rect, ¶ms2, NULL); - if (code == gs_error_rangecheck) - { - int i, j; + if (ds->claptrap) + code = gs_error_rangecheck; /* Always work a line at a time with claptrap */ + else + code = (*dev_proc(ds->dev, get_bits_rectangle))(ds->dev, &rect, ¶ms2, NULL); + if (code == gs_error_rangecheck) { /* At the bottom of a band, the get_bits_rectangle call can fail to be * able to return us enough lines of data at the same time. We therefore * drop back to reading them one at a time, and copying them into our @@ -1894,67 +2493,471 @@ if (rect.q.y > ds->dev->height) break; memcpy(¶ms2, &ds->params, sizeof(params2)); - code = (*dev_proc(ds->dev, get_bits_rectangle))(ds->dev, &rect, ¶ms2, NULL); + for (j = 0; j < ds->num_planes; j++) + params2.data[j] = ds->pre_cm[j] + i * ds->span; + if (ds->claptrap) { + ds->claptrap_params = ¶ms2; + code = ClapTrap_GetLinePlanar(ds->claptrap, ¶ms2.data[0]); + } else { + /* We always want a copy */ + params2.options &= ~GB_RETURN_POINTER; + params2.options |= GB_RETURN_COPY; + code = (*dev_proc(ds->dev, get_bits_rectangle))(ds->dev, &rect, ¶ms2, NULL); + } if (code < 0) break; - for (j = 0; j < ds->num_planes; j++) { - memcpy(ds->params.data[j] + i*ds->span, params2.data[j], copy); - } rect.p.y++; } if (i == 0) return code; /* If we still haven't got enough, we've hit the end of the page; just * duplicate the last line we did get. */ - for (;i < downfactor; i++) { - for (j = 0; j < ds->num_planes; j++) { - memcpy(ds->params.data[j] + i*ds->span, ds->params.data[j] + (i-1)*ds->span, copy); - } - } - for (j = 0; j < ds->num_planes; j++) { - params2.data[j] = ds->params.data[j]; - } + for (;i < downfactor; i++) + for (j = 0; j < ds->num_planes; j++) + memcpy(ds->pre_cm[j] + i*ds->span, ds->pre_cm[j] + (i-1)*ds->span, copy); } if (code < 0) return code; - if (upfactor) - { + if (ds->early_cm && ds->apply_cm) { + code = ds->apply_cm(ds->apply_cm_arg, ds->params.data, ds->post_cm, ds->dev->width, downfactor, params->raster); + if (code < 0) + return code; + for (j = 0; j < ds->num_planes; j++) + params2.data[j] = ds->post_cm[j]; + } + + if (upfactor > 1) { /* Downscale the block of lines into our output buffer */ - for (plane=0; plane < ds->num_planes; plane++) - { + for (plane=0; plane < ds->num_planes; plane++) { byte *scaled = ds->scaled_data + upfactor * plane * ds->scaled_span; (ds->down_core)(ds, scaled, params2.data[plane], row, plane, params2.raster); params->data[plane] = scaled; } - } - else - { + } else if (ds->down_core != NULL) { /* Downscale direct into output buffer */ for (plane=0; plane < ds->num_planes; plane++) - { (ds->down_core)(ds, params->data[plane], params2.data[plane], row, plane, params2.raster); + } else { + /* Copy into output buffer */ + /* No color management can be required here */ + assert(!ds->early_cm || ds->apply_cm == NULL); + for (plane=0; plane < ds->num_planes; plane++) + memcpy(params->data[plane], params2.data[plane], params2.raster); + } + + if (!ds->early_cm && ds->apply_cm) { + code = ds->apply_cm(ds->apply_cm_arg, ds->params.data, params2.data, ds->width, 1, params->raster); + if (code < 0) + return code; + } + + return code; +} + +typedef struct downscaler_process_page_arg_s +{ + gx_process_page_options_t *orig_options; + int upfactor; + int downfactor; + gx_downscaler_t ds; +} +downscaler_process_page_arg_t; + +typedef struct downscaler_process_page_buffer_s +{ + gx_device *bdev; + void *orig_buffer; +} +downscaler_process_page_buffer_t; + +static int downscaler_init_fn(void *arg_, gx_device *dev, gs_memory_t *memory, int w, int h, void **pbuffer) +{ + downscaler_process_page_arg_t *arg = (downscaler_process_page_arg_t *)arg_; + downscaler_process_page_buffer_t *buffer; + int code = 0; + + buffer = (downscaler_process_page_buffer_t *)gs_alloc_bytes(memory, sizeof(*buffer), "downscaler process_page buffer"); + if (buffer == NULL) + return_error(gs_error_VMerror); + memset(buffer, 0, sizeof(*buffer)); + + if (arg->upfactor > arg->downfactor) { + code = gx_default_create_buf_device(&buffer->bdev, dev, + (h*arg->upfactor + arg->downfactor-1)/arg->downfactor, + NULL, memory, NULL); + if (code < 0) { + gs_free_object(memory, buffer, "downscaler process_page buffer"); + return code; } } + if (arg->orig_options && arg->orig_options->init_buffer_fn) { + code = arg->orig_options->init_buffer_fn(arg->orig_options->arg, dev, memory, + (w * arg->upfactor + arg->downfactor-1)/arg->downfactor, + (h * arg->upfactor + arg->downfactor-1)/arg->downfactor, + &buffer->orig_buffer); + if (code < 0) { + if (buffer->bdev) + dev_proc(dev, close_device)(dev); + gs_free_object(memory, buffer, "downscaler process_page buffer"); + return code; + } + } + + *pbuffer = (void *)buffer; return code; } -int -gx_downscaler_copy_scan_lines(gx_downscaler_t *ds, int y, - byte * str, uint size) +static int downscaler_process_fn(void *arg_, gx_device *dev, gx_device *bdev, const gs_int_rect *rect, void *buffer_) { - uint line_size = gx_device_raster(ds->dev, 0); - int count = size / line_size; - int i; - int height = ds->dev->height/ds->factor; - byte *dest = str; + downscaler_process_page_arg_t *arg = (downscaler_process_page_arg_t *)arg_; + downscaler_process_page_buffer_t *buffer = (downscaler_process_page_buffer_t *)buffer_; + int code, raster_in, raster_out; + gs_get_bits_params_t params; + gs_int_rect in_rect, out_rect; + byte *in_ptr, *out_ptr; + + in_rect.p.x = 0; + in_rect.p.y = 0; + in_rect.q.x = rect->q.x - rect->p.x; + in_rect.q.y = rect->q.y - rect->p.y; + out_rect.p.x = 0; + out_rect.p.y = 0; + out_rect.q.x = (in_rect.q.x * arg->upfactor + arg->downfactor-1) / arg->downfactor; + out_rect.q.y = (in_rect.q.y * arg->upfactor + arg->downfactor-1) / arg->downfactor; + + /* Where do we get the data from? */ + params.options = GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_PACKING_CHUNKY | GB_RETURN_POINTER | GB_ALIGN_ANY | GB_OFFSET_0 | GB_RASTER_ANY; + code = dev_proc(bdev, get_bits_rectangle)(bdev, &in_rect, ¶ms, NULL); + if (code < 0) + return code; + raster_in = params.raster; + in_ptr = params.data[0]; - count = min(count, height - y); - for (i = 0; i < count; i++, dest += line_size) { - int code = gx_downscaler_getbits(ds, dest, y+i); + /* Where do we write it to? */ + if (buffer->bdev) { + code = dev_proc(bdev, get_bits_rectangle)(buffer->bdev, &out_rect, ¶ms, NULL); if (code < 0) return code; + raster_out = params.raster; + out_ptr = params.data[0]; + } else { + raster_out = raster_in; + out_ptr = params.data[0]; + } + + /* Do the downscale */ + if (arg->ds.down_core) { + int y; + for (y = rect->p.y; y < rect->q.y; y += arg->downfactor) + { + arg->ds.down_core(&arg->ds, out_ptr, in_ptr, y, 0, arg->ds.span); + in_ptr += arg->ds.span * arg->downfactor; + out_ptr += raster_out * arg->upfactor; + } + } + + /* Pass on to further processing */ + if (code >= 0 && arg->orig_options && arg->orig_options->process_fn) { + out_rect.p.y = rect->p.y*arg->upfactor/arg->downfactor; + out_rect.q.y += out_rect.p.y; + code = arg->orig_options->process_fn(arg->orig_options->arg, dev, + (buffer->bdev ? buffer->bdev : bdev), + &out_rect, buffer->orig_buffer); + } + return code; +} + +static void +downscaler_free_fn(void *arg_, gx_device *dev, gs_memory_t *memory, void *buffer_) +{ + downscaler_process_page_arg_t *arg = (downscaler_process_page_arg_t *)arg_; + downscaler_process_page_buffer_t *buffer = (downscaler_process_page_buffer_t *)buffer_; + + arg->orig_options->free_buffer_fn(arg->orig_options->arg, dev, memory, + buffer->orig_buffer); + if (buffer->bdev) + dev_proc(dev, close_device)(dev); + gs_free_object(memory, buffer, "downscaler process_page buffer"); +} + +static int +downscaler_output_fn(void *arg_, gx_device *dev, void *buffer_) +{ + downscaler_process_page_arg_t *arg = (downscaler_process_page_arg_t *)arg_; + downscaler_process_page_buffer_t *buffer = (downscaler_process_page_buffer_t *)buffer_; + + return arg->orig_options->output_fn(arg->orig_options->arg, dev, + buffer->orig_buffer); +} + +/* No error diffusion with process_page as bands need to be handled + * separately. */ +int gx_downscaler_process_page(gx_device *dev, + gx_process_page_options_t *options, + int factor) +{ + downscaler_process_page_arg_t arg = { 0 }; + gx_process_page_options_t my_options = { 0 }; + int num_comps = dev->color_info.num_components; + int src_bpc = dev->color_info.comp_bits[0]; + int scaled_w; + gx_downscale_core *core; + + arg.orig_options = options; + decode_factor(factor, &arg.upfactor, &arg.downfactor); + arg.ds.dev = dev; + arg.ds.width = (dev->width * arg.upfactor + arg.downfactor-1)/arg.downfactor; + arg.ds.awidth = arg.ds.width; + arg.ds.span = bitmap_raster(dev->width * num_comps * src_bpc); + scaled_w = (dev->width * arg.upfactor + arg.downfactor-1)/arg.downfactor; + arg.ds.factor = factor; + arg.ds.src_bpc = src_bpc; + arg.ds.scaled_span = bitmap_raster(scaled_w * num_comps * src_bpc); + arg.ds.num_planes = 0; + + /* Choose an appropriate core */ + if (factor > 8) + { + return gs_note_error(gs_error_rangecheck); + } + else if ((src_bpc == 16) && (num_comps == 1)) + { + core = &down_core16; + } + else if (factor == 1) + core = NULL; + else if ((src_bpc == 8) && (num_comps == 1)) + { + if (factor == 4) + core = &down_core8_4; + else if (factor == 3) + core = &down_core8_3; + else if (factor == 2) + core = &down_core8_2; + else + core = &down_core8; + } + else if ((src_bpc == 8) && (num_comps == 3)) + core = &down_core24; + else if ((src_bpc == 8) && (num_comps == 4)) + core = &down_core32; + else { + return gs_note_error(gs_error_rangecheck); + } + arg.ds.down_core = core; + + my_options.init_buffer_fn = downscaler_init_fn; + my_options.process_fn = downscaler_process_fn; + my_options.output_fn = downscaler_output_fn; + my_options.free_buffer_fn = downscaler_free_fn; + my_options.arg = &arg; + + return dev_proc(dev, process_page)(dev, &my_options); +} + +int gx_downscaler_read_params(gs_param_list *plist, + gx_downscaler_params *params, + int features) +{ + int code; + int downscale, mfs, ets; + int trap_w, trap_h; + const char *param_name; + gs_param_int_array trap_order; + + trap_order.data = NULL; + + switch (code = param_read_int(plist, + (param_name = "DownScaleFactor"), + &downscale)) { + case 1: + break; + case 0: + if (downscale >= 1) { + params->downscale_factor = downscale; + break; + } + code = gs_error_rangecheck; + default: + param_signal_error(plist, param_name, code); + return code; + } + + if (features & GX_DOWNSCALER_PARAMS_MFS) + { + switch (code = param_read_int(plist, (param_name = "MinFeatureSize"), &mfs)) { + case 1: + break; + case 0: + if ((mfs >= 0) && (mfs <= 4)) { + params->min_feature_size = mfs; + break; + } + code = gs_error_rangecheck; + default: + param_signal_error(plist, param_name, code); + return code; + } + } + + if (features & GX_DOWNSCALER_PARAMS_TRAP) + { + switch (code = param_read_int(plist, + (param_name = "TrapX"), + &trap_w)) { + case 1: + break; + case 0: + if (trap_w >= 0) + { + params->trap_w = trap_w; + break; + } + code = gs_error_rangecheck; + default: + param_signal_error(plist, param_name, code); + return code; + } + switch (code = param_read_int(plist, + (param_name = "TrapY"), + &trap_h)) { + case 1: + break; + case 0: + if (trap_h >= 0) + { + params->trap_h = trap_h; + break; + } + code = gs_error_rangecheck; + default: + param_signal_error(plist, param_name, code); + return code; + } + switch (code = param_read_int_array(plist, (param_name = "TrapOrder"), &trap_order)) { + case 0: + break; + case 1: + trap_order.data = 0; /* mark as not filled */ + break; + default: + param_signal_error(plist, param_name, code); + return code; + } + + if (trap_order.data != NULL) + { + int i; + int n = trap_order.size; + + if (n > GS_CLIENT_COLOR_MAX_COMPONENTS) + n = GS_CLIENT_COLOR_MAX_COMPONENTS; + + for (i = 0; i < n; i++) + { + params->trap_order[i] = trap_order.data[i]; + } + for (; i < GS_CLIENT_COLOR_MAX_COMPONENTS; i++) + { + params->trap_order[i] = i; + } + } + else + { + /* Set some sane defaults */ + int i; + + params->trap_order[0] = 3; /* K */ + params->trap_order[1] = 1; /* M */ + params->trap_order[2] = 0; /* C */ + params->trap_order[3] = 2; /* Y */ + + for (i = 4; i < GS_CLIENT_COLOR_MAX_COMPONENTS; i++) + { + params->trap_order[i] = i; + } + } } - return count; + if (features & GX_DOWNSCALER_PARAMS_ETS) + { + switch (code = param_read_int(plist, + (param_name = "DownScaleETS"), + &ets)) { + case 1: + break; + case 0: + if (ets >= 0) + { + params->ets = ets; + break; + } + code = gs_error_rangecheck; + default: + param_signal_error(plist, param_name, code); + return code; + } + } + + return 0; +} + +int gx_downscaler_write_params(gs_param_list *plist, + gx_downscaler_params *params, + int features) +{ + int code; + int ecode = 0; + gs_param_int_array trap_order; + + trap_order.data = params->trap_order; + trap_order.size = GS_CLIENT_COLOR_MAX_COMPONENTS; + trap_order.persistent = false; + + if ((code = param_write_int(plist, "DownScaleFactor", ¶ms->downscale_factor)) < 0) + ecode = code; + if (features & GX_DOWNSCALER_PARAMS_MFS) + { + if ((code = param_write_int(plist, "MinFeatureSize", ¶ms->min_feature_size)) < 0) + ecode = code; + } + if (features & GX_DOWNSCALER_PARAMS_TRAP) + { + if ((code = param_write_int(plist, "TrapX", ¶ms->trap_w)) < 0) + ecode = code; + if ((code = param_write_int(plist, "TrapY", ¶ms->trap_h)) < 0) + ecode = code; + if ((code = param_write_int_array(plist, "TrapOrder", &trap_order)) < 0) + ecode = code; + } + if (features & GX_DOWNSCALER_PARAMS_ETS) + { + if ((code = param_write_int(plist, "DownScaleETS", ¶ms->ets)) < 0) + ecode = code; + } + + return ecode; +} + +/* ETS relies on some malloc wrappers */ +void *ets_malloc(void *malloc_arg, int size) +{ + return gs_alloc_bytes((gs_memory_t *)malloc_arg, size, "ets_malloc"); +} + +void *ets_calloc(void *malloc_arg, int count, int size) +{ + void *p = ets_malloc(malloc_arg, count * size); + if (p) + memset(p, 0, count * size); + return p; +} + +void ets_free(void *malloc_arg, void *p) +{ + if (!p) + return; + + gs_free_object((gs_memory_t *)malloc_arg, p, "ets_malloc"); } diff -Nru ghostscript-9.10~dfsg/base/gxdownscale.h ghostscript-9.25~dfsg+1/base/gxdownscale.h --- ghostscript-9.10~dfsg/base/gxdownscale.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdownscale.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,6 +23,27 @@ #include "gxdevcli.h" #include "gxgetbit.h" +#include "claptrap.h" + +/* Function to apply color management to a rectangle of data. + * + * dst/src point to arrays of pointers, 1 per component. + * In the chunky case, only the first pointer is valid. + * In the planar case, with n planes, the first n pointers + * are valid. + * w and h are the width and height of the rectangle of + * data to be processed. + * raster is the number of bytes to offset from the start + * of one line to the next. This value should be ignored + * in chunky cases. + */ +typedef int (gx_downscale_cm_fn)(void *arg, + byte **dst, + byte **src, + int w, + int h, + int raster); + /* The following structure definitions should really be considered * private, and are exposed here only because it enables us to define * gx_downscaler_t's on the stack, thus avoiding mallocs. @@ -30,6 +51,7 @@ typedef struct gx_downscaler_s gx_downscaler_t; +/* Private function type for the core downscaler routines */ typedef void (gx_downscale_core)(gx_downscaler_t *ds, byte *out_buffer, byte *in_buffer, @@ -46,13 +68,27 @@ byte *mfs_data; /* MinFeatureSize data */ int src_bpc; /* Source bpc */ int *errors; /* Error diffusion table */ - byte *data; /* Downscaling buffer */ byte *scaled_data;/* Downscaled data (only used for non * integer downscales). */ int scaled_span;/* Num bytes in scaled scanline */ gx_downscale_core *down_core; /* Core downscaling function */ gs_get_bits_params_t params; /* Params if in planar mode */ int num_planes; /* Number of planes if planar, 0 otherwise */ + + ClapTrap *claptrap; /* ClapTrap pointer (if trapping) */ + int claptrap_y; /* y pointer (if trapping) */ + gs_get_bits_params_t *claptrap_params; /* params (if trapping) */ + + int early_cm; + gx_downscale_cm_fn *apply_cm; + void *apply_cm_arg; + int post_cm_num_comps; + + void *ets_config; + gx_downscale_core *ets_downscale; + + byte *pre_cm[GS_CLIENT_COLOR_MAX_COMPONENTS]; + byte *post_cm[GS_CLIENT_COLOR_MAX_COMPONENTS]; }; /* To use the downscaler: @@ -87,6 +123,104 @@ int (*adjust_width_proc)(int, int), int adjust_width); +int gx_downscaler_init_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int ets); + +int gx_downscaler_init_trapped(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order); + +int gx_downscaler_init_trapped_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order, + int ets); + +int gx_downscaler_init_cm(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps); + +int gx_downscaler_init_cm_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps, + int ets); + +int gx_downscaler_init_trapped_cm(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps); + +int gx_downscaler_init_trapped_cm_ets(gx_downscaler_t *ds, + gx_device *dev, + int src_bpc, + int dst_bpc, + int num_comps, + int factor, + int mfs, + int (*adjust_width_proc)(int, int), + int adjust_width, + int trap_w, + int trap_h, + const int *comp_order, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps, + int ets); + int gx_downscaler_init_planar(gx_downscaler_t *ds, gx_device *dev, gs_get_bits_params_t *params, @@ -96,6 +230,45 @@ int src_bpc, int dst_bpc); +int gx_downscaler_init_planar_trapped(gx_downscaler_t *ds, + gx_device *dev, + gs_get_bits_params_t *params, + int num_comps, + int factor, + int mfs, + int src_bpc, + int dst_bpc, + int trap_w, + int trap_h, + const int *comp_order); + +int gx_downscaler_init_planar_cm(gx_downscaler_t *ds, + gx_device *dev, + gs_get_bits_params_t *params, + int num_comps, + int factor, + int mfs, + int src_bpc, + int dst_bpc, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps); + +int gx_downscaler_init_planar_trapped_cm(gx_downscaler_t *ds, + gx_device *dev, + gs_get_bits_params_t *params, + int num_comps, + int factor, + int mfs, + int src_bpc, + int dst_bpc, + int trap_w, + int trap_h, + const int *comp_order, + gx_downscale_cm_fn *apply_cm, + void *apply_cm_arg, + int post_cm_num_comps); + int gx_downscaler_getbits(gx_downscaler_t *ds, byte *out_data, int row); @@ -108,13 +281,49 @@ * fin several times) */ void gx_downscaler_fin(gx_downscaler_t *ds); -/* A deliberate analogue to gdev_prn_copy_scan_lines, which despite being - * deprecated is still massively popular. */ int -gx_downscaler_copy_scan_lines(gx_downscaler_t *ds, int y, - byte *str, uint size); +gx_downscaler_scale(int width, int factor); int -gx_downscaler_scale(int width, int factor); +gx_downscaler_scale_rounded(int width, int factor); + +int gx_downscaler_adjust_bandheight(int factor, int band_height); + +/* Downscaling call to the process_page (downscaler also works on the + * rendering threads and chains calls through to supplied options functions). + */ +int gx_downscaler_process_page(gx_device *dev, + gx_process_page_options_t *options, + int factor); + +/* The following structure is used to hold the configuration + * parameters for the downscaler. + */ +typedef struct gx_downscaler_params_s +{ + int downscale_factor; + int min_feature_size; + int trap_w; + int trap_h; + int trap_order[GS_CLIENT_COLOR_MAX_COMPONENTS]; + int ets; +} gx_downscaler_params; + +#define GX_DOWNSCALER_PARAMS_DEFAULTS \ +{ 1, 0, 0, 0, { 3, 1, 0, 2 } } + +enum { + GX_DOWNSCALER_PARAMS_MFS = 1, + GX_DOWNSCALER_PARAMS_TRAP = 2, + GX_DOWNSCALER_PARAMS_ETS = 4 +}; + +int gx_downscaler_read_params(gs_param_list *plist, + gx_downscaler_params *params, + int features); + +int gx_downscaler_write_params(gs_param_list *plist, + gx_downscaler_params *params, + int features); #endif diff -Nru ghostscript-9.10~dfsg/base/gxdtfill.h ghostscript-9.25~dfsg+1/base/gxdtfill.h --- ghostscript-9.10~dfsg/base/gxdtfill.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxdtfill.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -143,7 +143,9 @@ const int iy1 = fixed2int_var(ymax); trap_line l, r; register int rxl, rxr; +#if !LINEAR_COLOR int ry; +#endif const fixed x0l = left->start.x, x1l = left->end.x, x0r = right->start.x, x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r; @@ -181,7 +183,9 @@ r.h = right->end.y - right->start.y; l.x = x0l + (fixed_half - fixed_epsilon); r.x = x0r + (fixed_half - fixed_epsilon); +#if !LINEAR_COLOR ry = iy; +#endif /* * Free variables of FILL_TRAP_RECT: @@ -204,11 +208,6 @@ (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h)) #endif -#define VD_RECT_SWAPPED(rxl, ry, rxr, iy)\ - vd_rect(int2fixed(SWAP_AXES ? ry : rxl), int2fixed(SWAP_AXES ? rxl : ry),\ - int2fixed(SWAP_AXES ? iy : rxr), int2fixed(SWAP_AXES ? rxr : iy),\ - 1, VD_RECT_COLOR); - /* Compute the dx/dy ratios. */ /* @@ -244,7 +243,6 @@ #define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill)\ if (adj1 < adj2) {\ if (iy - ry > 1) {\ - VD_RECT_SWAPPED(rxl, ry, rxr, iy - 1);\ code = fill(rxl, ry, rxr - rxl, iy - ry - 1);\ if (code < 0)\ goto xit;\ @@ -274,7 +272,6 @@ rxl = fixed2int_var(l.x); rxr = fixed2int_var(r.x); SET_MINIMAL_WIDTH(rxl, rxr, l, r); - VD_RECT_SWAPPED(rxl, ry, rxr, iy1); code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry); goto xit; } @@ -307,7 +304,7 @@ r.x += fixed_epsilon; # if LINEAR_COLOR # ifdef DEBUG - if (check_gradient_overflow(left, right, num_components)) { + if (check_gradient_overflow(left, right)) { /* The caller must care of. Checking it here looses some performance with triangles. */ return_error(gs_error_unregistered); @@ -347,7 +344,6 @@ code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components); if (code < 0) goto xit; - /*VD_RECT_SWAPPED(rxl, iy, rxr, iy + 1);*/ code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1); if (code < 0) goto xit; @@ -367,7 +363,6 @@ if (ixl != rxl || ixr != rxr) { CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT); CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT); - VD_RECT_SWAPPED(rxl, ry, rxr, iy); code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); if (code < 0) goto xit; @@ -376,7 +371,6 @@ # endif } # if !LINEAR_COLOR - VD_RECT_SWAPPED(rxl, ry, rxr, iy); code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); # else code = 0; @@ -388,7 +382,6 @@ #undef FILL_TRAP_RECT_DIRECT #undef FILL_TRAP_RECT_INRECT #undef YMULT_QUO -#undef VD_RECT_SWAPPED xit: if (code < 0 && FILL_DIRECT) return_error(code); return_if_interrupt(dev->memory); diff -Nru ghostscript-9.10~dfsg/base/gxfapi.c ghostscript-9.25~dfsg+1/base/gxfapi.c --- ghostscript-9.10~dfsg/base/gxfapi.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfapi.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -7,8 +7,8 @@ This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of that license. Refer to licensing information at http://www.artifex.com/ - or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, - San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,6 +32,7 @@ #include "gdebug.h" #include "gsimage.h" #include "gsbittab.h" +#include "gzpath.h" #include "gxfapi.h" @@ -230,7 +231,7 @@ * we know the character is well-behaved, i.e., is not defined by an * arbitrary PostScript procedure. */ -static bool +static inline bool fapi_gs_char_show_width_only(const gs_text_enum_t *penum) { if (!gs_text_is_width_only(penum)) @@ -255,14 +256,43 @@ * transparency is involved - if so, we have to produce * a path outline, and not a bitmap. */ -static bool -using_transparency_pattern(gs_state *pgs) +static inline bool +using_transparency_pattern(gs_gstate *pgs) { gx_device *dev = gs_currentdevice_inline(pgs); return ((!gs_color_writes_pure(pgs)) - && dev->procs.begin_transparency_group != NULL - && dev->procs.end_transparency_group != NULL); + && dev_proc(dev, begin_transparency_group) != gx_default_begin_transparency_group + && dev_proc(dev, end_transparency_group) != gx_default_end_transparency_group); +} + +static inline bool +recreate_multiple_master(gs_font_base *pbfont) +{ + bool r = false; + gs_fapi_server *I = pbfont->FAPI; + bool changed = false; + + if (I && I->face.font_id != gs_no_id && + (pbfont->FontType == ft_encrypted + || pbfont->FontType == ft_encrypted2)) { + gs_font_type1 *pfont1 = (gs_font_type1 *) pbfont; + if (I->face.WeightVector.count != pfont1->data.WeightVector.count) { + changed = true; + } + else { + changed = (memcmp(I->face.WeightVector.values, pfont1->data.WeightVector.values, + pfont1->data.WeightVector.count * sizeof(pfont1->data.WeightVector.values[0])) != 0); + } + + if (changed) { + r = (I->set_mm_weight_vector(I, &I->ff, pfont1->data.WeightVector.values, pfont1->data.WeightVector.count) == gs_error_invalidaccess); + I->face.WeightVector.count = pfont1->data.WeightVector.count; + memcpy(I->face.WeightVector.values, pfont1->data.WeightVector.values, + pfont1->data.WeightVector.count * sizeof(pfont1->data.WeightVector.values[0])); + } + } + return r; } static bool @@ -270,7 +300,7 @@ gs_font_base *pbfont, int abits, gs_log2_scale_point *log2_scale) { - gs_state *pgs = (gs_state *) penum_s->pis; + gs_gstate *pgs = (gs_gstate *) penum_s->pgs; log2_scale->x = 0; log2_scale->y = 0; @@ -286,7 +316,7 @@ return (pgs->in_charpath || pbfont->PaintType != 0 || (pgs->in_cachedevice != CACHE_DEVICE_CACHING - && using_transparency_pattern((gs_state *) penum_s->pis)) + && using_transparency_pattern((gs_gstate *) penum_s->pgs)) || (pgs->in_cachedevice != CACHE_DEVICE_CACHING && (log2_scale->x > 0 || log2_scale->y > 0)) || (pgs->in_cachedevice != CACHE_DEVICE_CACHING && abits > 1)); @@ -345,16 +375,18 @@ gs_font_base *pbfont = (gs_font_base *)pfont; int code, bbox_set = 0; int BBox[4], scale; - double size, size1; + int units[2]; + double size; gs_fapi_font_scale font_scale = { {1, 0, 0, 1, 0, 0}, {0, 0}, {1, 1}, true }; scale = 1 << I->frac_shift; - size1 = size = 1 / hypot(pbfont->FontMatrix.xx, pbfont->FontMatrix.xy); + size = 1 / hypot(pbfont->FontMatrix.xx, pbfont->FontMatrix.xy); + /* I believe this is just to ensure minimal rounding problems with scalers that + scale the FontBBox values with the font scale. + */ if (size < 1000) size = 1000; - if (size1 > 100) - size1 = (int)(size1 + 0.5); font_scale.matrix[0] = font_scale.matrix[3] = (int)(size * scale + 0.5); @@ -399,15 +431,15 @@ if ((code = gs_fapi_renderer_retcode(mem, I, I->get_font_bbox(I, &I->ff, - BBox))) < 0) { + BBox, units))) < 0) { gs_fapi_release_typeface(I, &pbfont->FAPI_font_data); return code; } /* Refine FontBBox : */ - pbfont->FontBBox.p.x = (double)BBox[0] * size1 / size; - pbfont->FontBBox.p.y = (double)BBox[1] * size1 / size; - pbfont->FontBBox.q.x = (double)BBox[2] * size1 / size; - pbfont->FontBBox.q.y = (double)BBox[3] * size1 / size; + pbfont->FontBBox.p.x = ((double)BBox[0] / units[0]); + pbfont->FontBBox.p.y = ((double)BBox[1] / units[1]); + pbfont->FontBBox.q.x = ((double)BBox[2] / units[0]); + pbfont->FontBBox.q.y = ((double)BBox[3] / units[1]); bbox_set = 1; } @@ -435,6 +467,7 @@ for (i = 0; i < n; i++) { gs_font_type1 *pbfont1 = FDArray[i]; int BBox_temp[4]; + int units_temp[2]; pbfont1->FontBBox = pbfont->FontBBox; /* Inherit FontBBox from the type 9 font. */ @@ -462,9 +495,14 @@ if ((code = gs_fapi_renderer_retcode(mem, I, I->get_font_bbox(I, &I->ff, - BBox_temp))) < 0) { + BBox_temp, units_temp))) < 0) { break; } + code = gs_notify_register(&pbfont1->notify_list, notify_remove_font, pbfont1); + if (code < 0) { + emprintf(mem, + "Ignoring gs_notify_register() failure for FAPI font....."); + } } if (i == n) { code = @@ -508,8 +546,8 @@ code = gs_notify_register(&pbfont->notify_list, notify_remove_font, pbfont); if (code < 0) { - emprintf(mem, - "Ignoring gs_notify_register() failure for FAPI font....."); + gs_fapi_release_typeface(I, &pbfont->FAPI_font_data); + return code; } return bbox_set; @@ -523,17 +561,17 @@ gs_fapi_path path_interface = path_interface_stub; gs_fapi_outline_handler olh; int code; - gs_state *pgs; + gs_gstate *pgs; extern_st(st_gs_show_enum); - extern_st(st_gs_state); + extern_st(st_gs_gstate); if (gs_object_type(penum_s->memory, penum_s) == &st_gs_show_enum) { pgs = penum_s->pgs; } else { - if (gs_object_type(penum_s->memory, penum_s->pis) == &st_gs_state) { - pgs = (gs_state *) penum_s->pis; + if (gs_object_type(penum_s->memory, penum_s->pgs) == &st_gs_gstate) { + pgs = (gs_gstate *) penum_s->pgs; } else /* No graphics state, give up... */ @@ -568,12 +606,11 @@ double *em_scale_y) { /* optimize : move this stuff to FAPI_refine_font */ gs_matrix mat; - gs_matrix *m = &pbfont->base->orig_FontMatrix; + gs_matrix *m = &mat; int rounding_x, rounding_y; /* Striking out the 'float' representation error in FontMatrix. */ double sx, sy; gs_fapi_server *I = pbfont->FAPI; - m = &mat; #if 1 I->get_fontmatrix(I, m); #else @@ -610,8 +647,10 @@ if (p == NULL) return_error(gs_error_VMerror); pe = p + rast->height * line_step; - for (; q < pe; q += line_step, r += rast->line_step) + for (; q < pe; q += line_step, r += rast->line_step) { memcpy(q, r, rast->line_step); + memset(q + rast->line_step, 0, line_step - rast->line_step); + } code = dev_proc(dev1, copy_mono) (dev1, p, 0, line_step, 0, dx, dy, rast->width, rast->height, 0, 1); @@ -641,7 +680,7 @@ bits_merge(byte *dest, const byte *src, uint nbytes) { long *dp = (long *)dest; const long *sp = (const long *)src; - uint n = (nbytes + sizeof(long) - 1) >> arch_log2_sizeof_long; + uint n = (nbytes + sizeof(long) - 1) >> ARCH_LOG2_SIZEOF_LONG; for ( ; n >= 4; sp += 4, dp += 4, n -= 4 ) dp[0] |= sp[0], dp[1] |= sp[1], dp[2] |= sp[2], dp[3] |= sp[3]; @@ -694,7 +733,7 @@ break; *dp++ = 0xff; bits_on += 8 - - byte_count_bits[(*zp & (zmask - 1)) + (zp[1] & -zmask)]; + byte_count_bits[(*zp & (zmask - 1)) + (zp[1] & -(int)zmask)]; ++zp; i += 8; goto on; @@ -743,11 +782,11 @@ * validation, or fapi_image_uncached_glyph() must be changed to include the validation. */ static int -fapi_image_uncached_glyph(gs_font *pfont, gs_state *pgs, gs_show_enum *penum, +fapi_image_uncached_glyph(gs_font *pfont, gs_gstate *pgs, gs_show_enum *penum, gs_fapi_raster *rast, const int import_shift_v) { gx_device *dev = penum->dev; - gs_state *penum_pgs = (gs_state *) penum->pis; + gs_gstate *penum_pgs = (gs_gstate *) penum->pgs; int code; const gx_clip_path *pcpath = pgs->clip_path; const gx_drawing_color *pdcolor = penum->pdcolor; @@ -763,6 +802,9 @@ int h, padbytes, cpbytes, dstr = bitmap_raster(rast->width); int sstr = rast->line_step; + double dx = penum_pgs->ctm.tx + (double)rast_orig_x / (1 << frac_pixel_shift) + 0.5; + double dy = penum_pgs->ctm.ty + (double)rast_orig_y / (1 << frac_pixel_shift) + 0.5; + /* we can only safely use the gx_image_fill_masked() "shortcut" if we're drawing * a "simple" colour, rather than a pattern. */ @@ -809,30 +851,22 @@ } if (gs_object_type(penum->memory, penum) == &st_gs_show_enum) { - code = gx_image_fill_masked(dev, r, 0, dstr, 0, - (int)(penum_pgs->ctm.tx + - (double)rast_orig_x / - (1 << frac_pixel_shift) + - penum->fapi_glyph_shift.x + - 0.5), - (int)(penum_pgs->ctm.ty + - (double)rast_orig_y / - (1 << frac_pixel_shift) + - penum->fapi_glyph_shift.y + - 0.5), rast->width, rast->height, - pdcolor, 1, rop3_default, pcpath); - } - else { - code = gx_image_fill_masked(dev, r, 0, dstr, 0, - (int)(penum_pgs->ctm.tx + - (double)rast_orig_x / - (1 << frac_pixel_shift) + 0.5), - (int)(penum_pgs->ctm.ty + - (double)rast_orig_y / - (1 << frac_pixel_shift) + 0.5), - rast->width, rast->height, pdcolor, 1, - rop3_default, pcpath); + dx += penum->fapi_glyph_shift.x; + dy += penum->fapi_glyph_shift.y; } + /* Processing an image object operation, but this may be for a text object */ + ensure_tag_is_set(pgs, pgs->device, GS_TEXT_TAG); /* NB: may unset_dev_color */ + code = gx_set_dev_color(pgs); + if (code != 0) + return code; + code = gs_gstate_color_load(pgs); + if (code < 0) + return code; + + code = gx_image_fill_masked(dev, r, 0, dstr, gx_no_bitmap_id, + (int)dx, (int)dy, + rast->width, rast->height, + pdcolor, 1, rop3_default, pcpath); if (rast->p != r) { gs_free_object(penum->memory, r, "fapi_finish_render_aux"); } @@ -844,7 +878,9 @@ int iy, nbytes; uint used; int code1; - int x, y, w, h; + int w, h; + int x = (int)dx; + int y = (int)dy; uint bold = 0; byte *bold_lines = NULL; byte *line = NULL; @@ -855,10 +891,6 @@ return_error(gs_error_VMerror); } - x = (int)(penum_pgs->ctm.tx + - (double)rast_orig_x / (1 << frac_pixel_shift) + 0.5); - y = (int)(penum_pgs->ctm.ty + - (double)rast_orig_y / (1 << frac_pixel_shift) + 0.5); w = rast->width; h = rast->height; if (I->ff.embolden != 0.0) { @@ -880,12 +912,12 @@ /* Make a matrix that will place the image */ /* at (x,y) with no transformation. */ gs_image_t_init_mask(&image, true); - gs_make_translation((floatp) - x, (floatp) (- y + ascent), &image.ImageMatrix); + gs_make_translation((double) - x, (double) (- y + ascent), &image.ImageMatrix); gs_matrix_multiply(&ctm_only(penum_pgs), &image.ImageMatrix, &image.ImageMatrix); image.Width = w + bold; image.Height = h + bold; image.adjust = false; - code = gs_image_init(pie, &image, false, penum_pgs); + code = gs_image_init(pie, &image, false, true, penum_pgs); nbytes = (rast->width + 7) >> 3; switch (code) { @@ -971,10 +1003,10 @@ } int -gs_fapi_finish_render(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, gs_fapi_server *I) +gs_fapi_finish_render(gs_font *pfont, gs_gstate *pgs, gs_text_enum_t *penum, gs_fapi_server *I) { gs_show_enum *penum_s = (gs_show_enum *) penum; - gs_state *penum_pgs; + gs_gstate *penum_pgs; gx_device *dev1; const int import_shift_v = _fixed_shift - 32; /* we always 32.32 values for the outline interface now */ gs_fapi_raster rast; @@ -983,15 +1015,15 @@ gs_font_base *pbfont = (gs_font_base *)pfont; extern_st(st_gs_show_enum); - extern_st(st_gs_state); + extern_st(st_gs_gstate); if (penum == NULL) { return_error(gs_error_undefined); } - /* Ensure that pis points to a st_gs_gstate (graphics state) structure */ - if (gs_object_type(penum->memory, penum->pis) != &st_gs_state) { - /* If pis is not a graphics state, see if the text enumerator is a + /* Ensure that pgs points to a st_gs_gstate (graphics state) structure */ + if (gs_object_type(penum->memory, penum->pgs) != &st_gs_gstate) { + /* If pgs is not a graphics state, see if the text enumerator is a * show enumerator, in which case we have a pointer to the graphics state there */ if (gs_object_type(penum->memory, penum) == &st_gs_show_enum) { @@ -1002,7 +1034,7 @@ return_error(gs_error_undefined); } else - penum_pgs = (gs_state *) penum->pis; + penum_pgs = (gs_gstate *) penum->pgs; dev1 = gs_currentdevice_inline(penum_pgs); /* Possibly changed by zchar_set_cache. */ @@ -1011,6 +1043,11 @@ * non-cacheing, non-marking cases, we must not draw the glyph. */ if (pgs->in_charpath && !SHOW_IS(penum, TEXT_DO_NONE)) { + gs_point pt; + + if ((code = gs_currentpoint(penum_pgs, &pt)) < 0) + return code; + if ((code = outline_char(mem, I, import_shift_v, penum_s, penum_pgs->path, !pbfont->PaintType)) < 0) { @@ -1027,25 +1064,31 @@ } else { int code; - memset(&rast, 0x00, sizeof(rast)); - code = I->get_char_raster(I, &rast); + if ((code = I->get_char_raster(I, &rast)) < 0 && code != gs_error_unregistered) + return code; if (!SHOW_IS(penum, TEXT_DO_NONE) && I->use_outline) { /* The server provides an outline instead the raster. */ - gs_imager_state *pis = (gs_imager_state *) penum_pgs->show_gstate; gs_point pt; + /* This mimics code which is used below in the case where I->Use_outline is set. + * This is usually caused by setting -dTextAlphaBits, and will result in 'undefinedresult' + * errors. We want the code to work the same regardless off the setting of -dTextAlphaBits + * and it seems the simplest way to provoke the same error is to do the same steps.... + * Note that we do not actually ever use the returned value. + */ if ((code = gs_currentpoint(penum_pgs, &pt)) < 0) return code; + if ((code = outline_char(mem, I, import_shift_v, penum_s, penum_pgs->path, !pbfont->PaintType)) < 0) return code; if ((code = - gs_imager_setflat((gs_imager_state *) penum_pgs, - gs_char_flatness(pis, 1.0))) < 0) + gs_gstate_setflat((gs_gstate *) penum_pgs, + gs_char_flatness(penum_pgs->show_gstate, 1.0))) < 0) return code; if (pbfont->PaintType) { float lw = gs_currentlinewidth(penum_pgs); @@ -1064,10 +1107,12 @@ penum_pgs->fill_adjust.x = penum_pgs->fill_adjust.y = 0; - if ((code = gs_fill(penum_pgs)) < 0) - return code; + code = gs_fill(penum_pgs); penum_pgs->in_cachedevice = in_cachedevice; + + if (code < 0) + return code; } if ((code = gs_moveto(penum_pgs, pt.x, pt.y)) < 0) return code; @@ -1075,6 +1120,16 @@ else { int rast_orig_x = rast.orig_x; int rast_orig_y = -rast.orig_y; + gs_point pt; + + /* This mimics code which is used above in the case where I->Use_outline is set. + * This is usually caused by setting -dTextAlphaBits, and will result in 'undefinedresult' + * errors. We want the code to work the same regardless off the setting of -dTextAlphaBits + * and it seems the simplest way to provoke the same error is to do the same steps.... + * Note that we do not actually ever use the returned value. + */ + if ((code = gs_currentpoint(penum_pgs, &pt)) < 0) + return code; if (penum_pgs->in_cachedevice == CACHE_DEVICE_CACHING) { /* Using GS cache */ /* GS and renderer may transform coordinates few differently. @@ -1156,11 +1211,10 @@ #define GET_S16_MSB(p) (int)((GET_U16_MSB(p) ^ 0x8000) - 0x8000) #define MTX_EQ(mtx1,mtx2) (mtx1->xx == mtx2->xx && mtx1->xy == mtx2->xy && \ - mtx1->yx == mtx2->yx && mtx1->yy == mtx2->yy && \ - mtx1->tx == mtx2->tx && mtx1->ty == mtx2->ty) + mtx1->yx == mtx2->yx && mtx1->yy == mtx2->yy) int -gs_fapi_do_char(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, char *font_file_path, +gs_fapi_do_char(gs_font *pfont, gs_gstate *pgs, gs_text_enum_t *penum, char *font_file_path, bool bBuildGlyph, gs_string *charstring, gs_string *glyphname, gs_char chr, gs_glyph index, int subfont) { /* Stack : --> - */ @@ -1193,7 +1247,6 @@ int code; bool imagenow = false; bool align_to_pixels = gs_currentaligntopixels(pbfont->dir); - gs_fapi_descendant_code fdc; gs_memory_t *mem = pfont->memory; enum { @@ -1202,7 +1255,7 @@ SBW_FROM_RENDERER } sbw_state = SBW_SCALE; - if ( index == gs_no_glyph ) + if ( index == GS_NO_GLYPH ) return 0; I->use_outline = false; @@ -1228,6 +1281,8 @@ (pbfont->dir->ccache.upper >> 1) : MAX_CCACHE_TEMP_BITMAP_BITS; } + I->grid_fit = pbfont->dir->grid_fit_tt; + /* Compute the scale : */ if (!SHOW_IS(penum, TEXT_DO_NONE) && !I->use_outline) { gs_currentcharmatrix(pgs, NULL, 1); /* make char_tm valid */ @@ -1253,6 +1308,7 @@ I->ff.is_type1 = bIsType1GlyphData; I->ff.is_cid = bCID; I->ff.is_outline_font = pbfont->PaintType != 0; + I->ff.metrics_only = fapi_gs_char_show_width_only(penum); if (!I->ff.is_mtx_skipped) I->ff.is_mtx_skipped = (gs_fapi_get_metrics_count(&I->ff) != 0); @@ -1260,7 +1316,17 @@ I->ff.is_vertical = bVertical; I->ff.client_ctx_p = I->client_ctx_p; - scale = 1 << I->frac_shift; + if (recreate_multiple_master(pbfont)) { + if ((void *)pbfont->base == (void *)pbfont) { + gs_fapi_release_typeface(I, &pbfont->FAPI_font_data); + } + else { + pbfont->FAPI_font_data = NULL; + pbfont->FAPI->face.font_id = gs_no_id; + } + } + + scale = 1 << I->frac_shift; retry_oversampling: if (I->face.font_id != pbfont->id || !MTX_EQ((&I->face.ctm), ctm) || @@ -1296,13 +1362,20 @@ scale_ctm.xx = dev->HWResolution[0] / 72; scale_ctm.yy = dev->HWResolution[1] / 72; - code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm); + if ((code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm)) < 0) + return code; + + if ((code = gs_matrix_multiply(ctm, &scale_ctm, &scale_mat)) < 0) /* scale_mat == CTM - resolution scaling */ + return code; - code = gs_matrix_multiply(ctm, &scale_ctm, &scale_mat); /* scale_mat == CTM - resolution scaling */ + if ((code = I->get_fontmatrix(I, &scale_ctm)) < 0) + return code; - code = I->get_fontmatrix(I, &scale_ctm); - code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm); - code = gs_matrix_multiply(&scale_mat, &scale_ctm, &scale_mat); /* scale_mat == CTM - resolution scaling - FontMatrix scaling */ + if ((code = gs_matrix_invert((const gs_matrix *)&scale_ctm, &scale_ctm)) < 0) + return code; + + if ((code = gs_matrix_multiply(&scale_mat, &scale_ctm, &scale_mat)) < 0) /* scale_mat == CTM - resolution scaling - FontMatrix scaling */ + return code; font_scale.matrix[0] = (fracint) (scale_mat.xx * FontMatrix_div * scale + 0.5); @@ -1338,25 +1411,18 @@ font_scale.matrix[3] = 1; } - if (!bCID - || (pbfont->FontType != ft_encrypted - && pbfont->FontType != ft_encrypted2)) { - fdc = gs_fapi_toplevel_prepared; - } - else { - fdc = gs_fapi_toplevel_prepared; - } if ((code = gs_fapi_renderer_retcode(mem, I, I->get_scaled_font(I, &I->ff, &font_scale, NULL, - fdc))) < 0) { + gs_fapi_toplevel_prepared))) < 0) { return code; } + pbfont->FAPI_font_data = I->ff.server_font_data; /* Save it back to GS font. */ } cr.char_codes_count = 1; - cr.char_codes[0] = (index == GS_NO_GLYPH) ? 0 : index; + cr.char_codes[0] = index; cr.client_char_code = chr; cr.is_glyph_index = true; enc_char_name_string.data = NULL; @@ -1364,7 +1430,7 @@ if (I->ff.get_glyphname_or_cid) { if ((code = - I->ff.get_glyphname_or_cid(pbfont, charstring, glyphname, index, + I->ff.get_glyphname_or_cid(penum, pbfont, charstring, glyphname, index, &enc_char_name_string, font_file_path, &cr, bCID)) < 0) return (code); @@ -1380,6 +1446,9 @@ int l = I->ff.get_glyphdirectory_data(&(I->ff), cr.char_codes[0], &data_ptr); + /* We do not need to apply the unitsPerEm scale here because + * these values are read directly from the glyph data. + */ if (MetricsCount == 2 && l >= 4) { if (!bVertical0) { cr.sb_x = GET_S16_MSB(data_ptr + 2) * scale; @@ -1396,6 +1465,15 @@ } } } + /* Metrics in GS are scaled to a 1.0x1.0 square, as that's what Postscript + * fonts expect. But for Truetype we need the "native" units, + */ + em_scale_x = 1.0; + if (pfont->FontType == ft_TrueType) { + gs_font_type42 *pfont42 = (gs_font_type42 *) pfont; + em_scale_x = pfont42->data.unitsPerEm; + } + if (cr.metrics_type != gs_fapi_metrics_replace && bVertical) { double pwv[4]; @@ -1406,10 +1484,10 @@ return code; if (code == 0 /* metricsNone */ ) { if (bCID && (!bIsType1GlyphData && font_file_path)) { - cr.sb_x = fapi_round(sbw[2] / 2 * scale); - cr.sb_y = fapi_round(pbfont->FontBBox.q.y * scale); - cr.aw_y = fapi_round(-pbfont->FontBBox.q.x * scale); /* Sic ! */ - cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1); + cr.sb_x = (fracint)(fapi_round( (sbw[2] / 2) * scale) * em_scale_x); + cr.sb_y = (fracint)(fapi_round( pbfont->FontBBox.q.y * scale) * em_scale_x); + cr.aw_y = (fracint)(fapi_round(-pbfont->FontBBox.q.x * scale) * em_scale_x); /* Sic ! */ + cr.metrics_scale = 1; cr.metrics_type = gs_fapi_metrics_replace; sbw[0] = sbw[2] / 2; sbw[1] = pbfont->FontBBox.q.y; @@ -1422,10 +1500,10 @@ } } else { - cr.sb_x = fapi_round(pwv[2] * scale); - cr.sb_y = fapi_round(pwv[3] * scale); - cr.aw_x = fapi_round(pwv[0] * scale); - cr.aw_y = fapi_round(pwv[1] * scale); + cr.sb_x = (fracint)(fapi_round(pwv[2] * scale) * em_scale_x); + cr.sb_y = (fracint)(fapi_round(pwv[3] * scale) * em_scale_x); + cr.aw_x = (fracint)(fapi_round(pwv[0] * scale) * em_scale_x); + cr.aw_y = (fracint)(fapi_round(pwv[1] * scale) * em_scale_x); cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1); cr.metrics_type = (code == 2 /* metricsSideBearingAndWidth */ ? gs_fapi_metrics_replace : gs_fapi_metrics_replace_width); @@ -1455,10 +1533,10 @@ } } else { - cr.sb_x = fapi_round(sbw[0] * scale); - cr.sb_y = fapi_round(sbw[1] * scale); - cr.aw_x = fapi_round(sbw[2] * scale); - cr.aw_y = fapi_round(sbw[3] * scale); + cr.sb_x = fapi_round(sbw[0] * scale * em_scale_x); + cr.sb_y = fapi_round(sbw[1] * scale * em_scale_x); + cr.aw_x = fapi_round(sbw[2] * scale * em_scale_x); + cr.aw_y = fapi_round(sbw[3] * scale * em_scale_x); cr.metrics_scale = (bIsType1GlyphData ? 1000 : 1); cr.metrics_type = (code == 2 /* metricsSideBearingAndWidth */ ? gs_fapi_metrics_replace : gs_fapi_metrics_replace_width); @@ -1467,20 +1545,10 @@ } memset(&metrics, 0x00, sizeof(metrics)); /* Take metrics from font : */ - if (fapi_gs_char_show_width_only(penum)) { - code = I->get_char_width(I, &I->ff, &cr, &metrics); - /* A VMerror could be a real out of memory, or the glyph being too big for a bitmap - * so it's worth retrying as an outline glyph - */ - if (code == gs_error_VMerror && I->use_outline == false) { - I->max_bitmap = 0; - I->use_outline = true; - goto retry_oversampling; - } - + if (I->ff.metrics_only) { + code = I->get_char_outline_metrics(I, &I->ff, &cr, &metrics); } else if (I->use_outline) { - code = I->get_char_outline_metrics(I, &I->ff, &cr, &metrics); } else { @@ -1499,14 +1567,7 @@ I->release_char_data(I); goto retry_oversampling; } - if ((code = - gs_fapi_renderer_retcode(mem, I, - I->get_char_outline_metrics(I, - &I->ff, - &cr, - &metrics))) - < 0) - return code; + code = I->get_char_outline_metrics(I, &I->ff, &cr, &metrics); } } @@ -1632,7 +1693,7 @@ */ /* Don't allow caching if we're only returning the metrics */ - if (fapi_gs_char_show_width_only(penum)) { + if (I->ff.metrics_only) { pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING; } @@ -1722,6 +1783,9 @@ list = gs_fapi_get_server_list(mem); + if (!list) /* Should never happen */ + return_error(gs_error_unregistered); + (*fapi_id) = NULL; pbfont = (gs_font_base *) pfont; @@ -1773,8 +1837,11 @@ if ((code = gs_fapi_renderer_retcode(mem, I, I->ensure_open(I, server_param, - server_param_size))) < 0) + server_param_size))) < 0) { + gs_free_object(mem->non_gc_memory, server_param, + "gs_fapi_passfont server params"); return code; + } if (free_params) { gs_free_object(mem->non_gc_memory, server_param, @@ -1879,13 +1946,10 @@ &server_param, &server_param_size); } - if ((code = - gs_fapi_renderer_retcode(mem, (*servs), - (*servs)->ensure_open((*servs), - server_param, - server_param_size))) - < 0) { - } + code = gs_fapi_renderer_retcode(mem, (*servs), + (*servs)->ensure_open((*servs), + server_param, + server_param_size)); if (free_params) { gs_free_object(mem->non_gc_memory, server_param, diff -Nru ghostscript-9.10~dfsg/base/gxfapi.h ghostscript-9.25~dfsg+1/base/gxfapi.h --- ghostscript-9.10~dfsg/base/gxfapi.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfapi.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -7,8 +7,8 @@ This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of that license. Refer to licensing information at http://www.artifex.com/ - or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, - San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Font API support */ @@ -26,9 +26,9 @@ typedef struct gs_font_base_s gs_font_base; #endif -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gs_text_enum_DEFINED @@ -89,6 +89,36 @@ gs_fapi_font_feature_BlendAxisTypes, gs_fapi_font_feature_BlendPrivate_count, gs_fapi_font_feature_BlendFontInfo_count, + gs_fapi_font_feature_BlendFontBBox_length, + gs_fapi_font_feature_BlendFontBBox, + + gs_fapi_font_feature_BlendBlueValues_length, + gs_fapi_font_feature_BlendBlueValues_count, + gs_fapi_font_feature_BlendBlueValues, + gs_fapi_font_feature_BlendOtherBlues_length, + gs_fapi_font_feature_BlendOtherBlues_count, + gs_fapi_font_feature_BlendOtherBlues, + gs_fapi_font_feature_BlendBlueScale_count, + gs_fapi_font_feature_BlendBlueScale, + gs_fapi_font_feature_BlendBlueShift_count, + gs_fapi_font_feature_BlendBlueShift, + gs_fapi_font_feature_BlendBlueFuzz_count, + gs_fapi_font_feature_BlendBlueFuzz, + gs_fapi_font_feature_BlendForceBold_count, + gs_fapi_font_feature_BlendForceBold, + gs_fapi_font_feature_BlendStdHW_length, + gs_fapi_font_feature_BlendStdHW_count, + gs_fapi_font_feature_BlendStdHW, + gs_fapi_font_feature_BlendStdVW_length, + gs_fapi_font_feature_BlendStdVW_count, + gs_fapi_font_feature_BlendStdVW, + gs_fapi_font_feature_BlendStemSnapH_length, + gs_fapi_font_feature_BlendStemSnapH_count, + gs_fapi_font_feature_BlendStemSnapH, + gs_fapi_font_feature_BlendStemSnapV_length, + gs_fapi_font_feature_BlendStemSnapV_count, + gs_fapi_font_feature_BlendStemSnapV, + gs_fapi_font_feature_WeightVector_count, gs_fapi_font_feature_WeightVector, gs_fapi_font_feature_BlendDesignPositionsArrays_count, @@ -104,6 +134,12 @@ typedef enum { + gs_fapi_glyph_invalid_format = -1, + gs_fapi_glyph_invalid_index = -2 +} gs_fapi_glyph_error; + +typedef enum +{ gs_fapi_metrics_notdef, gs_fapi_metrics_add, /* Add to native glyph width. */ gs_fapi_metrics_replace_width, /* Replace the native glyph width. */ @@ -150,6 +186,7 @@ bool is_outline_font; bool is_mtx_skipped; /* Ugly. Only UFST needs. */ bool is_vertical; + bool metrics_only; /* can save the expense of loading entire glyph */ gs_fapi_ttf_cmap_request ttf_cmap_req[GS_FAPI_NUM_TTF_CMAP_REQ]; /* Lets client request a specific cmap to be set. Also, a couple of fallbacks */ void *client_ctx_p; void *client_font_data; @@ -183,7 +220,7 @@ byte *buf, ushort buf_length); int (*get_glyphdirectory_data) (gs_fapi_font *ff, int char_code, const byte **ptr); - int (*get_glyphname_or_cid) (gs_font_base *pbfont, + int (*get_glyphname_or_cid) (gs_text_enum_t *penum, gs_font_base *pbfont, gs_string *charstring, gs_string *name, int ccode, gs_string *enc_char_name, char *font_file_path, gs_fapi_char_ref *cr, @@ -198,6 +235,8 @@ bool *imagenow); }; +#define GS_FAPI_WEIGHTVECTOR_MAX 16 + typedef struct gs_fapi_face_s gs_fapi_face; struct gs_fapi_face_s { @@ -206,6 +245,10 @@ gs_log2_scale_point log2_scale; bool align_to_pixels; float HWResolution[2]; + struct { + int count; + float values[GS_FAPI_WEIGHTVECTOR_MAX]; + } WeightVector; }; typedef struct gs_fapi_path_s gs_fapi_path; @@ -304,6 +347,7 @@ gs_fapi_font ff; int max_bitmap; bool use_outline; + uint grid_fit; gs_matrix initial_FontMatrix; /* Font Matrix at the time the font is defined */ /* Used to use the stored 'OrigFont' entry but */ /* this did not change f a font was defined */ @@ -314,7 +358,7 @@ gs_fapi_retcode(*ensure_open) (gs_fapi_server *server, const char *param, int param_size); gs_fapi_retcode(*get_scaled_font) (gs_fapi_server *server, gs_fapi_font *ff, const gs_fapi_font_scale *scale, const char *xlatmap, gs_fapi_descendant_code dc); gs_fapi_retcode(*get_decodingID) (gs_fapi_server *server, gs_fapi_font *ff, const char **decodingID); - gs_fapi_retcode(*get_font_bbox) (gs_fapi_server *server, gs_fapi_font *ff, int BBox[4]); + gs_fapi_retcode(*get_font_bbox) (gs_fapi_server *server, gs_fapi_font *ff, int BBox[4], int unitsPerEm[2]); gs_fapi_retcode(*get_font_proportional_feature) (gs_fapi_server *server, gs_fapi_font *ff, bool *bProportional); gs_fapi_retcode(*can_retrieve_char_by_name) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, int *result); gs_fapi_retcode(*can_replace_metrics) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_char_ref *c, int *result); @@ -330,6 +374,7 @@ gs_fapi_retcode(*release_typeface) (gs_fapi_server *server, void *server_font_data); gs_fapi_retcode(*check_cmap_for_GID) (gs_fapi_server *server, uint *index); gs_fapi_retcode(*get_font_info) (gs_fapi_server *server, gs_fapi_font *ff, gs_fapi_font_info item, int index, void *data, int *datalen); + gs_fapi_retcode(*set_mm_weight_vector) (gs_fapi_server *server, gs_fapi_font *ff, float *wvector, int length); /* Some people get confused with terms "font cache" and "character cache". "font cache" means a cache for scaled font objects, which mainly @@ -353,14 +398,14 @@ }; /* The font type 10 (ft_CID_user_defined) must not pass to FAPI. */ -#define FAPI_ISCIDFONT(basefont) basefont->FontType == ft_CID_encrypted ||\ +#define FAPI_ISCIDFONT(basefont) (basefont->FontType == ft_CID_encrypted ||\ basefont->FontType == ft_CID_user_defined || \ - basefont->FontType == ft_CID_TrueType + basefont->FontType == ft_CID_TrueType) -#define FAPI_ISTYPE1GLYPHDATA(basefont) pbfont->FontType == ft_encrypted || \ +#define FAPI_ISTYPE1GLYPHDATA(basefont) (pbfont->FontType == ft_encrypted || \ basefont->FontType == ft_encrypted2 ||\ - basefont->FontType == ft_CID_encrypted + basefont->FontType == ft_CID_encrypted) typedef int (*gs_fapi_get_server_param_callback) (gs_fapi_server *I, const char *subtype, @@ -401,10 +446,10 @@ gs_string *full_font_buf, const char *xlatmap, const char **decodingID); int -gs_fapi_finish_render(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, gs_fapi_server *I); +gs_fapi_finish_render(gs_font *pfont, gs_gstate *pgs, gs_text_enum_t *penum, gs_fapi_server *I); int -gs_fapi_do_char(gs_font *pfont, gs_state *pgs, gs_text_enum_t *penum, char *font_file_path, +gs_fapi_do_char(gs_font *pfont, gs_gstate *pgs, gs_text_enum_t *penum, char *font_file_path, bool bBuildGlyph, gs_string *charstring, gs_string *glyphname, gs_char chr, gs_glyph index, int subfont); diff -Nru ghostscript-9.10~dfsg/base/gxfapiu.c ghostscript-9.25~dfsg+1/base/gxfapiu.c --- ghostscript-9.10~dfsg/base/gxfapiu.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfapiu.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfapiu.h ghostscript-9.25~dfsg+1/base/gxfapiu.h --- ghostscript-9.10~dfsg/base/gxfapiu.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfapiu.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfarith.h ghostscript-9.25~dfsg+1/base/gxfarith.h --- ghostscript-9.10~dfsg/base/gxfarith.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfarith.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfcache.h ghostscript-9.25~dfsg+1/base/gxfcache.h --- ghostscript-9.10~dfsg/base/gxfcache.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfcache.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -62,9 +62,9 @@ # define gx_device_spot_analyzer_DEFINED typedef struct gx_device_spot_analyzer_s gx_device_spot_analyzer; #endif -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif /* @@ -174,21 +174,6 @@ uint pair_index; /* index of pair in mdata */ gs_fixed_point subpix_origin; /* glyph origin offset modulo pixel */ -#ifdef GSLITE - /* GSLite API needs to be able to lock a cache entry from being - evicted. We do this by counting how many times the GSLite user - has "retained" the slot. The initial value of this is zero. - For normal ghostscript operation it will never be changed, - so it has no effect. - - This is an ugly and ill conceived hack that was implemented - at the behest of a large customer. It is guarded by this ifdef - for a reason. We do not want our own code to depend on - this functionality. - */ - int dont_evict; -#endif - /* The rest of the structure is the 'value'. */ /* gx_cached_bits_common has width, height, raster, */ /* shift (not used here), id. */ @@ -242,11 +227,6 @@ #define chars_head_index(glyph, pair)\ ((uint)(glyph) * 59 + (pair)->hash * 73) /* scramble it a bit */ -#ifdef GSLITE -void gx_retain_cached_char(cached_char *cc); -void gx_release_cached_char(cached_char *cc); -#endif - /* ------ Character cache ------ */ /* diff -Nru ghostscript-9.10~dfsg/base/gxfcid.h ghostscript-9.25~dfsg+1/base/gxfcid.h --- ghostscript-9.10~dfsg/base/gxfcid.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfcid.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfcmap1.h ghostscript-9.25~dfsg+1/base/gxfcmap1.h --- ghostscript-9.10~dfsg/base/gxfcmap1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfcmap1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfcmap.h ghostscript-9.25~dfsg+1/base/gxfcmap.h --- ghostscript-9.10~dfsg/base/gxfcmap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfcmap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -197,6 +197,14 @@ GS_CMAP_COMMON; }; +typedef struct gs_cmap_ToUnicode_s { + GS_CMAP_COMMON; + int num_codes; + int key_size; + int value_size; + bool is_identity; +} gs_cmap_ToUnicode_t; + /* ---------------- Enumerators ---------------- */ /* @@ -222,7 +230,7 @@ }; typedef struct gs_cmap_lookups_enum_procs_s { - int (*next_lookup)(gs_cmap_lookups_enum_t *penum); + int (*next_lookup)(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum); int (*next_entry)(gs_cmap_lookups_enum_t *penum); } gs_cmap_lookups_enum_procs_t; struct gs_cmap_lookups_enum_s { @@ -286,7 +294,7 @@ */ void gs_cmap_lookups_enum_init(const gs_cmap_t *pcmap, int which, gs_cmap_lookups_enum_t *penum); -int gs_cmap_enum_next_lookup(gs_cmap_lookups_enum_t *penum); +int gs_cmap_enum_next_lookup(gs_memory_t *mem, gs_cmap_lookups_enum_t *penum); int gs_cmap_enum_next_entry(gs_cmap_lookups_enum_t *penum); /* ---------------- Implementation procedures ---------------- */ diff -Nru ghostscript-9.10~dfsg/base/gxfdrop.c ghostscript-9.25~dfsg+1/base/gxfdrop.c --- ghostscript-9.10~dfsg/base/gxfdrop.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfdrop.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,640 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Dropout prevention for a character rasterization. */ - -#include "gx.h" -#include "gserrors.h" -#include "gsstruct.h" -#include "gzpath.h" -#include "gxfixed.h" -#include "gxdevice.h" -#include "gxdcolor.h" -#include "gxfdrop.h" -#include "gxfill.h" -#include "vdtrace.h" - -#define INTERTRAP_STEM_BUG 0 /* We're not sure that 1 gives a - better painting with neighbour serifs. - Need more testing. - 0 is compatible to the old code. */ - -/* - * Rather some margins are placed in virtual memory, - * we never run garbager while some of them are allocated. - * Therefore we use "st_simple" for margins and sections. - */ -gs_private_st_simple(st_margin, margin, "margin"); -gs_public_st_simple(st_section, section, "section"); - -void init_section(section *sect, int i0, int i1) -{ int i; - - for (i = i0; i < i1; i++) { -# if ADJUST_SERIF && CHECK_SPOT_CONTIGUITY - sect[i].x0 = fixed_1; - sect[i].x1 = 0; -# endif - sect[i].y0 = sect[i].y1 = -1; - } -} - -static margin * alloc_margin(line_list * ll) -{ margin *m; - - if (ll->free_margin_list != 0) { - m = ll->free_margin_list; - ll->free_margin_list = ll->free_margin_list->next; - } else if (ll->local_margin_alloc_count < MAX_LOCAL_ACTIVE) { - m = ll->local_margins + ll->local_margin_alloc_count; - ++ ll->local_margin_alloc_count; - } else { - m = gs_alloc_struct(ll->memory, margin, &st_margin, "filling contiguity margin"); - /* The allocation happens only if ll->local_margins[MAX_LOCAL_ACTIVE] - is exceeded. We believe it does very seldom. */ - } - return m; -} - -static void release_margin_list(line_list * ll, margin_set *ms) -{ margin * m1 = ms->margin_list; - - if (m1 == 0) - return; - while (m1->next != 0) - m1 = m1->next; - m1->next = ll->free_margin_list; - ll->free_margin_list = ms->margin_list; - ms->margin_list = ms->margin_touched = 0; -} - -void free_all_margins(line_list * ll) -{ margin * m = ll->free_margin_list; - - ll->free_margin_list = 0; - while (m != 0) { - margin * m1 = m->next; - - if (m < ll->local_margins || m >= ll->local_margins + MAX_LOCAL_ACTIVE) - gs_free_object(ll->memory, m, "filling contiguity margin"); - m = m1; - } -} - -static int store_margin(line_list * ll, margin_set * set, int ii0, int ii1) -{ - /* - * We need to add margin to the ordered margin list. - * Contacting margins to be united. - */ - int i0 = ii0, i1 = ii1; - margin *m0 = set->margin_touched, *m1; - - if (!ll->fo->pseudo_rasterization) - return_error(gs_error_unregistered); /* Must not happen. */ - if (ii0 < 0 || ii1 > ll->bbox_width) - return_error(gs_error_unregistered); /* Must not happen. */ - set->margin_touched = 0; /* safety */ - /* Find contacting elements. */ - if (m0 != 0) { - margin *m_last = m0, *mb, *me; - - if (set->margin_list == 0) - return_error(gs_error_unregistered); /* Must not happen. */ - if (i1 < m0->ibeg) { - do { - m0 = m0->prev; - } while (m0 != 0 && i0 <= m0->iend); - /* m0 points to a non-contacting at left. */ - m1 = (m0 == 0 ? set->margin_list : m0)->next; - while (m1 != 0 && m1->ibeg <= i1) { - m_last = m1; - m1 = m1->next; - } - /* m1 points to a non-contacting at right. */ - } else if (i0 > m0->iend) { - m1 = m0; - do { - m_last = m1; - m1 = m1->next; - } while (m1 != 0 && i1 >= m1->ibeg); - /* m0 points to a non-contacting at right. */ - m0 = (m1 == 0 ? m_last : m1->prev); - while (m0 != 0 && m0->iend >= i0) - m0 = m0->prev; - /* m1 points to a non-contacting at left. */ - } else { - m1 = m0; - while (m1 != 0 && m1->ibeg <= i1) { - m_last = m1; - m1 = m1->next; - } - /* m1 points to a non-contacting at right. */ - while (m0 != 0 && m0->iend >= i0) - m0 = m0->prev; - /* m1 points to a non-contacting at left. */ - } - /* Remove elements from m0->next to m1->prev, excluding the latter. - m0 may be NULL if we riched list start. - m1 may be NULL if we riched list end. */ - mb = (m0 == 0 ? set->margin_list : m0->next); - if (mb != 0 && mb != m1) { - me = (m1 == 0 ? m_last : m1->prev); - /* Remove elements from mb to me, excluding the latter. - me may be NULL if we riched list start. */ - if (me != 0) { - if (mb != me && me->prev != 0) { - margin *mf = me->prev; - - /* Remove elements from mb to mf. */ - if (mb->prev != 0) - mb->prev->next = mf->next; - if (mf->next != 0) - mf->next->prev = mb->prev; - if (set->margin_list == mb) - set->margin_list = mf->next; - mf->next = ll->free_margin_list; - ll->free_margin_list = mb; - i0 = min(i0, mb->ibeg); - i1 = max(i1, mf->iend); - /* 'prev' links are not used in ll->free_margin_list. */ - } - } - } - me = (m0 == 0 ? set->margin_list : m0->next); - if (me == 0) - m0 = m0; /* Already set. */ - else if (me->iend < i0) - m0 = me; /* Insert after me. */ - else if (me->ibeg > i1) - m0 = me->prev; /* Insert before me. */ - else if (me->iend >= i0 && me->ibeg <= i1) { - /* Intersects with me. Replace me boundaries. */ - me->ibeg = min(i0, me->ibeg); - me->iend = max(i1, me->iend); - set->margin_touched = me; - return 0; - } - } - /* Insert after m0 */ - m1 = alloc_margin(ll); - if (m1 == 0) - return_error(gs_error_VMerror); - if (m0 != 0) { - m1->next = m0->next; - m1->prev = m0; - m0->next = m1; - if (m1->next!= 0) - m1->next->prev = m1; - } else { - m1->next = set->margin_list; - m1->prev = 0; - if (set->margin_list != 0) - set->margin_list->prev = m1; - set->margin_list = m1; - } - m1->ibeg = i0; - m1->iend = i1; - set->margin_touched = m1; - return 0; -} - -static inline int to_interval(int x, int l, int u) -{ return x < l ? l : x > u ? u : x; -} - -static inline fixed Y_AT_X(active_line *alp, fixed xp) -{ return alp->start.y + fixed_mult_quo(xp - alp->start.x, alp->diff.y, alp->diff.x); -} - -static int margin_boundary(line_list * ll, margin_set * set, active_line * alp, - fixed xx0, fixed xx1, fixed yy0, fixed yy1, int dir, fixed y0, fixed y1) -{ section *sect = set->sect; - fixed x0, x1, xmin, xmax; - int xp0, xp; - int i0, i; -# if !CHECK_SPOT_CONTIGUITY - int i1; -# endif - - if (yy0 > yy1) - return 0; - /* enumerate integral x's in [yy0,yy1] : */ - - if (alp == 0) - x0 = xx0, x1 = xx1; - else { - x0 = (yy0 == y0 ? alp->x_current : AL_X_AT_Y(alp, yy0)); - x1 = (yy1 == y1 ? alp->x_next : AL_X_AT_Y(alp, yy1)); - } - xmin = min(x0, x1); - xmax = max(x0, x1); -# if !CHECK_SPOT_CONTIGUITY - xp0 = fixed_floor(xmin) + fixed_half; - i0 = fixed2int(xp0) - ll->bbox_left; - if (xp0 < xmin) { - xp0 += fixed_1; - i0++; - } - if (i0 < 0) - return_error(gs_error_unregistered); /* Must not happen. */ - for (i = i0, xp = xp0; xp < xmax && i < ll->bbox_width; xp += fixed_1, i++) { - fixed y = (alp == 0 ? yy0 : Y_AT_X(alp, xp)); - fixed dy = y - set->y; - bool ud; - short *b, h; - section *s = §[i]; - - if (dy < 0) - dy = 0; /* fix rounding errors in Y_AT_X */ - if (dy >= fixed_1) - dy = fixed_1; /* safety */ - vd_circle(xp, y, 2, 0); - ud = (alp == 0 ? (dir > 0) : ((alp->start.x - alp->end.x) * dir > 0)); - b = (ud ? &s->y0 : &s->y1); - h = (short)dy; - if (*b == -1 || (*b != -2 && ( ud ? *b > h : *b < h))) - *b = h; - } -# else - xp0 = fixed_floor(xmin) + fixed_half; - i0 = fixed2int(xp0) - ll->bbox_left; - if (xp0 < xmin) { - i0++; - xp0 += fixed_1; - } - for (i = i0, xp = xp0; xp < xmax; xp += fixed_1, i++) { - section *s = §[i]; - fixed y = (alp==0 ? yy0 : Y_AT_X(alp, xp)); - fixed dy = y - set->y; - bool ud; - short *b, h; - - if (dy < 0) - dy = 0; /* fix rounding errors in Y_AT_X */ - if (dy >= fixed_1) - dy = fixed_1; /* safety */ - vd_circle(xp, y, 2, 0); - ud = (alp == 0 ? (dir > 0) : ((alp->start.x - alp->end.x) * dir > 0)); - b = (ud ? &s->y0 : &s->y1); - h = (short)dy; - if (*b == -1 || (*b != -2 && ( ud ? *b > h : *b < h))) - *b = h; - } - if (i0 < 0 || i > ll->bbox_width) - return_error(gs_error_unregistered); /* Must not happen. */ -# endif - if (i > i0) - return store_margin(ll, set, i0, i); - return 0; -} - -int continue_margin_common(line_list * ll, margin_set * set, active_line * flp, active_line * alp, fixed y0, fixed y1) -{ int code; -# if ADJUST_SERIF - section *sect = set->sect; - fixed yy0 = max(max(y0, alp->start.y), set->y); - fixed yy1 = min(min(y1, alp->end.y), set->y + fixed_1); - - if (yy0 <= yy1) { - fixed x00 = (yy0 == y0 ? flp->x_current : AL_X_AT_Y(flp, yy0)); - fixed x10 = (yy0 == y0 ? alp->x_current : AL_X_AT_Y(alp, yy0)); - fixed x01 = (yy1 == y1 ? flp->x_next : AL_X_AT_Y(flp, yy1)); - fixed x11 = (yy1 == y1 ? alp->x_next : AL_X_AT_Y(alp, yy1)); - fixed xmin = min(x00, x01), xmax = max(x10, x11); - - int i0 = fixed2int(xmin) - ll->bbox_left, i; - int i1 = fixed2int_ceiling(xmax) - ll->bbox_left; - - for (i = i0; i < i1; i++) { - section *s = §[i]; - int x_pixel = int2fixed(i + ll->bbox_left); - int xl = max(xmin - x_pixel, 0); - int xu = min(xmax - x_pixel, fixed_1); - - s->x0 = min(s->x0, xl); - s->x1 = max(s->x1, xu); - x_pixel+=0; /* Just a place for breakpoint */ - } - code = store_margin(ll, set, i0, i1); - if (code < 0) - return code; - /* fixme : after ADJUST_SERIF becames permanent, - * don't call margin_boundary if yy0 > yy1. - */ - } -# endif - - code = margin_boundary(ll, set, flp, 0, 0, yy0, yy1, 1, y0, y1); - if (code < 0) - return code; - return margin_boundary(ll, set, alp, 0, 0, yy0, yy1, -1, y0, y1); -} - -static inline int mark_margin_interior(line_list * ll, margin_set * set, active_line * flp, active_line * alp, fixed y, fixed y0, fixed y1) -{ - section *sect = set->sect; - fixed x0 = (y == y0 ? flp->x_current : y == y1 ? flp->x_next : AL_X_AT_Y(flp, y)); - fixed x1 = (y == y0 ? alp->x_current : y == y1 ? alp->x_next : AL_X_AT_Y(alp, y)); - int i0 = fixed2int(x0), ii0, ii1, i, code; - - if (int2fixed(i0) + fixed_half < x0) - i0++; - ii0 = i0 - ll->bbox_left; - ii1 = fixed2int_var_pixround(x1) - ll->bbox_left; - if (ii0 < ii1) { - if (ii0 < 0 || ii1 > ll->bbox_width) - return_error(gs_error_unregistered); /* Must not happen. */ - for (i = ii0; i < ii1; i++) { - sect[i].y0 = sect[i].y1 = -2; - vd_circle(int2fixed(i + ll->bbox_left) + fixed_half, y, 3, RGB(255, 0, 0)); - } - code = store_margin(ll, set, ii0, ii1); - if (code < 0) - return code; - } - return 0; -} - -int margin_interior(line_list * ll, active_line * flp, active_line * alp, fixed y0, fixed y1) -{ int code; - fixed yy0, yy1; - - yy0 = ll->margin_set0.y; - if (y0 <= yy0 && yy0 <= y1) { - code = mark_margin_interior(ll, &ll->margin_set0, flp, alp, yy0, y0, y1); - if (code < 0) - return code; - } - yy1 = ll->margin_set1.y + fixed_1; - if (y0 <= yy1 && yy1 <= y1) { - code = mark_margin_interior(ll, &ll->margin_set1, flp, alp, yy1, y0, y1); - if (code < 0) - return code; - } - return 0; -} - -static inline int process_h_sect(line_list * ll, margin_set * set, active_line * hlp0, - active_line * plp, active_line * flp, int side, fixed y0, fixed y1) -{ - active_line *hlp = hlp0; - fixed y = hlp->start.y; - fixed x0 = (plp != 0 ? (y == y0 ? plp->x_current : y == y1 ? plp->x_next : AL_X_AT_Y(plp, y)) - : int2fixed(ll->bbox_left)); - fixed x1 = (flp != 0 ? (y == y0 ? flp->x_current : y == y1 ? flp->x_next : AL_X_AT_Y(flp, y)) - : int2fixed(ll->bbox_left + ll->bbox_width)); - int code; - - for (; hlp != 0; hlp = hlp->next) { - fixed xx0 = max(x0, min(hlp->start.x, hlp->end.x)); - fixed xx1 = min(x1, max(hlp->start.x, hlp->end.x)); - - if (xx0 < xx1) { - vd_bar(xx0, y, xx1, y, 1, RGB(255, 0, 255)); - code = margin_boundary(ll, set, 0, xx0, xx1, y, y, side, 0, 0); - if (code < 0) - return code; - } - } - return 0; -} - -static inline int process_h_side(line_list * ll, margin_set * set, active_line * hlp, - active_line * plp, active_line * flp, active_line * alp, int side, fixed y0, fixed y1) -{ if (plp != 0 || flp != 0 || (plp == 0 && flp == 0 && alp == 0)) { - /* We don't know here, whether the opposite (-) side is painted with - * a trapezoid. mark_margin_interior may rewrite it later. - */ - int code = process_h_sect(ll, set, hlp, plp, flp, -side, y0, y1); - - if (code < 0) - return code; - } - if (flp != 0 && alp != 0) { - int code = process_h_sect(ll, set, hlp, flp, alp, side, y0, y1); - - if (code < 0) - return code; - } - return 0; -} - -static inline int process_h_list(line_list * ll, active_line * hlp, active_line * plp, - active_line * flp, active_line * alp, int side, fixed y0, fixed y1) -{ fixed y = hlp->start.y; - - if (ll->margin_set0.y <= y && y <= ll->margin_set0.y + fixed_1) { - int code = process_h_side(ll, &ll->margin_set0, hlp, plp, flp, alp, side, y0, y1); - - if (code < 0) - return code; - } - if (ll->margin_set1.y <= y && y <= ll->margin_set1.y + fixed_1) { - int code = process_h_side(ll, &ll->margin_set1, hlp, plp, flp, alp, side, y0, y1); - - if (code < 0) - return code; - } - return 0; -} - -int process_h_lists(line_list * ll, active_line * plp, active_line * flp, active_line * alp, - fixed y0, fixed y1) -{ - if (y0 == y1) { - /* fixme : Must not happen. Remove. */ - return 0; - } - if (ll->h_list0 != 0) { - int code = process_h_list(ll, ll->h_list0, plp, flp, alp, 1, y0, y1); - - if (code < 0) - return code; - } - if (ll->h_list1 != 0) { - int code = process_h_list(ll, ll->h_list1, plp, flp, alp, -1, y0, y1); - - if (code < 0) - return code; - } - return 0; -} - -static inline int compute_padding(section *s) -{ - return (s->y0 < 0 || s->y1 < 0 ? -2 : /* contacts a trapezoid - don't paint */ - s->y1 < fixed_half ? 0 : - s->y0 > fixed_half ? 1 : - fixed_half - s->y0 < s->y1 - fixed_half ? 1 : 0); -} - -static int fill_margin(gx_device * dev, const line_list * ll, margin_set *ms, int i0, int i1) -{ /* Returns the new index (positive) or return code (negative). */ - section *sect = ms->sect; - int iy = fixed2int_var_pixround(ms->y); - int i, ir, h = -2, code; - const fill_options * const fo = ll->fo; - const bool FILL_DIRECT = fo->fill_direct; - - if (i0 < 0 || i1 > ll->bbox_width) - return_error(gs_error_unregistered); /* Must not happen. */ - ir = i0; - for (i = i0; i < i1; i++) { - int y0 = sect[i].y0, y1 = sect[i].y1, hh; - - if (y0 == -1) - y0 = 0; - if (y1 == -1) - y1 = fixed_scale - 1; - hh = compute_padding(§[i]); -# if ADJUST_SERIF - if (hh >= 0) { -# if !CHECK_SPOT_CONTIGUITY - if (i == i0 && i + 1 < i1) { - int hhh = compute_padding(§[i + 1]); - - hh = hhh; - } else if (i == i1 - 1 && i > i0) - hh = h; - /* We could optimize it with moving outside the cycle. - * Delaying the optimization until the code is well tested. - */ -# else - if (sect[i].x0 > 0 && sect[i].x1 == fixed_1 && i + 1 < i1) { -# if INTERTRAP_STEM_BUG - int hhh = hh; -# endif - hh = (i + 1 < i1 ? compute_padding(§[i + 1]) : -2); - /* We could cache hh. - * Delaying the optimization until the code is well tested. - */ -# if INTERTRAP_STEM_BUG - /* A bug in the old code. */ - if (i > i0 && i + 1 < i1 && hh == -2 && - compute_padding(§[i - 1]) == -2) { - /* It can be either a thin stem going from left to up or down - (See 'r' in 01-001.ps in 'General', ppmraw, 72dpi), - or a serif from the left. - Since it is between 2 trapezoids, it is better to paint it - against a dropout. */ - hh = hhh; - } -# endif - } else if (sect[i].x0 == 0 && sect[i].x1 < fixed_1) { -# if INTERTRAP_STEM_BUG - int hhh = hh; -# endif - hh = h; -# if INTERTRAP_STEM_BUG - /* A bug in the old code. */ - if (i > i0 && i + 1 < i1 && hh == -2 && - compute_padding(§[i - 1]) == -2) { - /* It can be either a thin stem going from right to up or down - (See 'r' in 01-001.ps in 'General', ppmraw, 72dpi), - or a serif from the right. - Since it is between 2 trapezoids, it is better to paint it. - against a dropout. */ - DO_NOTHING; - } -# endif - } -# endif - } -# endif - if (h != hh) { - if (h >= 0) { - VD_RECT(ir + ll->bbox_left, iy + h, i - ir, 1, VD_MARG_COLOR); - code = LOOP_FILL_RECTANGLE_DIRECT(fo, ir + ll->bbox_left, iy + h, i - ir, 1); - if (code < 0) - return code; - } - ir = i; - h = hh; - } - } - if (h >= 0) { - VD_RECT(ir + ll->bbox_left, iy + h, i - ir, 1, VD_MARG_COLOR); - code = LOOP_FILL_RECTANGLE_DIRECT(fo, ir + ll->bbox_left, iy + h, i - ir, 1); - if (code < 0) - return code; - } - init_section(sect, i0, i1); - return 0; -/* - * We added the ADJUST_SERIF feature for small fonts, which are poorly hinted. - * An example is 033-52-5873.pdf at 72 dpi. - * We either suppress a serif or move it up or down for 1 pixel. - * If we would paint it as an entire pixel where it occures, it looks too big - * relatively to the character size. Besides, a stem end may - * be placed a little bit below the baseline, and our dropout prevention - * method desides to paint a pixel below baseline, so that it looks - * fallen down (or fallen up in the case of character top). - * - * We assume that contacting margins are merged in margin_list. - * This implies that areas outside a margin are not painted - * (Only useful without CHECK_SPOT_CONTIGUITY). - * - * With no CHECK_SPOT_CONTIGUITY we can't perfectly handle the case when 2 serifs - * contact each another inside a margin interior (such as Serif 'n'). - * Since we don't know the contiguty, we misrecognize them as a stem and - * leave them as they are (possibly still fallen down or up). - * - * CHECK_SPOT_CONTIGUITY computes the contiguity of the intersection of the spot - * and the section window. It allows to recognize contacting serifs properly. - * - * If a serif isn't painted with regular trapezoids, - * it appears a small one, so we don't need to measure its size. - * This heuristic isn't perfect, but it is very fast. - * Meanwhile with CHECK_SPOT_CONTIGUITY we actually have something - * like a bbox for a small serif, and a rough estimation is possible. - * - * We believe that in normal cases this stuff should work idle, - * because a perfect rendering should either use anti-aliasing - * (so that the character isn't small in the subpixel grid), - * and/or the path must be well fitted into the grid. So please consider - * this code as an attempt to do our best for the case of a - * non-well-setup rendering. - */ -} - -int close_margins(gx_device * dev, line_list * ll, margin_set *ms) -{ margin *m = ms->margin_list; - int code; - - for (; m != 0; m = m->next) { - code = fill_margin(dev, ll, ms, m->ibeg, m->iend); - if (code < 0) - return code; - } - release_margin_list(ll, ms); - return 0; -} - -int start_margin_set(gx_device * dev, line_list * ll, fixed y0) -{ int code; - fixed ym = fixed_pixround(y0) - fixed_half; - margin_set s; - - if (ll->margin_set0.y == ym) - return 0; - s = ll->margin_set1; - ll->margin_set1 = ll->margin_set0; - ll->margin_set0 = s; - code = close_margins(dev, ll, &ll->margin_set0); - ll->margin_set0.y = ym; - return code; -} diff -Nru ghostscript-9.10~dfsg/base/gxfdrop.h ghostscript-9.25~dfsg+1/base/gxfdrop.h --- ghostscript-9.10~dfsg/base/gxfdrop.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfdrop.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Dropout prevention for a character rasterization. */ - -#ifndef gxfdrop_INCLUDED -# define gxfdrop_INCLUDED - -/* The structure margin_set and related structures and functions are used for - preventing dropouts rasterizing a character with zero fill adjustment. The purpose - is to paint something along thin quazi-horizontal stems, - which are composed of multiple small segments (such as a result of flattenpath). - We call it "pseudo-rasterization". - When fill adjustment takes place, this stuff is not required and is being skipped. - - To prevent dropouts in thin quazi-horizontal stems we look at raster - through 1xN pixels window, where N is the width of the path bounding box. - This window moves from bottom to top synchronousely with the motion of - the filling loop, but its Y coordinate is always an integer plus one half - (actually it moves convulsively). - Through this window we can see an upper half of a pixel row, - and lower half of the next pixel row. Painted spots are visible through - this window as a set of "margins". To handle them we maintain - a list of margin_s structures (each of which describes an interval - to be painted), and array of "sections" (i-th section corresponds to - half-integer X-coordinate Xi = bbox_left + i + 0.5, and stores fraction - part of y-coordinate of intersection of the line x == Xi with margin - boudaries, being visible through window (only extremal coordinates are stored - into a section)). - - The structure margin_set snaps what has been painted inside window. - We handle 2 instances of margin_set : margin_set0 is being prepared and margin_set1 is - being refinished. When the filling loop steps down over a pixel center, - the refinished window is closed and released, the prapared window becomes - the refinished one, and a new one starts to prepare. - - fixme: - The current implementation is not optimised for very bold characters. - We could encrease performance for them with maintaining - a separate list of "exclusive" margins, which correspond - to intervals painted with regular trapezoids and made with - complete_margin. Using them we could skip access to 'sect' array elements - inside "exclusive" margins, so that the number of small steps - sensibly decreeses. - - fixme: - Another optimization could be applied to the regular(old) trapezoid algorithm. - Currently it breaks stems at any step of the Y cycle, - generating big number of trapezoids. - Perhaps we could store trapezoid vertices to active_line, - and delay rendering a trapezoid until stem changes boundary segments. - This also would make calls to the margin staff less frequent. - -*/ - -/* - * Configuration flags for the dropout prevention code. - */ -#define ADJUST_SERIF 1 /* See comments near occurances. */ -#define CHECK_SPOT_CONTIGUITY 1 /* See comments near occurances. */ - -#ifndef active_line_DEFINED -# define active_line_DEFINED -typedef struct active_line_s active_line; -#endif - -#ifndef line_list_DEFINED -# define line_list_DEFINED -typedef struct line_list_s line_list; -#endif - -typedef struct margin_s -{ int ibeg, iend; /* Pixel indices of an interval to paint. */ - struct margin_s *prev, *next; -} margin; - -typedef struct section_s -{ short y0, y1; /* Fraction part of y coordinates of intersections of the margin with line x==i + bbox_left */ -#if ADJUST_SERIF && CHECK_SPOT_CONTIGUITY - short x0, x1; /* Pixel coverage by X for checking the contiguity. */ -#endif -} section; - -typedef struct margin_set_s -{ fixed y; - margin *margin_list, *margin_touched; - section *sect; -} margin_set; - -extern_st(st_section); - -/* vd_trace helpers. */ -#define VD_SCALE 0.03 -#define VD_RECT(x, y, w, h, c) vd_rect(int2fixed(x), int2fixed(y), int2fixed(x + w), int2fixed(y + h), 1, c) -#define VD_TRAP_COLOR RGB(0, 255, 255) -#define VD_MARG_COLOR RGB(255, 0, 0) - -void init_section(section *sect, int i0, int i1); -void free_all_margins(line_list * ll); -int close_margins(gx_device * dev, line_list * ll, margin_set *ms); -int process_h_lists(line_list * ll, active_line * plp, active_line * flp, active_line * alp, fixed y0, fixed y1); -int margin_interior(line_list * ll, active_line * flp, active_line * alp, fixed y0, fixed y1); -int start_margin_set(gx_device * dev, line_list * ll, fixed y0); -int continue_margin_common(line_list * ll, margin_set * set, active_line * flp, active_line * alp, fixed y0, fixed y1); - -#endif /* gxfdrop_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxfill.c ghostscript-9.25~dfsg+1/base/gxfill.c --- ghostscript-9.10~dfsg/base/gxfill.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfill.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,8 +25,6 @@ 3. Fixed the contiguity of a spot covering for shading fills with no dropouts. */ -/* See PSEUDO_RASTERIZATION and "pseudo_rasterization". - about the dropout prevention logics. */ /* See is_spotan about the spot topology analysis support. */ /* Also defining lower-level path filling procedures */ @@ -39,9 +37,8 @@ #include "gzcpath.h" #include "gxdcolor.h" #include "gxhttile.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxpaint.h" /* for prototypes */ -#include "gxfdrop.h" #include "gxfill.h" #include "gxpath.h" #include "gsptype1.h" @@ -51,14 +48,15 @@ #include "gzspotan.h" /* Only for gx_san_trap_store. */ #include "memory_.h" #include "stdint_.h" -#include "vdtrace.h" #include "gsstate.h" /* for gs_currentcpsimode */ #include "gxdevsop.h" +#include "gxscanc.h" /* #include "gxfilltr.h" - Do not remove this comment. "gxfilltr.h" is included below. #include "gxfillsl.h" - Do not remove this comment. "gxfillsl.h" is included below. #include "gxfillts.h" - Do not remove this comment. "gxfillts.h" is included below. */ +#include "assert_.h" /* #define ENABLE_TRAP_AMALGAMATION */ @@ -112,7 +110,7 @@ bool s1; INCR(order); - if (lp1->x_current < lp2->x_current) + if (!lp1 || !lp2 || lp1->x_current < lp2->x_current) return -1; else if (lp1->x_current > lp2->x_current) return 1; @@ -201,7 +199,7 @@ * is allocaded on the stack i.e. has no block header with a descriptor * but has dev->memory set like a heap-allocated device. */ - return dev->procs.open_device == san_open; + return dev_proc(dev, open_device) == san_open; } /* Forward declarations */ @@ -220,7 +218,6 @@ /* * This is the general path filling algorithm. * It uses the center-of-pixel rule for filling - * (except for pseudo_rasterization - see below). * We can implement Microsoft's upper-left-corner-of-pixel rule * by subtracting (0.5, 0.5) from all the coordinates in the path. * @@ -245,13 +242,14 @@ ll->y_list = 0; ll->y_line = 0; ll->h_list0 = ll->h_list1 = 0; - ll->margin_set0.margin_list = ll->margin_set1.margin_list = 0; - ll->margin_set0.margin_touched = ll->margin_set1.margin_touched = 0; - ll->margin_set0.y = ll->margin_set1.y = 0; /* A stub against indeterminism. Don't use it. */ - ll->free_margin_list = 0; - ll->local_margin_alloc_count = 0; - ll->margin_set0.sect = ll->local_section0; - ll->margin_set1.sect = ll->local_section1; + + ll->x_head.prev = NULL; + /* Bug 695234: Initialise the following to pacify valgrind */ + ll->x_head.start.x = 0; + ll->x_head.start.y = 0; + ll->x_head.end.x = 0; + ll->x_head.end.y = 0; + /* Do not initialize ll->bbox_left, ll->bbox_width - they were set in advance. */ INCR(fill); } @@ -280,12 +278,12 @@ * The general fill path algorithm. */ static int -gx_general_fill_path(gx_device * pdev, const gs_imager_state * pis, +gx_general_fill_path(gx_device * pdev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { gs_fixed_point adjust; - gs_logical_operation_t lop = pis->log_op; + gs_logical_operation_t lop = pgs->log_op; gs_fixed_rect ibox, bbox, sbox; gx_device_clip cdev; gx_device *dev = pdev; @@ -295,12 +293,13 @@ int code; int max_fill_band = dev->max_fill_band; #define NO_BAND_MASK ((fixed)(-1) << (sizeof(fixed) * 8 - 1)) - const bool is_character = params->adjust.x == -1; /* See gxistate.h */ + const bool is_character = params->adjust.x == -1; /* See gxgstate.h */ bool fill_by_trapezoids; - bool pseudo_rasterization; bool big_path = ppath->subpath_count > 50; fill_options fo; line_list lst; + int clipping = 0; + int scanconverter; *(const fill_options **)&lst.fo = &fo; /* break 'const'. */ /* @@ -312,11 +311,6 @@ * but right now we don't bother. */ gx_path_bbox(ppath, &ibox); -# define SMALL_CHARACTER 500 - pseudo_rasterization = (is_character && - !is_spotan_device(dev) && - ibox.q.y - ibox.p.y < SMALL_CHARACTER * fixed_scale && - ibox.q.x - ibox.p.x < SMALL_CHARACTER * fixed_scale); if (is_character) adjust.x = adjust.y = 0; else @@ -325,17 +319,6 @@ lst.windings = NULL; lst.bbox_left = fixed2int(ibox.p.x - adjust.x - fixed_epsilon); lst.bbox_width = fixed2int(fixed_ceiling(ibox.q.x + adjust.x)) - lst.bbox_left; - if (vd_enabled) { - fixed x0 = int2fixed(fixed2int(ibox.p.x - adjust.x - fixed_epsilon)); - fixed x1 = int2fixed(fixed2int(ibox.q.x + adjust.x + fixed_scale - fixed_epsilon)); - fixed y0 = int2fixed(fixed2int(ibox.p.y - adjust.y - fixed_epsilon)); - fixed y1 = int2fixed(fixed2int(ibox.q.y + adjust.y + fixed_scale - fixed_epsilon)), k; - - for (k = x0; k <= x1; k += fixed_scale) - vd_bar(k, y0, k, y1, 1, RGB(128, 128, 128)); - for (k = y0; k <= y1; k += fixed_scale) - vd_bar(x0, k, x1, k, 1, RGB(128, 128, 128)); - } /* Check the bounding boxes. */ if_debug6m('f', pdev->memory, "[f]adjust=%g,%g bbox=(%g,%g),(%g,%g)\n", fixed2float(adjust.x), fixed2float(adjust.y), @@ -374,6 +357,7 @@ dev = (gx_device *) & cdev; gx_make_clip_device_on_stack(&cdev, pcpath, save_dev); cdev.max_fill_band = save_dev->max_fill_band; + clipping = 1; } } /* @@ -397,13 +381,10 @@ fo.adjust_above = fixed_half /* + fixed_epsilon */ ; /* see above */ else fo.adjust_below = fo.adjust_above = adjust.y; - /* Initialize the active line list. */ - init_line_list(&lst, ppath->memory); sbox.p.x = ibox.p.x - adjust.x; sbox.p.y = ibox.p.y - adjust.y; sbox.q.x = ibox.q.x + adjust.x; sbox.q.y = ibox.q.y + adjust.y; - fo.pseudo_rasterization = pseudo_rasterization; fo.pdevc = pdevc; fo.lop = lop; fo.fixed_flat = float2fixed(params->flatness); @@ -433,9 +414,9 @@ * pixel writing must be avoided, and the trapezoid algorithm otherwise. * However, we always use the trapezoid algorithm for rectangles. */ - fill_by_trapezoids = - (pseudo_rasterization || !gx_path_has_curves(ppath) || - params->flatness >= 1.0 || fo.is_spotan); + fill_by_trapezoids = (!gx_path_has_curves(ppath) || + params->flatness >= 1.0 || fo.is_spotan); + if (fill_by_trapezoids && !fo.is_spotan && !lop_is_idempotent(lop)) { gs_fixed_rect rbox; @@ -451,16 +432,114 @@ if (fo.adjust_left | fo.adjust_right | fo.adjust_below | fo.adjust_above) fill_by_trapezoids = false; /* avoid double writing pixels */ } + + if (!fo.is_spotan && ((scanconverter = gs_getscanconverter(pdev->memory)) >= GS_SCANCONVERTER_EDGEBUFFER || + (scanconverter == GS_SCANCONVERTER_DEFAULT && GS_SCANCONVERTER_DEFAULT_IS_EDGEBUFFER))) { + gx_edgebuffer eb = { 0 }; + /* If we have a request for accurate curves, make sure we exactly + * match what we'd get for stroking. */ + if (!big_path && pgs->accurate_curves && gx_path_has_curves(ppath)) + { + gx_path_init_local(&ffpath, ppath->memory); + code = gx_path_copy_reducing(ppath, &ffpath, fo.fixed_flat, NULL, + pco_small_curves | pco_accurate); + if (code < 0) + return code; + ppath = &ffpath; + } + + if (fill_by_trapezoids && !lop_is_idempotent(lop)) + fill_by_trapezoids = 0; + if (!fill_by_trapezoids) + { + if (adjust.x == 0 && adjust.y == 0) { + code = gx_scan_convert(dev, + ppath, + &ibox, + &eb, + fo.fixed_flat); + if (code >= 0) { + code = gx_filter_edgebuffer(dev, + &eb, + params->rule); + } + if (code >= 0) { + code = gx_fill_edgebuffer(dev, + pdevc, + &eb, + fo.fill_direct ? -1 : (int)pgs->log_op); + } + } else { + code = gx_scan_convert_app(dev, + ppath, + &ibox, + &eb, + fo.fixed_flat); + if (code >= 0) { + code = gx_filter_edgebuffer_app(dev, + &eb, + params->rule); + } + if (code >= 0) { + code = gx_fill_edgebuffer_app(dev, + pdevc, + &eb, + fo.fill_direct ? -1 : (int)pgs->log_op); + } + } + } else { + if (adjust.x == 0 && adjust.y == 0) { + code = gx_scan_convert_tr(dev, + ppath, + &ibox, + &eb, + fo.fixed_flat); + if (code >= 0) { + code = gx_filter_edgebuffer_tr(dev, + &eb, + params->rule); + } + if (code >= 0) { + code = gx_fill_edgebuffer_tr(dev, + pdevc, + &eb, + (int)pgs->log_op); + } + } else { + code = gx_scan_convert_tr_app(dev, + ppath, + &ibox, + &eb, + fo.fixed_flat); + if (code >= 0) { + code = gx_filter_edgebuffer_tr_app(dev, + &eb, + params->rule); + } + if (code >= 0) { + code = gx_fill_edgebuffer_tr_app(dev, + pdevc, + &eb, + (int)pgs->log_op); + } + } + } + if (ppath == &ffpath) + gx_path_free(ppath, "gx_general_fill_path"); + gx_edgebuffer_fin(dev,&eb); + return code; + } + gx_path_init_local(&ffpath, ppath->memory); if (!big_path && !gx_path_has_curves(ppath)) /* don't need to flatten */ pfpath = ppath; else if (is_spotan_device(dev)) pfpath = ppath; - else if (!big_path && gx_path__check_curves(ppath, pco_small_curves, fo.fixed_flat)) + else if (!big_path && !pgs->accurate_curves && gx_path__check_curves(ppath, pco_small_curves, fo.fixed_flat)) pfpath = ppath; else { code = gx_path_copy_reducing(ppath, &ffpath, fo.fixed_flat, NULL, - pco_small_curves); + pco_small_curves | (pgs->accurate_curves ? pco_accurate : 0)); if (code < 0) return code; pfpath = &ffpath; @@ -471,6 +550,8 @@ } } fo.fill_by_trapezoids = fill_by_trapezoids; + /* Initialize the active line list. */ + init_line_list(&lst, ppath->memory); if ((code = add_y_list(pfpath, &lst)) < 0) goto nope; { @@ -481,25 +562,7 @@ fill_loop = spot_into_trapezoids; else fill_loop = spot_into_scan_lines; - if (lst.bbox_width > MAX_LOCAL_SECTION && fo.pseudo_rasterization) { - /* - * Note that execution pass here only for character size - * grater that MAX_LOCAL_SECTION and lesser than - * SMALL_CHARACTER. Therefore with !arch_small_memory - * the dynamic allocation only happens for characters - * wider than 100 pixels. - */ - lst.margin_set0.sect = (section *)gs_alloc_struct_array(pdev->memory, lst.bbox_width * 2, - section, &st_section, "gx_general_fill_path"); - if (lst.margin_set0.sect == 0) - return_error(gs_error_VMerror); - lst.margin_set1.sect = lst.margin_set0.sect + lst.bbox_width; - } - if (fo.pseudo_rasterization) { - init_section(lst.margin_set0.sect, 0, lst.bbox_width); - init_section(lst.margin_set1.sect, 0, lst.bbox_width); - } - if (gs_currentcpsimode(pis->memory) && is_character) { + if (gs_currentcpsimode(pgs->memory) && is_character) { if (lst.contour_count > countof(lst.local_windings)) { lst.windings = (int *)gs_alloc_byte_array(pdev->memory, lst.contour_count, sizeof(int), "gx_general_fill_path"); @@ -509,9 +572,6 @@ } code = (*fill_loop) (&lst, (max_fill_band == 0 ? NO_BAND_MASK : int2fixed(-max_fill_band))); - if (lst.margin_set0.sect != lst.local_section0 && - lst.margin_set0.sect != lst.local_section1) - gs_free_object(pdev->memory, min(lst.margin_set0.sect, lst.margin_set1.sect), "gx_general_fill_path"); if (lst.windings != NULL && lst.windings != lst.local_windings) gs_free_object(pdev->memory, lst.windings, "gx_general_fill_path"); } @@ -543,21 +603,23 @@ stats_fill.slow_order); } #endif + if (clipping) + gx_destroy_clip_device_on_stack(&cdev); return code; } static int -pass_shading_area_through_clip_path_device(gx_device * pdev, const gs_imager_state * pis, +pass_shading_area_through_clip_path_device(gx_device * pdev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { if (pdevc == NULL) { gx_device_clip *cdev = (gx_device_clip *)pdev; - return dev_proc(cdev->target, fill_path)(cdev->target, pis, ppath, params, pdevc, pcpath); + return dev_proc(cdev->target, fill_path)(cdev->target, pgs, ppath, params, pdevc, pcpath); } /* We know that tha clip path device implements fill_path with default proc. */ - return gx_default_fill_path(pdev, pis, ppath, params, pdevc, pcpath); + return gx_default_fill_path(pdev, pgs, ppath, params, pdevc, pcpath); } /* @@ -565,7 +627,7 @@ * fill_path procedure. */ int -gx_default_fill_path(gx_device * pdev, const gs_imager_state * pis, +gx_default_fill_path(gx_device * pdev, const gs_gstate * pgs, gx_path * ppath, const gx_fill_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { @@ -591,7 +653,7 @@ */ gx_clip_path cpath_intersection, cpath_with_shading_bbox; const gx_clip_path *pcpath1, *pcpath2; - gs_imager_state *pis_noconst = (gs_imager_state *)pis; /* Break const. */ + gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */ if (ppath != NULL) { code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, pdev->memory, 1); @@ -605,7 +667,7 @@ } if (code >= 0) code = gx_cpath_intersect_with_params(&cpath_intersection, ppath, params->rule, - pis_noconst, params); + pgs_noconst, params); pcpath1 = &cpath_intersection; } else pcpath1 = pcpath; @@ -631,7 +693,7 @@ /* A special interaction with clist writer device : pass the intersected clipping path. It uses an unusual call to fill_path with NULL device color. */ - code = (*dev_proc(pdev, fill_path))(pdev, pis, ppath, params, NULL, pcpath1); + code = (*dev_proc(pdev, fill_path))(pdev, pgs, ppath, params, NULL, pcpath1); dev = pdev; } else { gx_make_clip_device_on_stack(&cdev, pcpath1, pdev); @@ -644,34 +706,14 @@ if (code >= 0) code = pdevc->type->fill_rectangle(pdevc, cb.p.x, cb.p.y, cb.q.x - cb.p.x, cb.q.y - cb.p.y, - dev, pis->log_op, rs); + dev, pgs->log_op, rs); } if (ppath != NULL) gx_cpath_free(&cpath_intersection, "shading_fill_cpath_intersection"); if (pcpath1 != pcpath2) gx_cpath_free(&cpath_with_shading_bbox, "shading_fill_cpath_intersection"); } else { -#ifndef GS_THREADSAFE - bool got_dc = false; - vd_save; - if (vd_allowed('F') || vd_allowed('f')) { - if (!vd_enabled) { - vd_get_dc( (params->adjust.x > 0 || params->adjust.y > 0) ? 'F' : 'f'); - got_dc = vd_enabled; - } - if (vd_enabled) { - vd_set_shift(0, 100); - vd_set_scale(VD_SCALE); - vd_set_origin(0, 0); - vd_erase(RGB(192, 192, 192)); - } - } else - vd_disable; - code = gx_general_fill_path(pdev, pis, ppath, params, pdevc, pcpath); - if (got_dc) - vd_release_dc; - vd_restore; -#endif + code = gx_general_fill_path(pdev, pgs, ppath, params, pdevc, pcpath); } return code; } @@ -690,7 +732,6 @@ gs_free_object(mem, alp, "active line"); ll->active_area = next; } - free_all_margins(ll); } static inline active_line * @@ -720,7 +761,6 @@ active_line *nyp; fixed y_start = alp->start.y; - vd_bar(alp->start.x, alp->start.y, alp->end.x, alp->end.y, 0, RGB(255, 0, 0)); if (yp == 0) { alp->next = alp->prev = 0; ll->y_list = alp; @@ -750,13 +790,12 @@ ll->y_list = alp; } ll->y_line = alp; - vd_bar(alp->start.x, alp->start.y, alp->end.x, alp->end.y, 1, RGB(0, 255, 0)); print_al(ll->memory, "add ", alp); } typedef struct contour_cursor_s { segment *prev, *pseg, *pfirst, *plast; - gx_flattened_iterator *fi; + gx_flattened_iterator fi; bool more_flattened; bool first_flattened; int dir; @@ -769,9 +808,9 @@ compute_dir(const fill_options *fo, fixed y0, fixed y1) { if (max(y0, y1) < fo->ymin) - return 2; + return DIR_OUT_OF_Y_RANGE; if (min(y0, y1) > fo->ymax) - return 2; + return DIR_OUT_OF_Y_RANGE; return (y0 < y1 ? DIR_UP : y0 > y1 ? DIR_DOWN : DIR_HORIZONTAL); } @@ -824,14 +863,14 @@ if (q->monotonic_y) code = add_y_line(q->prev, q->pseg, DIR_DOWN, ll); else - code = add_y_curve_part(ll, q->prev, q->pseg, DIR_DOWN, q->fi, + code = add_y_curve_part(ll, q->prev, q->pseg, DIR_DOWN, &q->fi, !q->first_flattened, false, q->monotonic_x); if (code < 0) return code; if (p->monotonic_y) code = add_y_line(p->prev, p->pseg, DIR_UP, ll); else - code = add_y_curve_part(ll, p->prev, p->pseg, DIR_UP, p->fi, + code = add_y_curve_part(ll, p->prev, p->pseg, DIR_UP, &p->fi, p->more_flattened, false, p->monotonic_x); return code; } @@ -845,41 +884,41 @@ /* q stands at the first segment, which isn't last. */ do { - code = gx_flattened_iterator__next(q->fi); + code = gx_flattened_iterator__next(&q->fi); if (code < 0) return code; q->more_flattened = code; - dir = compute_dir(fo, q->fi->ly0, q->fi->ly1); - if (q->fi->ly0 > fo->ymax && ll->y_break > q->fi->y0) - ll->y_break = q->fi->ly0; - if (q->fi->ly1 > fo->ymax && ll->y_break > q->fi->ly1) - ll->y_break = q->fi->ly1; - if (dir == DIR_UP && ll->main_dir == DIR_DOWN && q->fi->ly0 >= fo->ymin) { - code = add_y_curve_part(ll, q->prev, q->pseg, DIR_DOWN, q->fi, - true, true, q->monotonic_x); - if (code < 0) - return code; - code = add_y_curve_part(ll, q->prev, q->pseg, DIR_UP, q->fi, - q->more_flattened, false, q->monotonic_x); - if (code < 0) - return code; - } else if (q->fi->ly0 < fo->ymin && q->fi->ly1 >= fo->ymin) { - code = add_y_curve_part(ll, q->prev, q->pseg, DIR_UP, q->fi, - q->more_flattened, false, q->monotonic_x); - if (code < 0) - return code; - } else if (q->fi->ly0 >= fo->ymin && q->fi->ly1 < fo->ymin) { - code = add_y_curve_part(ll, q->prev, q->pseg, DIR_DOWN, q->fi, - true, false, q->monotonic_x); + dir = compute_dir(fo, q->fi.ly0, q->fi.ly1); + if (q->fi.ly0 > fo->ymax && ll->y_break > q->fi.y0) + ll->y_break = q->fi.ly0; + if (q->fi.ly1 > fo->ymax && ll->y_break > q->fi.ly1) + ll->y_break = q->fi.ly1; + if (q->fi.ly0 >= fo->ymin) { + if (dir == DIR_UP && ll->main_dir == DIR_DOWN) { + code = add_y_curve_part(ll, q->prev, q->pseg, DIR_DOWN, &q->fi, + true, true, q->monotonic_x); + if (code < 0) + return code; + code = add_y_curve_part(ll, q->prev, q->pseg, DIR_UP, &q->fi, + q->more_flattened, false, q->monotonic_x); + if (code < 0) + return code; + } else if (q->fi.ly1 < fo->ymin) { + code = add_y_curve_part(ll, q->prev, q->pseg, DIR_DOWN, &q->fi, + true, false, q->monotonic_x); + if (code < 0) + return code; + } + } else if (q->fi.ly1 >= fo->ymin) { + code = add_y_curve_part(ll, q->prev, q->pseg, DIR_UP, &q->fi, + q->more_flattened, false, q->monotonic_x); if (code < 0) return code; } q->first_flattened = false; q->dir = dir; - ll->main_dir = (dir == DIR_DOWN ? DIR_DOWN : - dir == DIR_UP ? DIR_UP : ll->main_dir); - if (!q->more_flattened) - break; + if (dir == DIR_DOWN || dir == DIR_UP) + ll->main_dir = dir; } while(q->more_flattened); /* q stands at the last segment. */ return 0; @@ -888,10 +927,8 @@ } static inline int -init_contour_cursor(line_list *ll, contour_cursor *q) +init_contour_cursor(const fill_options * const fo, contour_cursor *q) { - const fill_options * const fo = ll->fo; - if (q->pseg->type == s_curve) { curve_segment *s = (curve_segment *)q->pseg; fixed ymin = min(min(q->prev->pt.y, s->p1.y), min(s->p2.y, s->pt.y)); @@ -911,153 +948,196 @@ curve_segment *s = (curve_segment *)q->pseg; int k = gx_curve_log2_samples(q->prev->pt.x, q->prev->pt.y, s, fo->fixed_flat); - if (!gx_flattened_iterator__init(q->fi, q->prev->pt.x, q->prev->pt.y, s, k)) + if (!gx_flattened_iterator__init(&q->fi, q->prev->pt.x, q->prev->pt.y, s, k)) return_error(gs_error_rangecheck); } else { q->dir = compute_dir(fo, q->prev->pt.y, q->pseg->pt.y); - gx_flattened_iterator__init_line(q->fi, + gx_flattened_iterator__init_line(&q->fi, q->prev->pt.x, q->prev->pt.y, q->pseg->pt.x, q->pseg->pt.y); /* fake for curves. */ - vd_bar(q->prev->pt.x, q->prev->pt.y, q->pseg->pt.x, q->pseg->pt.y, 1, RGB(0, 0, 255)); } q->first_flattened = true; return 0; } static int -scan_contour(line_list *ll, contour_cursor *q) +scan_contour(line_list *ll, segment *pfirst, segment *plast, segment *prev) { - contour_cursor p; - gx_flattened_iterator fi, save_fi; - segment *pseg; + contour_cursor p, q; int code; bool only_horizontal = true, saved = false; const fill_options * const fo = ll->fo; contour_cursor save_q; + q.prev = prev; + q.pseg = plast; + q.pfirst = pfirst; + q.plast = plast; + memset(&save_q, 0, sizeof(save_q)); /* Quiet gcc warning. */ p.monotonic_x = false; /* Quiet gcc warning. */ - p.fi = &fi; - save_q.dir = 2; + q.monotonic_x = false; /* Quiet gcc warning. */ + + /* The first thing we do is to walk BACKWARDS along the contour (aka the subpath or + * set of curve segments). We stop either when we reach the beginning again, + * or when we hit a non-horizontal segment. If we hit the beginning, then we + * remember that the segment is 'only_horizontal'. Otherwise, we remember the + * direction of this contour (UP or DOWN). */ + save_q.dir = DIR_OUT_OF_Y_RANGE; ll->main_dir = DIR_HORIZONTAL; - for (; ; q->pseg = q->prev, q->prev = q->prev->prev) { - code = init_contour_cursor(ll, q); + for (; ; q.pseg = q.prev, q.prev = q.prev->prev) { + /* Prepare to walk FORWARDS along the single curve segment in 'q'. */ + code = init_contour_cursor(fo, &q); if (code < 0) return code; for (;;) { - code = gx_flattened_iterator__next(q->fi); + code = gx_flattened_iterator__next(&q.fi); + assert(code >= 0); /* Indicates an internal error */ if (code < 0) return code; + q.dir = compute_dir(fo, q.fi.ly0, q.fi.ly1); + if (q.dir == DIR_DOWN || q.dir == DIR_UP) + ll->main_dir = q.dir; + /* Exit the loop when we hit the end of the single curve segment */ if (!code) break; - q->first_flattened = false; - q->dir = compute_dir(fo, q->fi->ly0, q->fi->ly1); - ll->main_dir = (q->dir == DIR_DOWN ? DIR_DOWN : - q->dir == DIR_UP ? DIR_UP : ll->main_dir); - } - q->dir = compute_dir(fo, q->fi->ly0, q->fi->ly1); - q->more_flattened = false; - ll->main_dir = (q->dir == DIR_DOWN ? DIR_DOWN : - q->dir == DIR_UP ? DIR_UP : ll->main_dir); + q.first_flattened = false; + } + /* Thus first_flattened == true, iff the curve needed no subdivisions */ + q.more_flattened = false; + /* ll->maindir == DIR_HORIZONTAL, iff the curve is entirely horizontal + * (or entirely out of y range). It will contain whatever the last UP or DOWN + * section was otherwise. */ if (ll->main_dir != DIR_HORIZONTAL) { only_horizontal = false; + /* Now we know we're not entirely horizontal, we can abort this run. */ break; } - if (!saved && q->dir != 2) { - save_q = *q; - save_fi = *q->fi; + /* If we haven't saved one yet, and we are not out of range, save this one. + * i.e. save_q and save_fi are the first 'in range' section. We can save + * time in subsequent passes through by starting here. */ + if (!saved && q.dir != DIR_OUT_OF_Y_RANGE) { + save_q = q; saved = true; } - if (q->prev == q->pfirst) - break; + if (q.prev == q.pfirst) + break; /* Exit if we're back at the start of the contour */ } + + /* Second run through; this is where we actually do the hard work. */ + /* Restore q if we saved it above */ if (saved) { - *q = save_q; - *q->fi = save_fi; + q = save_q; } - for (pseg = q->pfirst; pseg != q->plast; pseg = pseg->next) { - p.prev = pseg; - p.pseg = pseg->next; - if (!fo->pseudo_rasterization || only_horizontal - || p.prev->pt.x != p.pseg->pt.x || p.prev->pt.y != p.pseg->pt.y - || p.pseg->type == s_curve) { - code = init_contour_cursor(ll, &p); - if (code < 0) - return code; + /* q is now at the start of a run that we know will head in an + * ll->main_dir direction. Start p at the next place and walk + * forwards. */ + for (p.prev = q.pfirst; p.prev != q.plast; p.prev = p.pseg) { + bool added; + p.pseg = p.prev->next; + /* Can we ignore this segment entirely? */ + if (!only_horizontal && p.pseg->type != s_curve && + p.prev->pt.x == p.pseg->pt.x && p.prev->pt.y == p.pseg->pt.y) + continue; + + /* Prepare to walk down 'p' */ + code = init_contour_cursor(fo, &p); + if (code < 0) + return code; + + do { + /* Find the next flattened section that is within range */ do { - code = gx_flattened_iterator__next(p.fi); + code = gx_flattened_iterator__next(&p.fi); + assert(code >= 0); /* Indicates an internal error */ if (code < 0) return code; p.more_flattened = code; - p.dir = compute_dir(fo, p.fi->ly0, p.fi->ly1); - } while (p.more_flattened && p.dir == 2); - if (p.fi->ly0 > fo->ymax && ll->y_break > p.fi->ly0) - ll->y_break = p.fi->ly0; - if (p.fi->ly1 > fo->ymax && ll->y_break > p.fi->ly1) - ll->y_break = p.fi->ly1; - if (p.monotonic_y && p.dir == DIR_HORIZONTAL && - !fo->pseudo_rasterization && + p.dir = compute_dir(fo, p.fi.ly0, p.fi.ly1); + } while (p.more_flattened && p.dir == DIR_OUT_OF_Y_RANGE); + + /* So either we're in range, or we've reached the end of the segment (or both) */ + /* FIXME: Can we break here if p.dir == DIR_OUT_OF_Y_RANGE? */ + + /* Set ll->y_break to be the smallest line endpoint we find > ymax */ + if (p.fi.ly0 > fo->ymax && ll->y_break > p.fi.ly0) + ll->y_break = p.fi.ly0; + if (p.fi.ly1 > fo->ymax && ll->y_break > p.fi.ly1) + ll->y_break = p.fi.ly1; + + added = 0; + if (p.dir == DIR_HORIZONTAL) { + if (p.monotonic_y) { + if ( #ifdef FILL_ZERO_WIDTH - (fo->adjust_below | fo->adjust_above) != 0) { + (fo->adjust_below | fo->adjust_above) != 0) { #else - fixed2int_pixround(p.pseg->pt.y - fo->adjust_below) < - fixed2int_pixround(p.pseg->pt.y + fo->adjust_above)) { + (fo->adjust_below + fo->adjust_above >= (fixed_1 - fixed_epsilon) || + fixed2int_pixround(p.pseg->pt.y - fo->adjust_below) < + fixed2int_pixround(p.pseg->pt.y + fo->adjust_above))) { #endif - /* Add it here to avoid double processing in process_h_segments. */ - code = add_y_line(p.prev, p.pseg, DIR_HORIZONTAL, ll); - if (code < 0) - return code; - } - if (p.monotonic_y && p.dir == DIR_HORIZONTAL && - fo->pseudo_rasterization && only_horizontal) { - /* Add it here to avoid double processing in process_h_segments. */ - code = add_y_line(p.prev, p.pseg, DIR_HORIZONTAL, ll); - if (code < 0) - return code; - } - if (p.fi->ly0 >= fo->ymin && p.dir == DIR_UP && ll->main_dir == DIR_DOWN) { - code = start_al_pair(ll, q, &p); - if (code < 0) - return code; - } - if (p.fi->ly0 < fo->ymin && p.fi->ly1 >= fo->ymin) { - if (p.monotonic_y) - code = add_y_line(p.prev, p.pseg, DIR_UP, ll); - else - code = add_y_curve_part(ll, p.prev, p.pseg, DIR_UP, p.fi, - p.more_flattened, false, p.monotonic_x); - if (code < 0) - return code; - } - if (p.fi->ly0 >= fo->ymin && p.fi->ly1 < fo->ymin) { - if (p.monotonic_y) - code = add_y_line(p.prev, p.pseg, DIR_DOWN, ll); - else - code = add_y_curve_part(ll, p.prev, p.pseg, DIR_DOWN, p.fi, - !p.first_flattened, false, p.monotonic_x); - if (code < 0) - return code; + /* Add it here to avoid double processing in process_h_segments. */ + code = add_y_line(p.prev, p.pseg, DIR_HORIZONTAL, ll); + if (code < 0) + return code; + added = 1; + } + } + } else { + if (p.fi.ly0 >= fo->ymin) + { + if (p.dir == DIR_UP && ll->main_dir == DIR_DOWN) { + /* p starts within range, and heads up. q was heading down. Therefore + * they meet at a local minima. Start a pair of active lines from that. */ + code = start_al_pair(ll, &q, &p); + if (code < 0) + return code; + added = 1; + } else if (p.fi.ly1 < fo->ymin) { + /* p heading downwards */ + if (p.monotonic_y) + code = add_y_line(p.prev, p.pseg, DIR_DOWN, ll); + else + code = add_y_curve_part(ll, p.prev, p.pseg, DIR_DOWN, &p.fi, + !p.first_flattened, false, p.monotonic_x); + if (code < 0) + return code; + added = 1; + } + } else if (p.fi.ly1 >= fo->ymin) { + /* p heading upwards */ + if (p.monotonic_y) + code = add_y_line(p.prev, p.pseg, DIR_UP, ll); + else + code = add_y_curve_part(ll, p.prev, p.pseg, DIR_UP, &p.fi, + p.more_flattened, false, p.monotonic_x); + if (code < 0) + return code; + added = 1; + } + if (p.dir == DIR_DOWN || p.dir == DIR_UP) + ll->main_dir = p.dir; } - ll->main_dir = (p.dir == DIR_DOWN ? DIR_DOWN : - p.dir == DIR_UP ? DIR_UP : ll->main_dir); if (!p.monotonic_y && p.more_flattened) { code = start_al_pair_from_min(ll, &p); if (code < 0) return code; + added = 1; } if (p.dir == DIR_DOWN || p.dir == DIR_HORIZONTAL) { - gx_flattened_iterator *fi1 = q->fi; - q->prev = p.prev; - q->pseg = p.pseg; - q->monotonic_y = p.monotonic_y; - q->more_flattened = p.more_flattened; - q->first_flattened = p.first_flattened; - q->fi = p.fi; - q->dir = p.dir; - p.fi = fi1; - } - } + q.prev = p.prev; + q.pseg = p.pseg; + q.monotonic_y = p.monotonic_y; + q.more_flattened = p.more_flattened; + q.first_flattened = p.first_flattened; + q.fi = p.fi; + q.dir = p.dir; + } + /* If we haven't added lines based on this segment, and there + * are more flattened lines to come from it, ensure we loop + * to get the rest of them. */ + /* FIXME: Do we need '!added' here? Try removing it. */ + } while (!added && p.more_flattened); } - q->fi = NULL; /* safety. */ return 0; } @@ -1073,10 +1153,7 @@ subpath *psub = ppath->first_subpath; int close_count = 0; int code; - contour_cursor q; - gx_flattened_iterator fi; - q.monotonic_x = false; /* Quiet gcc warning. */ ll->y_break = max_fixed; for (;psub; psub = (subpath *)psub->last->next) { @@ -1084,7 +1161,6 @@ segment *pfirst = (segment *)psub; segment *plast = psub->last, *prev; - q.fi = &fi; if (plast->type != s_line_close) { /* Create a fake s_line_close */ line_close_segment *lp = &psub->closer; @@ -1102,16 +1178,7 @@ ll->close_count++; } prev = plast->prev; - if (ll->fo->pseudo_rasterization && prev != pfirst && - prev->pt.x == plast->pt.x && prev->pt.y == plast->pt.y) { - plast = prev; - prev = prev->prev; - } - q.prev = prev; - q.pseg = plast; - q.pfirst = pfirst; - q.plast = plast; - code = scan_contour(ll, &q); + code = scan_contour(ll, pfirst, plast, prev); if (code < 0) return code; ll->contour_count++; @@ -1134,8 +1201,7 @@ if (code < 0) return code; alp->more_flattened = code; - } else - vd_bar(alp->fi.lx0, alp->fi.ly0, alp->fi.lx1, alp->fi.ly1, 1, RGB(0, 0, 255)); + } /* Note that we can get alp->fi.ly0 == alp->fi.ly1 if the curve tangent is horizontal. */ alp->start.x = (forth ? alp->fi.lx0 : alp->fi.lx1); @@ -1256,7 +1322,6 @@ active_line *next; active_line *prev = &ll->x_head; - vd_bar(alp->start.x, alp->start.y, alp->end.x, alp->end.y, 1, RGB(128, 128, 0)); alp->x_current = alp->start.x; alp->x_next = alp->start.x; /* If the spot starts with a horizontal segment, we need resort_x_line to work properly @@ -1356,30 +1421,10 @@ return true; } alp->x_current = alp->x_next = alp->start.x; - vd_bar(alp->start.x, alp->start.y, alp->end.x, alp->end.y, 1, RGB(128, 0, 128)); print_al(ll->memory, "repl", alp); return false; } -static inline int -add_margin(line_list * ll, active_line * flp, active_line * alp, fixed y0, fixed y1) -{ vd_bar(alp->start.x, alp->start.y, alp->end.x, alp->end.y, 1, RGB(255, 255, 255)); - vd_bar(flp->start.x, flp->start.y, flp->end.x, flp->end.y, 1, RGB(255, 255, 255)); - return continue_margin_common(ll, &ll->margin_set0, flp, alp, y0, y1); -} - -static inline int -continue_margin(line_list * ll, active_line * flp, active_line * alp, fixed y0, fixed y1) -{ - return continue_margin_common(ll, &ll->margin_set0, flp, alp, y0, y1); -} - -static inline int -complete_margin(line_list * ll, active_line * flp, active_line * alp, fixed y0, fixed y1) -{ - return continue_margin_common(ll, &ll->margin_set1, flp, alp, y0, y1); -} - /* * Handle the case of a slanted trapezoid with adjustment. * To do this exactly right requires filling a central trapezoid @@ -1399,8 +1444,6 @@ int code; INCR(slant); - vd_quad(flp->x_current, y, alp->x_current, y, - alp->x_next, y1, flp->x_next, y1, 1, VD_TRAP_COLOR); /* fixme: Wrong X. */ /* Set up all the edges, even though we may not need them all. */ @@ -1613,7 +1656,9 @@ /* next might be null, if alp was in the correct spot already. */ if (next) next->prev = alp; - prev->next = alp; + /* prev can be null if the path reaches (beyond) the extent of our coordinate space */ + if (prev) + prev->next = alp; } /* Move active lines by Y. */ @@ -1653,36 +1698,6 @@ } } } - if (ll->x_list != 0 && ll->fo->pseudo_rasterization) { - /* Ensure that contacting vertical stems are properly ordered. - We don't want to unite contacting stems into - a single margin, because it can cause a dropout : - narrow stems are widened against a dropout, but - an united wide one may be left unwidened. - */ - for (alp = ll->x_list; alp->next != 0; ) { - if (alp->start.x == alp->end.x && - alp->start.x == alp->next->start.x && - alp->next->start.x == alp->next->end.x && - alp->direction > alp->next->direction) { - /* Exchange. */ - active_line *prev = alp->prev; - active_line *next = alp->next; - active_line *next2 = next->next; - if (prev) - prev->next = next; - else - ll->x_list = next; - next->prev = prev; - alp->prev = next; - alp->next = next2; - next->next = alp; - if (next2) - next2->prev = alp; - } else - alp = alp->next; - } - } return 0; } @@ -1691,16 +1706,11 @@ process_h_segments(line_list *ll, fixed y) { active_line *alp, *nlp; - int code, inserted = 0; + int inserted = 0; for (alp = ll->x_list; alp != 0; alp = nlp) { nlp = alp->next; if (alp->start.y == y && alp->end.y == y) { - if (ll->fo->pseudo_rasterization) { - code = add_y_line_aux(NULL, NULL, &alp->start, &alp->end, DIR_HORIZONTAL, ll); - if (code < 0) - return code; - } inserted = 1; } } @@ -1717,7 +1727,6 @@ if (ybot >= ytop) return 0; - vd_quad(le->start.x, ybot, re->start.x, ybot, re->end.x, ytop, le->end.x, ytop, 1, VD_TRAP_COLOR); return (*fo->fill_trap) (fo->dev, le, re, ybot, ytop, false, fo->pdevc, fo->lop); } @@ -1747,7 +1756,7 @@ fixed dx_old = alp->x_current - endp->x_current; fixed dx_den = dx_old + endp->x_next - alp->x_next; - if (dx_den <= dx_old) + if (dx_den <= dx_old || dx_den == 0) return false; /* Intersection isn't possible. */ dy = y1 - y; if_debug3('F', "[F]cross: dy=%g, dx_old=%g, dx_new=%g\n", @@ -1756,7 +1765,7 @@ /* Do the computation in single precision */ /* if the values are small enough. */ y_new = - ((dy | dx_old) < 1L << (size_of(fixed) * 4 - 1) ? + (((ufixed)(dy | dx_old)) < (1L << (size_of(fixed) * 4 - 1)) ? dy * dx_old / dx_den : (INCR_EXPR(mq_cross), fixed_mult_quo(dy, dx_old, dx_den))) + y; @@ -1835,13 +1844,12 @@ active_line *alp, *stopx = NULL; active_line *endp = NULL; - /* don't bother if no pixels with no pseudo_rasterization */ if (y == y1) { /* Rather the intersection algorithm can handle this case with retrieving x_next equal to x_current, we bypass it for safety reason. */ - } else if (ll->fo->pseudo_rasterization || draw >= 0 || all_bands) { + } else if (draw >= 0 || all_bands) { /* * Loop invariants: * alp = endp->next; @@ -1884,7 +1892,6 @@ nx = nx0; } endp->x_next = alp->x_next = nx; /* Ensure same X. */ - draw = 0; /* Can't guarantee same x for triple intersections here. Will take care below */ } @@ -1970,11 +1977,6 @@ *y_top = y1; } -static inline int sign(int a) -{ - return a < 0 ? -1 : a > 0 ? 1 : 0; -} - /* ---------------- Trapezoid filling loop ---------------- */ /* Generate specialized algorythms for the most important cases : */ @@ -1990,56 +1992,24 @@ } #define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 1 -#define SMART_WINDING 1 -#define FILL_ADJUST 0 -#define FILL_DIRECT 1 -#define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__pr_fd_sw -#include "gxfilltr.h" -#undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION -#undef SMART_WINDING -#undef FILL_ADJUST -#undef FILL_DIRECT -#undef TEMPLATE_spot_into_trapezoids - -#define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 1 -#define SMART_WINDING 1 -#define FILL_ADJUST 0 -#define FILL_DIRECT 0 -#define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__pr_nd_sw -#include "gxfilltr.h" -#undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION -#undef SMART_WINDING -#undef FILL_ADJUST -#undef FILL_DIRECT -#undef TEMPLATE_spot_into_trapezoids - -#define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 0 #define SMART_WINDING 1 #define FILL_ADJUST 0 #define FILL_DIRECT 1 #define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__nj_fd_sw #include "gxfilltr.h" #undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION #undef SMART_WINDING #undef FILL_ADJUST #undef FILL_DIRECT #undef TEMPLATE_spot_into_trapezoids #define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 0 #define SMART_WINDING 1 #define FILL_ADJUST 0 #define FILL_DIRECT 0 #define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__nj_nd_sw #include "gxfilltr.h" #undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION #undef SMART_WINDING #undef FILL_ADJUST #undef FILL_DIRECT @@ -2051,98 +2021,60 @@ #define ADVANCE_WINDING(inside, alp, ll) inside += alp->direction #define IS_SPOTAN 1 -#define PSEUDO_RASTERIZATION 0 #define SMART_WINDING 0 #define FILL_ADJUST 0 #define FILL_DIRECT 1 #define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__spotan #include "gxfilltr.h" #undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION -#undef SMART_WINDING -#undef FILL_ADJUST -#undef FILL_DIRECT -#undef TEMPLATE_spot_into_trapezoids - -#define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 1 -#define SMART_WINDING 0 -#define FILL_ADJUST 0 -#define FILL_DIRECT 1 -#define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__pr_fd -#include "gxfilltr.h" -#undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION #undef SMART_WINDING #undef FILL_ADJUST #undef FILL_DIRECT #undef TEMPLATE_spot_into_trapezoids #define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 1 -#define SMART_WINDING 0 -#define FILL_ADJUST 0 -#define FILL_DIRECT 0 -#define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__pr_nd -#include "gxfilltr.h" -#undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION -#undef SMART_WINDING -#undef FILL_ADJUST -#undef FILL_DIRECT -#undef TEMPLATE_spot_into_trapezoids - -#define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 0 #define SMART_WINDING 0 #define FILL_ADJUST 1 #define FILL_DIRECT 1 #define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__aj_fd #include "gxfilltr.h" #undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION #undef SMART_WINDING #undef FILL_ADJUST #undef FILL_DIRECT #undef TEMPLATE_spot_into_trapezoids #define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 0 #define SMART_WINDING 0 #define FILL_ADJUST 1 #define FILL_DIRECT 0 #define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__aj_nd #include "gxfilltr.h" #undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION #undef SMART_WINDING #undef FILL_ADJUST #undef FILL_DIRECT #undef TEMPLATE_spot_into_trapezoids #define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 0 #define SMART_WINDING 0 #define FILL_ADJUST 0 #define FILL_DIRECT 1 #define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__nj_fd #include "gxfilltr.h" #undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION #undef SMART_WINDING #undef FILL_ADJUST #undef FILL_DIRECT #undef TEMPLATE_spot_into_trapezoids #define IS_SPOTAN 0 -#define PSEUDO_RASTERIZATION 0 #define SMART_WINDING 0 #define FILL_ADJUST 0 #define FILL_DIRECT 0 #define TEMPLATE_spot_into_trapezoids spot_into_trapezoids__nj_nd #include "gxfilltr.h" #undef IS_SPOTAN -#undef PSEUDO_RASTERIZATION #undef SMART_WINDING #undef FILL_ADJUST #undef FILL_DIRECT @@ -2161,19 +2093,6 @@ if (fo->is_spotan) return spot_into_trapezoids__spotan(ll, band_mask); - if (fo->pseudo_rasterization) { - if (ll->windings != NULL) { - if (fo->fill_direct) - return spot_into_trapezoids__pr_fd_sw(ll, band_mask); - else - return spot_into_trapezoids__pr_nd_sw(ll, band_mask); - } else { - if (fo->fill_direct) - return spot_into_trapezoids__pr_fd(ll, band_mask); - else - return spot_into_trapezoids__pr_nd(ll, band_mask); - } - } if (fo->adjust_below | fo->adjust_above | fo->adjust_left | fo->adjust_right) { if (fo->fill_direct) return spot_into_trapezoids__aj_fd(ll, band_mask); @@ -2436,7 +2355,6 @@ if (alp->start.y < y_min) continue; if (alp->monotonic_x && alp->monotonic_y && ye <= y_top) { - vd_bar(alp->start.x, alp->start.y, alp->end.x, alp->end.y, 0, RGB(255, 0, 0)); x1 = xe; if (x0 > x1) xt = x0, x0 = x1, x1 = xt; diff -Nru ghostscript-9.10~dfsg/base/gxfill.h ghostscript-9.25~dfsg+1/base/gxfill.h --- ghostscript-9.10~dfsg/base/gxfill.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfill.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,6 +19,14 @@ #ifndef gxfill_INCLUDED # define gxfill_INCLUDED +enum +{ + DIR_UP = 1, + DIR_HORIZONTAL = 0, + DIR_DOWN = -1, + DIR_OUT_OF_Y_RANGE = 2 +}; + /* Define the structure for keeping track of active lines. */ #ifndef active_line_DEFINED # define active_line_DEFINED @@ -71,9 +79,6 @@ fixed x_next; /* x position at end of band */ const segment *pseg; /* endpoint of this line */ int direction; /* direction of line segment */ -#define DIR_UP 1 -#define DIR_HORIZONTAL 0 /* (these are handled specially) */ -#define DIR_DOWN (-1) bool monotonic_x; /* "false" means "don't know"; only for scanline. */ bool monotonic_y; /* "false" means "don't know"; only for scanline. */ gx_flattened_iterator fi; @@ -91,7 +96,6 @@ }; typedef struct fill_options_s { - bool pseudo_rasterization; /* See comment about "pseudo-rasterization". */ fixed ymin, ymax; const gx_device_color * pdevc; gs_logical_operation_t lop; @@ -124,10 +128,7 @@ active_line x_head; /* X-sorted list of active lines */ #define x_list x_head.next active_line *h_list0, *h_list1; /* lists of horizontal lines for y, y1 */ - margin_set margin_set0, margin_set1; - margin *free_margin_list; int *windings; - int local_margin_alloc_count; int bbox_left, bbox_width; int main_dir; fixed y_break; @@ -137,7 +138,7 @@ /* small displacements. */ /* Allocate a few active_lines locally */ /* to avoid round trips through the allocator. */ -#if arch_small_memory +#if ARCH_SMALL_MEMORY # define MAX_LOCAL_ACTIVE 6 /* don't overburden the stack */ # define MAX_LOCAL_SECTION 50 #else @@ -145,9 +146,6 @@ # define MAX_LOCAL_SECTION 100 #endif active_line local_active[MAX_LOCAL_ACTIVE]; - margin local_margins[MAX_LOCAL_ACTIVE]; - section local_section0[MAX_LOCAL_SECTION]; - section local_section1[MAX_LOCAL_SECTION]; int local_windings[MAX_LOCAL_ACTIVE]; }; diff -Nru ghostscript-9.10~dfsg/base/gxfillsl.h ghostscript-9.25~dfsg+1/base/gxfillsl.h --- ghostscript-9.10~dfsg/base/gxfillsl.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfillsl.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -151,7 +151,6 @@ if_debug4m('Q', ll->memory, "[Qr]draw 0x%lx: [%d,%d),%d\n", (ulong)pcr, x0, x1, y0); - VD_RECT(x0, y0, x1 - x0, 1, VD_TRAP_COLOR); code = LOOP_FILL_RECTANGLE_DIRECT(&fo, x0, y0, x1 - x0, 1); if_debug3m('F', ll->memory, "[F]drawing [%d:%d),%d\n", x0, x1, y0); if (code < 0) diff -Nru ghostscript-9.10~dfsg/base/gxfilltr.h ghostscript-9.25~dfsg+1/base/gxfilltr.h --- ghostscript-9.10~dfsg/base/gxfilltr.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfilltr.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,7 +22,6 @@ * Configuration macros (template arguments) are : * * IS_SPOTAN - is the target device a spot analyzer ("spotan"). - * PSEUDO_RASTERIZATION - use pseudo-rasterization. * SMART_WINDING - even-odd filling rule for each contour independently. * FILL_ADJUST - fill adjustment is not zero * FILL_DIRECT - See LOOP_FILL_RECTANGLE_DIRECT. @@ -52,11 +51,9 @@ y = yll->start.y; /* first Y value */ ll->x_list = 0; ll->x_head.x_current = min_fixed; /* stop backward scan */ - ll->margin_set0.y = fixed_pixround(y) - fixed_half; - ll->margin_set1.y = fixed_pixround(y) - fixed_1 - fixed_half; while (1) { fixed y1; - active_line *alp, *plp = NULL; + active_line *alp; bool covering_pixel_centers; INCR(iter); @@ -70,27 +67,23 @@ if (ynext != NULL) ynext->prev = NULL; if (yll->direction == DIR_HORIZONTAL) { - if (!PSEUDO_RASTERIZATION) { - /* - * This is a hack to make sure that isolated horizontal - * lines get stroked. - */ - int yi = fixed2int_pixround(y - (!FILL_ADJUST ? 0 : fo.adjust_below)); - int xi, wi; - - if (yll->start.x <= yll->end.x) { - xi = fixed2int_pixround(yll->start.x - (!FILL_ADJUST ? 0 : fo.adjust_left)); - wi = fixed2int_pixround(yll->end.x + (!FILL_ADJUST ? 0 : fo.adjust_right)) - xi; - } else { - xi = fixed2int_pixround(yll->end.x - (!FILL_ADJUST ? 0 : fo.adjust_left)); - wi = fixed2int_pixround(yll->start.x + (!FILL_ADJUST ? 0 : fo.adjust_right)) - xi; - } - VD_RECT(xi, yi, wi, 1, VD_TRAP_COLOR); - code = LOOP_FILL_RECTANGLE_DIRECT(&fo, xi, yi, wi, 1); - if (code < 0) - return code; - } else if (PSEUDO_RASTERIZATION) - insert_h_new(yll, ll); + /* + * This is a hack to make sure that isolated horizontal + * lines get stroked. + */ + int yi = fixed2int_pixround(y - (!FILL_ADJUST ? 0 : fo.adjust_below)); + int xi, wi; + + if (yll->start.x <= yll->end.x) { + xi = fixed2int_pixround(yll->start.x - (!FILL_ADJUST ? 0 : fo.adjust_left)); + wi = fixed2int_pixround(yll->end.x + (!FILL_ADJUST ? 0 : fo.adjust_right)) - xi; + } else { + xi = fixed2int_pixround(yll->end.x - (!FILL_ADJUST ? 0 : fo.adjust_left)); + wi = fixed2int_pixround(yll->start.x + (!FILL_ADJUST ? 0 : fo.adjust_right)) - xi; + } + code = LOOP_FILL_RECTANGLE_DIRECT(&fo, xi, yi, wi, 1); + if (code < 0) + return code; } else insert_x_new(yll, ll); yll = ynext; @@ -106,10 +99,6 @@ ll->h_list0 = 0; continue; } - if (vd_enabled) { - vd_circle(0, y, 3, RGB(255, 0, 0)); - y += 0; /* Just a good place for a debugger breakpoint */ - } /* Find the next evaluation point. */ /* Start by finding the smallest y value */ /* at which any currently active line ends */ @@ -159,12 +148,6 @@ (!FILL_ADJUST ? 0 : fo.adjust_below), (!FILL_ADJUST ? 0 : fo.adjust_above)); } - /* Prepare dropout prevention. */ - if (PSEUDO_RASTERIZATION) { - code = start_margin_set(fo.dev, ll, y1); - if (code < 0) - return code; - } /* Fill a multi-trapezoid band for the active lines. */ if (covering_pixel_centers || all_bands) { int inside = 0; @@ -215,7 +198,6 @@ INCR(band_fill); if (FILL_ADJUST && !(flp->end.x == flp->start.x && alp->end.x == alp->start.x) && (fo.adjust_below | fo.adjust_above) != 0) { - /* Assuming pseudo_rasterization = false. */ if (FILL_DIRECT) code = slant_into_trapezoids__fd(ll, flp, alp, y, y1); else @@ -243,10 +225,10 @@ int xi = fixed2int_var_pixround(alp->end.x + (!FILL_ADJUST ? 0 : fo.adjust_right)); #ifdef FILL_ZERO_WIDTH - if ( (xli == xi) && (PSEUDO_RASTERIZATION || - (FILL_ADJUST && (fo.adjust_right | fo.adjust_left) != 0))) { + if ( xli == xi && FILL_ADJUST && + (fo.adjust_right | fo.adjust_left) != 0 ) { #else - if (PSEUDO_RASTERIZATION && xli == xi) { + if (0) { #endif /* * The scan is empty but we should paint something @@ -260,7 +242,6 @@ else --xli; } - vd_rect(flp->end.x, y, alp->end.x, y1, 1, VD_TRAP_COLOR); code = LOOP_FILL_RECTANGLE_DIRECT(&fo, xli, yi, xi - xli, hi); } else code = 0; @@ -271,77 +252,15 @@ le.end = flp->end; re.start = alp->start; re.end = alp->end; - vd_quad(flp->x_current, ybot, alp->x_current, ybot, alp->x_next, ytop, flp->x_next, ytop, 1, VD_TRAP_COLOR); - if (PSEUDO_RASTERIZATION) { - int flags = ftf_pseudo_rasterization; - - if (flp->start.x == alp->start.x && flp->start.y == y && alp->start.y == y) - flags |= ftf_peak0; - if (flp->end.x == alp->end.x && flp->end.y == y1 && alp->end.y == y1) - flags |= ftf_peak0; - if (FILL_DIRECT) - code = gx_fill_trapezoid_cf_fd(fo.dev, &le, &re, ybot, ytop, flags, fo.pdevc, fo.lop); - else - code = gx_fill_trapezoid_cf_nd(fo.dev, &le, &re, ybot, ytop, flags, fo.pdevc, fo.lop); - } else - code = fo.fill_trap(fo.dev, - &le, &re, ybot, ytop, false, fo.pdevc, fo.lop); + code = fo.fill_trap(fo.dev, + &le, &re, ybot, ytop, false, fo.pdevc, fo.lop); } else code = 0; } - if (PSEUDO_RASTERIZATION) { - if (code < 0) - return code; - code = complete_margin(ll, flp, alp, y, y1); - if (code < 0) - return code; - code = margin_interior(ll, flp, alp, y, y1); - if (code < 0) - return code; - code = add_margin(ll, flp, alp, y, y1); - if (code < 0) - return code; - code = process_h_lists(ll, plp, flp, alp, y, y1); - plp = alp; - } } if (code < 0) return code; } - } else { - /* No trapezoids generation needed. */ - if (PSEUDO_RASTERIZATION) { - /* Process dropouts near trapezoids. */ - active_line *flp = NULL; - int inside = 0; - - if (SMART_WINDING) - memset(ll->windings, 0, sizeof(ll->windings[0]) * ll->contour_count); - for (alp = ll->x_list; alp != 0; alp = alp->next) { - if (!INSIDE_PATH_P(inside, rule)) { /* i.e., outside */ - ADVANCE_WINDING(inside, alp, ll); - if (INSIDE_PATH_P(inside, rule)) /* about to go in */ - flp = alp; - continue; - } - /* We're inside a region being filled. */ - ADVANCE_WINDING(inside, alp, ll); - if (INSIDE_PATH_P(inside, rule)) /* not about to go out */ - continue; - code = continue_margin(ll, flp, alp, y, y1); - if (code < 0) - return code; - code = process_h_lists(ll, plp, flp, alp, y, y1); - plp = alp; - if (code < 0) - return code; - } - } - } - if (PSEUDO_RASTERIZATION && plp != 0) { - code = process_h_lists(ll, plp, 0, 0, y, y1); - if (code < 0) - return code; } code = move_al_by_y(ll, y1); if (code < 0) @@ -350,14 +269,5 @@ ll->h_list0 = 0; y = y1; } - if (PSEUDO_RASTERIZATION) { - code = process_h_lists(ll, 0, 0, 0, y, y + 1 /*stub*/); - if (code < 0) - return code; - code = close_margins(fo.dev, ll, &ll->margin_set1); - if (code < 0) - return code; - return close_margins(fo.dev, ll, &ll->margin_set0); - } return 0; } diff -Nru ghostscript-9.10~dfsg/base/gxfillts.h ghostscript-9.25~dfsg+1/base/gxfillts.h --- ghostscript-9.10~dfsg/base/gxfillts.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfillts.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -142,8 +142,6 @@ code = LOOP_FILL_RECTANGLE_DIRECT(fo, xli, fixed2int_pixround(y1 - fo->adjust_below), xri - xli, 1); - vd_rect(flp->x_next - fo->adjust_left, y1 - fo->adjust_below, - alp->x_next + fo->adjust_right, y1, 1, VD_TRAP_COLOR); if (code < 0) return code; } @@ -208,8 +206,6 @@ code = LOOP_FILL_RECTANGLE_DIRECT(fo, xli, fixed2int_pixround(y - fo->adjust_below), xri - xli, 1); - vd_rect(flp->x_current - fo->adjust_left, y - fo->adjust_below, - alp->x_current + fo->adjust_right, y, 1, VD_TRAP_COLOR); if (code < 0) return code; } diff -Nru ghostscript-9.10~dfsg/base/gxfixed.h ghostscript-9.25~dfsg+1/base/gxfixed.h --- ghostscript-9.10~dfsg/base/gxfixed.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfixed.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfmap.h ghostscript-9.25~dfsg+1/base/gxfmap.h --- ghostscript-9.10~dfsg/base/gxfmap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfmap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -96,11 +96,11 @@ /* Define a mapping procedure that just looks up the value in the cache. */ /* (It is equivalent to gx_map_color_float with the arguments swapped.) */ -float gs_mapped_transfer(floatp, const gx_transfer_map *); +float gs_mapped_transfer(double, const gx_transfer_map *); /* Define an identity mapping procedure. */ /* Don't store this directly in proc/closure.proc: */ /* use gx_set_identity_transfer. */ -float gs_identity_transfer(floatp, const gx_transfer_map *); +float gs_identity_transfer(double, const gx_transfer_map *); #endif /* gxfmap_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxfont0c.h ghostscript-9.25~dfsg+1/base/gxfont0c.h --- ghostscript-9.10~dfsg/base/gxfont0c.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfont0c.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfont0.h ghostscript-9.25~dfsg+1/base/gxfont0.h --- ghostscript-9.10~dfsg/base/gxfont0.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfont0.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfont1.h ghostscript-9.25~dfsg+1/base/gxfont1.h --- ghostscript-9.10~dfsg/base/gxfont1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfont1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfont42.h ghostscript-9.25~dfsg+1/base/gxfont42.h --- ghostscript-9.10~dfsg/base/gxfont42.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfont42.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -108,6 +108,10 @@ */ uint numGlyphs; /* from size of loca */ uint trueNumGlyphs; /* from maxp */ + uint maxPoints; /* from maxp (used by pdfwrite) */ + uint maxContours; /* from maxp (used by pdfwrite) */ + uint maxCPoints; /* from maxp (used by pdfwrite) */ + uint maxCContours; /* from maxp (used by pdfwrite) */ uint *len_glyphs; /* built from the loca table */ gs_glyph_cache *gdcache; bool warning_patented; @@ -155,7 +159,7 @@ #define MAX_NUM_TT_TABLES 40 /* Append the outline of a TrueType character to a path. */ -int gs_type42_append(uint glyph_index, gs_state * pgs, +int gs_type42_append(uint glyph_index, gs_gstate * pgs, gx_path * ppath, gs_text_enum_t *penum, gs_font *pfont, bool charpath_flag); @@ -188,4 +192,10 @@ int *pmp /*[2], may be null*/, const gs_font_type42 *pfont, const gs_matrix_fixed *pmat); +int +gs_woff2sfnt_stream(gs_memory_t *mem, stream *s, byte *outbuf, int *outbuflen); + +int +gs_woff2sfnt_buffer(gs_memory_t *mem, byte *inbuf, int inbuflen, byte *outbuf, int *outbuflen); + #endif /* gxfont42_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxfont.h ghostscript-9.25~dfsg+1/base/gxfont.h --- ghostscript-9.10~dfsg/base/gxfont.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfont.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -229,10 +229,17 @@ font_proc_encode_char((*encode_char)); /* Map a glyph name to Unicode UTF-16. + * decode_glyph procedures return '0' if the code is not in the map + * and could not be decoded. Otherwise they return the size of the + * string (in bytes) needed to contain the return values. Passing + * any value for the length less than the required number of bytes to the + * functions will cause them not to copy the data, they will still + * return the required size however, to allow for dynamic allocation + * of sufficiently large buffers. */ #define font_proc_decode_glyph(proc)\ - gs_char proc(gs_font *, gs_glyph, int) + int proc(gs_font *, gs_glyph, int, ushort *, unsigned int) font_proc_decode_glyph((*decode_glyph)); /* @@ -318,7 +325,7 @@ * did change, 2 if there are no more characters, or an error code. * * This procedure may set either *pchar to gs_no_char or *pglyph to - * gs_no_glyph, but not both. + * GS_NO_GLYPH, but not both. */ #define font_proc_next_char_glyph(proc)\ @@ -328,13 +335,13 @@ /* * Define a client-supplied BuildChar/BuildGlyph procedure. * The gs_char may be gs_no_char (for BuildGlyph), or the gs_glyph - * may be gs_no_glyph (for BuildChar), but not both. Return 0 for + * may be GS_NO_GLYPH (for BuildChar), but not both. Return 0 for * success, 1 if the procedure was unable to render the character * (but no error occurred), <0 for error. */ #define font_proc_build_char(proc)\ - int proc(gs_show_enum *, gs_state *, gs_font *, gs_char, gs_glyph) + int proc(gs_show_enum *, gs_gstate *, gs_font *, gs_char, gs_glyph) font_proc_build_char((*build_char)); } gs_font_procs; diff -Nru ghostscript-9.10~dfsg/base/gxfrac.h ghostscript-9.25~dfsg+1/base/gxfrac.h --- ghostscript-9.10~dfsg/base/gxfrac.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfrac.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,8 +27,8 @@ typedef short frac; typedef short signed_frac; -#define arch_log2_sizeof_frac arch_log2_sizeof_short -#define arch_sizeof_frac arch_sizeof_short +#define arch_log2_sizeof_frac ARCH_LOG2_SIZEOF_SHORT +#define arch_sizeof_frac ARCH_SIZEOF_SHORT #define frac_bits 15 #define frac_0 ((frac)0) @@ -71,13 +71,31 @@ /* * Conversion between fracs and unsigned shorts. */ -#define ushort_bits (arch_sizeof_short * 8) +#define ushort_bits (ARCH_SIZEOF_SHORT * 8) #define frac2ushort(fr) ((ushort)(\ ((fr) << (ushort_bits - frac_bits)) +\ ((fr) >> (frac_bits * 2 - ushort_bits - frac_1_0bits)) )) #define ushort2frac(us) ((frac)(\ ((us) >> (ushort_bits - frac_bits)) -\ ((us) >> (ushort_bits - frac_1_0bits)) )) + +/* + * Conversion between frac31s and unsigned shorts. + */ +#define ushort_bits (ARCH_SIZEOF_SHORT * 8) +#define frac31_bits 31 +#if 0 +#define frac312ushort(fr) ((ushort)(\ + ((fr) >> (frac31_bits - ushort_bits)) +\ + ((fr) >> (frac31_bits - ushort_bits + frac_bits - frac_1_0bits)) )) +#define ushort2frac31(us) ((frac31)(\ + ((us) << (frac31_bits - ushort_bits)) -\ + ((us) << (frac31_bits - ushort_bits - frac_bits + frac_1_0bits)) )) +#else +#define frac312ushort(fr) ((ushort)((fr) >> (frac31_bits - ushort_bits))) +#define ushort2frac31(us) ((frac31)((us) << (frac31_bits - ushort_bits))) +#endif + /* * Compute the quotient Q = floor(P / frac_1), * where P is the (ulong) product of a uint or ushort V and a frac F. diff -Nru ghostscript-9.10~dfsg/base/gxftype.h ghostscript-9.25~dfsg+1/base/gxftype.h --- ghostscript-9.10~dfsg/base/gxftype.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxftype.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxfunc.h ghostscript-9.25~dfsg+1/base/gxfunc.h --- ghostscript-9.10~dfsg/base/gxfunc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxfunc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxgetbit.h ghostscript-9.25~dfsg+1/base/gxgetbit.h --- ghostscript-9.10~dfsg/base/gxgetbit.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxgetbit.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxgstate.h ghostscript-9.25~dfsg+1/base/gxgstate.h --- ghostscript-9.10~dfsg/base/gxgstate.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxgstate.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,516 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* graphics state definition */ + +#ifndef gxistate_INCLUDED +# define gxistate_INCLUDED + +#include "gscsel.h" +#include "gsrefct.h" +#include "gsropt.h" +#include "gstparam.h" +#include "gxcvalue.h" +#include "gxcmap.h" +#include "gxfixed.h" +#include "gxline.h" +#include "gxmatrix.h" +#include "gxtmap.h" +#include "gscspace.h" +#include "gstrans.h" +#include "gsnamecl.h" +#include "gscms.h" +#include "gscpm.h" +#include "gscspace.h" +#include "gxdcolor.h" +#include "gxstate.h" + + +/* + * Define the color rendering state information. + * This should be a separate object (or at least a substructure), + * but making this change would require editing too much code. + */ + +/* Opaque types referenced by the color rendering state. */ +#ifndef gs_halftone_DEFINED +# define gs_halftone_DEFINED +typedef struct gs_halftone_s gs_halftone; +#endif +#ifndef gx_device_color_DEFINED +# define gx_device_color_DEFINED +typedef struct gx_device_color_s gx_device_color; +#endif +#ifndef gx_device_halftone_DEFINED +# define gx_device_halftone_DEFINED +typedef struct gx_device_halftone_s gx_device_halftone; +#endif +#ifndef gs_color_space_DEFINED +# define gs_color_space_DEFINED +typedef struct gs_color_space_s gs_color_space; +#endif + +/* + * We need some special memory management for the components of a + * c.r. state, as indicated by the following notations on the elements: + * (RC) means the element is reference-counted. + * (Shared) means the element is shared among an arbitrary number of + * c.r. states and is never freed. + * (Owned) means exactly one c.r. state references the element, + * and it is guaranteed that no references to it will outlive + * the c.r. state itself. + */ + +/* Define the interior structure of a transfer function. */ +typedef struct gx_transfer_s { + int red_component_num; + gx_transfer_map *red; /* (RC) */ + int green_component_num; + gx_transfer_map *green; /* (RC) */ + int blue_component_num; + gx_transfer_map *blue; /* (RC) */ + int gray_component_num; + gx_transfer_map *gray; /* (RC) */ +} gx_transfer; + +#define gs_color_rendering_state_common\ +\ + /* Halftone screen: */\ +\ + gs_halftone *halftone; /* (RC) */\ + gs_int_point screen_phase[gs_color_select_count];\ + /* dev_ht depends on halftone and device resolution. */\ + gx_device_halftone *dev_ht; /* (RC) */\ +\ + /* Color (device-dependent): */\ +\ + struct gs_cie_render_s *cie_render; /* (RC) may be 0 */\ + bool cie_to_xyz; /* flag for conversion to XYZ, no CRD req'd */\ + gx_transfer_map *black_generation; /* (RC) may be 0 */\ + gx_transfer_map *undercolor_removal; /* (RC) may be 0 */\ + /* set_transfer holds the transfer functions specified by */\ + /* set[color]transfer; effective_transfer includes the */\ + /* effects of overrides by TransferFunctions in halftone */\ + /* dictionaries. (In Level 1 systems, set_transfer and */\ + /* effective_transfer are always the same.) */\ + gx_transfer set_transfer; /* members are (RC) */\ + int effective_transfer_non_identity_count;\ + gx_transfer_map *effective_transfer[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* see below */\ +\ + /* Color caches: */\ +\ + /* cie_joint_caches depend on cie_render and */\ + /* the color space. */\ + struct gx_cie_joint_caches_s *cie_joint_caches; /* (RC) */\ + /* cmap_procs depend on the device's color_info. */\ + const struct gx_color_map_procs_s *cmap_procs; /* static */\ + /* DeviceN component map for current color space */\ + gs_devicen_color_map color_component_map;\ + /* The contents of pattern_cache depend on the */\ + /* the color space and the device's color_info and */\ + /* resolution. */\ + struct gx_pattern_cache_s *pattern_cache; /* (Shared) by all gstates */\ +\ + /* Simple color spaces, stored here for easy access from */ \ + /* gx_concrete_space_CIE */ \ + gs_color_space *devicergb_cs;\ + gs_color_space *devicecmyk_cs;\ +\ + /* Stores for cached values which correspond to whichever */\ + /* color isn't in force at the moment */\ + struct gx_cie_joint_caches_s *cie_joint_caches_alt;\ + gs_devicen_color_map color_component_map_alt + + +/* Current colors (non-stroking, and stroking) */ +typedef struct gs_gstate_color_s { + gs_color_space *color_space; /* after substitution */ + gs_client_color *ccolor; + gx_device_color *dev_color; +} gs_gstate_color; + +/* + * Enumerate the reference-counted pointers in a c.r. state. Note that + * effective_transfer doesn't contribute to the reference count: it points + * either to the same objects as set_transfer, or to objects in a halftone + * structure that someone else worries about. + */ +#define gs_cr_state_do_rc_ptrs(m)\ + m(halftone) \ + m(dev_ht) \ + m(cie_render) \ + m(black_generation) \ + m(undercolor_removal) \ + m(set_transfer.red) \ + m(set_transfer.green) \ + m(set_transfer.blue) \ + m(set_transfer.gray) \ + m(cie_joint_caches) \ + m(devicergb_cs) \ + m(devicecmyk_cs)\ + m(cie_joint_caches_alt) + +/* Enumerate the pointers in a c.r. state. */ +#define gs_cr_state_do_ptrs(m)\ + m(0,halftone) \ + m(1,dev_ht) \ + m(2,cie_render) \ + m(3,black_generation) \ + m(4,undercolor_removal) \ + m(5,set_transfer.red) \ + m(6,set_transfer.green) \ + m(7,set_transfer.blue) \ + m(8,set_transfer.gray)\ + m(9,cie_joint_caches) \ + m(10,pattern_cache) \ + m(11,devicergb_cs) \ + m(12,devicecmyk_cs)\ + m(13,cie_joint_caches_alt) + /* + * We handle effective_transfer specially in gsistate.c since its pointers + * are not enumerated for garbage collection but they are are relocated. + */ +/* + * This count does not include the effective_transfer pointers since they + * are not enumerated for GC. + */ +#define st_cr_state_num_ptrs 14 + +#ifndef gs_devicen_color_map_DEFINED +# define gs_devicen_color_map_DEFINED +typedef struct gs_devicen_color_map_s gs_devicen_color_map; +#endif + +struct gs_devicen_color_map_s { + bool use_alt_cspace; + separation_type sep_type; + uint num_components; /* Input - Duplicate of value in gs_device_n_params */ + uint num_colorants; /* Number of colorants - output */ + gs_id cspace_id; /* Used to verify color space and map match */ + int color_map[GS_CLIENT_COLOR_MAX_COMPONENTS]; +}; + + +/* These flags are used to keep track of qQ + combinations surrounding a graphic state + change that includes a softmask setting. + The transparency compositor must be notified + when a Q event occurs following a softmask */ + +typedef struct gs_xstate_trans_flags { + bool xstate_pending; + bool xstate_change; +} gs_xstate_trans_flags_t; + +#define gs_currentdevicecolor_inline(pgs) ((pgs)->color[0].dev_color) +#define gs_currentcolor_inline(pgs) ((pgs)->color[0].ccolor) +#define gs_currentcolorspace_inline(pgs) ((pgs)->color[0].color_space) +#define gs_altdevicecolor_inline(pgs) ((pgs)->color[1].dev_color) + +#define char_tm_only(pgs) *(gs_matrix *)&(pgs)->char_tm + +#undef gs_currentdevice_inline /* remove definition in gsdevice.h?? */ +#define gs_currentdevice_inline(pgs) ((pgs)->device) + +#define gs_gstate_client_data(pgs) ((pgs)->client_data) + +/* Opaque types referenced by the graphics state. */ +#ifndef gx_path_DEFINED +# define gx_path_DEFINED +typedef struct gx_path_s gx_path; +#endif +#ifndef gx_clip_path_DEFINED +# define gx_clip_path_DEFINED +typedef struct gx_clip_path_s gx_clip_path; +#endif +#ifndef gx_clip_stack_DEFINED +# define gx_clip_stack_DEFINED +typedef struct gx_clip_stack_s gx_clip_stack_t; +#endif +#ifndef gs_color_space_DEFINED +# define gs_color_space_DEFINED +typedef struct gs_color_space_s gs_color_space; +#endif +#ifndef gs_client_color_DEFINED +# define gs_client_color_DEFINED +typedef struct gs_client_color_s gs_client_color; +#endif +#ifndef gs_font_DEFINED +# define gs_font_DEFINED +typedef struct gs_font_s gs_font; +#endif +#ifndef gs_device_filter_stack_DEFINED +# define gs_device_filter_stack_DEFINED +typedef struct gs_device_filter_stack_s gs_device_filter_stack_t; +#endif + +/* Define the graphics state structure itself. */ +/* + * Note that the ctm member is a gs_matrix_fixed. As such, it cannot be + * used directly as the argument for procedures like gs_point_transform. + * Instead, one must use the ctm_only macro, e.g., &ctm_only(pgs) rather + * than &pgs->ctm. + */ + +/* Access macros */ +#define ctm_only(pgs) (*(const gs_matrix *)&(pgs)->ctm) +#define ctm_only_writable(pgs) (*(gs_matrix *)&(pgs)->ctm) +#define set_ctm_only(pgs, mat) (*(gs_matrix *)&(pgs)->ctm = (mat)) +#define gs_init_rop(pgs) ((pgs)->log_op = lop_default) +#define gs_currentflat_inline(pgs) ((pgs)->flatness) +#define gs_currentlineparams_inline(pgs) (&(pgs)->line_params) +#define gs_current_logical_op_inline(pgs) ((pgs)->log_op) +#define gs_set_logical_op_inline(pgs, lop) ((pgs)->log_op = (lop)) + +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; +#endif + +struct gs_gstate_s { + gs_memory_t *memory; + void *client_data; + gx_line_params line_params; + bool hpgl_path_mode; + gs_matrix_fixed ctm; + bool current_point_valid; + gs_point current_point; + gs_point subpath_start; + bool clamp_coordinates; + gs_logical_operation_t log_op; + gx_color_value alpha; + gs_blend_mode_t blend_mode; + gs_transparency_source_t opacity, shape; + gs_xstate_trans_flags_t trans_flags; + gs_id soft_mask_id; + bool text_knockout; + uint text_rendering_mode; + bool has_transparency; /* used to keep from doing shading fills in device color space */ + gx_device *trans_device; /* trans device has all mappings to group color space */ + bool overprint; + int overprint_mode; + int effective_overprint_mode; + bool stroke_overprint; + int overprint_mode_alt; + int effective_overprint_mode_alt; + float flatness; + gs_fixed_point fill_adjust; /* A path expansion for fill; -1 = dropout prevention*/ + bool stroke_adjust; + bool accurate_curves; + bool have_pattern_streams; + float smoothness; + int renderingintent; /* See gsstate.c */ + bool blackptcomp; + gsicc_manager_t *icc_manager; /* ICC color manager, profile */ + gsicc_link_cache_t *icc_link_cache; /* ICC linked transforms */ + gsicc_profile_cache_t *icc_profile_cache; /* ICC profiles from PS. */ + CUSTOM_COLOR_PTR /* Pointer to custom color callback struct */ + const gx_color_map_procs * + (*get_cmap_procs)(const gs_gstate *, const gx_device *); + gs_color_rendering_state_common; + + gs_gstate *saved; /* previous state from gsave */ + + /* Transformation: */ + gs_matrix ctm_inverse; + bool ctm_inverse_valid; /* true if ctm_inverse = ctm^-1 */ + gs_matrix ctm_default; + bool ctm_default_set; /* if true, use ctm_default; */ + /* if false, ask device */ + /* Paths: */ + + gx_path *path; + gx_clip_path *clip_path; + gx_clip_stack_t *clip_stack; /* (LanguageLevel 3 only) */ + gx_clip_path *view_clip; /* (may be 0, or have rule = 0) */ + + /* Effective clip path cache */ + gs_id effective_clip_id; /* (key) clip path id */ + gs_id effective_view_clip_id; /* (key) view clip path id */ + gx_clip_path *effective_clip_path; /* (value) effective clip path, */ + /* possibly = clip_path or view_clip */ + bool effective_clip_shared; /* true iff e.c.p. = c.p. or v.c. */ + + /* PDF graphics state parameters */ + float strokeconstantalpha, fillconstantalpha; + /* *SMask is stored in int_gstate as its a ref object */ + bool alphaisshape; + float textspacing; + float textleading; + float textrise; + float wordspacing; + float texthscaling; + float PDFfontsize; + gs_matrix textlinematrix; + gs_matrix textmatrix; + /* Current colors (non-stroking, and stroking) */ + gs_gstate_color color[2]; + + /* Font: */ + gs_font *font; + gs_font *root_font; + gs_matrix_fixed char_tm; /* font matrix * ctm */ + bool char_tm_valid; /* true if char_tm is valid */ + gs_in_cache_device_t in_cachedevice; /* (see gscpm.h) */ + gs_char_path_mode in_charpath; /* (see gscpm.h) */ + gs_gstate *show_gstate; /* gstate when show was invoked */ + /* (so charpath can append to path) */ + /* Other stuff: */ + int level; /* incremented by 1 per gsave */ + gx_device *device; + gs_gstate_client_procs client_procs; +}; + +/* Initialization for gs_gstate */ +#define gs_gstate_initial(scale)\ + 0, 0, { gx_line_params_initial }, 0,\ + { (float)(scale), 0.0, 0.0, (float)(-(scale)), 0.0, 0.0 },\ + false, {0, 0}, {0, 0}, false, \ + lop_default, gx_max_color_value, BLEND_MODE_Compatible,\ +{ 1.0 }, { 1.0 }, {0, 0}, 0, 0/*false*/, 0, 0, 0, 0/*false*/, 0, 0, 0/*false*/, 0, 0, 1.0, \ + { fixed_half, fixed_half }, 0/*false*/, 1/*true*/, 0/*false*/, 1.0,\ + 1, 1/* bpt true */, 0, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \ + gx_default_get_cmap_procs + +#define GS_STATE_INIT_VALUES(s, scale) \ + do { \ + static const struct gs_gstate_s __state_init = {gs_gstate_initial(scale)}; \ + s->memory = __state_init.memory; \ + s->client_data = __state_init.client_data; \ + s->line_params = __state_init.line_params; \ + s->hpgl_path_mode = __state_init.hpgl_path_mode; \ + s->ctm = __state_init.ctm; \ + s->current_point_valid = __state_init.current_point_valid; \ + s->current_point = __state_init.current_point; \ + s->subpath_start = __state_init.subpath_start; \ + s->clamp_coordinates = __state_init.clamp_coordinates; \ + s->log_op = __state_init.log_op; \ + s->alpha = __state_init.alpha; \ + s->blend_mode = __state_init.blend_mode; \ + s->opacity = __state_init.opacity; \ + s->shape = __state_init.shape; \ + s->trans_flags = __state_init.trans_flags; \ + s->soft_mask_id = __state_init.soft_mask_id; \ + s->text_knockout = __state_init.text_knockout; \ + s->text_rendering_mode = __state_init.text_rendering_mode; \ + s->has_transparency = __state_init.has_transparency; \ + s->trans_device = __state_init.trans_device; \ + s->overprint = __state_init.overprint; \ + s->overprint_mode = __state_init.overprint_mode; \ + s->effective_overprint_mode = __state_init.effective_overprint_mode; \ + s->stroke_overprint = __state_init.stroke_overprint; \ + s->overprint_mode_alt = __state_init.overprint_mode_alt; \ + s->effective_overprint_mode_alt = __state_init.effective_overprint_mode_alt; \ + s->flatness = __state_init.flatness; \ + s->fill_adjust = __state_init.fill_adjust; \ + s->stroke_adjust = __state_init.stroke_adjust; \ + s->accurate_curves = __state_init.accurate_curves; \ + s->have_pattern_streams = __state_init.have_pattern_streams; \ + s->smoothness = __state_init.smoothness; \ + s->renderingintent = __state_init.renderingintent; \ + s->blackptcomp = __state_init.blackptcomp; \ + s->icc_manager = __state_init.icc_manager; \ + s->icc_link_cache = __state_init.icc_link_cache; \ + s->icc_profile_cache = __state_init.icc_profile_cache; \ + s->get_cmap_procs = __state_init.get_cmap_procs; \ + s->show_gstate = NULL; \ + } while (0) + +struct_proc_finalize(gs_gstate_finalize); +#define public_st_gs_gstate() /* in gsstate.c */\ + gs_public_st_composite_use_final(st_gs_gstate, gs_gstate, "gs_gstate",\ + gs_gstate_enum_ptrs, gs_gstate_reloc_ptrs, gs_gstate_finalize) + +/* + * Enumerate the pointers in a graphics state + * except device which must + * be handled specially. + */ +#define gs_gstate_do_ptrs(m)\ + m(0, client_data) \ + m(1, trans_device) \ + m(2, icc_manager) \ + m(3, icc_link_cache) \ + m(4, icc_profile_cache) \ + m(5, saved) \ + m(6, path) \ + m(7, clip_path) \ + m(8, clip_stack) \ + m(9, view_clip) \ + m(10, effective_clip_path) \ + m(11, color[0].color_space) \ + m(12, color[0].ccolor) \ + m(13, color[0].dev_color) \ + m(14, color[1].color_space) \ + m(15, color[1].ccolor) \ + m(16, color[1].dev_color)\ + m(17, font) \ + m(18, root_font) \ + m(19, show_gstate) + +#define gs_gstate_num_ptrs 20 + +/* The '+1' in the following is because gs_gstate.device + * is handled specially + */ +#define st_gs_gstate_num_ptrs\ + (st_line_params_num_ptrs + st_cr_state_num_ptrs + gs_gstate_num_ptrs + 1) + +/* Initialize an graphics state, other than the parts covered by */ +/* gs_gstate_initial. */ +int gs_gstate_initialize(gs_gstate * pgs, gs_memory_t * mem); + +/* Make a temporary copy of a gs_gstate. Note that this does not */ +/* do all the necessary reference counting, etc. */ +gs_gstate * gs_gstate_copy_temp(const gs_gstate * pgs, gs_memory_t * mem); + +/* Increment reference counts to note that a graphics state has been copied. */ +void gs_gstate_copied(gs_gstate * pgs); + +/* Adjust reference counts before assigning one gs_gstate to another. */ +void gs_gstate_pre_assign(gs_gstate *to, const gs_gstate *from); + +/* Release an gs_gstate. */ +void gs_gstate_release(gs_gstate * pgs); +int gs_currentscreenphase_pgs(const gs_gstate *, gs_int_point *, gs_color_select_t); + + +/* The following macro is used for development purpose for designating places + where current point is changed. Clients must not use it. */ +#define gx_setcurrentpoint(pgs, xx, yy)\ + (pgs)->current_point.x = xx;\ + (pgs)->current_point.y = yy; + +int gs_swapcolors(gs_gstate *); +void gs_swapcolors_quick(gs_gstate *); + +/* Set the graphics_type_tag iff the requested tag bit is not set in the dev_color and */ +/* unset the dev_color so that gx_set_dev_color will remap (encode) with the new tag. */ +/* Also make sure the tag is set in the device so the two remain in sync. */ +static inline void ensure_tag_is_set(gs_gstate *pgs, gx_device *dev, gs_graphics_type_tag_t tag) +{ + if (device_encodes_tags(dev)) { + if ((dev->graphics_type_tag & tag) == 0) + dev_proc(dev, set_graphics_type_tag)(dev, tag); + if ((pgs->color[0].dev_color->tag & tag) == 0) { + gx_unset_dev_color(pgs); /* current dev_color needs update to new tag */ + pgs->color[0].dev_color->tag = tag; /* after unset, now set it */ + } + } +} + + +#endif /* gxistate_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gx.h ghostscript-9.25~dfsg+1/base/gx.h --- ghostscript-9.10~dfsg/base/gx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -29,14 +29,9 @@ /* Define opaque types for the graphics state. */ /* This is used so pervasively that we define it here, */ /* rather than at a higher level as perhaps would be more appropriate. */ -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; - -#endif -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif diff -Nru ghostscript-9.10~dfsg/base/gxhintn1.c ghostscript-9.25~dfsg+1/base/gxhintn1.c --- ghostscript-9.10~dfsg/base/gxhintn1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhintn1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,6 @@ #include "gxmatrix.h" #include "gxhintn.h" #include "gzpath.h" -#include "vdtrace.h" #define CURVE_FLATTENING (fixed_1) /* Design units in 'fixed'. */ diff -Nru ghostscript-9.10~dfsg/base/gxhintn.c ghostscript-9.25~dfsg+1/base/gxhintn.c --- ghostscript-9.10~dfsg/base/gxhintn.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhintn.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,7 +30,6 @@ #include "gxhintn.h" #include "gzpath.h" #include "gserrors.h" -#include "vdtrace.h" /* todo : - Diagonal stems are not hinted; @@ -115,13 +114,6 @@ With type 2 it is handled by gstype2.c . */ -#define VD_DRAW_IMPORT 0 /* CAUTION: with 1 can't close DC on import error */ -#define VD_SCALE (4.0 / 4096.0) -#define VD_SHIFT_X 50 -#define VD_SHIFT_Y 100 -#define VD_PAINT_POLE_IDS 1 -#define VD_IMPORT_COLOR RGB(255, 0, 0) - #define ADOBE_OVERSHOOT_COMPATIBILIY 0 #define ADOBE_SHIFT_CHARPATH 0 @@ -151,7 +143,9 @@ static const unsigned int max_coord_bits = 24; /* = split_bits * 2 */ static const unsigned int matrix_bits = 19; /* <= sizeof(int) * 8 - 1 - split_bits */ static const unsigned int g2o_bitshift = 12; /* <= matrix_bits + max_coord_bits - (sizeof(int) * 8 + 1) */ +#ifndef HAVE_INT64_T static const int32_t FFFFF000 = ~(int32_t)0xFFF; /* = ~(((int32_t)1 << split_bits) - 1) */ +#endif /* Constants above must satisfy expressions given in comments. */ /* Computes (a*b)>>s, s <= 12 */ @@ -188,16 +182,9 @@ { return a > b ? a : b; } -static inline int32_t Min(int32_t a, int32_t b) -{ return a < b ? a : b; -} - static inline long rshift(long a, int b) { return b > 0 ? a << b : a >> -b; } -static inline ulong urshift(ulong a, int b) -{ return b > 0 ? a << b : a >> -b; -} /*---------------------- members of matrix classes -------------------------*/ static inline void double_matrix__set(double_matrix * self, const gs_matrix_fixed * m) @@ -233,8 +220,8 @@ double ayx = fabs(pmat->yx), ayy = fabs(pmat->yy); double scale = max(axx + axy, ayx + ayy); int matrix_exp, m; - double unused = frexp(scale, &matrix_exp); + (void)frexp(scale, &matrix_exp); self->bitshift = matrix_bits - matrix_exp; if (self->bitshift >= sizeof( self->denominator) * 8) { self->denominator = 0; @@ -247,7 +234,7 @@ self->yx = (int32_t)(pmat->yx * self->denominator + 0.5); self->yy = (int32_t)(pmat->yy * self->denominator + 0.5); m = Max(Max(any_abs(self->xx), any_abs(self->xy)), Max(any_abs(self->yx), any_abs(self->yy))); - unused = frexp(m, &matrix_exp); + (void)frexp(m, &matrix_exp); if (matrix_exp > matrix_bits) fraction_matrix__drop_bits(self, matrix_exp - matrix_bits); } @@ -326,7 +313,8 @@ } static inline void g2d(t1_hinter * h, t1_glyph_space_coord gx, t1_glyph_space_coord gy, fixed *dx, fixed *dy) -{ *dx = fraction_matrix__transform_x(&h->ctmf, gx, gy, g2o_bitshift); +{ + *dx = fraction_matrix__transform_x(&h->ctmf, gx, gy, g2o_bitshift); *dy = fraction_matrix__transform_y(&h->ctmf, gx, gy, g2o_bitshift); *dx = o2d(h, *dx); *dy = o2d(h, *dy); @@ -345,11 +333,6 @@ { return shift_rounded(mul_shift(od, coef, split_bits), h->g2o_fraction_bits + h->ctmi.bitshift - _fixed_shift - split_bits); } -static inline void o2g_float(t1_hinter * h, t1_hinter_space_coord ox, t1_hinter_space_coord oy, t1_glyph_space_coord *gx, t1_glyph_space_coord *gy) -{ *gx = (long)(((double)ox * h->ctmi.xx + (double)oy * h->ctmi.yx) * fixed_scale / h->g2o_fraction / h->ctmi.denominator); - *gy = (long)(((double)ox * h->ctmi.xy + (double)oy * h->ctmi.yy) * fixed_scale / h->g2o_fraction / h->ctmi.denominator); -} - /* --------------------- t1_hint class members ---------------------*/ static void t1_hint__set_aligned_coord(t1_hint * self, t1_glyph_space_coord gc, t1_pole * pole, enum t1_align_type align, int quality) @@ -364,115 +347,11 @@ } } -/* --------------------- t1_hinter class members - debug graphics --------------------*/ - -static void t1_hinter__paint_glyph(t1_hinter * self, bool aligned) -{ -#if VD_TRACE -#define X(j) *member_prt(t1_glyph_space_coord, &self->pole[j], offset_x) -#define Y(j) *member_prt(t1_glyph_space_coord, &self->pole[j], offset_y) - t1_glyph_space_coord *p_x = (aligned ? &self->pole[0].ax : &self->pole[0].gx); - t1_glyph_space_coord *p_y = (aligned ? &self->pole[0].ay : &self->pole[0].gy); - int offset_x = (char *)p_x - (char *)&self->pole[0]; - int offset_y = (char *)p_y - (char *)&self->pole[0]; - int i, j; - char buf[15]; - - if (!vd_enabled) - return; -# if VD_PAINT_POLE_IDS - for(i = 0; i < self->contour_count; i++) { - int beg_pole = self->contour[i]; - int end_pole = self->contour[i + 1] - 2; - - for(j = beg_pole; j <= end_pole; j++) { - vd_circle(X(j), Y(j), 3, RGB(0,0,255)); - gs_sprintf(buf, "%d", j); - vd_text(self->pole[j].gx, self->pole[j].gy, buf, RGB(0,0,0)); - if (self->pole[j + 1].type == offcurve) - j+=2; - } - } -# endif - vd_setcolor(aligned ? RGB(0,255,0) : RGB(0,0,255)); - for(i = 0; i < self->contour_count; i++) { - int beg_pole = self->contour[i]; - int end_pole = self->contour[i + 1] - 2; - - vd_moveto(X(beg_pole), Y(beg_pole)); - for(j = beg_pole + 1; j <= end_pole; j++) { - if (self->pole[j].type == oncurve) { - vd_lineto(X(j), Y(j)); - } else { - int jj = (j + 2 > end_pole ? beg_pole : j + 2); - vd_curveto(X(j), Y(j), X(j + 1), Y(j + 1), X(jj), Y(jj)); - j+=2; - } - } - vd_lineto(X(beg_pole), Y(beg_pole)); - } -#undef X -#undef Y -#endif -} - -static void t1_hinter__paint_raster_grid(t1_hinter * self) -{ -#if VD_TRACE - int i; - double j; /* 'long' can overflow */ - unsigned long c0 = RGB(192, 192, 192), c1 = RGB(64, 64, 64); - t1_hinter_space_coord min_ox, max_ox, min_oy, max_oy; - long div_x = self->g2o_fraction, div_xx = div_x << self->log2_pixels_x; - long div_y = self->g2o_fraction, div_yy = div_y << self->log2_pixels_y; - long ext_x = div_x * 5; - long ext_y = div_y * 5; - long sx = self->orig_ox % div_xx; - long sy = self->orig_oy % div_yy; - - if (!vd_enabled) - return; - g2o(self, self->pole[0].gx, self->pole[0].gy, &min_ox, &min_oy); - max_ox = min_ox, max_oy = min_oy; - /* Compute BBox in outliner's space : */ - for (i = 1; i < self->pole_count - 1; i++) { - t1_hinter_space_coord ox, oy; - - g2o(self, self->pole[i].gx, self->pole[i].gy, &ox, &oy); - min_ox = min(min_ox, ox); - min_oy = min(min_oy, oy); - max_ox = max(max_ox, ox); - max_oy = max(max_oy, oy); - } - min_ox -= ext_x; - min_oy -= ext_y; - max_ox += ext_x; - max_oy += ext_y; - /* Paint columns : */ - for (j = min_ox / div_x * div_x; j < (double)max_ox + div_x; j += div_x) { - t1_glyph_space_coord gx0, gy0, gx1, gy1; - bool pix = ((int)j / div_xx * div_xx == (int)j); - - o2g_float(self, (int)j - sx, min_oy - sy, &gx0, &gy0); /* o2g may overflow here due to ext. */ - o2g_float(self, (int)j - sx, max_oy - sy, &gx1, &gy1); - vd_bar(gx0, gy0, gx1, gy1, 1, (!j ? 0 : pix ? c1 : c0)); - } - /* Paint rows : */ - for (j = min_oy / div_y * div_y; j < max_oy + div_y; j += div_y) { - t1_glyph_space_coord gx0, gy0, gx1, gy1; - bool pix = ((int)j / div_yy * div_yy == (int)j); - - o2g_float(self, min_ox - sx, (int)j - sy, &gx0, &gy0); - o2g_float(self, max_ox - sx, (int)j - sy, &gx1, &gy1); - vd_bar(gx0, gy0, gx1, gy1, 1, (!j ? 0 : pix ? c1 : c0)); - } -#endif -} - /* --------------------- t1_hinter class members - import --------------------*/ void t1_hinter__init(t1_hinter * self, gx_path *output_path) -{ self->max_import_coord = (1 << max_coord_bits); +{ + self->max_import_coord = (1 << max_coord_bits); self->stem_snap_count[0] = self->stem_snap_count[1] = 0; self->stem_snap_vote_count = 0; self->zone_count = 0; @@ -525,8 +404,15 @@ self->pass_through = self->disable_hinting; self->autohinting = false; self->fix_contour_sign = false; + self->path_opened = false; + self->orig_dx = 0; + self->orig_dy = 0; + self->g2o_fraction_bits = 0; self->stem_snap[0][0] = self->stem_snap[1][0] = 100; /* default */ + + memset(&self->ctmf, 0x00, sizeof(self->ctmf)); + memset(&self->ctmi, 0x00, sizeof(self->ctmi)); } static inline void t1_hinter__free_arrays(t1_hinter * self) @@ -561,7 +447,8 @@ } static inline void t1_hinter__init_outline(t1_hinter * self) -{ self->contour_count = 0; +{ + self->contour_count = 0; self->pole_count = 0; self->contour[0] = 0; self->hint_count = 0; @@ -772,13 +659,13 @@ return false; } -static int t1_hinter__set_alignment_zones(t1_hinter * self, float * blues, int count, enum t1_zone_type type, bool family) +static int t1_hinter__set_alignment_zones(gs_memory_t *mem, t1_hinter * self, float * blues, int count, enum t1_zone_type type, bool family) { int count2 = count / 2, i, j; if (!family) { /* Store zones : */ if (count2 + self->zone_count >= self->max_zone_count) - if(t1_hinter__realloc_array(self->memory, (void **)&self->zone, self->zone0, &self->max_zone_count, + if(t1_hinter__realloc_array(mem, (void **)&self->zone, self->zone0, &self->max_zone_count, sizeof(self->zone0) / count_of(self->zone0), max(T1_MAX_ALIGNMENT_ZONES, count), s_zone_array)) return_error(gs_error_VMerror); @@ -801,19 +688,19 @@ return 0; } -static int t1_hinter__set_stem_snap(t1_hinter * self, float * value, int count, unsigned short hv) +static int t1_hinter__set_stem_snap(gs_memory_t *mem, t1_hinter * self, float * value, int count, unsigned short hv) { int count0 = self->stem_snap_count[hv], i, j; t1_glyph_space_coord pixel_g = (!hv ? self->pixel_gh : self->pixel_gw); if (pixel_g == 0) return 0; if (count + count0 >= self->max_stem_snap_count[hv]) - if(t1_hinter__realloc_array(self->memory, (void **)&self->stem_snap[hv], self->stem_snap0[hv], &self->max_stem_snap_count[hv], + if(t1_hinter__realloc_array(mem, (void **)&self->stem_snap[hv], self->stem_snap0[hv], &self->max_stem_snap_count[hv], sizeof(self->stem_snap0[0]) / count_of(self->stem_snap0[0]), max(T1_MAX_STEM_SNAPS, count), s_stem_snap_array)) return_error(gs_error_VMerror); if (count + count0 >= self->max_stem_snap_vote_count) - if(t1_hinter__realloc_array(self->memory, (void **)&self->stem_snap_vote, self->stem_snap_vote0, &self->max_stem_snap_vote_count, + if(t1_hinter__realloc_array(mem, (void **)&self->stem_snap_vote, self->stem_snap_vote0, &self->max_stem_snap_vote_count, sizeof(self->stem_snap_vote0) / count_of(self->stem_snap_vote0), max(T1_MAX_STEM_SNAPS, count), s_stem_snap_vote_array)) return_error(gs_error_VMerror); @@ -859,18 +746,7 @@ */ } -static void enable_draw_import(void) -{ /* CAUTION: can't close DC on import error */ - vd_get_dc('h'); - vd_set_shift(VD_SHIFT_X, VD_SHIFT_Y); - vd_set_scale(VD_SCALE); - vd_set_origin(0,0); - vd_erase(RGB(255, 255, 255)); - vd_setcolor(VD_IMPORT_COLOR); - vd_setlinewidth(0); -} - -int t1_hinter__set_font_data(t1_hinter * self, int FontType, gs_type1_data *pdata, bool no_grid_fitting, bool is_resource) +int t1_hinter__set_font_data(gs_memory_t *mem, t1_hinter * self, int FontType, gs_type1_data *pdata, bool no_grid_fitting, bool is_resource) { int code; t1_hinter__init_outline(self); @@ -887,29 +763,27 @@ self->fix_contour_sign = (!is_resource && self->memory != NULL); if (self->fix_contour_sign) self->pass_through = false; - if (!vd_enabled && (VD_DRAW_IMPORT || self->pass_through)) - enable_draw_import(); if (self->pass_through) return 0; - code = t1_hinter__set_alignment_zones(self, pdata->OtherBlues.values, pdata->OtherBlues.count, botzone, false); + code = t1_hinter__set_alignment_zones(mem, self, pdata->OtherBlues.values, pdata->OtherBlues.count, botzone, false); if (code >= 0) - code = t1_hinter__set_alignment_zones(self, pdata->BlueValues.values, min(2, pdata->BlueValues.count), botzone, false); + code = t1_hinter__set_alignment_zones(mem, self, pdata->BlueValues.values, min(2, pdata->BlueValues.count), botzone, false); if (code >= 0) - code = t1_hinter__set_alignment_zones(self, pdata->BlueValues.values + 2, pdata->BlueValues.count - 2, topzone, false); + code = t1_hinter__set_alignment_zones(mem, self, pdata->BlueValues.values + 2, pdata->BlueValues.count - 2, topzone, false); if (code >= 0) - code = t1_hinter__set_alignment_zones(self, pdata->FamilyOtherBlues.values, pdata->FamilyOtherBlues.count, botzone, true); + code = t1_hinter__set_alignment_zones(mem, self, pdata->FamilyOtherBlues.values, pdata->FamilyOtherBlues.count, botzone, true); if (code >= 0) - code = t1_hinter__set_alignment_zones(self, pdata->FamilyBlues.values, min(2, pdata->FamilyBlues.count), botzone, true); + code = t1_hinter__set_alignment_zones(mem, self, pdata->FamilyBlues.values, min(2, pdata->FamilyBlues.count), botzone, true); if (code >= 0) - code = t1_hinter__set_alignment_zones(self, pdata->FamilyBlues.values + 2, pdata->FamilyBlues.count - 2, topzone, true); + code = t1_hinter__set_alignment_zones(mem, self, pdata->FamilyBlues.values + 2, pdata->FamilyBlues.count - 2, topzone, true); if (code >= 0) - code = t1_hinter__set_stem_snap(self, pdata->StdHW.values, pdata->StdHW.count, 0); + code = t1_hinter__set_stem_snap(mem, self, pdata->StdHW.values, pdata->StdHW.count, 0); if (code >= 0) - code = t1_hinter__set_stem_snap(self, pdata->StdVW.values, pdata->StdVW.count, 1); + code = t1_hinter__set_stem_snap(mem, self, pdata->StdVW.values, pdata->StdVW.count, 1); if (code >= 0) - code = t1_hinter__set_stem_snap(self, pdata->StemSnapH.values, pdata->StemSnapH.count, 0); + code = t1_hinter__set_stem_snap(mem, self, pdata->StemSnapH.values, pdata->StemSnapH.count, 0); if (code >= 0) - code = t1_hinter__set_stem_snap(self, pdata->StemSnapV.values, pdata->StemSnapV.count, 1); + code = t1_hinter__set_stem_snap(mem, self, pdata->StemSnapV.values, pdata->StemSnapV.count, 1); return code; } @@ -926,8 +800,6 @@ self->pass_through |= no_grid_fitting; self->charpath_flag = no_grid_fitting; self->autohinting = true; - if (!vd_enabled && (VD_DRAW_IMPORT || self->pass_through)) - enable_draw_import(); if (self->pass_through) return 0; /* Currently we don't provice alignments zones or stem snap. */ @@ -1007,14 +879,13 @@ /* Compute the curvity direction relative to the middle coord. */ bool gt = false, lt = false; double area = 0, area0; - int pl = i; int dir = 0, prev_dir = 0, dir_change = 0; *gm = gc0; /* Safety. */ /* fixme: optimize: the computaion of gt, lt may be replaced with a longer loop, so that dir_change accounts outer segments. optimize : move the 1st iteratiot outside the loop. */ - for (l = i; ; pl = l, gcp = gcl, gdp = gdl, prev_dir = dir, l++) { + for (l = i; ; gcp = gcl, gdp = gdl, prev_dir = dir, l++) { if (l == contour_end) l = contour_beg; gcl = *member_prt(t1_glyph_space_coord, &self->pole[l], offset_gc); @@ -1081,7 +952,7 @@ t1_hinter__compact_flex(self, contour_beg, contour_end, i0, contour_end, pi); t1_hinter__compact_flex(self, contour_beg, contour_end, contour_beg, i1, pi); } else if (i0 < i1) { - int i, j; + int j; int s = i1 - i0 - 1; for (j = 0; j < self->hint_range_count; j++) { @@ -1094,10 +965,6 @@ else if (self->hint_range[j].end_pole > i0) self->hint_range[j].end_pole = i0; } - if (VD_DRAW_IMPORT) { - for (i = i0; i <= i1; i++) - vd_square(self->pole[i].gx, self->pole[i].gy, 7, RGB(0,0,0)); - } memmove(&self->pole[i0 + 1], &self->pole[i1], sizeof(*self->pole) * (self->pole_count - i1)); self->contour[self->contour_count] -= s; self->pole_count -= s; @@ -1125,11 +992,12 @@ t1_glyph_space_coord gg = g0; int i; + k = !k; if (gm < g0) { g0 ^= gm; gm ^= g0; g0 ^= gm; } for (i = 0; i < self->hint_count; i++) - if (!k == (self->hint[i].type != hstem)) { + if (k == (self->hint[i].type != hstem)) { t1_hint *hint = &self->hint[i]; if (g0 <= hint->g0 && hint->g0 <= gm) @@ -1236,8 +1104,6 @@ } g2d(self, gx, gy, &fx, &fy); code = gx_path_add_point(self->output_path, fx, fy); - vd_circle(self->cx, self->cy, 2, RGB(255, 0, 0)); - vd_moveto(self->cx, self->cy); if (self->flex_count == 0) { self->bx = self->cx; self->by = self->cy; @@ -1259,8 +1125,6 @@ self->bx = self->cx; self->by = self->cy; } - vd_circle(self->cx, self->cy, 2, RGB(255, 0, 0)); - vd_moveto(self->cx, self->cy); return code; } @@ -1284,7 +1148,6 @@ t1_glyph_space_coord gy = self->cy += yy; fixed fx, fy; - vd_lineto(self->cx, self->cy); self->path_opened = true; g2d(self, gx, gy, &fx, &fy); return gx_path_add_line(self->output_path, fx, fy); @@ -1293,7 +1156,6 @@ if (code < 0) return code; - vd_lineto(self->cx, self->cy); t1_hinter__skip_degenerate_segnment(self, 1); return 0; } @@ -1313,7 +1175,6 @@ t1_glyph_space_coord gy2 = self->cy += yy2; fixed fx0, fy0, fx1, fy1, fx2, fy2; - vd_curveto(gx0, gy0, gx1, gy1, gx2, gy2); self->path_opened = true; g2d(self, gx0, gy0, &fx0, &fy0); g2d(self, gx1, gy1, &fx1, &fy1); @@ -1331,9 +1192,6 @@ code = t1_hinter__add_pole(self, xx2, yy2, oncurve); if (code < 0) return code; - vd_curveto(self->pole[self->pole_count - 3].gx, self->pole[self->pole_count - 3].gy, - self->pole[self->pole_count - 2].gx, self->pole[self->pole_count - 2].gy, - self->cx, self->cy); t1_hinter__skip_degenerate_segnment(self, 3); return 0; } @@ -1364,7 +1222,6 @@ int t1_hinter__closepath(t1_hinter * self) { if (self->pass_through) { - vd_lineto(self->bx, self->by); self->path_opened = false; return gx_path_close_subpath(self->output_path); } else { @@ -1372,11 +1229,6 @@ if (contour_beg == self->pole_count) return 0; /* maybe a single trailing moveto */ - if (vd_enabled && (VD_DRAW_IMPORT || self->pass_through)) { - vd_setcolor(VD_IMPORT_COLOR); - vd_setlinewidth(0); - vd_lineto(self->bx, self->by); - } if (self->bx == self->cx && self->by == self->cy) { /* Don't create degenerate segment */ self->pole[self->pole_count - 1].type = closepath; @@ -1456,9 +1308,6 @@ if (any_abs(ox) > div_x * fixed2float(flex_height) / 100 || any_abs(oy) > div_y * fixed2float(flex_height) / 100) { /* do with curves */ - vd_moveto (pole0[0].gx, pole0[0].gy); - vd_curveto(pole0[2].gx, pole0[2].gy, pole0[3].gx, pole0[3].gy, pole0[4].gx, pole0[4].gy); - vd_curveto(pole0[5].gx, pole0[5].gy, pole0[6].gx, pole0[6].gy, pole0[7].gx, pole0[7].gy); if (self->pass_through) { fixed fx0, fy0, fx1, fy1, fx2, fy2; int code; @@ -1485,8 +1334,6 @@ } } else { /* do with line */ - vd_moveto(pole0[0].gx, pole0[0].gy); - vd_lineto(pole0[7].gx, pole0[7].gy); if (self->pass_through) { fixed fx, fy; @@ -1818,23 +1665,6 @@ return true; } -static inline bool t1_hinter__is_conjugated(t1_hinter * self, int pole_index) -{ int prev = t1_hinter__segment_beg(self, pole_index); - int next = t1_hinter__segment_end(self, pole_index); - long gx0 = self->pole[prev].gx - self->pole[pole_index].gx; - long gy0 = self->pole[prev].gy - self->pole[pole_index].gy; - long gx1 = self->pole[next].gx - self->pole[pole_index].gx; - long gy1 = self->pole[next].gy - self->pole[pole_index].gy; - long vp = gx0 * gy1 - gy0 * gx1; - long sp = gx0 * gy1 - gy0 * gx1; - - if (sp > 0) - return false; - if (vp == 0) - return true; - return any_abs(vp) < -sp / 1000; /* The threshold is taken from scratch. */ -} - static inline bool t1_hinter__next_contour_pole(t1_hinter * self, int pole_index) { int contour_index = self->pole[pole_index].contour_index; int beg_contour_pole = self->contour[contour_index]; @@ -2171,7 +2001,6 @@ } gx0 = gx; gy0 = gy; - vd_circle(gx, gy, 7, RGB(255,0,0)); if (horiz) { t1_pole * pole = &self->pole[segment_index]; int contour_index = pole->contour_index; @@ -2234,7 +2063,6 @@ } } } - vd_circle(gx, gy, 7, RGB(0,255,0)); if (align_by_stem) { t1_glyph_space_coord gx1, gy1; @@ -2268,7 +2096,6 @@ if (!align_by_stem) t1_hinter__align_to_grid(self, self->g2o_fraction, &gx, &gy, CONTRAST_STEMS || self->align_to_pixels); - vd_circle(gx, gy, 7, RGB(0,0,255)); *gc = gc0 + (horiz ? gy - gy0 : gx - gx0); return (align == unaligned ? aligned : align); } @@ -2420,8 +2247,6 @@ } align = t1_hinter__compute_aligned_coord(self, &gc, segment_index, t, &self->hint[i], align); - vd_square(self->pole[segment_index].gx, self->pole[segment_index].gy, - (horiz ? 7 : 9), (i < self->primary_hint_count ? RGB(0,0,255) : RGB(0,255,0))); /* todo: optimize: primary commands don't need to align, if suppressed by secondary ones. */ t1_hint__set_aligned_coord(&self->hint[i], gc, &self->pole[j], align, quality); jj = j; @@ -2478,7 +2303,6 @@ agm = (!k ? self->hint[m].ag0 : self->hint[m].ag1); } if (md < d) { md = d; - m = j; } } } @@ -2623,7 +2447,6 @@ if (gt0 != gt1) { d = any_abs(t1 - t0); if (md > d) { - d = md; mj = j; } } @@ -2711,7 +2534,6 @@ return; /* The contour was aligned with stem commands - nothing to do. */ center_gx = center_agx = (min_gx + max_gx) / 2; center_gy = center_agy = (min_gy + max_gy) / 2; - vd_circle(center_agx, center_agy, 7, RGB(255,0,0)); if (!aligned_x) { /* Heuristic : apply vstem if it is close to the center : */ t1_hint * hint = t1_hinter__find_vstem_by_center(self, center_gx); @@ -2720,10 +2542,8 @@ aligned_x = true; } } - vd_circle(center_agx, center_agy, 7, RGB(0,255,0)); t1_hinter__align_to_grid(self, self->g2o_fraction / 2, ¢er_agx, ¢er_agy, CONTRAST_STEMS || self->align_to_pixels); - vd_circle(center_agx, center_agy, 7, RGB(0,0,255)); sx = center_agx - center_gx; sy = center_agy - center_gy; if (aligned_x) @@ -2787,7 +2607,7 @@ bool moved = false; do { - int min_l = 0, max_l = 0, jp; + int min_l = 0, max_l = 0; int min_w, max_w, w0; g0 = *member_prt(t1_glyph_space_coord, &self->pole[start_pole], offset_gc); @@ -2796,7 +2616,6 @@ min_g = g0; max_g = g0; min_w = max_w = w0; - jp = start_pole; for (j = ranger_step_f(start_pole, beg_contour_pole, end_contour_pole), l = 1; j != start_pole; j = ranger_step_f(j, beg_contour_pole, end_contour_pole), l++) { @@ -2815,7 +2634,6 @@ break; if (j == stop_pole) break; - jp = j; } stop_pole = j; cut_l = l; @@ -2935,8 +2753,6 @@ return code; if (i >= self->contour_count) break; - vd_setcolor(RGB(255,0,0)); - vd_moveto(fx,fy); end_pole = self->contour[i + 1] - 2; for(j = beg_pole + 1; j <= end_pole; j++) { pole = & self->pole[j]; @@ -2945,8 +2761,6 @@ code = gx_path_add_line(self->output_path, fx, fy); if (code < 0) return code; - vd_setcolor(RGB(255,0,0)); - vd_lineto(fx,fy); } else { int j1 = j + 1, j2 = (j + 2 > end_pole ? beg_pole : j + 2); fixed fx1, fy1, fx2, fy2; @@ -2956,8 +2770,6 @@ code = gx_path_add_curve(self->output_path, fx, fy, fx1, fy1, fx2, fy2); if (code < 0) return code; - vd_setcolor(RGB(255,0,0)); - vd_curveto(fx,fy,fx1,fy1,fx2,fy2); j+=2; } } @@ -2990,23 +2802,12 @@ int t1_hinter__endglyph(t1_hinter * self) { int code = 0; - if (!vd_enabled) { /* Maybe enabled in t1_hinter__set_mapping. */ - vd_get_dc('h'); - vd_set_shift(VD_SHIFT_X, VD_SHIFT_Y); - vd_set_scale(VD_SCALE); - vd_set_origin(0, 0); - if (!VD_DRAW_IMPORT && !self->disable_hinting) - vd_erase(RGB(255, 255, 255)); - } - if (vd_enabled && self->g2o_fraction != 0 && !self->disable_hinting) - t1_hinter__paint_raster_grid(self); code = t1_hinter__add_trailing_moveto(self); if (code < 0) goto exit; code = t1_hinter__end_subglyph(self); if (code < 0) goto exit; - t1_hinter__paint_glyph(self, false); t1_hinter__adjust_matrix_precision(self, self->orig_gx, self->orig_gy); t1_hinter__compute_y_span(self); t1_hinter__simplify_representation(self); @@ -3026,27 +2827,14 @@ goto exit; t1_hinter__process_dotsections(self); t1_hinter__interpolate_other_poles(self); - t1_hinter__paint_glyph(self, true); } if (self->pole_count) { if (self->fix_contour_sign) { t1_hinter__fix_contour_signs(self); - t1_hinter__paint_glyph(self, true); - } - if (vd_enabled) { - double_matrix m; - - fraction_matrix__to_double(&self->ctmi, &m); - vd_set_scaleXY(vd_get_scale_x * m.xx, vd_get_scale_y * m.yy); - vd_set_origin(self->orig_dx, self->orig_dy); - /* fixme : general transform requires changes to vdtrace. - Current implementation paints exported rotated glyph in wrong coordinates. - */ } code = t1_hinter__export(self); } exit: t1_hinter__free_arrays(self); - vd_release_dc; return code; } diff -Nru ghostscript-9.10~dfsg/base/gxhintn.h ghostscript-9.25~dfsg+1/base/gxhintn.h --- ghostscript-9.10~dfsg/base/gxhintn.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhintn.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -190,7 +190,7 @@ int log2_pixels_x, int log2_pixels_y, int log2_subpixels_x, int log2_subpixels_y, fixed origin_x, fixed origin_y, bool align_to_pixels); -int t1_hinter__set_font_data(t1_hinter * this, int FontType, gs_type1_data *pdata, +int t1_hinter__set_font_data(gs_memory_t *mem, t1_hinter * this, int FontType, gs_type1_data *pdata, bool no_grid_fitting, bool is_resource); int t1_hinter__set_font42_data(t1_hinter * this, int FontType, gs_type42_data *pdata, bool no_grid_fitting); diff -Nru ghostscript-9.10~dfsg/base/gxhldevc.c ghostscript-9.25~dfsg+1/base/gxhldevc.c --- ghostscript-9.10~dfsg/base/gxhldevc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhldevc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* High level device color save/compare procedures */ @@ -43,29 +43,15 @@ } /* - * Get graphics state pointer (from imager state pointer) - */ -const gs_state * gx_hld_get_gstate_ptr(const gs_imager_state * pis) -{ - - /* Check to verify the structure type is really (gs_state *) */ - if (pis == NULL || pis->is_gstate == false) - return NULL; - - return (const gs_state *) pis; -} - -/* * Save the device color information including the color space id and * client color data (if available). * * More description in src/gxhldevc.h */ bool -gx_hld_save_color(const gs_imager_state * pis, const gx_device_color * pdevc, +gx_hld_save_color(const gs_gstate * pgs, const gx_device_color * pdevc, gx_hl_saved_color * psc) { - const gs_state * pgs = gx_hld_get_gstate_ptr(pis); memset(psc, 0, sizeof(*psc)); /* clear the entire structure */ if (pdevc == NULL) { @@ -209,12 +195,10 @@ * Check if a high level color is availavble. */ bool -gx_hld_is_hl_color_available(const gs_imager_state * pis, +gx_hld_is_hl_color_available(const gs_gstate * pgs, const gx_device_color * pdevc) { - const gs_state * pgs = gx_hld_get_gstate_ptr(pis); - - if (pgs != NULL && pdevc != NULL && pdevc->ccolor_valid) + if (pgs != NULL && pdevc != NULL && pdevc->type != gx_dc_type_null && pdevc->ccolor_valid) return true; return false; } @@ -225,13 +209,12 @@ * More description in src/gxhldevc.h */ gx_hld_get_color_space_and_ccolor_status -gx_hld_get_color_space_and_ccolor(const gs_imager_state * pis, +gx_hld_get_color_space_and_ccolor(const gs_gstate * pgs, const gx_device_color * pdevc, const gs_color_space ** ppcs, const gs_client_color ** ppcc) { /* Check if the current color space was used to build the device color */ - if (gx_hld_is_hl_color_available(pis, pdevc)) { - const gs_state * pgs = gx_hld_get_gstate_ptr(pis); + if (gx_hld_is_hl_color_available(pgs, pdevc)) { const gs_color_space * pcs = gs_currentcolorspace_inline(pgs); *ppcs = pcs; @@ -256,10 +239,8 @@ * More description in src/gxhldevc.h */ int -gx_hld_get_number_color_components(const gs_imager_state * pis) +gx_hld_get_number_color_components(const gs_gstate * pgs) { - const gs_state * pgs = gx_hld_get_gstate_ptr(pis); - if (pgs != NULL) { const gs_color_space * pcs = gs_currentcolorspace_inline(pgs); int n = gs_color_space_num_components(pcs); @@ -275,12 +256,12 @@ * More description in src/gxhldevc.h */ gx_hld_get_color_component_status -gx_hld_get_color_component(const gs_imager_state * pis, +gx_hld_get_color_component(const gs_gstate * pgs, const gx_device_color * pdevc, int comp_num, float * output) { if (pdevc != NULL && pdevc->ccolor_valid) { - int ncomp = gx_hld_get_number_color_components(pis); + int ncomp = gx_hld_get_number_color_components(pgs); if (ncomp < 0) return invalid_color_info; diff -Nru ghostscript-9.10~dfsg/base/gxhldevc.h ghostscript-9.25~dfsg+1/base/gxhldevc.h --- ghostscript-9.10~dfsg/base/gxhldevc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhldevc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* High level device color save/compare procedures */ @@ -51,9 +51,9 @@ * saving, comparing, and getting high level color information. */ -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_device_color_DEFINED @@ -78,12 +78,6 @@ void gx_hld_saved_color_init(gx_hl_saved_color * psc); /* - * Get graphics state pointer (from imager state pointer) - * Return NULL if the imager state is not also a graphics state. - */ -const gs_state * gx_hld_get_gstate_ptr(const gs_imager_state * pis); - -/* * Save the device color information including the color space id and * client color data (if available). The pattern id is also saved for * detection of changes in the pattern. @@ -94,9 +88,9 @@ * a save and test on the given color. * * If the device can't handle high level colors, it must pass NULL to - * the 'pis' argument. + * the 'pgs' argument. */ -bool gx_hld_save_color(const gs_imager_state * pis, +bool gx_hld_save_color(const gs_gstate * pgs, const gx_device_color * pdevc, gx_hl_saved_color * psc); /* @@ -117,7 +111,7 @@ * Check if a high level color is availavble. */ bool -gx_hld_is_hl_color_available(const gs_imager_state * pis, +gx_hld_is_hl_color_available(const gs_gstate * pgs, const gx_device_color * pdevc); /* @@ -137,7 +131,7 @@ * Get pointers to the current color space and client color. * * There are four possible cases: - * 1. Either the device color or imager state pointer is NULL. If so then + * 1. Either the device color or gs_gstate pointer is NULL. If so then * we do not have enough information. Thus we need to fall back to the * process color model color. Return NULL for both pointers. * 2. The device color was not created from a color space and a client color. @@ -157,17 +151,17 @@ * a pattern or non pattern). */ gx_hld_get_color_space_and_ccolor_status gx_hld_get_color_space_and_ccolor( - const gs_imager_state * pis, const gx_device_color * pdevc, + const gs_gstate * pgs, const gx_device_color * pdevc, const gs_color_space ** ppcs, const gs_client_color ** ppcc); /* * This routine will return the number of components in the current color * space. * - * The routine will return -1 if the imager state does not point to a + * The routine will return -1 if the gs_gstate does not point to a * graphics state (and thus we cannot get the current color space). */ -int gx_hld_get_number_color_components(const gs_imager_state * pis); +int gx_hld_get_number_color_components(const gs_gstate * pgs); /* * This defines sthe possible status to be returned from get_color_component. @@ -187,7 +181,7 @@ * device fall back to using the process color model. */ gx_hld_get_color_component_status gx_hld_get_color_component( - const gs_imager_state * pis, const gx_device_color * pdevc, + const gs_gstate * pgs, const gx_device_color * pdevc, int comp_numi, float * output); #endif diff -Nru ghostscript-9.10~dfsg/base/gxhtbit.c ghostscript-9.25~dfsg+1/base/gxhtbit.c --- ghostscript-9.10~dfsg/base/gxhtbit.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhtbit.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxht.c ghostscript-9.25~dfsg+1/base/gxht.c --- ghostscript-9.10~dfsg/base/gxht.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxht.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,7 +24,7 @@ #include "gxdcolor.h" #include "gxfixed.h" #include "gxdevice.h" /* for gzht.h */ -#include "gxistate.h" +#include "gxgstate.h" #include "gzht.h" #include "gsserial.h" @@ -215,7 +215,7 @@ /* Load the device color into the halftone cache if needed. */ static int -gx_dc_ht_binary_load(gx_device_color * pdevc, const gs_imager_state * pis, +gx_dc_ht_binary_load(gx_device_color * pdevc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { int component_index = pdevc->colors.binary.b_index; @@ -226,7 +226,7 @@ gx_ht_cache *pcache = porder->cache; if (pcache->order.bit_data != porder->bit_data) - gx_ht_init_cache(pis->memory, pcache, porder); + gx_ht_init_cache(pgs->memory, pcache, porder); /* * We do not load the cache now. Instead we wait until we are ready * to actually render the color. This allows multiple colors to be @@ -277,6 +277,7 @@ { gx_rop_source_t no_source; + fit_fill(dev, x, y, w, h); /* Load the halftone cache for the color */ gx_dc_ht_binary_load_cache(pdevc); /* @@ -462,7 +463,7 @@ /* check if sufficient space has been provided */ if (req_size > *psize) { *psize = req_size; - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } /* write out the flag byte */ @@ -506,12 +507,12 @@ * pdevc pointer to the location in which to write the * reconstructed device color * - * pis pointer to the current imager state (to access the + * pgs pointer to the current gs_gstate (to access the * current halftone) * * prior_devc pointer to the current device color (this is provided * separately because the device color is not part of the - * imager state) + * gs_gstate) * * dev pointer to the current device, used to retrieve process * color model information @@ -531,7 +532,7 @@ static int gx_dc_ht_binary_read( gx_device_color * pdevc, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_device_color * prior_devc, const gx_device * dev, /* ignored */ int64_t offset, @@ -553,8 +554,8 @@ memset(&devc, 0, sizeof(devc)); /* clear pointers */ devc.type = gx_dc_type_ht_binary; - /* the halftone is always taken from the imager state */ - devc.colors.binary.b_ht = pis->dev_ht; + /* the halftone is always taken from the gs_gstate */ + devc.colors.binary.b_ht = pgs->dev_ht; /* cache is not porvided until the device color is used */ devc.colors.binary.b_tile = 0; @@ -601,14 +602,14 @@ devc.colors.binary.b_index = *pdata++; } - if (pis->dev_ht == NULL) + if (pgs->dev_ht == NULL) return_error(gs_error_unregistered); /* Must not happen. */ /* set the phase as required (select value is arbitrary) */ color_set_phase_mod( &devc, - pis->screen_phase[0].x, - pis->screen_phase[0].y, - pis->dev_ht->lcm_width, - pis->dev_ht->lcm_height ); + pgs->screen_phase[0].x, + pgs->screen_phase[0].y, + pgs->dev_ht->lcm_width, + pgs->dev_ht->lcm_height ); /* everything looks good */ *pdevc = devc; diff -Nru ghostscript-9.10~dfsg/base/gxht.h ghostscript-9.25~dfsg+1/base/gxht.h --- ghostscript-9.10~dfsg/base/gxht.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxht.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -89,7 +89,7 @@ typedef struct gs_threshold_halftone_s { GS_THRESHOLD_HALFTONE_COMMON; /* must be first */ gs_const_string thresholds; - gs_mapping_proc transfer; /* OBSOLETE */ + gs_mapping_proc transfer; } gs_threshold_halftone; #define st_threshold_halftone_max_ptrs 2 @@ -101,6 +101,7 @@ int height2; int bytes_per_sample; /* 1 or 2 */ gs_const_bytestring thresholds; /* nota bene */ + gs_mapping_proc transfer; } gs_threshold2_halftone; /* Client-defined halftone that generates a halftone order. */ @@ -118,7 +119,7 @@ */ int (*create_order) (gx_ht_order * porder, - gs_state * pgs, + gs_gstate * pgs, const gs_client_order_halftone * phcop, gs_memory_t * mem); @@ -213,7 +214,7 @@ bool gs_currentaccuratescreens(gs_memory_t *); /* Initiate screen sampling with optional AccurateScreens. */ -int gs_screen_init_memory(gs_screen_enum *, gs_state *, +int gs_screen_init_memory(gs_screen_enum *, gs_gstate *, gs_screen_halftone *, bool, gs_memory_t *); #define gs_screen_init_accurate(penum, pgs, phsp, accurate)\ diff -Nru ghostscript-9.10~dfsg/base/gxht_thresh.c ghostscript-9.25~dfsg+1/base/gxht_thresh.c --- ghostscript-9.10~dfsg/base/gxht_thresh.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxht_thresh.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,17 +9,18 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /*$Id: gxhts_thresh.c $ */ /* Halftone thresholding code */ +#include /* abs() */ #include "memory_.h" #include "gx.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gsiparam.h" #include "math_.h" #include "gxfixed.h" /* needed for gximage.h */ @@ -37,7 +38,7 @@ /* #define PACIFY_VALGRIND */ #ifndef __WIN32__ -#define __align16 __attribute__((align(16))) +#define __align16 __attribute__((aligned(16))) #else #define __align16 __declspec(align(16)) #endif @@ -177,7 +178,7 @@ } #endif -/* SSE2 and non-SSE2 implememntation of thresholding a row. Subtractive case +/* SSE2 and non-SSE2 implememntation of thresholding a row. Subtractive case There is some code replication between the two of these (additive and subtractive) that I need to go back and determine how we can combine them without any performance loss. */ @@ -390,18 +391,18 @@ #endif } -/* This thresholds a buffer that is LAND_BITS wide by data_length tall. +/* This thresholds a buffer that is LAND_BITS wide by data_length tall. Subtractive case */ void gx_ht_threshold_landscape_sub(byte *contone_align, byte *thresh_align, - ht_landscape_info_t ht_landscape, byte *halftone, + ht_landscape_info_t *ht_landscape, byte *halftone, int data_length) { __align16 byte contone[LAND_BITS]; int position_start, position, curr_position; - int *widths = &(ht_landscape.widths[0]); + int *widths = &(ht_landscape->widths[0]); int local_widths[LAND_BITS]; - int num_contone = ht_landscape.num_contones; + int num_contone = ht_landscape->num_contones; int k, j, w, contone_out_posit; byte *contone_ptr, *thresh_ptr, *halftone_ptr; #ifdef PACIFY_VALGRIND @@ -410,10 +411,10 @@ /* Work through chunks of 16. */ /* Data may have come in left to right or right to left. */ - if (ht_landscape.index > 0) { + if (ht_landscape->index > 0) { position = position_start = 0; } else { - position = position_start = ht_landscape.curr_pos + 1; + position = position_start = ht_landscape->curr_pos + 1; } thresh_ptr = thresh_align; halftone_ptr = halftone; @@ -423,7 +424,7 @@ for (j = 0; j < num_contone; j++) k += (local_widths[j] = widths[position_start+j]); if (k > LAND_BITS) { - if (ht_landscape.index > 0) { + if (ht_landscape->index > 0) { local_widths[num_contone-1] -= k-LAND_BITS; } else { local_widths[0] -= k-LAND_BITS; @@ -485,14 +486,14 @@ the additive and subtractive cases */ void gx_ht_threshold_landscape(byte *contone_align, byte *thresh_align, - ht_landscape_info_t ht_landscape, byte *halftone, + ht_landscape_info_t *ht_landscape, byte *halftone, int data_length) { __align16 byte contone[LAND_BITS]; int position_start, position, curr_position; - int *widths = &(ht_landscape.widths[0]); + int *widths = &(ht_landscape->widths[0]); int local_widths[LAND_BITS]; - int num_contone = ht_landscape.num_contones; + int num_contone = ht_landscape->num_contones; int k, j, w, contone_out_posit; byte *contone_ptr, *thresh_ptr, *halftone_ptr; #ifdef PACIFY_VALGRIND @@ -501,10 +502,10 @@ /* Work through chunks of 16. */ /* Data may have come in left to right or right to left. */ - if (ht_landscape.index > 0) { + if (ht_landscape->index > 0) { position = position_start = 0; } else { - position = position_start = ht_landscape.curr_pos + 1; + position = position_start = ht_landscape->curr_pos + 1; } thresh_ptr = thresh_align; halftone_ptr = halftone; @@ -514,7 +515,7 @@ for (j = 0; j < num_contone; j++) k += (local_widths[j] = widths[position_start+j]); if (k > LAND_BITS) { - if (ht_landscape.index > 0) { + if (ht_landscape->index > 0) { local_widths[num_contone-1] -= k-LAND_BITS; } else { local_widths[0] -= k-LAND_BITS; @@ -575,19 +576,20 @@ gxht_thresh_image_init(gx_image_enum *penum) { int code = 0; - fixed ox, oy; + fixed ox; int temp; int dev_width, max_height; int spp_out; int k; gx_ht_order *d_order; + gx_dda_fixed dda_ht; if (gx_device_must_halftone(penum->dev)) { - if (penum->pis != NULL && penum->pis->dev_ht != NULL) { - for (k = 0; k < penum->pis->dev_ht->num_comp; k++) { - d_order = &(penum->pis->dev_ht->components[k].corder); + if (penum->pgs != NULL && penum->pgs->dev_ht != NULL) { + for (k = 0; k < penum->pgs->dev_ht->num_comp; k++) { + d_order = &(penum->pgs->dev_ht->components[k].corder); code = gx_ht_construct_threshold(d_order, penum->dev, - penum->pis, k); + penum->pgs, k); if (code < 0 ) { return gs_rethrow(code, "threshold creation failed"); } @@ -597,6 +599,8 @@ } } spp_out = penum->dev->color_info.num_components; + /* Precompute values needed for rasterizing. */ + penum->dxx = float2fixed(penum->matrix.xx + fixed2float(fixed_epsilon) / 2); /* If the image is landscaped then we want to maintain a buffer that is sufficiently large so that we can hold a byte of halftoned data along the column. This way we avoid doing @@ -615,14 +619,16 @@ with h=0 we will flush the buffer as we are at the end of the data. */ if (penum->posture == image_landscape) { - int col_length = - fixed2int_var_rounded(any_abs(penum->x_extent.y)); + int col_length = fixed2int_var_rounded(any_abs(penum->x_extent.y)); + dda_ht = penum->dda.pixel0.y; + if (penum->dxx > 0) + dda_translate(dda_ht, -fixed_epsilon); /* to match rounding in non-fast code */ + ox = dda_current(penum->dda.pixel0.x); - oy = dda_current(penum->dda.pixel0.y); - /* Line_size is col_length rounded up - why? */ - /* RJW: This was 16 here, but as I don't understand why, I'm using - * LAND_BITS instead. Check with Michael. */ - temp = (col_length + LAND_BITS-1)/LAND_BITS; + temp = gxht_dda_length(&dda_ht, penum->rect.w); + if (col_length < temp) + col_length = temp; /* choose max to make sure line_size is large enough */ + temp = (col_length + LAND_BITS)/LAND_BITS; /* round up to allow for offset bits */ /* bitmap_raster() expects the width in bits, hence "* 8" */ penum->line_size = bitmap_raster((temp * LAND_BITS) * 8); /* The stride */ /* Now we need at most LAND_BITS of these */ @@ -681,20 +687,20 @@ boundary after an offset to ensure that we can make use of the SSE2 operations for thresholding. We do the allocations now to avoid doing them with every line */ + dda_ht = penum->dda.pixel0.x; + if (penum->dxx > 0) + dda_translate(dda_ht, -fixed_epsilon); /* to match rounding in non-fast code */ /* Initialize the ht_landscape stuff to zero */ memset(&(penum->ht_landscape), 0, sizeof(ht_landscape_info_t)); - ox = dda_current(penum->dda.pixel0.x); - oy = dda_current(penum->dda.pixel0.y); - dev_width = - (int) fabs((long) fixed2long_pixround(ox + penum->x_extent.x) - - fixed2long_pixround(ox)); + ox = dda_current(dda_ht); + dev_width = gxht_dda_length(&dda_ht, penum->rect.w); /* Get the bit position so that we can do a copy_mono for the left remainder and then 16 bit aligned copies for the rest. The right remainder will be OK as it will land in the MSBit positions. Note the #define chunk bits16 in gdevm1.c. Allow also for a 15 sample over run. */ - penum->ht_offset_bits = (-fixed2int_var_pixround(ox)) & (bitmap_raster(1) - 1); + penum->ht_offset_bits = (-fixed2int_var_rounded(ox)) & (bitmap_raster(1) - 1); if (penum->ht_offset_bits > 0) { penum->ht_stride = bitmap_raster((7 + (dev_width + 4)) + (ARCH_SIZEOF_LONG * 8)); } else { @@ -705,6 +711,11 @@ space */ max_height = (int) ceil(fixed2float(any_abs(penum->dst_height)) / (float) penum->Height); + if (max_height <= 0) + return -1; /* shouldn't happen, but check so we don't div by zero */ + if (penum->ht_stride * spp_out > max_int / max_height) + return -1; /* overflow */ + penum->ht_buffer = gs_alloc_bytes(penum->memory, penum->ht_stride * max_height * spp_out, @@ -725,6 +736,11 @@ Also allow a 15 sample over run during the execution. */ temp = (int) ceil((float) ((dev_width + 15.0) + 15.0)/16.0); penum->line_size = bitmap_raster(temp * 16 * 8); /* The stride */ + if (penum->line_size > max_int / max_height) { + gs_free_object(penum->memory, penum->ht_buffer, "gxht_thresh"); + penum->ht_buffer = NULL; + return -1; /* thresh_buffer size overflow */ + } penum->line = gs_alloc_bytes(penum->memory, penum->line_size * spp_out, "gxht_thresh"); penum->thresh_buffer = gs_alloc_bytes(penum->memory, @@ -741,13 +757,11 @@ #endif } } - /* Precompute values needed for rasterizing. */ - penum->dxx = float2fixed(penum->matrix.xx + fixed2float(fixed_epsilon) / 2); return code; } static void -fill_threshhold_buffer(byte *dest_strip, byte *src_strip, int src_width, +fill_threshold_buffer(byte *dest_strip, byte *src_strip, int src_width, int left_offset, int left_width, int num_tiles, int right_width) { @@ -789,10 +803,12 @@ position_curr = ht_landscape->curr_pos - 1; position_new = 0; } - for (k = 0; k < data_length; k++) { - contone_align[position_new] = contone_align[position_curr]; - position_curr += LAND_BITS; - position_new += LAND_BITS; + if (position_curr != position_new) { + for (k = 0; k < data_length; k++) { + contone_align[position_new] = contone_align[position_curr]; + position_curr += LAND_BITS; + position_new += LAND_BITS; + } } } @@ -803,14 +819,11 @@ reset_landscape_buffer(ht_landscape_info_t *ht_landscape, byte *contone_align, int data_length, int num_used) { - int k; - int position_curr, position_new, delta; + int delta; int curr_x_pos = ht_landscape->xstart; if (ht_landscape->index < 0) { /* Moving right to left, move column to far right */ - position_curr = ht_landscape->curr_pos + 1; - position_new = LAND_BITS-1; delta = ht_landscape->count - num_used; memset(&(ht_landscape->widths[0]), 0, sizeof(int)*LAND_BITS); ht_landscape->widths[LAND_BITS-1] = delta; @@ -818,8 +831,6 @@ ht_landscape->xstart = curr_x_pos - num_used; } else { /* Moving left to right, move column to far left */ - position_curr = ht_landscape->curr_pos - 1; - position_new = 0; delta = ht_landscape->count - num_used; memset(&(ht_landscape->widths[0]), 0, sizeof(int)*LAND_BITS); ht_landscape->widths[0] = delta; @@ -828,11 +839,6 @@ } ht_landscape->count = delta; ht_landscape->num_contones = 1; - for (k = 0; k < data_length; k++) { - contone_align[position_new] = contone_align[position_curr]; - position_curr += LAND_BITS; - position_new += LAND_BITS; - } } /* This performs a thresholding operation on multiple planes of data and @@ -860,12 +866,9 @@ int offset_bits = penum->ht_offset_bits; byte *halftone; int dithered_stride = penum->ht_stride; - bool is_planar_dev = dev_proc(dev, dev_spec_op)(dev, - gxdso_is_native_planar, NULL, 0) > 0; + bool is_planar_dev = dev->is_planar; gx_color_index dev_white = gx_device_white(dev); gx_color_index dev_black = gx_device_black(dev); - bool done = false; - bool allow_reset = false; /* Init to silence compiler warnings */ int spp_out = dev->color_info.num_components; byte *contone_align = NULL; /* Init to silence compiler warnings */ @@ -876,16 +879,17 @@ /* Figure out the tile steps. Left offset, Number of tiles, Right offset. */ switch (posture) { case image_portrait: - allow_reset = true; vdi = penum->hci; /* Iterate over the vdi and fill up our threshold buffer. We also need to loop across the planes of data */ for (j = 0; j < spp_out; j++) { - thresh_width = penum->pis->dev_ht->components[j].corder.width; - thresh_height = penum->pis->dev_ht->components[j].corder.full_height; + bool threshold_inverted = penum->pgs->dev_ht->components[j].corder.threshold_inverted; + + thresh_width = penum->pgs->dev_ht->components[j].corder.width; + thresh_height = penum->pgs->dev_ht->components[j].corder.full_height; halftone = penum->ht_buffer + j * vdi * dithered_stride; /* Compute the tiling positions with dest_width */ - dx = fixed2int_var(xrun) % thresh_width; + dx = (fixed2int_var_rounded(xrun) + penum->pgs->screen_phase[0].x) % thresh_width; /* Left remainder part */ left_rem_end = min(dx + dest_width, thresh_width); /* The left width of our tile part */ @@ -897,13 +901,14 @@ right_tile_width = dest_width - num_full_tiles * thresh_width - left_width; /* Get the proper threshold for the colorant count */ - threshold = penum->pis->dev_ht->components[j].corder.threshold; + threshold = penum->pgs->dev_ht->components[j].corder.threshold; /* Point to the proper contone data */ contone_align = penum->line + contone_stride * j + offset_contone[j]; for (k = 0; k < vdi; k++) { /* Get a pointer to our tile row */ - dy = (penum->yci + k + penum->dev->band_offset_y) % thresh_height; + dy = (penum->yci + k - + penum->pgs->screen_phase[0].y) % thresh_height; if (dy < 0) dy += thresh_height; thresh_tile = threshold + thresh_width * dy; @@ -911,7 +916,7 @@ to update with stride */ position = contone_stride * k; /* Tile into the 128 bit aligned threshold strip */ - fill_threshhold_buffer(&(thresh_align[position]), + fill_threshold_buffer(&(thresh_align[position]), thresh_tile, thresh_width, dx, left_width, num_full_tiles, right_tile_width); } @@ -919,8 +924,8 @@ if (offset_bits > dest_width) offset_bits = dest_width; - if (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE - && is_planar_dev) { + if (threshold_inverted || + (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && is_planar_dev)) { gx_ht_threshold_row_bit_sub(contone_align, thresh_align, contone_stride, halftone, dithered_stride, dest_width, vdi, offset_bits); @@ -942,7 +947,7 @@ /* Now do the copy mono or copy plane operation */ /* First the left remainder bits */ if (offset_bits > 0) { - int x_pos = fixed2int_var(xrun); + int x_pos = fixed2int_var_rounded(xrun); if (!is_planar_dev) { (*dev_proc(dev, copy_mono)) (dev, penum->ht_buffer, 0, dithered_stride, gx_no_bitmap_id, x_pos, y_pos, @@ -957,14 +962,14 @@ if ((dest_width - offset_bits) > 0 ) { /* Now the primary aligned bytes */ int curr_width = dest_width - offset_bits; - int x_pos = fixed2int_var(xrun) + offset_bits; + int x_pos = fixed2int_var_rounded(xrun) + offset_bits; /* FIXME: This assumes the allowed offset_bits will always be <= 16 */ int xoffs = offset_bits > 0 ? 16 : 0; if (!is_planar_dev) { (*dev_proc(dev, copy_mono)) (dev, penum->ht_buffer, xoffs, dithered_stride, gx_no_bitmap_id, x_pos, y_pos, - curr_width, vdi, dev_white, + curr_width, vdi, dev_white, dev_black); } else { (*dev_proc(dev, copy_planes)) (dev, penum->ht_buffer, xoffs, dithered_stride, @@ -983,39 +988,34 @@ first if we have enough data or are all done */ while ( (penum->ht_landscape.count >= LAND_BITS || ((penum->ht_landscape.count >= offset_bits) && - penum->ht_landscape.offset_set)) && !done ) { + penum->ht_landscape.offset_set))) { /* Go ahead and 2D tile in the threshold buffer at this time */ /* Always work the tiling from the upper left corner of our LAND_BITS columns */ for (j = 0; j < spp_out; j++) { halftone = penum->ht_buffer + j * penum->ht_plane_height * (LAND_BITS>>3); - thresh_width = penum->pis->dev_ht->components[j].corder.width; + thresh_width = penum->pgs->dev_ht->components[j].corder.width; thresh_height = - penum->pis->dev_ht->components[j].corder.full_height; + penum->pgs->dev_ht->components[j].corder.full_height; /* Get the proper threshold for the colorant count */ - threshold = penum->pis->dev_ht->components[j].corder.threshold; + threshold = penum->pgs->dev_ht->components[j].corder.threshold; /* Point to the proper contone data */ contone_align = penum->line + offset_contone[j] + LAND_BITS * j * contone_stride; - if (j == spp_out - 1) { - allow_reset = true; - } else { - allow_reset = false; - } if (penum->ht_landscape.offset_set) { width = offset_bits; } else { width = LAND_BITS; } if (penum->y_extent.x < 0) { - dx = (penum->ht_landscape.xstart - width + 1) % - thresh_width; + dx = penum->ht_landscape.xstart - width + 1; } else { - dx = penum->ht_landscape.xstart % thresh_width; + dx = penum->ht_landscape.xstart; } - dy = (penum->dev->band_offset_y + - penum->ht_landscape.y_pos) % thresh_height; + dx = (dx + penum->pgs->screen_phase[0].x) % thresh_width; + dy = (penum->ht_landscape.y_pos - + penum->pgs->screen_phase[0].y) % thresh_height; if (dy < 0) dy += thresh_height; /* Left remainder part */ @@ -1071,10 +1071,17 @@ if (dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && is_planar_dev) { gx_ht_threshold_landscape_sub(contone_align, thresh_align, - penum->ht_landscape, halftone, dest_height); + &(penum->ht_landscape), halftone, dest_height); } else { gx_ht_threshold_landscape(contone_align, thresh_align, - penum->ht_landscape, halftone, dest_height); + &(penum->ht_landscape), halftone, dest_height); + } + /* We may have a line left over that has to be maintained + due to line replication in the resolution conversion. */ + if (width != penum->ht_landscape.count) { + /* move the line do not reset the stuff */ + move_landscape_buffer(&(penum->ht_landscape), + contone_align, dest_height); } } /* Perform the copy mono */ @@ -1085,7 +1092,7 @@ gx_no_bitmap_id, penum->ht_landscape.xstart - width + 1, penum->ht_landscape.y_pos, - width, dest_height, + width, dest_height, dev_white, dev_black); } else { (*dev_proc(dev, copy_planes)) @@ -1113,36 +1120,23 @@ penum->ht_plane_height); } } - /* Clean up and reset our buffer. We may have a line left - over that has to be maintained due to line replication in the - resolution conversion. However, pay attention to the reset - flag which indicates we are done with our last plane */ - if (!allow_reset) { - if (width != penum->ht_landscape.count) { - /* move the line do not reset the stuff */ - move_landscape_buffer(&(penum->ht_landscape), - contone_align, dest_height); - } - done = true; + penum->ht_landscape.offset_set = false; + if (width != penum->ht_landscape.count) { + reset_landscape_buffer(&(penum->ht_landscape), + contone_align, dest_height, + width); } else { - penum->ht_landscape.offset_set = false; - if (width != penum->ht_landscape.count) { - reset_landscape_buffer(&(penum->ht_landscape), - contone_align, dest_height, - width); + /* Reset the whole buffer */ + penum->ht_landscape.count = 0; + if (penum->ht_landscape.index < 0) { + /* Going right to left */ + penum->ht_landscape.curr_pos = LAND_BITS-1; } else { - /* Reset the whole buffer */ - penum->ht_landscape.count = 0; - if (penum->ht_landscape.index < 0) { - /* Going right to left */ - penum->ht_landscape.curr_pos = LAND_BITS-1; - } else { - /* Going left to right */ - penum->ht_landscape.curr_pos = 0; - } - penum->ht_landscape.num_contones = 0; - memset(&(penum->ht_landscape.widths[0]), 0, sizeof(int)*LAND_BITS); + /* Going left to right */ + penum->ht_landscape.curr_pos = 0; } + penum->ht_landscape.num_contones = 0; + memset(&(penum->ht_landscape.widths[0]), 0, sizeof(int)*LAND_BITS); } } break; @@ -1151,3 +1145,10 @@ } return 0; } + +int gxht_dda_length(gx_dda_fixed *dda, int src_size) +{ + gx_dda_fixed d = (*dda); + dda_advance(d, src_size); + return abs(fixed2int_var_rounded(dda_current(d)) - fixed2int_var_rounded(dda_current(*dda))); +} diff -Nru ghostscript-9.10~dfsg/base/gxht_thresh.h ghostscript-9.25~dfsg+1/base/gxht_thresh.h --- ghostscript-9.10~dfsg/base/gxht_thresh.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxht_thresh.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -38,13 +38,17 @@ int dithered_stride, int width, int num_rows, int offset_bits); void gx_ht_threshold_landscape(byte *contone_align, byte *thresh_align, - ht_landscape_info_t ht_landscape, byte *halftone, + ht_landscape_info_t *ht_landscape, byte *halftone, int data_length); void gx_ht_threshold_landscape_sub(byte *contone_align, byte *thresh_align, - ht_landscape_info_t ht_landscape, byte *halftone, + ht_landscape_info_t *ht_landscape, byte *halftone, int data_length); int gxht_thresh_image_init(gx_image_enum *penum); int gxht_thresh_planes(gx_image_enum *penum, fixed xrun, int dest_width, int dest_height, byte *thresh_align, gx_device * dev, int offset_contone[], int contone_stride); + +/* Helper function for an operation performed several times */ +int gxht_dda_length(gx_dda_fixed *dda, int src_size); + #endif /* gshtx_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxhttile.h ghostscript-9.25~dfsg+1/base/gxhttile.h --- ghostscript-9.10~dfsg/base/gxhttile.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhttile.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxhttype.h ghostscript-9.25~dfsg+1/base/gxhttype.h --- ghostscript-9.10~dfsg/base/gxhttype.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxhttype.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxi12bit.c ghostscript-9.25~dfsg+1/base/gxi12bit.c --- ghostscript-9.10~dfsg/base/gxi12bit.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxi12bit.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,11 +28,10 @@ #include "gxdevice.h" #include "gxcmap.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdevmem.h" #include "gxcpath.h" #include "gximage.h" -#include "vdtrace.h" #include "gsicc.h" #include "gsicc_cache.h" #include "gsicc_cms.h" @@ -42,7 +41,7 @@ /* ---------------- Unpacking procedures ---------------- */ -static const byte * +const byte * sample_unpack_12(byte * bptr, int *pdata_x, const byte * data, int data_x, uint dsize, const sample_map *ignore_smap, int spread, int ignore_num_components_per_plane) @@ -98,8 +97,6 @@ return bptr; } -const sample_unpack_proc_t sample_unpack_12_proc = sample_unpack_12; - /* ------ Strategy procedure ------ */ /* Check the prototype. */ @@ -127,11 +124,12 @@ then we will need to use those and go through pixel by pixel instead of blasting through buffers. This is true for example with many of the color spaces for CUPs */ - std_cmap_procs = gx_device_uses_std_cmap_procs(penum->dev, penum->pis); + std_cmap_procs = gx_device_uses_std_cmap_procs(penum->dev, penum->pgs); if ( (gs_color_space_get_index(penum->pcs) == gs_color_space_index_DeviceN && penum->pcs->cmm_icc_profile_data == NULL) || penum->use_mask_color || penum->bps != 16 || !std_cmap_procs || - gs_color_space_get_index(penum->pcs) == gs_color_space_index_DevicePixel) { + gs_color_space_get_index(penum->pcs) == gs_color_space_index_DevicePixel || + gs_color_space_get_index(penum->pcs) == gs_color_space_index_Indexed) { /* DevicePixel color space used in mask from 3x type. Basically a simple color space that just is scaled to the device bit depth when remapped. No CM needed */ @@ -148,6 +146,8 @@ cmm_dev_profile_t *dev_profile; code = dev_proc(penum->dev, get_profile)(penum->dev, &dev_profile); + if (code < 0) + return 0; num_des_comps = gsicc_get_device_profile_comps(dev_profile); penum->icc_setup.need_decode = false; /* Check if we need to do any decoding. If yes, then that will slow us down */ @@ -158,11 +158,11 @@ } } /* Define the rendering intents */ - rendering_params.black_point_comp = penum->pis->blackptcomp; + rendering_params.black_point_comp = penum->pgs->blackptcomp; rendering_params.graphics_type_tag = GS_IMAGE_TAG; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = penum->pis->renderingintent; + rendering_params.rendering_intent = penum->pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; if (gs_color_space_is_PSCIE(penum->pcs) && penum->pcs->icc_equivalent != NULL) { pcs = penum->pcs->icc_equivalent; @@ -172,14 +172,14 @@ penum->icc_setup.is_lab = pcs->cmm_icc_profile_data->islab; penum->icc_setup.must_halftone = gx_device_must_halftone(penum->dev); penum->icc_setup.has_transfer = - gx_has_transfer(penum->pis, num_des_comps); + gx_has_transfer(penum->pgs, num_des_comps); if (penum->icc_setup.is_lab) penum->icc_setup.need_decode = false; if (penum->icc_link == NULL) { - penum->icc_link = gsicc_get_link(penum->pis, penum->dev, pcs, NULL, + penum->icc_link = gsicc_get_link(penum->pgs, penum->dev, pcs, NULL, &rendering_params, penum->memory); } /* Use the direct unpacking proc */ - penum->unpack = sample_unpackicc_16_proc; + penum->unpack = sample_unpackicc_16; if_debug0m('b', penum->memory, "[b]render=icc16\n"); return &image_render_icc16; } @@ -191,7 +191,7 @@ /* ------ Rendering for 12-bit samples ------ */ -#define FRACS_PER_LONG (arch_sizeof_long / arch_sizeof_frac) +#define FRACS_PER_LONG (ARCH_SIZEOF_LONG / arch_sizeof_frac) typedef union { frac v[GS_IMAGE_MAX_COLOR_COMPONENTS]; #define LONGS_PER_COLOR_FRACS\ @@ -199,7 +199,7 @@ long all[LONGS_PER_COLOR_FRACS]; /* for fast comparison */ } color_fracs; -#define LONGS_PER_4_FRACS ((arch_sizeof_frac * 4 + arch_sizeof_long - 1) / arch_sizeof_long) +#define LONGS_PER_4_FRACS ((arch_sizeof_frac * 4 + ARCH_SIZEOF_LONG - 1) / ARCH_SIZEOF_LONG) #if LONGS_PER_4_FRACS == 1 # define COLOR_FRACS_4_EQ(f1, f2)\ ((f1).all[0] == (f2).all[0]) @@ -231,7 +231,7 @@ image_render_frac(gx_image_enum * penum, const byte * buffer, int data_x, uint w, int h, gx_device * dev) { - const gs_imager_state *pis = penum->pis; + const gs_gstate *pgs = penum->pgs; gs_logical_operation_t lop = penum->log_op; gx_dda_fixed_point pnext; image_posture posture = penum->posture; @@ -242,7 +242,7 @@ cs_proc_remap_color((*remap_color)) = pcs->type->remap_color; gs_client_color cc; bool device_color = penum->device_color; - const gx_color_map_procs *cmap_procs = gx_get_cmap_procs(pis, dev); + const gx_color_map_procs *cmap_procs = gx_get_cmap_procs(pgs, dev); cmap_proc_rgb((*map_rgb)) = cmap_procs->map_rgb; cmap_proc_cmyk((*map_cmyk)) = cmap_procs->map_cmyk; bool use_mask_color = penum->use_mask_color; @@ -307,7 +307,7 @@ if (device_color) { (*map_cmyk) (next.v[0], next.v[1], next.v[2], next.v[3], - pdevc_next, pis, dev, + pdevc_next, pgs, dev, gs_color_select_source, NULL); goto f; } @@ -331,7 +331,7 @@ } if (device_color) { (*map_rgb) (next.v[0], next.v[1], - next.v[2], pdevc_next, pis, dev, + next.v[2], pdevc_next, pgs, dev, gs_color_select_source); goto f; } @@ -365,7 +365,7 @@ } if (device_color) { (*map_rgb) (next.v[0], next.v[0], - next.v[0], pdevc_next, pis, dev, + next.v[0], pdevc_next, pgs, dev, gs_color_select_source); goto f; } @@ -403,7 +403,7 @@ } break; } - mcode = remap_color(&cc, pcs, pdevc_next, pis, dev, + mcode = remap_color(&cc, pcs, pdevc_next, pgs, dev, gs_color_select_source); if (mcode < 0) goto fill; @@ -448,9 +448,6 @@ xi += wi, wi = -wi; code = gx_fill_rectangle_device_rop(xi, yt, wi, iht, pdevc, dev, lop); - vd_set_scale(0.01); - vd_rect(int2fixed(xi), int2fixed(yt), int2fixed(xi + wi), int2fixed(yt + iht), - 1, (int)pdevc->colors.pure); } if (code < 0) goto err; @@ -472,8 +469,6 @@ if (posture != image_portrait) { code = (*dev_proc(dev, fill_parallelogram)) (dev, xrun, yrun, xl - xrun, ytf - yrun, pdyx, pdyy, pdevc, lop); - /*vd_quad(xrun, yrun, xl, ytf, xl + pdyx, ytf + pdyy, xrun + pdyx, yrun + pdyy, - 1, (int)pdevc->colors.pure); */ } else { /* Same code as above near 'fill:' : */ int xi = irun; @@ -483,9 +478,6 @@ xi += wi, wi = -wi; code = gx_fill_rectangle_device_rop(xi, yt, wi, iht, pdevc, dev, lop); - vd_set_scale(0.01); - vd_rect(int2fixed(xi), int2fixed(yt), int2fixed(xi + wi), int2fixed(yt + iht), - 1, (int)pdevc->colors.pure); } return (code < 0 ? code : 1); @@ -586,42 +578,33 @@ image_render_icc16(gx_image_enum * penum, const byte * buffer, int data_x, uint w, int h, gx_device * dev) { - const gs_imager_state *pis = penum->pis; + const gs_gstate *pgs = penum->pgs; gs_logical_operation_t lop = penum->log_op; gx_dda_fixed_point pnext; image_posture posture = penum->posture; - fixed xprev, yprev; fixed pdyx, pdyy; /* edge of parallelogram */ int vci, vdi; - const gs_color_space *pcs; - gx_device_color devc1; - gx_device_color devc2; - gx_device_color *pdevc; - gx_device_color *pdevc_next; - gx_device_color *ptemp; int spp = penum->spp; - const unsigned short *psrc_initial = (const unsigned short *)buffer + data_x * spp; - const unsigned short *psrc = psrc_initial; - const unsigned short *rsrc = psrc + spp; /* psrc + spp at start of run */ + const unsigned short *psrc = (const unsigned short *)buffer + data_x * spp; fixed xrun; /* x at start of run */ int irun; /* int xrun */ fixed yrun; /* y ditto */ - color_fracs run; /* run value */ - color_fracs next; /* next sample value */ const unsigned short *bufend = psrc + w; + unsigned short *run; int code = 0; gsicc_bufferdesc_t input_buff_desc; gsicc_bufferdesc_t output_buff_desc; - unsigned short *psrc_cm, *psrc_cm_start, *psrc_decode; + unsigned short *psrc_cm, *psrc_cm_start, *psrc_decode, *psrc_cm_initial; int k; - gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS]; int spp_cm, num_pixels; - gx_color_index color; bool need_decode = penum->icc_setup.need_decode; bool must_halftone = penum->icc_setup.must_halftone; bool has_transfer = penum->icc_setup.has_transfer; int num_des_comps; cmm_dev_profile_t *dev_profile; + gx_cmapper_data data; + gx_cmapper_fn *mapper = gx_get_cmapper(&data, pgs, dev, has_transfer, must_halftone, gs_color_select_source); + gx_color_value *conc = &data.conc[0]; if (h == 0) return 0; @@ -630,17 +613,6 @@ return gs_rethrow(-1, "ICC Link not created during image render icc16"); } /* Needed for device N */ - memset(&(conc[0]), 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS])); - if (gs_color_space_is_PSCIE(penum->pcs) && penum->pcs->icc_equivalent != NULL) { - pcs = penum->pcs->icc_equivalent; - } else { - pcs = penum->pcs; - } - pdevc = &devc1; - pdevc_next = &devc2; - /* These used to be set by init clues */ - pdevc->type = gx_dc_type_none; - pdevc_next->type = gx_dc_type_none; code = dev_proc(dev, get_profile)(dev, &dev_profile); num_des_comps = gsicc_get_device_profile_comps(dev_profile); /* If the link is the identity, then we don't need to do any color @@ -653,7 +625,7 @@ psrc_cm_start = NULL; } else { spp_cm = num_des_comps; - psrc_cm = (unsigned short*) gs_alloc_bytes(pis->memory, + psrc_cm = (unsigned short*) gs_alloc_bytes(pgs->memory, sizeof(unsigned short) * w * spp_cm/spp, "image_render_icc16"); psrc_cm_start = psrc_cm; @@ -677,7 +649,7 @@ less than or equal to the new one. */ if (need_decode) { /* Need decode and CM. This is slow but does not happen that often */ - psrc_decode = (unsigned short*) gs_alloc_bytes(pis->memory, + psrc_decode = (unsigned short*) gs_alloc_bytes(pgs->memory, sizeof(unsigned short) * w * spp_cm/spp, "image_render_icc16"); if (!penum->use_cie_range) { @@ -694,7 +666,7 @@ &output_buff_desc, (void*) psrc_decode, (void*) psrc_cm); - gs_free_object(pis->memory, (byte *)psrc_decode, "image_render_color_icc"); + gs_free_object(pgs->memory, (byte *)psrc_decode, "image_render_color_icc"); } else { /* CM only. No decode */ (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, @@ -705,10 +677,11 @@ } } } + psrc_cm_initial = psrc_cm; pnext = penum->dda.pixel0; - xrun = xprev = dda_current(pnext.x); - yrun = yprev = dda_current(pnext.y); + xrun = dda_current(pnext.x); + yrun = dda_current(pnext.y); pdyx = dda_current(penum->dda.row.x) - penum->cur.x; pdyy = dda_current(penum->dda.row.y) - penum->cur.y; switch (posture) { @@ -723,95 +696,84 @@ break; } if_debug5m('b', penum->memory, "[b]y=%d data_x=%d w=%d xt=%f yt=%f\n", - penum->y, data_x, w, fixed2float(xprev), fixed2float(yprev)); - memset(&run, 0, sizeof(run)); - memset(&next, 0, sizeof(next)); - run.v[0] = ~psrc_cm[0]; /* Force intial setting */ + penum->y, data_x, w, fixed2float(xrun), fixed2float(yrun)); while (psrc_cm < bufend) { - dda_next(pnext.x); - dda_next(pnext.y); - if ( penum->alpha ) { - /* If the pixels are different, then take care of the alpha now */ - /* will need to adjust spp below.... */ - } else { - memcpy(&(next.v[0]),psrc_cm, spp_cm * 2); - psrc_cm += spp_cm; + /* Find the length of the next run. It will either end when we hit + * the end of the source data, or when the pixel data differs. */ + run = psrc_cm + spp_cm; + while (1) + { + dda_next(pnext.x); + dda_next(pnext.y); + if (run >= bufend) + break; + if (memcmp(run, psrc_cm, spp_cm * 2)) + break; + if (posture == image_skewed) + /* The color doesn't need remapping, but we can't handle a run */ + goto skewed_but_same; + run += spp_cm; } - /* Compare to previous. If same then move on */ - if (posture != image_skewed && !memcmp(next.all, run.all, spp_cm * 2)) - goto inc; + /* So we have a run of pixels from psrc_cm to run that are all the same. */ /* This needs to be sped up */ for ( k = 0; k < spp_cm; k++ ) { - conc[k] = next.v[k]; - } - /* Now we can do an encoding directly or we have to apply transfer - and or halftoning */ - if (must_halftone || has_transfer) { - /* We need to do the tranfer function and/or the halftoning */ - cmap_transfer_halftone(&(conc[0]), pdevc_next, pis, dev, - has_transfer, must_halftone, gs_color_select_source); - } else { - /* encode as a color index. avoid all the cv to frac to cv - conversions */ - color = dev_proc(dev, encode_color)(dev, &(conc[0])); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdevc_next, color); + conc[k] = psrc_cm[k]; } + mapper(&data); /* Fill the region between */ - /* xrun/irun and xprev */ - if (posture != image_portrait) { /* Parallelogram */ + /* xrun/irun and pnext.x/pnext.y */ + switch(posture) + { + default: /* skew */ +skewed_but_same: + { + fixed xprev = dda_current(pnext.x); + fixed yprev = dda_current(pnext.y); code = (*dev_proc(dev, fill_parallelogram)) (dev, xrun, yrun, xprev - xrun, yprev - yrun, pdyx, pdyy, - pdevc, lop); + &data.devc, lop); xrun = xprev; yrun = yprev; - } else { /* Rectangle */ + break; + } + case image_portrait: + { int xi = irun; - int wi = (irun = fixed2int_var_rounded(xprev)) - xi; + int wi = (irun = fixed2int_var_rounded(dda_current(pnext.x))) - xi; if (wi < 0) xi += wi, wi = -wi; if (wi > 0) code = gx_fill_rectangle_device_rop(xi, vci, wi, vdi, - pdevc, dev, lop); + &data.devc, dev, lop); + break; + } + case image_landscape: + { + int yi = irun; + int hi = (irun = fixed2int_var_rounded(dda_current(pnext.y))) - yi; + + if (hi < 0) + yi += hi, hi = -hi; + if (hi > 0) + code = gx_fill_rectangle_device_rop(vci, yi, vdi, hi, + &data.devc, dev, lop); + } } if (code < 0) goto err; - rsrc = psrc; - /* Swap around the colors due to a change */ - ptemp = pdevc; - pdevc = pdevc_next; - pdevc_next = ptemp; - run = next; -inc: xprev = dda_current(pnext.x); - yprev = dda_current(pnext.y); /* harmless if no skew */ - } - /* Fill the final run. */ - if (posture != image_portrait) { - code = (*dev_proc(dev, fill_parallelogram)) - (dev, xrun, yrun, xprev - xrun, yprev - yrun, pdyx, pdyy, - pdevc, lop); - } else { - int xi = irun; - int wi = (irun = fixed2int_var_rounded(xprev)) - xi; - - if (wi < 0) - xi += wi, wi = -wi; - if (wi > 0) - code = gx_fill_rectangle_device_rop(xi, vci, wi, vdi, - pdevc, dev, lop); + psrc_cm = run; } /* Free cm buffer, if it was used */ if (psrc_cm_start != NULL) { - gs_free_object(pis->memory, (byte *)psrc_cm_start, "image_render_icc16"); + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_icc16"); } return (code < 0 ? code : 1); /* Save position if error, in case we resume. */ err: - gs_free_object(pis->memory, (byte *)psrc_cm_start, "image_render_icc16"); - penum->used.x = (rsrc - spp - psrc_initial) / spp; + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_icc16"); + penum->used.x = (psrc_cm - psrc_cm_initial) / spp_cm; penum->used.y = 0; return code; } diff -Nru ghostscript-9.10~dfsg/base/gxi16bit.c ghostscript-9.25~dfsg+1/base/gxi16bit.c --- ghostscript-9.10~dfsg/base/gxi16bit.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxi16bit.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,14 +28,14 @@ #include "gxdevice.h" #include "gxcmap.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdevmem.h" #include "gxcpath.h" #include "gximage.h" /* ---------------- Unpacking procedures ---------------- */ -static const byte * +const byte * sample_unpack_16(byte * bptr, int *pdata_x, const byte * data, int data_x, uint dsize, const sample_map *ignore_smap, int spread, int ignore_num_components_per_plane) @@ -59,7 +59,7 @@ return bptr; } -static const byte * +const byte * sample_unpackicc_16(byte * bptr, int *pdata_x, const byte * data, int data_x, uint dsize, const sample_map *ignore_smap, int spread, int ignore_num_components_per_plane) diff -Nru ghostscript-9.10~dfsg/base/gxiclass.h ghostscript-9.25~dfsg+1/base/gxiclass.h --- ghostscript-9.10~dfsg/base/gxiclass.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxiclass.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxicolor.c ghostscript-9.25~dfsg+1/base/gxicolor.c --- ghostscript-9.10~dfsg/base/gxicolor.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxicolor.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,7 +31,7 @@ #include "gxcmap.h" #include "gxdcconv.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdevmem.h" #include "gxcpath.h" #include "gximage.h" @@ -58,7 +58,9 @@ iclass_proc(gs_image_class_4_color); static irender_proc(image_render_color_DeviceN); -static irender_proc(image_render_color_icc); +static irender_proc(image_render_color_icc_portrait); +static irender_proc(image_render_color_icc_landscape); +static irender_proc(image_render_color_icc_skew); static irender_proc(image_render_color_thresh); irender_proc_t @@ -71,7 +73,6 @@ #else bool use_fast_thresh = false; #endif - bool is_planar_dev = false; if (penum->use_mask_color) { /* @@ -108,7 +109,7 @@ then we will need to use those and go through pixel by pixel instead of blasting through buffers. This is true for example with many of the color spaces for CUPs */ - std_cmap_procs = gx_device_uses_std_cmap_procs(penum->dev, penum->pis); + std_cmap_procs = gx_device_uses_std_cmap_procs(penum->dev, penum->pgs); if ( (gs_color_space_get_index(penum->pcs) == gs_color_space_index_DeviceN && penum->pcs->cmm_icc_profile_data == NULL) || penum->use_mask_color || !std_cmap_procs) { @@ -119,11 +120,15 @@ gsicc_rendering_param_t rendering_params; int k; int src_num_comp = cs_num_components(penum->pcs); - int des_num_comp; + int des_num_comp, bpc; cmm_dev_profile_t *dev_profile; code = dev_proc(penum->dev, get_profile)(penum->dev, &dev_profile); + if (code < 0) + return NULL; /* This function does not return errors, best we can do is say 'we can't handle this' */ + des_num_comp = gsicc_get_device_profile_comps(dev_profile); + bpc = penum->dev->color_info.depth / des_num_comp; /* bits per component */ penum->icc_setup.need_decode = false; /* Check if we need to do any decoding. If yes, then that will slow us down */ for (k = 0; k < src_num_comp; k++) { @@ -133,11 +138,11 @@ } } /* Define the rendering intents */ - rendering_params.black_point_comp = penum->pis->blackptcomp; + rendering_params.black_point_comp = penum->pgs->blackptcomp; rendering_params.graphics_type_tag = GS_IMAGE_TAG; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = penum->pis->renderingintent; + rendering_params.rendering_intent = penum->pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; if (gs_color_space_is_PSCIE(penum->pcs) && penum->pcs->icc_equivalent != NULL) { pcs = penum->pcs->icc_equivalent; @@ -146,11 +151,11 @@ } penum->icc_setup.is_lab = pcs->cmm_icc_profile_data->islab; penum->icc_setup.must_halftone = gx_device_must_halftone(penum->dev); - penum->icc_setup.has_transfer = - gx_has_transfer(penum->pis, des_num_comp); - if (penum->icc_setup.is_lab) penum->icc_setup.need_decode = false; + penum->icc_setup.has_transfer = gx_has_transfer(penum->pgs, des_num_comp); + if (penum->icc_setup.is_lab) + penum->icc_setup.need_decode = false; if (penum->icc_link == NULL) { - penum->icc_link = gsicc_get_link(penum->pis, penum->dev, pcs, NULL, + penum->icc_link = gsicc_get_link(penum->pgs, penum->dev, pcs, NULL, &rendering_params, penum->memory); } /* PS CIE color spaces may have addition decoding that needs to @@ -170,21 +175,33 @@ if (gx_device_must_halftone(penum->dev) && use_fast_thresh && (penum->posture == image_portrait || penum->posture == image_landscape) && penum->image_parent_type == gs_image_type1) { + bool transfer_is_monotonic = true; + for (k=0; kpgs, k)) { + transfer_is_monotonic = false; + break; + } + } /* If num components is 1 or if we are going to CMYK planar device then we will may use the thresholding if it is a halftone - device*/ - is_planar_dev = (dev_proc(penum->dev, dev_spec_op)(penum->dev, - gxdso_is_native_planar, NULL, 0) > 0); - if ((penum->dev->color_info.num_components == 1 || is_planar_dev) && - penum->bps == 8 ) { + device IFF we have one bit per component */ + if ((bpc == 1) && transfer_is_monotonic && + (penum->dev->color_info.num_components == 1 || penum->dev->is_planar) && + penum->bps == 8) { code = gxht_thresh_image_init(penum); if (code == 0) { + /* NB: transfer function is pickled into the threshold arrray */ + penum->icc_setup.has_transfer = false; return &image_render_color_thresh; } } } - return &image_render_color_icc; + if (penum->posture == image_portrait) + return &image_render_color_icc_portrait; + if (penum->posture == image_landscape) + return &image_render_color_icc_landscape; + return &image_render_color_icc_skew; } } @@ -296,7 +313,7 @@ byte **psrc_cm_start, byte **bufend, bool planar_out) { const gx_image_enum *const penum = penum_orig; /* const within proc */ - const gs_imager_state *pis = penum->pis; + const gs_gstate *pgs = penum->pgs; bool need_decode = penum->icc_setup.need_decode; gsicc_bufferdesc_t input_buff_desc; gsicc_bufferdesc_t output_buff_desc; @@ -309,7 +326,7 @@ byte *psrc_decode; const byte *planar_src; byte *planar_des; - int k, j; + int j, k; int width; code = dev_proc(dev, get_profile)(dev, &dev_profile); @@ -330,11 +347,11 @@ /* Fastest case. No decode or CM needed */ *psrc_cm = (unsigned char *) psrc; spp_cm = spp; - *bufend = *psrc_cm + w; + *bufend = *psrc_cm + w; *psrc_cm_start = NULL; } else { spp_cm = num_des_comps; - *psrc_cm = gs_alloc_bytes(pis->memory, w * spp_cm/spp, + *psrc_cm = gs_alloc_bytes(pgs->memory, w * spp_cm/spp, "image_color_icc_prep"); *psrc_cm_start = *psrc_cm; *bufend = *psrc_cm + w * spp_cm/spp; @@ -343,12 +360,12 @@ /* decode only. no CM. This is slow but does not happen that often */ decode_row(penum, psrc, spp, *psrc_cm, *bufend); } else { - /* CM is identity but we may need to do decode and then off + /* CM is identity but we may need to do decode and then off to planar. The planar out case is only used when coming from imager_render_color_thresh, which is limited to 8 bit case */ if (need_decode) { /* Need decode and then to planar */ - psrc_decode = gs_alloc_bytes(pis->memory, w, + psrc_decode = gs_alloc_bytes(pgs->memory, w, "image_color_icc_prep"); if (!penum->use_cie_range) { decode_row(penum, psrc, spp, psrc_decode, psrc_decode+w); @@ -367,13 +384,13 @@ planar_des = *psrc_cm; for (k = 0; k < width; k++) { for (j = 0; j < spp; j++) { - *(planar_des + j * width) = *planar_src++; + *(planar_des + j * width) = *planar_src++; } planar_des++; } /* Free up decode if we used it */ if (psrc_decode != NULL) { - gs_free_object(pis->memory, (byte *) psrc_decode, + gs_free_object(pgs->memory, (byte *) psrc_decode, "image_render_color_icc"); } } @@ -399,7 +416,7 @@ less than or equal to the new one. */ if (need_decode) { /* Need decode and CM. This is slow but does not happen that often */ - psrc_decode = gs_alloc_bytes(pis->memory, w, + psrc_decode = gs_alloc_bytes(pgs->memory, w, "image_color_icc_prep"); if (!penum->use_cie_range) { decode_row(penum, psrc, spp, psrc_decode, psrc_decode+w); @@ -408,18 +425,18 @@ decode_row_cie(penum, psrc, spp, psrc_decode, psrc_decode+w, get_cie_range(penum->pcs)); } - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, - &output_buff_desc, + &output_buff_desc, (void*) psrc_decode, (void*) *psrc_cm); - gs_free_object(pis->memory, psrc_decode, "image_color_icc_prep"); + gs_free_object(pgs->memory, psrc_decode, "image_color_icc_prep"); } else { /* CM only. No decode */ - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, - &output_buff_desc, - (void*) psrc, + &output_buff_desc, + (void*) psrc, (void*) *psrc_cm); } } @@ -443,40 +460,29 @@ const byte *psrc = buffer + data_x; int dest_width, dest_height, data_length; int spp_out = dev->color_info.num_components; - int position, k, j; + int position, i, j, k; int offset_bits = penum->ht_offset_bits; int contone_stride = 0; /* Not used in landscape case */ - fixed scale_factor, offset; + fixed offset; int src_size; bool flush_buff = false; byte *psrc_temp; int offset_contone[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* to ensure 128 bit boundary */ int offset_threshold; /* to ensure 128 bit boundary */ - gx_dda_int_t dda_ht; + gx_dda_fixed dda_ht; + int xn, xr; /* destination position (pixel, not contone buffer offset) */ int code = 0; int spp_cm = 0; byte *psrc_cm = NULL, *psrc_cm_start = NULL; - byte *bufend = NULL, *curr_ptr; + byte *bufend = NULL; int psrc_planestride = w/penum->spp; - gx_color_value conc; - int num_des_comp = penum->dev->color_info.num_components; - if (h != 0) { + if (h != 0 && penum->line_size != 0) { /* line_size == 0, nothing to do */ /* Get the buffer into the device color space */ code = image_color_icc_prep(penum, psrc, w, dev, &spp_cm, &psrc_cm, &psrc_cm_start, &bufend, true); - /* Also, if need apply the transfer function at this time. This - should be reworked so that we are not doing all these conversions */ - if (penum->icc_setup.has_transfer) { - for (k = 0; k < num_des_comp; k++) { - curr_ptr = psrc_cm + psrc_planestride * k; - for (j = 0; j < psrc_planestride; j++, curr_ptr++) { - conc = gx_color_value_from_byte(curr_ptr[0]); - cmap_transfer_plane(&(conc), penum->pis, penum->dev, k); - curr_ptr[0] = gx_color_value_to_byte(conc); - } - } - } + if (code < 0) + return code; } else { if (penum->ht_landscape.count == 0 || posture == image_portrait) { return 0; @@ -492,12 +498,22 @@ to go ahead and get the data into the proper spatial setting and then threshold. First get the data spatially sampled correctly */ src_size = penum->rect.w; + + /* Set up the dda. We could move this out but the cost is pretty small */ + dda_ht = (posture == image_portrait) ? penum->dda.pixel0.x : penum->dda.pixel0.y; + if (penum->dxx > 0) + dda_translate(dda_ht, -fixed_epsilon); /* to match rounding in non-fast code */ + switch (posture) { case image_portrait: /* Figure out our offset in the contone and threshold data buffers so that we ensure that we are on the 128bit memory boundaries when we get offset_bits into the data. */ /* Can't do this earlier, as GC might move the buffers. */ + xrun = dda_current(dda_ht); + dest_width = gxht_dda_length(&dda_ht, src_size); + if (penum->x_extent.x < 0) + xrun += penum->x_extent.x; vdi = penum->hci; contone_stride = penum->line_size; offset_threshold = (- (((long)(penum->thresh_buffer)) + @@ -507,14 +523,8 @@ contone_stride * k + penum->ht_offset_bits)) & 15; } - xrun = dda_current(penum->dda.pixel0.x); - xrun = xrun - penum->adjust + (fixed_half - fixed_epsilon); - dest_width = fixed2int_var_rounded(any_abs(penum->x_extent.x)); - if (penum->x_extent.x < 0) - xrun += penum->x_extent.x; data_length = dest_width; dest_height = fixed2int_var_rounded(any_abs(penum->y_extent.y)); - scale_factor = float2fixed_rounded((float) src_size / (float) dest_width); #ifdef DEBUG /* Help in spotting problems */ memset(penum->ht_buffer, 0x00, penum->ht_stride * vdi * spp_out); @@ -528,15 +538,16 @@ */ vdi = penum->wci; contone_stride = penum->line_size; + dest_width = fixed2int_var_rounded(any_abs(penum->y_extent.x)); + /* match height in gxht_thresh.c dev_width calculation */ + xrun = dda_current(dda_ht); /* really yrun, but just used here for landscape */ + dest_height = gxht_dda_length(&dda_ht, src_size); + data_length = dest_height; offset_threshold = (-(long)(penum->thresh_buffer)) & 15; for (k = 0; k < spp_out; k ++) { offset_contone[k] = (- ((long)(penum->line) + contone_stride * k)) & 15; } - dest_width = fixed2int_var_rounded(any_abs(penum->y_extent.x)); - dest_height = fixed2int_var_rounded(any_abs(penum->x_extent.y)); - data_length = dest_height; - scale_factor = float2fixed_rounded((float) src_size / (float) dest_height); /* In the landscaped case, we want to accumulate multiple columns of data before sending to the device. We want to have a full byte of HT data in one write. This may not be possible at the @@ -571,16 +582,13 @@ } break; } + if (flush_buff) + goto flush; /* All done */ + /* Get the pointers to our buffers */ - if (flush_buff) goto flush; /* All done */ - /* Set up the dda. We could move this out but the cost is pretty small */ - dda_init_half(dda_ht, 0, src_size, data_length); - /* Do conversion to device resolution in quick small loops. */ - /* For now we have 3 cases. A CMYK (4 channel), gray, or other case - the latter of which is not yet implemented */ for (k = 0; k < spp_out; k++) { if (posture == image_portrait) { - devc_contone[k] = penum->line + contone_stride * k + + devc_contone[k] = penum->line + contone_stride * k + offset_contone[k]; } else { devc_contone[k] = penum->line + offset_contone[k] + @@ -588,6 +596,11 @@ } psrc_plane[k] = psrc_cm + psrc_planestride * k; } + xr = fixed2int_var_rounded(dda_current(dda_ht)); /* indexes in the destination (contone) */ + + /* Do conversion to device resolution in quick small loops. */ + /* For now we have 3 cases. A CMYK (4 channel), gray, or other case + the latter of which is not yet implemented */ switch (spp_out) { /* Monochrome output case */ @@ -607,18 +620,31 @@ *(devc_contone_gray+1) = *psrc_temp; } } else { - for (k = 0; k < data_length; k++, - devc_contone_gray++) { - *devc_contone_gray = psrc_cm[dda_ht.state.Q]; - dda_next(dda_ht); + /* Mono case, forward */ + psrc_temp = psrc_cm; + for (k=0; k= xr */ + psrc_temp++; } } } else { + /* Mono case, backwards */ devc_contone_gray += (data_length - 1); - for (k = 0; k < data_length; k++, devc_contone_gray--) { - *devc_contone_gray = psrc_cm[dda_ht.state.Q]; + psrc_temp = psrc_cm; + for (k=0; k xn) { + *devc_contone_gray-- = *psrc_temp; + xr--; + } /* at loop exit xn will be >= xr */ + psrc_temp++; + } } break; /* Monochrome landscape */ @@ -629,10 +655,16 @@ if (penum->ht_landscape.flipy) { position = penum->ht_landscape.curr_pos + LAND_BITS * (data_length - 1); - for (k = 0; k < data_length; k++) { - devc_contone_gray[position] = psrc_cm[dda_ht.state.Q]; - position -= LAND_BITS; + psrc_temp = psrc_cm; + for (k=0; k xn) { + devc_contone_gray[position] = *psrc_temp; + position -= LAND_BITS; + xr--; + } /* at loop exit xn will be <= xr */ + psrc_temp++; } } else { position = penum->ht_landscape.curr_pos; @@ -644,9 +676,9 @@ devc_contone_gray[position] = psrc_cm[k]; position += LAND_BITS; } - } else if (scale_factor == fixed_half) { + } else if (src_size*2 == dest_height) { for (k = 0; k < data_length; k+=2) { - offset = fixed2int_rounded(scale_factor * k); + offset = fixed2int_var_rounded(fixed_half * k); devc_contone_gray[position] = devc_contone_gray[position + LAND_BITS] = psrc_cm[offset]; @@ -654,11 +686,16 @@ } } else { /* use dda */ - for (k = 0; k < data_length; k++) { - devc_contone_gray[position] = - psrc_cm[dda_ht.state.Q]; - position += LAND_BITS; + psrc_temp = psrc_cm; + for (k=0; k= xr */ + psrc_temp++; } } } @@ -701,48 +738,62 @@ devc_contone[3] += 2; } } else { - for (k = 0; k < data_length; k++) { - *(devc_contone[0])++ = - (psrc_plane[0])[dda_ht.state.Q]; - *(devc_contone[1])++ = - (psrc_plane[1])[dda_ht.state.Q]; - *(devc_contone[2])++ = - (psrc_plane[2])[dda_ht.state.Q]; - *(devc_contone[3])++ = - (psrc_plane[3])[dda_ht.state.Q]; + /* CMYK case, forward */ + for (k=0, j=0; k= xr */ + j++; } } } else { + /* CMYK case, backwards */ + /* Move to the other end and we will decrement */ devc_contone[0] += (data_length - 1); devc_contone[1] += (data_length - 1); devc_contone[2] += (data_length - 1); devc_contone[3] += (data_length - 1); - for (k = 0; k < data_length; k++) { - *(devc_contone[0])-- = (psrc_plane[0])[dda_ht.state.Q]; - *(devc_contone[1])-- = (psrc_plane[1])[dda_ht.state.Q]; - *(devc_contone[2])-- = (psrc_plane[2])[dda_ht.state.Q]; - *(devc_contone[3])-- = (psrc_plane[3])[dda_ht.state.Q]; + for (k=0, j=0; k xn) { + *(devc_contone[0])-- = (psrc_plane[0])[j]; + *(devc_contone[1])-- = (psrc_plane[1])[j]; + *(devc_contone[2])-- = (psrc_plane[2])[j]; + *(devc_contone[3])-- = (psrc_plane[3])[j]; + xr--; + } /* at loop exit xn will be <= xr */ + j++; } } break; /* CMYK landscape */ case image_landscape: /* Data is already color managed. */ - /* We store the data at this point into a columns in - seperate planes. Depending upon our landscape direction + /* We store the data at this point into columns in + seperate planes. Depending upon our landscape direction we may be going left to right or right to left. */ if (penum->ht_landscape.flipy) { position = penum->ht_landscape.curr_pos + LAND_BITS * (data_length - 1); - for (k = 0; k < data_length; k++) { - for (j = 0; j < spp_out; j++) { - *(devc_contone[j] + position) = - (psrc_plane[j])[dda_ht.state.Q]; - } - position -= LAND_BITS; + /* use dda */ + for (k=0, i=0; k xn) { + for (j = 0; j < spp_out; j++) { + *(devc_contone[j] + position) = (psrc_plane[j])[i]; + position -= LAND_BITS; + } + xr--; + } /* at loop exit xn will be <= xr */ + i++; } } else { position = penum->ht_landscape.curr_pos; @@ -761,27 +812,30 @@ devc_contone[j] += LAND_BITS; } } - } else if (scale_factor == fixed_half) { + } else if (src_size*2 == dest_height) { for (k = 0; k < data_length; k+=2) { - offset = fixed2int_rounded(scale_factor * k); + offset = fixed2int_var_rounded(fixed_half * k); /* Is it better to unwind this? We know it is 4 */ for (j = 0; j < spp_out; j++) { *(devc_contone[j]) = - *(devc_contone[j] + LAND_BITS) = + *(devc_contone[j] + LAND_BITS) = (psrc_plane[j])[offset]; devc_contone[j] += 2 * LAND_BITS; } } } else { /* use dda */ - for (k = 0; k < data_length; k++) { - /* Is it better to unwind this? We know it is 4 */ - for (j = 0; j < spp_out; j++) { - *(devc_contone[j]) = - (psrc_plane[j])[dda_ht.state.Q]; - devc_contone[j] += LAND_BITS; - } + for (k=0, i=0; k xn) { + for (j = 0; j < spp_out; j++) { + *(devc_contone[j] + position) = (psrc_plane[j])[i]; + position -= LAND_BITS; + } + xr--; + } /* at loop exit xn will be <= xr */ + i++; } } } @@ -809,7 +863,7 @@ contone_stride); /* Free cm buffer, if it was used */ if (psrc_cm_start != NULL) { - gs_free_object(penum->pis->memory, (byte *)psrc_cm_start, + gs_free_object(penum->pgs->memory, (byte *)psrc_cm_start, "image_render_color_thresh"); } return code; @@ -817,206 +871,255 @@ /* Render a color image with 8 or fewer bits per sample using ICC profile. */ static int -image_render_color_icc(gx_image_enum *penum_orig, const byte *buffer, int data_x, - uint w, int h, gx_device * dev) +image_render_color_icc_portrait(gx_image_enum *penum_orig, const byte *buffer, int data_x, + uint w, int h, gx_device * dev) { const gx_image_enum *const penum = penum_orig; /* const within proc */ - const gs_imager_state *pis = penum->pis; + const gs_gstate *pgs = penum->pgs; gs_logical_operation_t lop = penum->log_op; gx_dda_fixed_point pnext; - image_posture posture = penum->posture; - fixed xprev, yprev; - fixed pdyx, pdyy; /* edge of parallelogram */ int vci, vdi; - gx_device_color devc1; - gx_device_color devc2; - gx_device_color *pdevc; - gx_device_color *pdevc_next; - gx_device_color *ptemp; int spp = penum->spp; - const byte *psrc_initial = buffer + data_x * spp; - const byte *psrc = psrc_initial; - const byte *rsrc = psrc + spp; /* psrc + spp at start of run */ - fixed xrun; /* x ditto */ - fixed yrun; /* y ditto */ + const byte *psrc = buffer + data_x * spp; int irun; /* int x/rrun */ - color_samples run; /* run value */ - color_samples next; /* next sample value */ byte *bufend = NULL; int code = 0; byte *psrc_cm = NULL, *psrc_cm_start = NULL; + byte *psrc_cm_initial; + byte *run; int k; - gx_color_value conc[GX_DEVICE_COLOR_MAX_COMPONENTS]; int spp_cm = 0; - gx_color_index color; bool must_halftone = penum->icc_setup.must_halftone; bool has_transfer = penum->icc_setup.has_transfer; + gx_cmapper_data data; + gx_cmapper_fn *mapper = gx_get_cmapper(&data, pgs, dev, has_transfer, must_halftone, gs_color_select_source); + gx_color_value *conc = &data.conc[0]; - pdevc = &devc1; - pdevc_next = &devc2; - /* These used to be set by init clues */ - pdevc->type = gx_dc_type_none; - pdevc_next->type = gx_dc_type_none; if (h == 0) return 0; code = image_color_icc_prep(penum_orig, psrc, w, dev, &spp_cm, &psrc_cm, &psrc_cm_start, &bufend, false); if (code < 0) return code; + psrc_cm_initial = psrc_cm; /* Needed for device N */ - memset(&(conc[0]), 0, sizeof(gx_color_value[GX_DEVICE_COLOR_MAX_COMPONENTS])); pnext = penum->dda.pixel0; - xrun = xprev = dda_current(pnext.x); - yrun = yprev = dda_current(pnext.y); - pdyx = dda_current(penum->dda.row.x) - penum->cur.x; - pdyy = dda_current(penum->dda.row.y) - penum->cur.y; - switch (posture) { - case image_portrait: - vci = penum->yci, vdi = penum->hci; - irun = fixed2int_var_rounded(xrun); - break; - case image_landscape: - default: /* we don't handle skew -- treat as landscape */ - vci = penum->xci, vdi = penum->wci; - irun = fixed2int_var_rounded(yrun); - break; - } + dda_translate(pnext.x, (-fixed_epsilon)); + irun = fixed2int_var_rounded(dda_current(pnext.x)); + vci = penum->yci, vdi = penum->hci; if_debug5m('b', penum->memory, "[b]y=%d data_x=%d w=%d xt=%f yt=%f\n", - penum->y, data_x, w, fixed2float(xprev), fixed2float(yprev)); - memset(&run, 0, sizeof(run)); - memset(&next, 0, sizeof(next)); - run.v[0] = ~psrc_cm[0]; /* Force intial setting */ + penum->y, data_x, w, fixed2float(dda_current(pnext.x)), fixed2float(dda_current(pnext.y))); while (psrc_cm < bufend) { - dda_next(pnext.x); - dda_next(pnext.y); - if ( penum->alpha ) { - /* If the pixels are different, then take care of the alpha now */ - /* will need to adjust spp below.... */ - } else { - memcpy(&(next.v[0]),psrc_cm, spp_cm); - psrc_cm += spp_cm; + /* Find the length of the next run. It will either end when we hit + * the end of the source data, or when the pixel data differs. */ + run = psrc_cm + spp_cm; + while (1) + { + dda_next(pnext.x); + if (run >= bufend) + break; + if (memcmp(run, psrc_cm, spp_cm)) + break; + run += spp_cm; } - /* Compare to previous. If same then move on */ - if (posture != image_skewed && next.all[0] == run.all[0]) - goto inc; + /* So we have a run of pixels from psrc_cm to run that are all the same. */ /* This needs to be sped up */ - for ( k = 0; k < spp_cm; k++ ) { - conc[k] = gx_color_value_from_byte(next.v[k]); + for (k = 0; k < spp_cm; k++) { + conc[k] = gx_color_value_from_byte(psrc_cm[k]); } - /* Now we can do an encoding directly or we have to apply transfer - and or halftoning */ - if (must_halftone || has_transfer) { - /* We need to do the tranfer function and/or the halftoning */ - cmap_transfer_halftone(&(conc[0]), pdevc_next, pis, dev, - has_transfer, must_halftone, gs_color_select_source); - } else { - /* encode as a color index. avoid all the cv to frac to cv - conversions */ - color = dev_proc(dev, encode_color)(dev, &(conc[0])); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(pdevc_next, color); + mapper(&data); + /* Fill the region between irun and fixed2int_var_rounded(pnext.x) */ + { + int xi = irun; + int wi = (irun = fixed2int_var_rounded(dda_current(pnext.x))) - xi; + + if (wi < 0) + xi += wi, wi = -wi; + if (wi > 0) + code = gx_fill_rectangle_device_rop(xi, vci, wi, vdi, + &data.devc, dev, lop); } - /* Fill the region between */ - /* xrun/irun and xprev */ - /* - * Note; This section is nearly a copy of a simlar section below - * for processing the last image pixel in the loop. This would have been - * made into a subroutine except for complications about the number of - * variables that would have been needed to be passed to the routine. - */ - switch (posture) { - case image_portrait: - { /* Rectangle */ - int xi = irun; - int wi = (irun = fixed2int_var_rounded(xprev)) - xi; + if (code < 0) + goto err; + psrc_cm = run; + } + /* Free cm buffer, if it was used */ + if (psrc_cm_start != NULL) { + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_color_icc"); + } + return (code < 0 ? code : 1); + /* Save position if error, in case we resume. */ +err: + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_color_icc"); + penum_orig->used.x = (run - psrc_cm_initial) / spp_cm; + penum_orig->used.y = 0; + return code; +} - if (wi < 0) - xi += wi, wi = -wi; - if (wi > 0) - code = gx_fill_rectangle_device_rop(xi, vci, wi, vdi, - pdevc, dev, lop); - } - break; - case image_landscape: - { /* 90 degree rotated rectangle */ - int yi = irun; - int hi = (irun = fixed2int_var_rounded(yprev)) - yi; +static int +image_render_color_icc_landscape(gx_image_enum *penum_orig, const byte *buffer, int data_x, + uint w, int h, gx_device * dev) +{ + const gx_image_enum *const penum = penum_orig; /* const within proc */ + const gs_gstate *pgs = penum->pgs; + gs_logical_operation_t lop = penum->log_op; + gx_dda_fixed_point pnext; + int vci, vdi; + int spp = penum->spp; + const byte *psrc = buffer + data_x * spp; + int irun; /* int x/rrun */ + byte *bufend = NULL; + int code = 0; + byte *psrc_cm = NULL, *psrc_cm_start = NULL; + byte *psrc_cm_initial; + byte *run; + int k; + int spp_cm = 0; + bool must_halftone = penum->icc_setup.must_halftone; + bool has_transfer = penum->icc_setup.has_transfer; + gx_cmapper_data data; + gx_cmapper_fn *mapper = gx_get_cmapper(&data, pgs, dev, has_transfer, must_halftone, gs_color_select_source); + gx_color_value *conc = &data.conc[0]; - if (hi < 0) - yi += hi, hi = -hi; - if (hi > 0) - code = gx_fill_rectangle_device_rop(vci, yi, vdi, hi, - pdevc, dev, lop); - } - break; - default: - { /* Parallelogram */ - code = (*dev_proc(dev, fill_parallelogram)) - (dev, xrun, yrun, xprev - xrun, yprev - yrun, pdyx, pdyy, - pdevc, lop); - xrun = xprev; - yrun = yprev; - } - } + if (h == 0) + return 0; + code = image_color_icc_prep(penum_orig, psrc, w, dev, &spp_cm, &psrc_cm, + &psrc_cm_start, &bufend, false); + if (code < 0) return code; + psrc_cm_initial = psrc_cm; + /* Needed for device N */ + pnext = penum->dda.pixel0; + dda_translate(pnext.x, (-fixed_epsilon)); + irun = fixed2int_var_rounded(dda_current(pnext.y)); + vci = penum->xci, vdi = penum->wci; + if_debug5m('b', penum->memory, "[b]y=%d data_x=%d w=%d xt=%f yt=%f\n", + penum->y, data_x, w, fixed2float(dda_current(pnext.x)), fixed2float(dda_current(pnext.y))); + while (psrc_cm < bufend) { + /* Find the length of the next run. It will either end when we hit + * the end of the source data, or when the pixel data differs. */ + run = psrc_cm + spp_cm; + while (1) + { + dda_next(pnext.y); + if (run >= bufend) + break; + if (memcmp(run, psrc_cm, spp_cm)) + break; + run += spp_cm; + } + /* So we have a run of pixels from psrc_cm to run that are all the same. */ + /* This needs to be sped up */ + for (k = 0; k < spp_cm; k++) { + conc[k] = gx_color_value_from_byte(psrc_cm[k]); + } + mapper(&data); + /* Fill the region between irun and fixed2int_var_rounded(pnext.y) */ + { /* 90 degree rotated rectangle */ + int yi = irun; + int hi = (irun = fixed2int_var_rounded(dda_current(pnext.y))) - yi; + + if (hi < 0) + yi += hi, hi = -hi; + if (hi > 0) + code = gx_fill_rectangle_device_rop(vci, yi, vdi, hi, + &data.devc, dev, lop); + } if (code < 0) goto err; - rsrc = psrc; - /* Swap around the colors due to a change */ - ptemp = pdevc; - pdevc = pdevc_next; - pdevc_next = ptemp; - run = next; -inc: xprev = dda_current(pnext.x); - yprev = dda_current(pnext.y); /* harmless if no skew */ - } - /* Fill the last run. */ - /* - * Note; This section is nearly a copy of a simlar section above - * for processing an image pixel in the loop. This would have been - * made into a subroutine except for complications about the number - * variables that would have been needed to be passed to the routine. - */ - switch (posture) { - case image_portrait: - { /* Rectangle */ - int xi = irun; - int wi = (irun = fixed2int_var_rounded(xprev)) - xi; + psrc_cm = run; + } + /* Free cm buffer, if it was used */ + if (psrc_cm_start != NULL) { + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_color_icc"); + } + return (code < 0 ? code : 1); + /* Save position if error, in case we resume. */ +err: + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_color_icc"); + penum_orig->used.x = (run - psrc_cm_initial) / spp_cm; + penum_orig->used.y = 0; + return code; +} - if (wi < 0) - xi += wi, wi = -wi; - if (wi > 0) - code = gx_fill_rectangle_device_rop(xi, vci, wi, vdi, - pdevc, dev, lop); - } - break; - case image_landscape: - { /* 90 degree rotated rectangle */ - int yi = irun; - int hi = (irun = fixed2int_var_rounded(yprev)) - yi; +static int +image_render_color_icc_skew(gx_image_enum *penum_orig, const byte *buffer, int data_x, + uint w, int h, gx_device * dev) +{ + const gx_image_enum *const penum = penum_orig; /* const within proc */ + const gs_gstate *pgs = penum->pgs; + gs_logical_operation_t lop = penum->log_op; + gx_dda_fixed_point pnext; + fixed xprev, yprev; + fixed pdyx, pdyy; /* edge of parallelogram */ + int spp = penum->spp; + const byte *psrc = buffer + data_x * spp; + fixed xpos; /* x ditto */ + fixed ypos; /* y ditto */ + byte *bufend = NULL; + int code = 0; + byte *psrc_cm = NULL, *psrc_cm_start = NULL; + byte *psrc_cm_initial; + int k; + int spp_cm = 0; + bool must_halftone = penum->icc_setup.must_halftone; + bool has_transfer = penum->icc_setup.has_transfer; + byte initial_run[GX_DEVICE_COLOR_MAX_COMPONENTS] = { 0 }; + byte *prev_cm = &initial_run[0]; + gx_cmapper_data data; + gx_cmapper_fn *mapper = gx_get_cmapper(&data, pgs, dev, has_transfer, must_halftone, gs_color_select_source); + gx_color_value *conc = &data.conc[0]; - if (hi < 0) - yi += hi, hi = -hi; - if (hi > 0) - code = gx_fill_rectangle_device_rop(vci, yi, vdi, hi, - pdevc, dev, lop); - } - break; - default: - { /* Parallelogram */ - code = (*dev_proc(dev, fill_parallelogram)) - (dev, xrun, yrun, xprev - xrun, yprev - yrun, pdyx, pdyy, - pdevc, lop); - } + if (h == 0) + return 0; + code = image_color_icc_prep(penum_orig, psrc, w, dev, &spp_cm, &psrc_cm, + &psrc_cm_start, &bufend, false); + if (code < 0) return code; + psrc_cm_initial = psrc_cm; + /* Needed for device N */ + pnext = penum->dda.pixel0; + dda_translate(pnext.x, (-fixed_epsilon)); + xprev = dda_current(pnext.x); + yprev = dda_current(pnext.y); + pdyx = dda_current(penum->dda.row.x) - penum->cur.x; + pdyy = dda_current(penum->dda.row.y) - penum->cur.y; + if_debug5m('b', penum->memory, "[b]y=%d data_x=%d w=%d xt=%f yt=%f\n", + penum->y, data_x, w, fixed2float(xprev), fixed2float(yprev)); + prev_cm[0] = ~psrc_cm[0]; /* Force intial setting */ + while (psrc_cm < bufend) { + dda_next(pnext.x); + dda_next(pnext.y); + xpos = dda_current(pnext.x); + ypos = dda_current(pnext.y); + + if (memcmp(prev_cm, psrc_cm, spp_cm) != 0) + { + /* This needs to be sped up */ + for (k = 0; k < spp_cm; k++) { + conc[k] = gx_color_value_from_byte(psrc_cm[k]); } + mapper(&data); + } + /* Fill the region between */ + /* xprev/yprev and xpos/ypos */ + /* Parallelogram */ + code = (*dev_proc(dev, fill_parallelogram)) + (dev, xprev, yprev, xpos - xprev, ypos - yprev, pdyx, pdyy, + &data.devc, lop); + xprev = xpos; + yprev = ypos; + if (code < 0) + goto err; + prev_cm = psrc_cm; + psrc_cm += spp_cm; + } /* Free cm buffer, if it was used */ if (psrc_cm_start != NULL) { - gs_free_object(pis->memory, (byte *)psrc_cm_start, "image_render_color_icc"); + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_color_icc"); } return (code < 0 ? code : 1); /* Save position if error, in case we resume. */ err: - gs_free_object(pis->memory, (byte *)psrc_cm_start, "image_render_color_icc"); - penum_orig->used.x = (rsrc - spp - psrc_initial) / spp; + gs_free_object(pgs->memory, (byte *)psrc_cm_start, "image_render_color_icc"); + penum_orig->used.x = (psrc_cm - psrc_cm_initial) / spp_cm; penum_orig->used.y = 0; return code; } @@ -1029,7 +1132,7 @@ uint w, int h, gx_device * dev) { const gx_image_enum *const penum = penum_orig; /* const within proc */ - const gs_imager_state *pis = penum->pis; + const gs_gstate *pgs = penum->pgs; gs_logical_operation_t lop = penum->log_op; gx_dda_fixed_point pnext; image_posture posture = penum->posture; @@ -1125,7 +1228,7 @@ /* Data is already properly set up for ICC use of LAB */ if (lab_case) for (i = 0; i < spp; ++i) - cc.paint.values[i] = (next.v[i]) * (1.0f / 255.0f); + cc.paint.values[i] = (next.v[i]) * (1.0f / 255.0f); else for (i = 0; i < spp; ++i) decode_sample(next.v[i], cc, i); @@ -1138,7 +1241,7 @@ dmputs(dev->memory, "\n"); } #endif - mcode = remap_color(&cc, pcs, pdevc_next, pis, dev, + mcode = remap_color(&cc, pcs, pdevc_next, pgs, dev, gs_color_select_source); mapped: if (mcode < 0) goto fill; @@ -1195,7 +1298,7 @@ code = gx_fill_rectangle_device_rop(vci, yi, vdi, hi, pdevc, dev, lop); } - break; + break; default: { /* Parallelogram */ code = (*dev_proc(dev, fill_parallelogram)) diff -Nru ghostscript-9.10~dfsg/base/gxidata.c ghostscript-9.25~dfsg+1/base/gxidata.c --- ghostscript-9.10~dfsg/base/gxidata.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxidata.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -84,16 +84,93 @@ const byte *buffer; int sourcex; int x_used = penum->used.x; + int skip = 0; + /* Bump DDA's if it doesn't cause overflow */ + penum->cur.x = dda_current(penum->dda.row.x); + if (max_int - any_abs(penum->dda.row.x.step.dQ) > any_abs(penum->cur.x)) + dda_next(penum->dda.row.x); + penum->cur.y = dda_current(penum->dda.row.y); + if (max_int - any_abs(penum->dda.row.y.step.dQ) > any_abs(penum->cur.y)) + dda_next(penum->dda.row.y); + + if (penum->interpolate == interp_off) { + if (penum->skip_next_line) { + if (penum->skip_next_line(penum, dev)) + goto mt; + } else { + switch (penum->posture) { + case image_portrait: + { /* Precompute integer y and height, */ + /* and check for clipping. */ + fixed yc = penum->cur.y, + yn = dda_current(penum->dda.row.y); + + if (yn < yc) { + fixed temp = yn; + + yn = yc; + yc = temp; + } + yc -= adjust; + if (yc >= penum->clip_outer.q.y) + goto mt; + yn += adjust; + if (yn <= penum->clip_outer.p.y) + goto mt; + penum->yci = fixed2int_pixround_perfect(yc); + penum->hci = fixed2int_pixround_perfect(yn) - penum->yci; + if (penum->hci == 0) + goto mt; + if_debug2m('b', penum->memory, "[b]yci=%d, hci=%d\n", + penum->yci, penum->hci); + } + break; + case image_landscape: + { /* Check for no pixel centers in x. */ + fixed xc = penum->cur.x, + xn = dda_current(penum->dda.row.x); + + if (xn < xc) { + fixed temp = xn; + + xn = xc; + xc = temp; + } + xc -= adjust; + if (xc >= penum->clip_outer.q.x) + goto mt; + xn += adjust; + if (xn <= penum->clip_outer.p.x) + goto mt; + penum->xci = fixed2int_pixround_perfect(xc); + penum->wci = fixed2int_pixround_perfect(xn) - penum->xci; + if (penum->wci == 0) + goto mt; + if_debug2m('b', penum->memory, "[b]xci=%d, wci=%d\n", + penum->xci, penum->wci); + } + break; + case image_skewed: + ; + } + } + } + if (0) + { + mt: + skip = 1; + } if (bit_planar) { /* Repack the bit planes into byte-wide samples. */ buffer = penum->buffer; sourcex = 0; - for (px = 0; px < num_planes; px += penum->bps) - repack_bit_planes(planes, offsets, penum->bps, penum->buffer, - penum->rect.w, &penum->map[px].table, - penum->spread); + if (!skip) + for (px = 0; px < num_planes; px += penum->bps) + repack_bit_planes(planes, offsets, penum->bps, penum->buffer, + penum->rect.w, &penum->map[px].table, + penum->spread); for (px = 0; px < num_planes; ++px) offsets[px] += planes[px].raster; } else { @@ -103,19 +180,23 @@ * input samples, we may use the data directly. */ sourcex = planes[0].data_x; - buffer = - (*penum->unpack)(penum->buffer, &sourcex, - planes[0].data + offsets[0], - planes[0].data_x, BCOUNT(planes[0]), - &penum->map[0], penum->spread, num_components_per_plane); + if (!skip) + buffer = + (*penum->unpack)(penum->buffer, &sourcex, + planes[0].data + offsets[0], + planes[0].data_x, BCOUNT(planes[0]), + &penum->map[0], penum->spread, num_components_per_plane); + else + buffer = NULL; offsets[0] += planes[0].raster; for (px = 1; px < num_planes; ++px) { - (*penum->unpack)(penum->buffer + (px << penum->log2_xbytes), - &ignore_data_x, - planes[px].data + offsets[px], - planes[px].data_x, BCOUNT(planes[px]), - &penum->map[px], penum->spread, 1); + if (!skip) + (*penum->unpack)(penum->buffer + (px << penum->log2_xbytes), + &ignore_data_x, + planes[px].data + offsets[px], + planes[px].data_x, BCOUNT(planes[px]), + &penum->map[px], penum->spread, 1); offsets[px] += planes[px].raster; } } @@ -135,96 +216,38 @@ dmputs(dev->memory, "\n"); } #endif - penum->cur.x = dda_current(penum->dda.row.x); - dda_next(penum->dda.row.x); - penum->cur.y = dda_current(penum->dda.row.y); - dda_next(penum->dda.row.y); - if (!penum->interpolate) - switch (penum->posture) { - case image_portrait: - { /* Precompute integer y and height, */ - /* and check for clipping. */ - fixed yc = penum->cur.y, - yn = dda_current(penum->dda.row.y); - - if (yn < yc) { - fixed temp = yn; - - yn = yc; - yc = temp; - } - yc -= adjust; - if (yc >= penum->clip_outer.q.y) - goto mt; - yn += adjust; - if (yn <= penum->clip_outer.p.y) - goto mt; - penum->yci = fixed2int_pixround_perfect(yc); - penum->hci = fixed2int_pixround_perfect(yn) - penum->yci; - if (penum->hci == 0) - goto mt; - if_debug2m('b', penum->memory, "[b]yci=%d, hci=%d\n", - penum->yci, penum->hci); - } - break; - case image_landscape: - { /* Check for no pixel centers in x. */ - fixed xc = penum->cur.x, - xn = dda_current(penum->dda.row.x); - - if (xn < xc) { - fixed temp = xn; - - xn = xc; - xc = temp; - } - xc -= adjust; - if (xc >= penum->clip_outer.q.x) - goto mt; - xn += adjust; - if (xn <= penum->clip_outer.p.x) - goto mt; - penum->xci = fixed2int_pixround_perfect(xc); - penum->wci = fixed2int_pixround_perfect(xn) - penum->xci; - if (penum->wci == 0) - goto mt; - if_debug2m('b', penum->memory, "[b]xci=%d, wci=%d\n", - penum->xci, penum->wci); - } - break; - case image_skewed: - ; + if (!skip) + { + update_strip(penum); + if (x_used) { + /* + * Processing was interrupted by an error. Skip over pixels + * already processed. + */ + dda_advance(penum->dda.pixel0.x, x_used); + dda_advance(penum->dda.pixel0.y, x_used); + penum->used.x = 0; } - update_strip(penum); - if (x_used) { - /* - * Processing was interrupted by an error. Skip over pixels - * already processed. - */ - dda_advance(penum->dda.pixel0.x, x_used); - dda_advance(penum->dda.pixel0.y, x_used); - penum->used.x = 0; - } - if_debug2m('b', penum->memory, "[b]pixel0 x=%g, y=%g\n", - fixed2float(dda_current(penum->dda.pixel0.x)), - fixed2float(dda_current(penum->dda.pixel0.y))); - code = (*penum->render)(penum, buffer, sourcex + x_used, - width_spp - x_used * penum->spp, 1, dev); - if (code < 0) { - /* Error or interrupt, restore original state. */ - penum->used.x += x_used; - if (!penum->used.y) { - dda_previous(penum->dda.row.x); - dda_previous(penum->dda.row.y); - dda_translate(penum->dda.strip.x, - penum->prev.x - penum->cur.x); - dda_translate(penum->dda.strip.y, - penum->prev.y - penum->cur.y); + if_debug2m('b', penum->memory, "[b]pixel0 x=%g, y=%g\n", + fixed2float(dda_current(penum->dda.pixel0.x)), + fixed2float(dda_current(penum->dda.pixel0.y))); + code = (*penum->render)(penum, buffer, sourcex + x_used, + width_spp - x_used * penum->spp, 1, dev); + if (code < 0) { + /* Error or interrupt, restore original state. */ + penum->used.x += x_used; + if (!penum->used.y) { + dda_previous(penum->dda.row.x); + dda_previous(penum->dda.row.y); + dda_translate(penum->dda.strip.x, + penum->prev.x - penum->cur.x); + dda_translate(penum->dda.strip.y, + penum->prev.y - penum->cur.y); + } + goto out; } - goto out; + penum->prev = penum->cur; } - penum->prev = penum->cur; - mt:; } if (penum->y < penum->rect.h) { code = 0; @@ -352,7 +375,7 @@ */ for (x = 0; x < width; x += 8) { bits32 w0 = 0, w1 = 0; -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN static const bits32 expand[16] = { 0x00000000, 0x00000001, 0x00000100, 0x00000101, 0x00010000, 0x00010001, 0x00010100, 0x00010101, diff -Nru ghostscript-9.10~dfsg/base/gxifast.c ghostscript-9.25~dfsg+1/base/gxifast.c --- ghostscript-9.10~dfsg/base/gxifast.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxifast.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -29,7 +29,7 @@ #include "gxdevice.h" #include "gxcmap.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdevmem.h" #include "gdevmem.h" /* for mem_mono_device */ #include "gxcpath.h" @@ -82,9 +82,6 @@ penum->line = gs_alloc_bytes(penum->memory, penum->line_size, "image line"); if (penum->line == 0) { - gx_default_end_image(penum->dev, - (gx_image_enum_common_t *)penum, - false); return 0; } } @@ -318,12 +315,21 @@ /* Pre-clear the row. */ fill_row(line, line_x, raster, zero); + + /* Extreme negative values of x_extent cause the xl0 calculation + * to explode. Workaround this here. */ + if (x_extent < min_int + 0x100) + x_extent += 0x100; + /* Set up the DDAs. */ xl0 = (x_extent >= 0 ? fixed_fraction(fixed_pre_pixround(xcur)) : fixed_fraction(fixed_pre_pixround(xcur + x_extent)) - x_extent); xl0 += int2fixed(line_x); + /* We should never get a negative x10 here. If we do, all bets are off. */ + if (xl0 < 0) + xl0 = 0, x_extent = 0; dda_init(xl, xl0, x_extent, w); dxx4 = xl.step; dda_step_add(dxx4, xl.step); @@ -554,9 +560,9 @@ if (h == 0) return 0; if ((!DC_IS_NULL(pdc0) && - (code = gx_color_load(pdc0, penum->pis, dev)) < 0) || + (code = gx_color_load(pdc0, penum->pgs, dev)) < 0) || (!DC_IS_NULL(pdc1) && - (code = gx_color_load(pdc1, penum->pis, dev)) < 0) + (code = gx_color_load(pdc1, penum->pgs, dev)) < 0) ) return code; if (penum->line == 0) { /* A direct BitBlt is possible. */ @@ -611,8 +617,6 @@ return 1; /****** MAY BE UNALIGNED ******/ line = scan_line + (line_ix >> 3); - if (dxx < 0) - ix -= line_width; for (dy = 1; dy < ih; dy++) { int code = (*copy_mono) (dev, line, line_x, line_size, gx_no_bitmap_id, diff -Nru ghostscript-9.10~dfsg/base/gximag3x.c ghostscript-9.25~dfsg+1/base/gximag3x.c --- ghostscript-9.10~dfsg/base/gximag3x.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximag3x.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,7 +27,7 @@ #include "gxdevice.h" #include "gxdevmem.h" #include "gximag3x.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gdevbbox.h" extern_st(st_color_space); @@ -125,7 +125,7 @@ gs_memory_t *mem); int gx_begin_image3x_generic(gx_device * dev, - const gs_imager_state *pis, const gs_matrix *pmat, + const gs_gstate *pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect *prect, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *mem, @@ -198,7 +198,7 @@ penum->bpc = pim->BitsPerComponent; penum->memory = mem; if (pmat == 0) - pmat = &ctm_only(pis); + pmat = &ctm_only(pgs); for (i = 0; i < NUM_MASKS; ++i) { gs_rect mrect; gx_device *mdev; @@ -230,10 +230,12 @@ (int)ceil(mrect.q.x) - origin[i].x, (int)ceil(mrect.q.y) - origin[i].y, penum->mask[i].depth, mem); - code = dev_proc(dev, get_profile)(dev, &mdev->icc_struct); - rc_increment(mdev->icc_struct); if (code < 0) goto out1; + code = dev_proc(dev, get_profile)(dev, &mdev->icc_struct); + if (code < 0) + goto out1; /* Device not yet open */ + rc_increment(mdev->icc_struct); penum->mask[i].mdev = mdev; gs_image_t_init(&mask[i].image, pmcs); mask[i].image.ColorSpace = pmcs; @@ -261,15 +263,15 @@ m_mat.tx -= origin[i].x; m_mat.ty -= origin[i].y; /* - * Peter put in a comment that said " Note that pis = NULL here, - * since we don't want to have to create another imager state with - * default log_op, etc." and passed NULL instead of pis to this - * routine. However Image type 1 need the imager state (see + * Peter put in a comment that said " Note that pgs = NULL here, + * since we don't want to have to create another gs_gstate with + * default log_op, etc." and passed NULL instead of pgs to this + * routine. However Image type 1 need the gs_gstate (see * bug 688348) thus his optimization was removed. * dcolor = NULL is OK because this is an opaque image with * CombineWithColor = false. */ - code = gx_device_begin_typed_image(mdev, pis, &m_mat, + code = gx_device_begin_typed_image(mdev, pgs, &m_mat, (const gs_image_common_t *)&mask[i].image, &mask[i].rect, NULL, NULL, mem, &penum->mask[i].info); @@ -287,7 +289,7 @@ pixel.image.type = type1; pixel.image.image_parent_type = gs_image_type3x; } - code = make_mcde(dev, pis, pmat, (const gs_image_common_t *)&pixel.image, + code = make_mcde(dev, pgs, pmat, (const gs_image_common_t *)&pixel.image, prect, pdcolor, pcpath, mem, &penum->pixel.info, &pcdev, midev, minfo, origin, pim); if (code < 0) @@ -359,7 +361,7 @@ return code; } static bool -check_image3x_extent(floatp mask_coeff, floatp data_coeff) +check_image3x_extent(double mask_coeff, double data_coeff) { if (mask_coeff == 0) return data_coeff == 0; @@ -524,7 +526,7 @@ } static IMAGE3X_MAKE_MCDE_PROC(make_mcdex_default); /* check prototype */ static int -make_mcdex_default(gx_device *dev, const gs_imager_state *pis, +make_mcdex_default(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect *prect, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *mem, @@ -565,7 +567,7 @@ gx_device_bbox_fwd_open_close(bbdev, false); code = dev_proc(bbdev, begin_typed_image) - ((gx_device *)bbdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, + ((gx_device *)bbdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); if (code < 0) { gs_free_object(mem, bbdev, "make_mcdex_default"); @@ -576,12 +578,12 @@ } static int gx_begin_image3x(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum_common_t ** pinfo) { - return gx_begin_image3x_generic(dev, pis, pmat, pic, prect, pdcolor, + return gx_begin_image3x_generic(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, make_midx_default, make_mcdex_default, pinfo); } @@ -609,6 +611,7 @@ int mh = mask_height[i] = penum->mask[i].height; mask_plane[i].data = 0; + mask_plane[i].raster = 0; mask_used[i] = 0; if (!penum->mask[i].depth) continue; @@ -644,12 +647,14 @@ /* Pull apart the source data and the mask data. */ /* We do this in the simplest (not fastest) way for now. */ uint bit_x = bpc * (num_components + num_chunky) * planes[pi].data_x; - sample_load_declare_setup(sptr, sbit, planes[0].data + (bit_x >> 3), - bit_x & 7, bpc); - sample_store_declare_setup(pptr, pbit, pbbyte, - penum->pixel.data, 0, bpc); - sample_store_declare(dptr[NUM_MASKS], dbit[NUM_MASKS], - dbbyte[NUM_MASKS]); + const byte *sptr = planes[0].data + (bit_x >> 3); + int sbit = bit_x & 7; + byte *pptr = penum->pixel.data; + int pbit = 0; + byte pbbyte = (pbit ? (byte)(*pptr & (0xff00 >> pbit)) : 0); + byte *dptr[NUM_MASKS]; + int dbit[NUM_MASKS]; + byte dbbyte[NUM_MASKS]; int depth[NUM_MASKS]; int x; @@ -663,8 +668,8 @@ mask_plane[i].data = dptr[i] = penum->mask[i].data; mask_plane[i].data_x = 0; /* raster doesn't matter */ - sample_store_setup(dbit[i], 0, depth[i]); - sample_store_preload(dbbyte[i], dptr[i], 0, depth[i]); + dbit[i] = 0; + dbbyte[i] = 0; } else depth[i] = 0; pixel_plane.data = pptr; @@ -676,19 +681,24 @@ for (i = 0; i < NUM_MASKS; ++i) if (depth[i]) { - sample_load_next12(value, sptr, sbit, bpc); - sample_store_next12(value, dptr[i], dbit[i], depth[i], - dbbyte[i]); + if (sample_load_next12(&value, &sptr, &sbit, bpc) < 0) + return_error(gs_error_rangecheck); + if (sample_store_next12(value, &dptr[i], &dbit[i], depth[i], + &dbbyte[i]) < 0) + return_error(gs_error_rangecheck); } for (i = 0; i < num_components; ++i) { - sample_load_next12(value, sptr, sbit, bpc); - sample_store_next12(value, pptr, pbit, bpc, pbbyte); + if (sample_load_next12(&value, &sptr, &sbit, bpc) < 0) + return_error(gs_error_rangecheck); + if (sample_store_next12(value, &pptr, &pbit, bpc, &pbbyte) < 0) + return_error(gs_error_rangecheck); } } for (i = 0; i < NUM_MASKS; ++i) - if (penum->mask[i].data) - sample_store_flush(dptr[i], dbit[i], depth[i], dbbyte[i]); - sample_store_flush(pptr, pbit, bpc, pbbyte); + if (penum->mask[i].data) { + sample_store_flush(dptr[i], dbit[i], dbbyte[i]); + } + sample_store_flush(pptr, pbit, pbbyte); } /* * Process the mask data first, so it will set up the mask diff -Nru ghostscript-9.10~dfsg/base/gximag3x.h ghostscript-9.25~dfsg+1/base/gximag3x.h --- ghostscript-9.10~dfsg/base/gximag3x.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximag3x.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -46,7 +46,7 @@ #define IMAGE3X_MAKE_MCDE_PROC(proc)\ int proc(/* The initial arguments are those of begin_typed_image. */\ gx_device *dev,\ - const gs_imager_state *pis,\ + const gs_gstate *pgs,\ const gs_matrix *pmat,\ const gs_image_common_t *pic,\ const gs_int_rect *prect,\ @@ -65,7 +65,7 @@ * procedures as additional parameters. */ int gx_begin_image3x_generic(gx_device * dev, - const gs_imager_state *pis, + const gs_gstate *pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect *prect, diff -Nru ghostscript-9.10~dfsg/base/gximage1.c ghostscript-9.25~dfsg+1/base/gximage1.c --- ghostscript-9.10~dfsg/base/gximage1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximage1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -74,7 +74,7 @@ /* Start processing an ImageType 1 image. */ int gx_begin_image1(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum_common_t ** pinfo) @@ -91,10 +91,13 @@ penum->masked = pim->ImageMask; penum->adjust = (pim->ImageMask && pim->adjust ? float2fixed(0.25) : fixed_0); - code = gx_image_enum_begin(dev, pis, pmat, pic, pdcolor, pcpath, mem, + code = gx_image_enum_begin(dev, pgs, pmat, pic, pdcolor, pcpath, mem, penum); if (code >= 0) *pinfo = (gx_image_enum_common_t *)penum; + else { + *pinfo = NULL; + } return code; } diff -Nru ghostscript-9.10~dfsg/base/gximage2.c ghostscript-9.25~dfsg+1/base/gximage2.c --- ghostscript-9.10~dfsg/base/gximage2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximage2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -65,7 +65,7 @@ static int image2_set_data(const gs_image2_t * pim, image2_data_t * pid) { - gs_state *pgs = pim->DataSource; + gs_gstate *pgs = pim->DataSource; gs_matrix smat; gs_rect sbox, dbox; @@ -87,7 +87,7 @@ /* Compute the source size of an ImageType 2 image. */ static int -gx_image2_source_size(const gs_imager_state * pis, const gs_image_common_t * pim, +gx_image2_source_size(const gs_gstate * pgs, const gs_image_common_t * pim, gs_int_point * psize) { image2_data_t idata; @@ -103,13 +103,13 @@ /* this procedure does all the work. */ static int gx_begin_image2(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs1, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum_common_t ** pinfo) { const gs_image2_t *pim = (const gs_image2_t *)pic; - gs_state *pgs = pim->DataSource; + gs_gstate *pgs = pim->DataSource; gx_device *sdev = gs_currentdevice(pgs); int depth = sdev->color_info.depth; bool pixel_copy = pim->PixelCopy; @@ -123,23 +123,21 @@ int code; /* verify that color models are the same for PixelCopy */ - if ( pixel_copy && - memcmp( &dev->color_info, - &sdev->color_info, - sizeof(dev->color_info) ) != 0 ) + if ( pixel_copy && + !gx_color_info_equal(&dev->color_info, &sdev->color_info)) return_error(gs_error_typecheck); /****** ONLY HANDLE depth <= 8 FOR PixelCopy ******/ if (pixel_copy && depth <= 8) return_error(gs_error_unregistered); - gs_image_t_init(&idata.image, gs_currentcolorspace((const gs_state *)pis)); + gs_image_t_init(&idata.image, gs_currentcolorspace((const gs_gstate *)pgs1)); /* Add Decode entries for K and alpha */ idata.image.Decode[6] = idata.image.Decode[8] = 0.0; idata.image.Decode[7] = idata.image.Decode[9] = 1.0; if (pmat == 0) { - gs_currentmatrix((const gs_state *)pis, &dmat); + gs_currentmatrix((const gs_gstate *)pgs1, &dmat); pmat = &dmat; } else dmat = *pmat; @@ -229,7 +227,7 @@ } if (!direct_copy) code = (*dev_proc(dev, begin_typed_image)) - (dev, pis, pmat, (const gs_image_common_t *)&idata.image, NULL, + (dev, pgs1, pmat, (const gs_image_common_t *)&idata.image, NULL, pdcolor, pcpath, mem, &info); if (code >= 0) { int y; diff -Nru ghostscript-9.10~dfsg/base/gximage3.c ghostscript-9.25~dfsg+1/base/gximage3.c --- ghostscript-9.10~dfsg/base/gximage3.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximage3.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -26,7 +26,7 @@ #include "gxdevmem.h" #include "gxclipm.h" #include "gximage3.h" -#include "gxistate.h" +#include "gxgstate.h" /* Forward references */ static dev_proc_begin_typed_image(gx_begin_image3); @@ -108,6 +108,7 @@ midev->bitmap_memory = mem; midev->width = width; midev->height = height; + midev->raster = gx_device_raster((gx_device *)midev, 1); check_device_separable((gx_device *)midev); gx_device_fill_in_procs((gx_device *)midev); code = dev_proc(midev, open_device)((gx_device *)midev); @@ -123,7 +124,7 @@ } static IMAGE3_MAKE_MCDE_PROC(make_mcde_default); /* check prototype */ static int -make_mcde_default(gx_device *dev, const gs_imager_state *pis, +make_mcde_default(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect *prect, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *mem, @@ -156,7 +157,7 @@ } mcdev->tiles = bits; code = dev_proc(mcdev, begin_typed_image) - ((gx_device *)mcdev, pis, pmat, pic, prect, pdcolor, pcpath, mem, + ((gx_device *)mcdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo); if (code < 0) { gs_free_object(mem, mcdev, "make_mcde_default"); @@ -167,12 +168,12 @@ } static int gx_begin_image3(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum_common_t ** pinfo) { - return gx_begin_image3_generic(dev, pis, pmat, pic, prect, pdcolor, + return gx_begin_image3_generic(dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, make_mid_default, make_mcde_default, pinfo); } @@ -181,10 +182,10 @@ * Begin a generic ImageType 3 image, with client handling the creation of * the mask image and mask clip devices. */ -static bool check_image3_extent(floatp mask_coeff, floatp data_coeff); +static bool check_image3_extent(double mask_coeff, double data_coeff); int gx_begin_image3_generic(gx_device * dev, - const gs_imager_state *pis, const gs_matrix *pmat, + const gs_gstate *pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect *prect, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *mem, @@ -348,7 +349,7 @@ mrect.q.x = pim->MaskDict.Width; mrect.q.y = pim->MaskDict.Height; if (pmat == 0) - pmat = &ctm_only(pis); + pmat = &ctm_only(pgs); if ((code = gs_matrix_multiply(&mi_mask, pmat, &mat)) < 0 || (code = gs_bbox_transform(&mrect, &mat, &mrect)) < 0 ) @@ -384,8 +385,8 @@ m_mat.tx -= origin.x; m_mat.ty -= origin.y; /* - * Note that pis = NULL here, since we don't want to have to - * create another imager state with default log_op, etc. + * Note that pgs = NULL here, since we don't want to have to + * create another gs_gstate with default log_op, etc. */ code = gx_device_begin_typed_image(mdev, NULL, &m_mat, (const gs_image_common_t *)&i_mask, @@ -402,7 +403,7 @@ i_pixel.type = type1; i_pixel.image_parent_type = gs_image_type3; } - code = make_mcde(dev, pis, pmat, (const gs_image_common_t *)&i_pixel, + code = make_mcde(dev, pgs, pmat, (const gs_image_common_t *)&i_pixel, prect, pdcolor, pcpath, mem, &penum->pixel_info, &pcdev, mdev, penum->mask_info, &origin); if (code < 0) @@ -458,7 +459,7 @@ return code; } static bool -check_image3_extent(floatp mask_coeff, floatp data_coeff) +check_image3_extent(double mask_coeff, double data_coeff) { if (mask_coeff == 0) return data_coeff == 0; @@ -544,13 +545,15 @@ /* We do this in the simplest (not fastest) way for now. */ uint bit_x = bpc * (num_components + 1) * planes[0].data_x; - sample_load_declare_setup(sptr, sbit, - planes[0].data + (bit_x >> 3), - bit_x & 7, bpc); - sample_store_declare_setup(mptr, mbit, mbbyte, - penum->mask_data, 0, 1); - sample_store_declare_setup(pptr, pbit, pbbyte, - penum->pixel_data, 0, bpc); + const byte *sptr = planes[0].data + (bit_x >> 3); + int sbit = bit_x & 7; + + byte *mptr = penum->mask_data; + int mbit = 0; + byte mbbyte = 0; + byte *pptr = penum->pixel_data; + int pbit = 0; + byte pbbyte = 0; int x; mask_plane.data = mptr; @@ -564,15 +567,19 @@ uint value; int i; - sample_load_next12(value, sptr, sbit, bpc); - sample_store_next12(value != 0, mptr, mbit, 1, mbbyte); + if (sample_load_next12(&value, &sptr, &sbit, bpc) < 0) + return_error(gs_error_rangecheck); + if (sample_store_next12(value != 0, &mptr, &mbit, 1, &mbbyte) < 0) + return_error(gs_error_rangecheck); for (i = 0; i < num_components; ++i) { - sample_load_next12(value, sptr, sbit, bpc); - sample_store_next12(value, pptr, pbit, bpc, pbbyte); + if (sample_load_next12(&value, &sptr, &sbit, bpc) < 0) + return_error(gs_error_rangecheck); + if (sample_store_next12(value, &pptr, &pbit, bpc, &pbbyte) < 0) + return_error (gs_error_rangecheck); } } - sample_store_flush(mptr, mbit, 1, mbbyte); - sample_store_flush(pptr, pbit, bpc, pbbyte); + sample_store_flush(mptr, mbit, mbbyte); + sample_store_flush(pptr, pbit, pbbyte); } break; case interleave_scan_lines: diff -Nru ghostscript-9.10~dfsg/base/gximage3.h ghostscript-9.25~dfsg+1/base/gximage3.h --- ghostscript-9.10~dfsg/base/gximage3.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximage3.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -46,7 +46,7 @@ #define IMAGE3_MAKE_MCDE_PROC(proc)\ int proc(/* The initial arguments are those of begin_typed_image. */\ gx_device *dev,\ - const gs_imager_state *pis,\ + const gs_gstate *pgs,\ const gs_matrix *pmat,\ const gs_image_common_t *pic,\ const gs_int_rect *prect,\ @@ -64,7 +64,7 @@ * procedures as additional parameters. */ int gx_begin_image3_generic(gx_device * dev, - const gs_imager_state *pis, + const gs_gstate *pgs, const gs_matrix *pmat, const gs_image_common_t *pic, const gs_int_rect *prect, diff -Nru ghostscript-9.10~dfsg/base/gximage4.c ghostscript-9.25~dfsg+1/base/gximage4.c --- ghostscript-9.10~dfsg/base/gximage4.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximage4.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -61,7 +61,7 @@ /* Start processing an ImageType 4 image. */ static int gx_begin_image4(gx_device * dev, - const gs_imager_state * pis, const gs_matrix * pmat, + const gs_gstate * pgs, const gs_matrix * pmat, const gs_image_common_t * pic, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum_common_t ** pinfo) @@ -104,10 +104,13 @@ } penum->use_mask_color = !opaque; } - code = gx_image_enum_begin(dev, pis, pmat, pic, pdcolor, pcpath, mem, + code = gx_image_enum_begin(dev, pgs, pmat, pic, pdcolor, pcpath, mem, penum); if (code >= 0) *pinfo = (gx_image_enum_common_t *)penum; + else { + *pinfo = NULL; + } return code; } diff -Nru ghostscript-9.10~dfsg/base/gximage.c ghostscript-9.25~dfsg+1/base/gximage.c --- ghostscript-9.10~dfsg/base/gximage.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximage.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -113,7 +113,7 @@ /* Compute the source size of an ordinary image with explicit data. */ int -gx_data_image_source_size(const gs_imager_state * pis, +gx_data_image_source_size(const gs_gstate * pgs, const gs_image_common_t * pim, gs_int_point * psize) { const gs_data_image_t *pdi = (const gs_data_image_t *)pim; diff -Nru ghostscript-9.10~dfsg/base/gximage.h ghostscript-9.25~dfsg+1/base/gximage.h --- ghostscript-9.10~dfsg/base/gximage.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximage.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -123,19 +123,6 @@ frac_value_out =\ gx_unit_frac(penum->map[i].decode_base + (frac_value) * penum->map[i].decode_factor) -/* - * Declare the pointer that holds the 12-bit unpacking procedure - * if 12-bit samples are supported, 0 otherwise. - */ -extern const sample_unpack_proc_t sample_unpack_12_proc; - -/* - * Declare the pointer that holds the 16-bit unpacking procedure - * if 16-bit samples are supported, 0 otherwise. - */ -extern const sample_unpack_proc_t sample_unpack_16_proc; -extern const sample_unpack_proc_t sample_unpackicc_16_proc; - /* Define the distinct postures of an image. */ /* Each posture includes its reflected variant. */ typedef enum { @@ -144,6 +131,13 @@ image_skewed /* any other transformation */ } image_posture; +/* Interpolation request allows for off, on or forced */ +typedef enum { + interp_off = 0, /* no interpolation */ + interp_on, /* interpolation requested, but not forced */ + interp_force /* force interpolation */ +} image_interp; + /* * Define an entry in the image color table. For single-source-plane * images, the table index is the sample value, and the key is not used; @@ -209,12 +203,16 @@ byte spread; /* (spp if multi-plane, 1 if not) */ /* << log2_xbytes */ byte masked; /* 0 = [color]image, 1 = imagemask */ - byte interpolate; /* true if Interpolate requested */ + image_interp interpolate; /* interpolation: off, on, forced */ gs_matrix matrix; /* image space -> device space */ + /* We send 3 rectangles, rect >= drect >= rrect */ struct r_ { int x, y, w, h; /* subrectangle for which data is supplied */ } rect; struct { + int x, y, w, h; /* subrectangle that actually needs to be decoded */ + } drect; + struct { int x, y, w, h; /* subrectangle that actually needs to be rendered */ } rrect; fixed dst_height; /* Full height covered by the transformed image @@ -228,7 +226,8 @@ gs_fixed_point x_extent, y_extent; /* extent of one row of rect */ SAMPLE_UNPACK_PROC((*unpack)); irender_proc((*render)); - const gs_imager_state *pis; + int (*skip_next_line)(gx_image_enum *penum, gx_device *dev); + const gs_gstate *pgs; const gs_color_space *pcs; /* color space of image */ byte *buffer; /* for expanding samples to a */ /* byte or frac */ @@ -310,7 +309,7 @@ /* Enumerate the pointers in an image enumerator. */ #define gx_image_enum_do_ptrs(m)\ - m(0,pis) m(1,pcs) m(2,dev) m(3,buffer) m(4,line)\ + m(0,pgs) m(1,pcs) m(2,dev) m(3,buffer) m(4,line)\ m(5,clip_dev) m(6,rop_dev) m(7,scaler) m(8,icc_link)\ m(9,color_cache) m(10,ht_buffer) m(11,thresh_buffer) \ m(12,clues) @@ -332,7 +331,12 @@ void gx_image_scale_mask_colors(gx_image_enum *penum, int component_index); /* Used by icc processing to detect decode cases */ -bool gx_has_transfer(const gs_imager_state *pis, int num_comps); +bool gx_has_transfer(const gs_gstate *pgs, int num_comps); + +/* Compute the image matrix combining the ImageMatrix with either the pmat or the pgs ctm */ +/* Exported for use outside gx_image_enum_begin */ +int gx_image_compute_mat(const gs_gstate *pgs, const gs_matrix *pmat, const gs_matrix *ImageMatrix, + gs_matrix_double *rmat); /* * Do common initialization for processing an ImageType 1 or 4 image. * Allocate the enumerator and fill in the following members: @@ -351,7 +355,7 @@ * masked, adjust */ int -gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis, +gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs, const gs_matrix *pmat, const gs_image_common_t * pic, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, diff -Nru ghostscript-9.10~dfsg/base/gximask.c ghostscript-9.25~dfsg+1/base/gximask.c --- ghostscript-9.10~dfsg/base/gximask.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximask.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -35,19 +35,23 @@ */ int -gx_image_fill_masked_start(gx_device *dev, const gx_device_color *pdevc, const gx_clip_path *pcpath, - gs_memory_t *mem, gx_device **cdev) +gx_image_fill_masked_start(gx_device *dev, const gx_device_color *pdevc, bool transpose, + const gx_clip_path *pcpath, gs_memory_t *mem, gs_logical_operation_t lop, + gx_device **cdev) { - if (gx_dc_is_pattern2_color(pdevc) || gx_dc_is_pattern1_color_clist_based(pdevc)) { + if ((lop == lop_default) && (gx_dc_is_pattern2_color(pdevc) || gx_dc_is_pattern1_color_clist_based(pdevc))) { if (!dev_proc(dev, dev_spec_op)(dev, gxdso_pattern_can_accum, NULL, gs_no_id)) { extern_st(st_device_cpath_accum); - gx_device_cpath_accum *pcdev = gs_alloc_struct(mem, - gx_device_cpath_accum, &st_device_cpath_accum, "gx_image_fill_masked_start"); + gx_device_cpath_accum *pcdev; gs_fixed_rect cbox; + if (pcpath == NULL) + return_error(gs_error_nocurrentpoint); /* close enough if no clip path */ + pcdev = gs_alloc_struct(mem, + gx_device_cpath_accum, &st_device_cpath_accum, "gx_image_fill_masked_start"); if (pcdev == NULL) return_error(gs_error_VMerror); - gx_cpath_accum_begin(pcdev, mem); + gx_cpath_accum_begin(pcdev, mem, transpose); gx_cpath_outer_box(pcpath, &cbox); gx_cpath_accum_set_cbox(pcdev, &cbox); pcdev->rc.memory = mem; @@ -104,11 +108,21 @@ gx_device *cdev = dev; int code; - code = gx_image_fill_masked_start(dev, pdc, pcpath, dev->memory, &cdev); - if (code >= 0) + if ((code = gx_image_fill_masked_start(dev, pdc, false, pcpath, dev->memory, lop, &cdev)) < 0) + return code; + + if (cdev == dev) code = (*dev_proc(cdev, fill_mask))(cdev, data, data_x, raster, id, x, y, width, height, pdc, depth, lop, pcpath); - if (code >= 0 && cdev != dev) - code = gx_image_fill_masked_end(cdev, dev, pdc); + else { + /* cdev != dev means that a cpath_accum device was inserted */ + gx_device_color dc_temp; /* if fill_masked_start did cpath_accum, use pure color */ + + set_nonclient_dev_color(&dc_temp, 1); /* arbitrary color since cpath_accum doesn't use it */ + if ((code = (*dev_proc(cdev, fill_mask))(cdev, data, data_x, raster, id, + x, y, width, height, &dc_temp, depth, lop, pcpath)) < 0) + return code; + code = gx_image_fill_masked_end(cdev, dev, pdc); /* fill with the actual device color */ + } return code; } diff -Nru ghostscript-9.10~dfsg/base/gximask.h ghostscript-9.25~dfsg+1/base/gximask.h --- ghostscript-9.10~dfsg/base/gximask.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximask.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -35,8 +35,9 @@ typedef struct gx_clip_path_s gx_clip_path; #endif -int gx_image_fill_masked_start(gx_device *dev, const gx_device_color *pdevc, const gx_clip_path *pcpath, - gs_memory_t *mem, gx_device **cdev); +int gx_image_fill_masked_start(gx_device *dev, const gx_device_color *pdevc, bool transpose, + const gx_clip_path *pcpath, gs_memory_t *mem, gs_logical_operation_t lop, + gx_device **cdev); int gx_image_fill_masked_end(gx_device *dev, gx_device *tdev, const gx_device_color *pdevc); diff -Nru ghostscript-9.10~dfsg/base/gximdecode.c ghostscript-9.25~dfsg+1/base/gximdecode.c --- ghostscript-9.10~dfsg/base/gximdecode.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximdecode.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,249 @@ +/* Copyright (C) 2014-2018 Artifex Software, Inc. +All Rights Reserved. + +This software is provided AS-IS with no warranty, either express or +implied. + +This software is distributed under license and may not be copied, +modified or distributed except as expressly authorized under the terms +of the license contained in the file LICENSE in this distribution. + +Refer to licensing information at http://www.artifex.com or contact +Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Methods for decoding and unpacking image data. Used for color +monitoring in clist and for creating TIFF files for xpswrite device */ + +#include "gximdecode.h" +#include "string_.h" + +/* We need to have the unpacking proc so that we can monitor the data for color + or decode during xpswrite */ +void +get_unpack_proc(gx_image_enum_common_t *pie, image_decode_t *imd, + gs_image_format_t format, const float *decode) { + + static sample_unpack_proc_t procs[2][6] = { + { sample_unpack_1, sample_unpack_2, + sample_unpack_4, sample_unpack_8, + sample_unpack_12, sample_unpackicc_16 + }, + { sample_unpack_1_interleaved, sample_unpack_2_interleaved, + sample_unpack_4_interleaved, sample_unpack_8_interleaved, + sample_unpack_12, sample_unpackicc_16 + } }; + int num_planes = pie->num_planes; + bool interleaved = (num_planes == 1 && pie->plane_depths[0] != imd->bps); + int i; + int index_bps = (imd->bps < 8 ? imd->bps >> 1 : (imd->bps >> 2) + 1); + int log2_xbytes = (imd->bps <= 8 ? 0 : arch_log2_sizeof_frac); + + switch (format) { + case gs_image_format_chunky: + imd->spread = 1 << log2_xbytes; + break; + case gs_image_format_component_planar: + imd->spread = (imd->spp) << log2_xbytes; + break; + case gs_image_format_bit_planar: + imd->spread = (imd->spp) << log2_xbytes; + break; + default: + imd->spread = 0; + } + + if (interleaved) { + int num_components = pie->plane_depths[0] / imd->bps; + + for (i = 1; i < num_components; i++) { + if (decode[0] != decode[i * 2 + 0] || + decode[1] != decode[i * 2 + 1]) + break; + } + if (i == num_components) + interleaved = false; /* Use single table. */ + } + imd->unpack = procs[interleaved][index_bps]; +} + +/* We also need the mapping method for the unpacking proc */ +void +get_map(image_decode_t *imd, gs_image_format_t format, const float *decode) +{ + int ci = 0; + int decode_type; + int bps = imd->bps; + int spp = imd->spp; + static const float default_decode[] = { + 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0 + }; + const float *this_decode = &decode[ci * 2]; + const float *map_decode; /* decoding used to */ + /* construct the expansion map */ + const float *real_decode; /* decoding for expanded samples */ + + decode_type = 3; /* 0=custom, 1=identity, 2=inverted, 3=impossible */ + for (ci = 0; ci < spp; ci += 2) { + decode_type &= (decode[ci] == 0. && decode[ci + 1] == 1.) | + (decode[ci] == 1. && decode[ci + 1] == 0.) << 1; + } + + /* Initialize the maps from samples to intensities. */ + for (ci = 0; ci < spp; ci++) { + sample_map *pmap = &imd->map[ci]; + + if (bps > 8) + imd->applymap = applymap16; + else + imd->applymap = applymap8; + + /* If the decoding is [0 1] or [1 0], we can fold it */ + /* into the expansion of the sample values; */ + /* otherwise, we have to use the floating point method. */ + + this_decode = &decode[ci * 2]; + + map_decode = real_decode = this_decode; + if (!(decode_type & 1)) { + if ((decode_type & 2) && bps <= 8) { + real_decode = default_decode; + } + else { + map_decode = default_decode; + } + } + if (bps > 2 || format != gs_image_format_chunky) { + if (bps <= 8) + image_init_map(&pmap->table.lookup8[0], 1 << bps, + map_decode); + } + else { /* The map index encompasses more than one pixel. */ + byte map[4]; + register int i; + + image_init_map(&map[0], 1 << bps, map_decode); + switch (bps) { + case 1: + { + register bits32 *p = &pmap->table.lookup4x1to32[0]; + + if (map[0] == 0 && map[1] == 0xff) + memcpy((byte *)p, lookup4x1to32_identity, 16 * 4); + else if (map[0] == 0xff && map[1] == 0) + memcpy((byte *)p, lookup4x1to32_inverted, 16 * 4); + else + for (i = 0; i < 16; i++, p++) + ((byte *)p)[0] = map[i >> 3], + ((byte *)p)[1] = map[(i >> 2) & 1], + ((byte *)p)[2] = map[(i >> 1) & 1], + ((byte *)p)[3] = map[i & 1]; + } + break; + case 2: + { + register bits16 *p = &pmap->table.lookup2x2to16[0]; + + for (i = 0; i < 16; i++, p++) + ((byte *)p)[0] = map[i >> 2], + ((byte *)p)[1] = map[i & 3]; + } + break; + } + } + pmap->decode_base /* = decode_lookup[0] */ = real_decode[0]; + pmap->decode_factor = + (real_decode[1] - real_decode[0]) / + (bps <= 8 ? 255.0 : (float)frac_1); + pmap->decode_max /* = decode_lookup[15] */ = real_decode[1]; + if (decode_type) { + pmap->decoding = sd_none; + pmap->inverted = map_decode[0] != 0; + } + else if (bps <= 4) { + int step = 15 / ((1 << bps) - 1); + int i; + + pmap->decoding = sd_lookup; + for (i = 15 - step; i > 0; i -= step) + pmap->decode_lookup[i] = pmap->decode_base + + i * (255.0 / 15) * pmap->decode_factor; + } + else + pmap->decoding = sd_compute; + } +} + +/* We only provide 8 or 16 bit output with the application of the mapping */ +void applymap8(sample_map map[], const void *psrc_in, int spp, void *pdes, + void *bufend) +{ + byte* psrc = (byte*)psrc_in; + byte *curr_pos = (byte*) pdes; + int k; + float temp; + + while (curr_pos < (byte*) bufend) { + for (k = 0; k < spp; k++) { + switch (map[k].decoding) { + case sd_none: + *curr_pos = *psrc; + break; + case sd_lookup: + temp = map[k].decode_lookup[(*psrc) >> 4] * 255; + if (temp > 255) temp = 255; + if (temp < 0) temp = 0; + *curr_pos = (byte)temp; + break; + case sd_compute: + temp = map[k].decode_base + + *(psrc) * map[k].decode_factor; + temp *= 255; + if (temp > 255) temp = 255; + if (temp < 0) temp = 0; + *curr_pos = (byte)temp; + default: + break; + } + curr_pos++; + psrc++; + } + } +} + +void applymap16(sample_map map[], const void *psrc_in, int spp, void *pdes, + void *bufend) +{ + unsigned short *curr_pos = (unsigned short*)pdes; + unsigned short *psrc = (unsigned short*)psrc_in; + int k; + float temp; + + while (curr_pos < (unsigned short*) bufend) { + for (k = 0; k < spp; k++) { + switch (map[k].decoding) { + case sd_none: + *curr_pos = *psrc; + break; + case sd_lookup: + temp = map[k].decode_lookup[*(psrc) >> 4] * 65535.0; + if (temp > 65535) temp = 65535; + if (temp < 0) temp = 0; + *curr_pos = (unsigned short)temp; + break; + case sd_compute: + temp = map[k].decode_base + + *psrc * map[k].decode_factor; + temp *= 65535; + if (temp > 65535) temp = 65535; + if (temp < 0) temp = 0; + *curr_pos = (unsigned short)temp; + default: + break; + } + curr_pos++; + psrc++; + } + } +} diff -Nru ghostscript-9.10~dfsg/base/gximdecode.h ghostscript-9.25~dfsg+1/base/gximdecode.h --- ghostscript-9.10~dfsg/base/gximdecode.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximdecode.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,42 @@ +/* Copyright (C) 2014-2018 Artifex Software, Inc. +All Rights Reserved. + +This software is provided AS-IS with no warranty, either express or +implied. + +This software is distributed under license and may not be copied, +modified or distributed except as expressly authorized under the terms +of the license contained in the file LICENSE in this distribution. + +Refer to licensing information at http://www.artifex.com or contact +Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Prototypes for decoding and unpacking image data. Used for color + monitoring in clist and for creating TIFF files for xpswrite device */ + +#include "gx.h" +#include "gxfixed.h" +#include "gximage.h" +#include "gxsample.h" +#include "gxfrac.h" + +typedef void(*applymap_t) (sample_map map[], const void *psrc, int spp, + void *pdes, void *bufend); + +/* Define the structure the image_enums can use for handling decoding */ +typedef struct image_decode_s { + int bps; + int spp; + SAMPLE_UNPACK_PROC((*unpack)); + int spread; + sample_map map[GS_IMAGE_MAX_COMPONENTS]; + applymap_t applymap; +} image_decode_t; + +void get_unpack_proc(gx_image_enum_common_t *pie, image_decode_t *imd, + gs_image_format_t format, const float *decode); +void get_map(image_decode_t *imd, gs_image_format_t format, const float *decode); +void applymap16(sample_map map[], const void *psrc, int spp, void *pdes, void *bufend); +void applymap8(sample_map map[], const void *psrc, int spp, void *pdes, void *bufend); diff -Nru ghostscript-9.10~dfsg/base/gximono.c ghostscript-9.25~dfsg+1/base/gximono.c --- ghostscript-9.10~dfsg/base/gximono.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gximono.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,13 +28,12 @@ #include "gxdevice.h" #include "gxcmap.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdevmem.h" #include "gdevmem.h" /* for mem_mono_device */ #include "gxcpath.h" #include "gximage.h" #include "gzht.h" -#include "vdtrace.h" #include "gsicc.h" #include "gsicc_cache.h" #include "gsicc_cms.h" @@ -72,12 +71,10 @@ /* Set up the link now */ const gs_color_space *pcs; gsicc_rendering_param_t rendering_params; - int num_des_comps; cmm_dev_profile_t *dev_profile; bool dev_color_ok = false; - bool is_planar_dev = (dev_proc(penum->dev, dev_spec_op)(penum->dev, - gxdso_is_native_planar, NULL, 0) > 0); - + bool is_planar_dev = penum->dev->is_planar; + if (penum->spp == 1) { /* At this point in time, only use the ht approach if our device uses halftoning, and our source image is a reasonable size. We @@ -102,7 +99,8 @@ if (use_fast_code && penum->pcs != NULL && dev_color_ok && penum->bps == 8 && (penum->posture == image_portrait || penum->posture == image_landscape) && - penum->image_parent_type == gs_image_type1) { + penum->image_parent_type == gs_image_type1 && + gx_transfer_is_monotonic(penum->pgs, 0)) { penum->icc_setup.need_decode = false; /* Check if we need to do any decoding. */ if ( penum->map[0].decoding != sd_none ) { @@ -113,13 +111,15 @@ } } code = dev_proc(penum->dev, get_profile)(penum->dev, &dev_profile); - num_des_comps = gsicc_get_device_profile_comps(dev_profile); + if (code < 0) + return NULL; /* This function does not return errors, best we can do is say 'we can't handle this' */ + /* Define the rendering intents */ - rendering_params.black_point_comp = penum->pis->blackptcomp; + rendering_params.black_point_comp = penum->pgs->blackptcomp; rendering_params.graphics_type_tag = GS_IMAGE_TAG; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = penum->pis->renderingintent; + rendering_params.rendering_intent = penum->pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; if (gs_color_space_get_index(penum->pcs) == gs_color_space_index_Indexed) { @@ -139,13 +139,12 @@ penum->icc_setup.is_lab = pcs->cmm_icc_profile_data->islab; penum->icc_setup.must_halftone = gx_device_must_halftone(penum->dev); - /* The effective transfer is built into the threshold array and - need require a special lookup to decode it */ - penum->icc_setup.has_transfer = - gx_has_transfer(penum->pis, num_des_comps); - if (penum->icc_setup.is_lab) penum->icc_setup.need_decode = false; + /* The effective transfer is built into the threshold array */ + penum->icc_setup.has_transfer = false; + if (penum->icc_setup.is_lab) + penum->icc_setup.need_decode = false; if (penum->icc_link == NULL) { - penum->icc_link = gsicc_get_link(penum->pis, penum->dev, pcs, NULL, + penum->icc_link = gsicc_get_link(penum->pgs, penum->dev, pcs, NULL, &rendering_params, penum->memory); } /* PS CIE color spaces may have addition decoding that needs to @@ -163,7 +162,7 @@ } } /* If the image has more than 256 pixels then go ahead and - precompute the con-tone device colors for all of our 256 source + precompute the contone device colors for all of our 256 source values. We should not be taking this path for cases where we have lots of tiny little images. Mark those that are transparent or masked also at this time. Since halftoning will @@ -211,11 +210,12 @@ } #define USE_SET_GRAY_FUNCTION 0 +#if USE_SET_GRAY_FUNCTION /* Temporary function to make it easier to debug the uber-macro below */ static inline int image_set_gray(byte sample_value, const bool masked, uint mask_base, uint mask_limit, gx_device_color **ppdevc, gs_client_color *cc, - const gs_color_space *pcs, const gs_imager_state *pis, + const gs_color_space *pcs, const gs_gstate *pgs, gx_device * dev, gs_color_select_t gs_color_select_source, gx_image_enum * penum) { @@ -242,16 +242,17 @@ penum->map[0].decode_base + (sample_value) * penum->map[0].decode_factor; } remap_color = pcs->type->remap_color; - code = (*remap_color)(cc, pcs, pdevc, pis, dev, gs_color_select_source); + code = (*remap_color)(cc, pcs, pdevc, pgs, dev, gs_color_select_source); return(code); } } else if (!color_is_pure(pdevc)) { - code = gx_color_load_select(pdevc, pis, dev, gs_color_select_source); + code = gx_color_load_select(pdevc, pgs, dev, gs_color_select_source); if (code < 0) return(code); } return(0); } +#endif /* * Rendering procedure for general mono-component images, dealing with @@ -264,7 +265,7 @@ image_render_mono(gx_image_enum * penum, const byte * buffer, int data_x, uint w, int h, gx_device * dev) { - const gs_imager_state *pis = penum->pis; + const gs_gstate *pgs = penum->pgs; gs_logical_operation_t lop = penum->log_op; const bool masked = penum->masked; const gs_color_space *pcs = NULL; /* only set for non-masks */ @@ -278,7 +279,7 @@ penum->mask_color.values[1] - mask_base + 1 : 0); /* * Free variables of IMAGE_SET_GRAY: - * Read: penum, pis, dev, mask_base, mask_limit + * Read: penum, pgs, dev, mask_base, mask_limit * Set: pdevc, code, cc */ #define IMAGE_SET_GRAY(sample_value)\ @@ -289,12 +290,12 @@ color_set_null(pdevc);\ else {\ decode_sample(sample_value, cc, 0);\ - code = (*remap_color)(&cc, pcs, pdevc, pis, dev, gs_color_select_source);\ + code = (*remap_color)(&cc, pcs, pdevc, pgs, dev, gs_color_select_source);\ if (code < 0)\ goto err;\ }\ } else if (!color_is_pure(pdevc)) {\ - code = gx_color_load_select(pdevc, pis, dev, gs_color_select_source);\ + code = gx_color_load_select(pdevc, pgs, dev, gs_color_select_source);\ if (code < 0)\ goto err;\ }\ @@ -359,7 +360,7 @@ **********************/ pdevc = penum->icolor1; - code = gx_color_load(pdevc, pis, dev); + code = gx_color_load(pdevc, pgs, dev); if (code < 0) return code; if ((stop <= psrc) && (penum->adjust == 0) && @@ -524,45 +525,131 @@ } - } else if (penum->posture == image_portrait || - penum->posture == image_landscape - ) { - + } else if (penum->posture == image_portrait) { /************************************** - * Slow case, not masked, orthogonal. * + * Slow case, not masked, portrait. * **************************************/ + dev_proc_fill_rectangle((*fill_proc)) = + dev_proc(dev, fill_rectangle); + int iy = fixed2int_pixround(yrun); + int ih = fixed2int_pixround(yrun + pdyy) - iy; + if (ih < 0) + iy += ih, ih = -ih; /* In this case, we can fill runs quickly. */ /****** DOESN'T DO ADJUSTMENT ******/ if (stop <= psrc) goto last; for (;;) { - if (*psrc != run) { - if (run != htrun) { - htrun = run; + byte c = *psrc++; + if (c != run) { + int ix = fixed2int_pixround(xrun); + int iw = fixed2int_pixround(xl) - ix; + if (iw < 0) + ix += iw, iw = -iw; + switch (run) + { + case 0: + if (!color_is_pure(penum->icolor0)) + goto ht_port; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor0->colors.pure); + break; + case 0xff: + if (!color_is_pure(penum->icolor1)) + goto ht_port; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor1->colors.pure); + break; + default: + ht_port: + if (run != htrun) { + htrun = run; #if USE_SET_GRAY_FUNCTION - code = image_set_gray(run,masked,mask_base,mask_limit,&pdevc, - &cc,pcs,pis,dev,gs_color_select_source,penum); - if (code < 0) - goto err; + code = image_set_gray(run,masked,mask_base,mask_limit,&pdevc, + &cc,pcs,pgs,dev,gs_color_select_source,penum); + if (code < 0) + goto err; #else - IMAGE_SET_GRAY(run); + IMAGE_SET_GRAY(run); #endif + } + code = gx_fill_rectangle_device_rop(ix, iy, iw, ih, + pdevc, dev, lop); } - code = (*fill_pgram)(dev, xrun, yrun, xl - xrun, - ytf - yrun, pdyx, pdyy, - pdevc, lop); if (code < 0) goto err; - yrun = ytf; xrun = xl; rsrc = psrc; - if (psrc >= stop) + if (psrc > stop) break; - run = *psrc; + run = c; } - psrc++; dda_next(next.x); + if (psrc >= endp) + break; + } + } else if (penum->posture == image_landscape) { + + /************************************** + * Slow case, not masked, landscape. * + **************************************/ + dev_proc_fill_rectangle((*fill_proc)) = + dev_proc(dev, fill_rectangle); + int ix = fixed2int_pixround(xrun); + int iw = fixed2int_pixround(xrun + pdyx) - ix; + if (iw < 0) + ix += iw, iw = -iw; + + /* In this case, we can fill runs quickly. */ + /****** DOESN'T DO ADJUSTMENT ******/ + if (stop <= psrc) + goto last; + for (;;) { + byte c = *psrc++; + if (c != run) { + int iy = fixed2int_pixround(yrun); + int ih = fixed2int_pixround(ytf) - iy; + if (ih < 0) + iy += ih, ih = -ih; + switch (run) + { + case 0: + if (!color_is_pure(penum->icolor0)) + goto ht_land; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor0->colors.pure); + break; + case 0xff: + if (!color_is_pure(penum->icolor1)) + goto ht_land; + code = (*fill_proc) (dev, ix, iy, iw, ih, + penum->icolor1->colors.pure); + break; + default: + ht_land: + if (run != htrun) { + htrun = run; +#if USE_SET_GRAY_FUNCTION + code = image_set_gray(run,masked,mask_base,mask_limit,&pdevc, + &cc,pcs,pgs,dev,gs_color_select_source,penum); + if (code < 0) + goto err; +#else + IMAGE_SET_GRAY(run); +#endif + } + code = gx_fill_rectangle_device_rop(ix, iy, iw, ih, + pdevc, dev, lop); + } + if (code < 0) + goto err; + yrun = ytf; + rsrc = psrc; + if (psrc > stop) + break; + run = c; + } dda_next(next.y); if (psrc >= endp) break; @@ -586,7 +673,7 @@ htrun = run; #if USE_SET_GRAY_FUNCTION code = image_set_gray(run,masked,mask_base,mask_limit,&pdevc, - &cc,pcs,pis,dev,gs_color_select_source,penum); + &cc,pcs,pgs,dev,gs_color_select_source,penum); if (code < 0) goto err; #else @@ -613,7 +700,7 @@ if (!masked) { #if USE_SET_GRAY_FUNCTION code = image_set_gray(*stop, masked,mask_base,mask_limit,&pdevc, - &cc,pcs,pis,dev,gs_color_select_source,penum); + &cc,pcs,pgs,dev,gs_color_select_source,penum); if (code < 0) goto err; #else @@ -723,7 +810,7 @@ if (run != htrun) { #if USE_SET_GRAY_FUNCTION code = image_set_gray(run, masked,mask_base,mask_limit,&pdevc, - &cc,pcs,pis,dev,gs_color_select_source,penum); + &cc,pcs,pgs,dev,gs_color_select_source,penum); if (code < 0) goto err; #else @@ -733,8 +820,6 @@ } code = gx_fill_rectangle_device_rop(xi, yt, wi, iht, pdevc, dev, lop); - vd_rect(int2fixed(xi), int2fixed(yt), int2fixed(xi + wi), int2fixed(yt + iht), - 0, pdevc->colors.pure /* wrong with halftones */); } if (code < 0) goto err; @@ -770,7 +855,7 @@ } #if USE_SET_GRAY_FUNCTION code = image_set_gray(*stop, masked,mask_base,mask_limit,&pdevc, - &cc,pcs,pis,dev,gs_color_select_source,penum); + &cc,pcs,pgs,dev,gs_color_select_source,penum); if (code < 0) goto err; #else @@ -815,16 +900,17 @@ int position, k, j; int offset_bits = penum->ht_offset_bits; int contone_stride = 0; /* Not used in landscape case */ - fixed scale_factor, offset; + fixed offset; int src_size; bool flush_buff = false; int offset_contone[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* to ensure 128 bit boundary */ int offset_threshold; /* to ensure 128 bit boundary */ - gx_dda_int_t dda_ht; + gx_dda_fixed dda_ht; + int xn, xr; /* destination position (pixel, not contone buffer offset) */ int code = 0; byte *dev_value; - if (h == 0) { + if (h == 0 || penum->line_size == 0) { /* line_size == 0, nothing to do */ if (penum->ht_landscape.count == 0 || posture == image_portrait) { return 0; } else { @@ -837,15 +923,19 @@ } src_size = penum->rect.w; + /* Set up the dda. We could move this out but the cost is pretty small */ + dda_ht = (posture == image_portrait) ? penum->dda.pixel0.x : penum->dda.pixel0.y; + if (penum->dxx > 0) + dda_translate(dda_ht, -fixed_epsilon); /* to match rounding in non-fast code */ + switch (posture) { case image_portrait: /* Figure out our offset in the contone and threshold data buffers so that we ensure that we are on the 128bit memory boundaries when we get offset_bits into the data. */ /* Can't do this earlier, as GC might move the buffers. */ - xrun = dda_current(penum->dda.pixel0.x); - xrun = xrun - penum->adjust + (fixed_half - fixed_epsilon); - dest_width = fixed2int_var_rounded(any_abs(penum->x_extent.x)); + xrun = dda_current(dda_ht); + dest_width = gxht_dda_length(&dda_ht, src_size); if (penum->x_extent.x < 0) xrun += penum->x_extent.x; vdi = penum->hci; @@ -859,10 +949,9 @@ } data_length = dest_width; dest_height = fixed2int_var_rounded(any_abs(penum->y_extent.y)); - scale_factor = float2fixed_rounded((float) src_size / (float) dest_width); #ifdef DEBUG /* Help in spotting problems */ - memset(penum->ht_buffer,0x00, penum->ht_stride * vdi * spp_out); + memset(penum->ht_buffer, 0x00, penum->ht_stride * vdi * spp_out); #endif break; case image_landscape: @@ -872,11 +961,12 @@ Can't do this earlier as GC may move the buffers. */ vdi = penum->wci; - contone_stride = penum->line_size; + contone_stride = penum->line_size; dest_width = fixed2int_var_rounded(any_abs(penum->y_extent.x)); - dest_height = fixed2int_var_rounded(any_abs(penum->x_extent.y)); + /* match height in gxht_thresh.c dev_width calculation */ + xrun = dda_current(dda_ht); /* really yrun, but just used here for landscape */ + dest_height = gxht_dda_length(&dda_ht, src_size); data_length = dest_height; - scale_factor = float2fixed_rounded((float) src_size / (float) dest_height); offset_threshold = (-(long)(penum->thresh_buffer)) & 15; for (k = 0; k < spp_out; k ++) { offset_contone[k] = (- ((long)(penum->line) + @@ -916,24 +1006,26 @@ } break; } + if (flush_buff) + goto flush; /* All done */ + /* Get the pointers to our buffers */ for (k = 0; k < spp_out; k++) { if (posture == image_portrait) { - devc_contone[k] = penum->line + contone_stride * k + + devc_contone[k] = penum->line + contone_stride * k + offset_contone[k]; } else { devc_contone[k] = penum->line + offset_contone[k] + LAND_BITS * k * contone_stride; } } - if (flush_buff) goto flush; /* All done */ - /* Set up the dda. We could move this out but the cost is pretty small */ - dda_init_half(dda_ht, 0, src_size, data_length); + xr = fixed2int_var_rounded(dda_current(dda_ht)); /* indexes in the destination (contone) */ + devc_contone_gray = devc_contone[0]; if (penum->color_cache == NULL) { /* No look-up in the cache to fill the source buffer. Still need to have the data at device resolution. Do these in quick small - loops. This likely could be a vectorized function. Note that + loops. This likely could be a vectorized function. Note that since the color_cache is NULL we must be in a case where we are going to a monochrome device. */ switch (posture) { @@ -948,16 +1040,28 @@ *devc_contone_gray = *(devc_contone_gray+1) = *psrc_temp; } } else { - for (k = 0; k < data_length; k++, devc_contone_gray++) { - *devc_contone_gray = psrc[dda_ht.state.Q]; + /* Mono case, forward */ + for (k=0; k= xr */ + psrc++; } } } else { + /* Mono case, backwards */ devc_contone_gray += (data_length - 1); - for (k = 0; k < data_length; k++, devc_contone_gray--) { - *devc_contone_gray = psrc[dda_ht.state.Q]; + for (k=0; k xn) { + *devc_contone_gray-- = *psrc; + xr--; + } /* at loop exit xn will be >= xr */ + psrc++; } } break; @@ -968,10 +1072,15 @@ if (penum->ht_landscape.flipy) { position = penum->ht_landscape.curr_pos + LAND_BITS * (data_length - 1); - for (k = 0; k < data_length; k++) { - devc_contone_gray[position] = psrc[dda_ht.state.Q]; - position -= LAND_BITS; + for (k=0; k xn) { + devc_contone_gray[position] = *psrc; + position -= LAND_BITS; + xr--; + } /* at loop exit xn will be <= xr */ + psrc++; } } else { position = penum->ht_landscape.curr_pos; @@ -983,19 +1092,24 @@ devc_contone_gray[position] = psrc[k]; position += LAND_BITS; } - } else if (scale_factor == fixed_half) { + } else if (src_size*2 == dest_height) { for (k = 0; k < data_length; k+=2) { - offset = fixed2int_rounded(scale_factor * k); + offset = fixed2int_rounded(fixed_half * k); devc_contone_gray[position] = devc_contone_gray[position + LAND_BITS] = psrc[offset]; position += LAND_BITS*2; } } else { /* use dda */ - for (k = 0; k < data_length; k++) { - devc_contone_gray[position] = psrc[dda_ht.state.Q]; - position += LAND_BITS; + for (k=0; k= xr */ + psrc++; } } } @@ -1017,39 +1131,63 @@ switch (posture) { case image_portrait: if (penum->dst_width > 0) { + /* loop filling contone values selected from the source */ if (spp_out == 1) { - /* Mono case */ - for (k = 0; k < data_length; k++) { - *devc_contone_gray++ = color_cache[psrc[dda_ht.state.Q]]; + /* Mono case, forward */ + for (k=0; k= xr */ + psrc++; } } else { - /* CMYK case */ - for (k = 0; k < data_length; k++) { - dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; - for (j = 0; j < spp_out; j++) { - *(devc_contone[j])++ = dev_value[j]; - } + /* CMYK case, forward */ + for (k=0; k= xr */ + psrc++; } } } else { if (spp_out == 1) { - for (k = data_length-1; k >= 0; k--) { - devc_contone_gray[k] = color_cache[psrc[dda_ht.state.Q]]; + /* Mono case, backwards */ + devc_contone_gray += data_length - 1; /* move to end */ + for (k=0; k xn) { + *devc_contone_gray-- = color_cache[*psrc]; + xr--; + } /* at loop exit xn will be <= xr */ + psrc++; } } else { + /* CMYK case, backwards */ /* Move to the other end and we will decrement */ for (j = 0; j < spp_out; j++) { devc_contone[j] = devc_contone[j] + data_length - 1; } - for (k = 0; k < data_length; k++) { - dev_value = color_cache + psrc[dda_ht.state.Q] * spp_out; - for (j = 0; j < spp_out; j++) { - *(devc_contone[j])-- = dev_value[j]; - } - dda_next(dda_ht); + for (k=0; k xn) { + dev_value = &(color_cache[*psrc * spp_out]); + for (j = 0; j < spp_out; j++) { + *(devc_contone[j])-- = dev_value[j]; + } + xr--; + } /* at loop exit xn will be <= xr */ + psrc++; } } } @@ -1063,30 +1201,49 @@ LAND_BITS * (data_length - 1); /* use dda */ if (spp_out == 1) { - for (k = 0; k < data_length; k++) { - devc_contone_gray[position] = color_cache[psrc[dda_ht.state.Q]]; - position -= LAND_BITS; + /* Mono case */ + /* loop filling contone values selected from the source */ + for (k=0; k xn) { + devc_contone_gray[position] = color_cache[*psrc]; + position -= LAND_BITS; + xr--; + } /* at loop exit xn will be <= xr */ + psrc++; } } else { - for (k = 0; k < data_length; k++) { - for (j = 0; j < spp_out; j++) { - *(devc_contone[j] + position) = - color_cache[psrc[dda_ht.state.Q] * spp_out + j]; - } - position -= LAND_BITS; + /* CMYK case */ + for (k=0; k xn) { + dev_value = &(color_cache[*psrc * spp_out]); + for (j = 0; j < spp_out; j++) { + *(devc_contone[j] + position) = dev_value[j]; + } + position -= LAND_BITS; + xr--; + } /* at loop exit xn will be <= xr */ + psrc++; } } } else { /* Not flipped in Y */ position = penum->ht_landscape.curr_pos; /* use dda */ if (spp_out == 1) { - for (k = 0; k < data_length; k++) { - devc_contone_gray[position] = - color_cache[psrc[dda_ht.state.Q]]; - position += LAND_BITS; + /* Mono case */ + /* loop filling contone values selected from the source */ + for (k=0; k= xr */ + psrc++; } } else { /* CMYK case */ @@ -1094,14 +1251,19 @@ for (k = 0; k < spp_out; k++) { devc_contone[k] = devc_contone[k] + position; } - for (k = 0; k < data_length; k++) { - /* Is it better to unwind this? We know it is 4 */ - for (j = 0; j < spp_out; j++) { - *(devc_contone[j]) = - color_cache[psrc[dda_ht.state.Q] * spp_out + j]; - devc_contone[j] += LAND_BITS; - } + /* CMYK case */ + for (k=0; k= xr */ + psrc++; } } } diff -Nru ghostscript-9.10~dfsg/base/gxino12b.c ghostscript-9.25~dfsg+1/base/gxino12b.c --- ghostscript-9.10~dfsg/base/gxino12b.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxino12b.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Dummy 12-bit image procedure */ -#include "std.h" -#include "gstypes.h" -#include "gxsample.h" - -const sample_unpack_proc_t sample_unpack_12_proc = 0; diff -Nru ghostscript-9.10~dfsg/base/gxino16b.c ghostscript-9.25~dfsg+1/base/gxino16b.c --- ghostscript-9.10~dfsg/base/gxino16b.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxino16b.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Dummy 16-bit image procedure */ -#include "std.h" -#include "gstypes.h" -#include "gxsample.h" - -const sample_unpack_proc_t sample_unpack_16_proc = 0; -const sample_unpack_proc_t sample_unpackicc_16_proc = 0; diff -Nru ghostscript-9.10~dfsg/base/gxiodev.h ghostscript-9.25~dfsg+1/base/gxiodev.h --- ghostscript-9.10~dfsg/base/gxiodev.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxiodev.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,6 +21,7 @@ # define gxiodev_INCLUDED #include "stat_.h" +#include "gsstype.h" /* * Note that IODevices are not the same as Ghostscript output devices. @@ -34,6 +35,14 @@ #endif typedef struct gx_io_device_procs_s gx_io_device_procs; /* defined here */ +/* the number of slots reserved in the io device table for io devices to + * be added at run time. + */ +#define NUM_RUNTIME_IODEVS 16 + +int +gs_iodev_register_dev(gs_memory_t * mem, const gx_io_device *newiodev); + /* The IODevice table is defined in gconf.c; its extern is in gscdefs.h. */ #ifndef file_enum_DEFINED /* also defined in gp.h */ @@ -81,6 +90,10 @@ int proc(gx_io_device *iodev, gs_memory_t *mem) iodev_proc_init((*init)); /* one-time initialization */ +#define iodev_proc_finit(proc)\ + void proc(gx_io_device *iodev, gs_memory_t *mem) + iodev_proc_finit((*finit)); /* finalization */ + #define iodev_proc_open_device(proc)\ int proc(gx_io_device *iodev, const char *access, stream **ps,\ gs_memory_t *mem) @@ -146,6 +159,7 @@ /* Default implementations of procedures */ iodev_proc_init(iodev_no_init); +iodev_proc_finit(iodev_no_finit); iodev_proc_open_device(iodev_no_open_device); iodev_proc_open_file(iodev_no_open_file); iodev_proc_fopen(iodev_no_fopen); @@ -196,8 +210,17 @@ void *state; /* (if the IODevice has state) */ }; +struct_proc_finalize(io_device_finalize); + #define private_st_io_device() /* in gsiodev.c */\ - gs_private_st_ptrs1(st_io_device, gx_io_device, "gx_io_device",\ - io_device_enum_ptrs, io_device_reloc_ptrs, state) + gs_public_st_ptrs1_final(st_io_device, gx_io_device, "gx_io_device",\ + io_device_enum_ptrs, io_device_reloc_ptrs, io_device_finalize, state) + + +int +gs_iodev_init(gs_memory_t * mem); + +void +gs_iodev_finit(gs_memory_t * mem); #endif /* gxiodev_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxiparam.h ghostscript-9.25~dfsg+1/base/gxiparam.h --- ghostscript-9.10~dfsg/base/gxiparam.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxiparam.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -55,7 +55,7 @@ * structure, but ImageType 2 images must compute it. */ #define image_proc_source_size(proc)\ - int proc(const gs_imager_state *pis, const gs_image_common_t *pic,\ + int proc(const gs_gstate *pgs, const gs_image_common_t *pic,\ gs_int_point *psize) image_proc_source_size((*source_size)); diff -Nru ghostscript-9.10~dfsg/base/gxipixel.c ghostscript-9.25~dfsg+1/base/gxipixel.c --- ghostscript-9.10~dfsg/base/gxipixel.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxipixel.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -41,6 +41,8 @@ #include "gscindex.h" #include "gsicc_cache.h" #include "gsicc_cms.h" +#include "gsicc_manage.h" +#include "gxdevsop.h" /* Structure descriptors */ private_st_gx_image_enum(); @@ -128,10 +130,10 @@ /* Forward declarations */ static int color_draws_b_w(gx_device * dev, const gx_drawing_color * pdcolor); -static void image_init_colors(gx_image_enum * penum, int bps, int spp, +static int image_init_colors(gx_image_enum * penum, int bps, int spp, gs_image_format_t format, const float *decode, - const gs_imager_state * pis, gx_device * dev, + const gs_gstate * pgs, gx_device * dev, const gs_color_space * pcs, bool * pdcb); /* Procedures for unpacking the input data into bytes or fracs. */ @@ -173,10 +175,12 @@ ) return_error(gs_error_rangecheck); } + *ppenum = NULL; /* in case alloc fails and caller doesn't check code */ penum = gs_alloc_struct(mem, gx_image_enum, &st_gx_image_enum, "gx_default_begin_image"); if (penum == 0) return_error(gs_error_VMerror); + memset(penum, 0, sizeof(gx_image_enum)); /* in case of failure, no dangling pointers */ if (prect) { penum->rect.x = prect->p.x; penum->rect.y = prect->p.y; @@ -190,6 +194,10 @@ penum->rrect.y = penum->rect.y; penum->rrect.w = penum->rect.w; penum->rrect.h = penum->rect.h; + penum->drect.x = penum->rect.x; + penum->drect.y = penum->rect.y; + penum->drect.w = penum->rect.w; + penum->drect.h = penum->rect.h; #ifdef DEBUG if (gs_debug_c('b')) { dmlprintf2(mem, "[b]Image: w=%d h=%d", width, height); @@ -204,14 +212,40 @@ /* Convert and restrict to a valid range. */ static inline fixed float2fixed_rounded_boxed(double src) { - float v = floor(src*fixed_scale + 0.5); + float v = floor(src*fixed_scale + 0.5); - if (v <= min_fixed) - return min_fixed; - else if (v >= max_fixed) - return max_fixed; - else - return (fixed)v; + if (v <= min_fixed) + return min_fixed; + else if (v >= max_fixed) + return max_fixed; + else + return (fixed)v; +} + +/* Compute the image matrix combining the ImageMatrix with either the pmat or the pgs ctm */ +int +gx_image_compute_mat(const gs_gstate *pgs, const gs_matrix *pmat, const gs_matrix *ImageMatrix, + gs_matrix_double *rmat) +{ + int code = 0; + + if (pmat == 0) + pmat = &ctm_only(pgs); + if (ImageMatrix->xx == pmat->xx && ImageMatrix->xy == pmat->xy && + ImageMatrix->yx == pmat->yx && ImageMatrix->yy == pmat->yy) { + /* Process common special case separately to accept singular matrix. */ + rmat->xx = rmat->yy = 1.; + rmat->xy = rmat->yx = 0.; + rmat->tx = pmat->tx - ImageMatrix->tx; + rmat->ty = pmat->ty - ImageMatrix->ty; + } else { + if ((code = gs_matrix_invert_to_double(ImageMatrix, rmat)) < 0 || + (code = gs_matrix_multiply_double(rmat, pmat, rmat)) < 0 + ) { + return code; + } + } + return code; } /* @@ -222,7 +256,7 @@ * masked, adjust */ int -gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis, +gx_image_enum_begin(gx_device * dev, const gs_gstate * pgs, const gs_matrix *pmat, const gs_image_common_t * pic, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum *penum) @@ -237,16 +271,20 @@ gs_matrix_double mat; int index_bps; const gs_color_space *pcs = pim->ColorSpace; - gs_logical_operation_t lop = (pis ? pis->log_op : lop_default); + gs_logical_operation_t lop = (pgs ? pgs->log_op : lop_default); int code; int log2_xbytes = (bps <= 8 ? 0 : arch_log2_sizeof_frac); int spp, nplanes, spread; uint bsize; - byte *buffer; + byte *buffer = NULL; fixed mtx, mty; gs_fixed_point row_extent, col_extent, x_extent, y_extent; bool device_color = true; gs_fixed_rect obox, cbox; + bool gridfitimages = 0; + bool in_pattern_accumulator = 0; + int orthogonal; + int force_interpolation = 0; penum->clues = NULL; penum->icc_setup.has_transfer = false; @@ -255,22 +293,9 @@ penum->icc_setup.need_decode = false; penum->Width = width; penum->Height = height; - if (pmat == 0) - pmat = &ctm_only(pis); - if (pim->ImageMatrix.xx == pmat->xx && pim->ImageMatrix.xy == pmat->xy && - pim->ImageMatrix.yx == pmat->yx && pim->ImageMatrix.yy == pmat->yy) { - /* Process common special case separately to accept singular matrix. */ - mat.xx = mat.yy = 1.; - mat.xy = mat.yx = 0.; - mat.tx = pmat->tx - pim->ImageMatrix.tx; - mat.ty = pmat->ty - pim->ImageMatrix.ty; - } else { - if ((code = gs_matrix_invert_to_double(&pim->ImageMatrix, &mat)) < 0 || - (code = gs_matrix_multiply_double(&mat, pmat, &mat)) < 0 - ) { - gs_free_object(mem, penum, "gx_default_begin_image"); - return code; - } + + if ((code = gx_image_compute_mat(pgs, pmat, &(pim->ImageMatrix), &mat)) < 0) { + return code; } /* Grid fit: A common construction in postscript/PDF files is for images * to be constructed as a series of 'stacked' 1 pixel high images. @@ -281,7 +306,7 @@ * covered. Bug 692666 is such a problem. * * As a workaround for this problem, the code below was introduced. The - * concept is that orthogonal images can be 'grid fitted' (or 'stretched') + * concept is that orthogonal images can be 'grid fitted' (or 'stretch') * to entirely cover pixels that they touch. Initially I had this working * for all images regardless of type, but as testing has proceeded, this * showed more and more regressions, so I've cut the cases back in which @@ -289,15 +314,40 @@ * either 1 pixel high, or wide, and then not if we are rendering a * glyph (such as from a type3 font). */ - if (pis != NULL && pis->is_gstate && ((gs_state *)pis)->show_gstate != NULL) { + + /* Ask the device if we are in a pattern accumulator */ + in_pattern_accumulator = (dev_proc(dev, dev_spec_op)(dev, gxdso_in_pattern_accumulator, NULL, 0)); + if (in_pattern_accumulator < 0) + in_pattern_accumulator = 0; + + /* Figure out if we are orthogonal */ + if (mat.xy == 0 && mat.yx == 0) + orthogonal = 1; + else if (mat.xx == 0 && mat.yy == 0) + orthogonal = 2; + else + orthogonal = 0; + + /* If we are in a pattern accumulator, we choose to always grid fit + * orthogonal images. We do this by asking the device whether we + * should grid fit. This allows us to avoid nasty blank lines around + * the edges of cells. + */ + gridfitimages = in_pattern_accumulator && orthogonal; + + if (pgs != NULL && pgs->show_gstate != NULL) { /* If we're a graphics state, and we're in a text object, then we * must be in a type3 font. Don't fiddle with it. */ - } else if (!penum->masked || penum->image_parent_type != 0) { - /* We only grid fit for ImageMasks, currently */ - } else if (pis != NULL && pis->fill_adjust.x == 0 && pis->fill_adjust.y == 0) { + } else if (!gridfitimages && + (!penum->masked || penum->image_parent_type != 0)) { + /* Other than for images we are specifically looking to grid fit (such as + * ones in a pattern device), we only grid fit imagemasks */ + } else if (gridfitimages && (penum->masked && penum->image_parent_type == 0)) { + /* We don't gridfit imagemasks in a pattern accumulator */ + } else if (pgs != NULL && pgs->fill_adjust.x == 0 && pgs->fill_adjust.y == 0) { /* If fill adjust is disabled, so is grid fitting */ - } else if (mat.xy == 0 && mat.yx == 0) { - if (width == 1) { + } else if (orthogonal == 1) { + if (width == 1 || gridfitimages) { if (mat.xx > 0) { fixed ix0 = int2fixed(fixed2int(float2fixed(mat.tx))); double x1 = mat.tx + mat.xx * width; @@ -312,7 +362,7 @@ mat.xx = (double)(fixed2float(ix1 - ix0)/width); } } - if (height == 1) { + if (height == 1 || gridfitimages) { if (mat.yy > 0) { fixed iy0 = int2fixed(fixed2int(float2fixed(mat.ty))); double y1 = mat.ty + mat.yy * height; @@ -327,8 +377,8 @@ mat.yy = ((double)fixed2float(iy1 - iy0)/height); } } - } else if (mat.xx == 0 && mat.yy == 0) { - if (height == 1) { + } else if (orthogonal == 2) { + if (height == 1 || gridfitimages) { if (mat.yx > 0) { fixed ix0 = int2fixed(fixed2int(float2fixed(mat.tx))); double x1 = mat.tx + mat.yx * height; @@ -343,7 +393,7 @@ mat.yx = (double)(fixed2float(ix1 - ix0)/height); } } - if (width == 1) { + if (width == 1 || gridfitimages) { if (mat.xy > 0) { fixed iy0 = int2fixed(fixed2int(float2fixed(mat.ty))); double y1 = mat.ty + mat.xy * width; @@ -360,14 +410,32 @@ } } + /* When rendering to a pattern accumulator, if we are downscaling + * then enable interpolation, as otherwise dropouts can cause + * serious problems. */ + if (in_pattern_accumulator) { + double ome = ((double)(fixed_1 - fixed_epsilon)) / (double)fixed_1; /* One Minus Epsilon */ + + if (orthogonal == 1) { + if ((mat.xx > -ome && mat.xx < ome) || (mat.yy > -ome && mat.yy < ome)) { + force_interpolation = true; + } + } else if (orthogonal == 2) { + if ((mat.xy > -ome && mat.xy < ome) || (mat.yx > -ome && mat.yx < ome)) { + force_interpolation = true; + } + } + } + /* Can we restrict the amount of image we need? */ while (pcpath) /* So we can break out of it */ { gs_rect rect, rect_out; gs_matrix mi; + const gs_matrix *m = pgs != NULL ? &ctm_only(pgs) : NULL; gs_fixed_rect obox; gs_int_rect irect; - if ((code = gs_matrix_invert(&ctm_only(pis), &mi)) < 0 || + if (m == NULL || (code = gs_matrix_invert(m, &mi)) < 0 || (code = gs_matrix_multiply(&mi, &pic->ImageMatrix, &mi)) < 0) { /* Give up trying to shrink the render box, but continue processing */ break; @@ -379,37 +447,14 @@ rect.q.y = fixed2float(obox.q.y); code = gs_bbox_transform(&rect, &mi, &rect_out); if (code < 0) { - /* Give up trying to shrink the render box, but continue processing */ + /* Give up trying to shrink the render/decode boxes, but continue processing */ break; } irect.p.x = (int)(rect_out.p.x-1.0); irect.p.y = (int)(rect_out.p.y-1.0); irect.q.x = (int)(rect_out.q.x+1.0); irect.q.y = (int)(rect_out.q.y+1.0); - /* Need to expand the region to allow for the fact that the mitchell - * scaler reads multiple pixels in. This calculation can probably be - * improved. */ - /* If mi.{xx,yy} > 1 then we are downscaling. During downscaling, - * the support increases to ensure that we don't lose pixels contributions - * entirely. */ - /* I do not understand the need for the +/- 1 fudge factors, - * but they seem to be required. Increasing the render rectangle can - * never be bad at least... RJW */ - { - float support = any_abs(mi.xx); - int isupport; - if (any_abs(mi.yy) > support) - support = any_abs(mi.yy); - if (any_abs(mi.xy) > support) - support = any_abs(mi.xy); - if (any_abs(mi.yx) > support) - support = any_abs(mi.yx); - isupport = (int)(MAX_ISCALE_SUPPORT * (support+1)) + 1; - irect.p.x -= isupport; - irect.p.y -= isupport; - irect.q.x += isupport; - irect.q.y += isupport; - } + /* We therefore only need to render within irect. Restrict rrect to this. */ if (penum->rrect.x < irect.p.x) { penum->rrect.w -= irect.p.x - penum->rrect.x; if (penum->rrect.w < 0) @@ -432,18 +477,75 @@ if (penum->rrect.h < 0) penum->rrect.h = 0; } + /* Need to expand the region to allow for the fact that the mitchell + * scaler reads multiple pixels in. */ + /* If mi.{xx,yy} > 1 then we are downscaling. During downscaling, + * the support increases to ensure that we don't lose pixels contributions + * entirely. */ + /* I do not understand the need for the +/- 1 fudge factors, + * but they seem to be required. Increasing the decode rectangle can + * never be bad at least... RJW */ + { + float support = any_abs(mi.xx); + int isupport; + if (any_abs(mi.yy) > support) + support = any_abs(mi.yy); + if (any_abs(mi.xy) > support) + support = any_abs(mi.xy); + if (any_abs(mi.yx) > support) + support = any_abs(mi.yx); + isupport = (int)(MAX_ISCALE_SUPPORT * (support+1)) + 1; + irect.p.x -= isupport; + irect.p.y -= isupport; + irect.q.x += isupport; + irect.q.y += isupport; + } + if (penum->drect.x < irect.p.x) { + penum->drect.w -= irect.p.x - penum->drect.x; + if (penum->drect.w < 0) + penum->drect.w = 0; + penum->drect.x = irect.p.x; + } + if (penum->drect.x + penum->drect.w > irect.q.x) { + penum->drect.w = irect.q.x - penum->drect.x; + if (penum->drect.w < 0) + penum->drect.w = 0; + } + if (penum->drect.y < irect.p.y) { + penum->drect.h -= irect.p.y - penum->drect.y; + if (penum->drect.h < 0) + penum->drect.h = 0; + penum->drect.y = irect.p.y; + } + if (penum->drect.y + penum->drect.h > irect.q.y) { + penum->drect.h = irect.q.y - penum->drect.y; + if (penum->drect.h < 0) + penum->drect.h = 0; + } break; /* Out of the while */ } /* Check for the intersection being null */ - if (penum->rrect.x + penum->rrect.w <= penum->rect.x || - penum->rect.x + penum->rect.w <= penum->rrect.x || - penum->rrect.y + penum->rrect.h <= penum->rect.y || - penum->rect.y + penum->rect.h <= penum->rrect.y) + if (penum->drect.x + penum->drect.w <= penum->rect.x || + penum->rect.x + penum->rect.w <= penum->drect.x || + penum->drect.y + penum->drect.h <= penum->rect.y || + penum->rect.y + penum->rect.h <= penum->drect.y) { /* Something may have gone wrong with the floating point above. * set the region to something sane. */ - penum->rrect.x = penum->rect.x; - penum->rrect.y = penum->rect.y; + penum->drect.x = penum->rect.x; + penum->drect.y = penum->rect.y; + penum->drect.w = 0; + penum->drect.h = 0; + } + if (penum->rrect.x + penum->rrect.w <= penum->drect.x || + penum->drect.x + penum->drect.w <= penum->rrect.x || + penum->rrect.y + penum->rrect.h <= penum->drect.y || + penum->drect.y + penum->drect.h <= penum->rrect.y) + { + /* Something may have gone wrong with the floating point above. + * set the region to something sane. */ + penum->rrect.x = penum->drect.x; + penum->rrect.y = penum->drect.y; penum->rrect.w = 0; penum->rrect.h = 0; } @@ -455,7 +557,7 @@ penum->matrix.yy = mat.yy; penum->matrix.tx = mat.tx; penum->matrix.ty = mat.ty; - if_debug6m('b', pis->memory, " [%g %g %g %g %g %g]\n", + if_debug6m('b', mem, " [%g %g %g %g %g %g]\n", mat.xx, mat.xy, mat.yx, mat.yy, mat.tx, mat.ty); /* following works for 1, 2, 4, 8, 12, 16 */ index_bps = (bps < 8 ? bps >> 1 : (bps >> 2) + 1); @@ -514,6 +616,10 @@ eliminate the 256 bytes for the >8bpp image enumerator */ penum->clues = (gx_image_clue*) gs_alloc_bytes(mem, sizeof(gx_image_clue)*256, "gx_image_enum_begin"); + if (penum->clues == NULL) { + code = gs_error_VMerror; + goto fail; + } penum->icolor0 = &(penum->clues[0].dev_color); penum->icolor1 = &(penum->clues[255].dev_color); } else { @@ -522,8 +628,8 @@ } if (masked) { /* This is imagemask. */ if (bps != 1 || pcs != NULL || penum->alpha || decode[0] == decode[1]) { - gs_free_object(mem, penum, "gx_default_begin_image"); - return_error(gs_error_rangecheck); + code = gs_error_rangecheck; + goto fail; } /* Initialize color entries 0 and 255. */ set_nonclient_dev_color(penum->icolor0, gx_no_color_index); @@ -542,8 +648,8 @@ spp = cs_num_components(pcs); if (spp < 0) { /* Pattern not allowed */ - gs_free_object(mem, penum, "gx_default_begin_image"); - return_error(gs_error_rangecheck); + code = gs_error_rangecheck; + goto fail; } if (penum->alpha) ++spp; @@ -563,25 +669,32 @@ if (pcs->cmm_icc_profile_data != NULL) { device_color = false; } else { - device_color = (*pcst->concrete_space) (pcs, pis) == pcs; + device_color = (*pcst->concrete_space) (pcs, pgs) == pcs; } - image_init_colors(penum, bps, spp, format, decode, pis, dev, + code = image_init_colors(penum, bps, spp, format, decode, pgs, dev, pcs, &device_color); + if (code < 0) { + gs_free_object(mem, penum->clues, "gx_image_enum_begin"); + gs_free_object(mem, penum, "gx_default_begin_image"); + return gs_throw(code, "Image colors initialization failed"); + } /* If we have a CIE based color space and the icc equivalent profile is not yet set, go ahead and handle that now. It may already be done due to the above init_colors which may go through remap. */ if (gs_color_space_is_PSCIE(pcs) && pcs->icc_equivalent == NULL) { - gs_colorspace_set_icc_equivalent((gs_color_space *)pcs, &(penum->icc_setup.is_lab), - pis->memory); + code = gs_colorspace_set_icc_equivalent((gs_color_space *)pcs, &(penum->icc_setup.is_lab), + pgs->memory); + if (code < 0) + goto fail; if (penum->icc_setup.is_lab) { /* Free what ever profile was created and use the icc manager's cielab profile */ gs_color_space *curr_pcs = (gs_color_space *)pcs; rc_decrement(curr_pcs->icc_equivalent,"gx_image_enum_begin"); - rc_decrement(curr_pcs->cmm_icc_profile_data,"gx_image_enum_begin"); - curr_pcs->cmm_icc_profile_data = pis->icc_manager->lab_profile; - rc_increment(curr_pcs->cmm_icc_profile_data); + gsicc_adjust_profile_rc(curr_pcs->cmm_icc_profile_data, -1,"gx_image_enum_begin"); + curr_pcs->cmm_icc_profile_data = pgs->icc_manager->lab_profile; + gsicc_adjust_profile_rc(curr_pcs->cmm_icc_profile_data, 1,"gx_image_enum_begin"); } } /* Try to transform non-default RasterOps to something */ @@ -648,8 +761,8 @@ bsize = ((bps > 8 ? width * 2 : width) + 15) * spp; buffer = gs_alloc_bytes(mem, bsize, "image buffer"); if (buffer == 0) { - gs_free_object(mem, penum, "gx_default_begin_image"); - return_error(gs_error_VMerror); + code = gs_error_VMerror; + goto fail; } penum->bps = bps; penum->unpack_bps = bps; @@ -680,19 +793,19 @@ * the given sub-image, or else is constructing output out of * overlapping pieces. */ - penum->interpolate = pim->Interpolate; + penum->interpolate = force_interpolation ? interp_force : pim->Interpolate ? interp_on : interp_off; penum->x_extent = x_extent; penum->y_extent = y_extent; penum->posture = ((x_extent.y | y_extent.x) == 0 ? image_portrait : (x_extent.x | y_extent.y) == 0 ? image_landscape : image_skewed); - penum->pis = pis; + penum->pgs = pgs; penum->pcs = pcs; penum->memory = mem; penum->buffer = buffer; penum->buffer_size = bsize; - penum->line = 0; + penum->line = NULL; penum->icc_link = NULL; penum->color_cache = NULL; penum->ht_buffer = NULL; @@ -776,10 +889,10 @@ mty = (((mty + diff) | fixed_half) & -fixed_half) - diff; } } - if_debug5m('b', penum->memory, "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n", + if_debug5m('b', mem, "[b]Image: %sspp=%d, bps=%d, mt=(%g,%g)\n", (masked? "masked, " : ""), spp, bps, fixed2float(mtx), fixed2float(mty)); - if_debug9m('b', penum->memory, + if_debug9m('b', mem, "[b] cbox=(%g,%g),(%g,%g), obox=(%g,%g),(%g,%g), clip_image=0x%x\n", fixed2float(cbox.p.x), fixed2float(cbox.p.y), fixed2float(cbox.q.x), fixed2float(cbox.q.y), @@ -837,22 +950,52 @@ penum->y = 0; penum->used.x = 0; penum->used.y = 0; + if (penum->clip_image && pcpath) { /* Set up the clipping device. */ + gx_device_clip *cdev = + gs_alloc_struct(mem, gx_device_clip, + &st_device_clip, "image clipper"); + + if (cdev == NULL) { + code = gs_error_VMerror; + goto fail; + } + gx_make_clip_device_in_heap(cdev, pcpath, dev, mem); + penum->clip_dev = cdev; + penum->dev = (gx_device *)cdev; /* Will restore this in a mo. Hacky! */ + } + if (penum->use_rop) { /* Set up the RasterOp source device. */ + gx_device_rop_texture *rtdev; + + code = gx_alloc_rop_texture_device(&rtdev, mem, + "image RasterOp"); + if (code < 0) + return code; + /* The 'target' must not be NULL for gx_make_rop_texture_device */ + if (!penum->clip_dev && !dev) + return_error(gs_error_undefined); + + gx_make_rop_texture_device(rtdev, + (penum->clip_dev != 0 ? + (gx_device *) penum->clip_dev : + dev), lop, pdcolor); + gx_device_retain((gx_device *)rtdev, true); + penum->rop_dev = rtdev; + penum->dev = (gx_device *)rtdev; /* Will restore this in a mo. Hacky! */ + } { static sample_unpack_proc_t procs[2][6] = { { sample_unpack_1, sample_unpack_2, sample_unpack_4, sample_unpack_8, - 0, 0 + sample_unpack_12, sample_unpack_16 }, { sample_unpack_1_interleaved, sample_unpack_2_interleaved, sample_unpack_4_interleaved, sample_unpack_8_interleaved, - 0, 0 + sample_unpack_12, sample_unpack_16 }}; int num_planes = penum->num_planes; bool interleaved = (num_planes == 1 && penum->plane_depths[0] != penum->bps); int i; - procs[0][4] = procs[1][4] = sample_unpack_12_proc; - procs[0][5] = procs[1][5] = sample_unpack_16_proc; if (interleaved) { int num_components = penum->plane_depths[0] / penum->bps; @@ -864,61 +1007,28 @@ if (i == num_components) interleaved = false; /* Use single table. */ } - if (index_bps >= 4) { - if ((penum->unpack = procs[interleaved][index_bps]) == 0) { /* bps case not supported. */ - gx_default_end_image(dev, - (gx_image_enum_common_t *) penum, - false); - return_error(gs_error_rangecheck); - } - } else { - penum->unpack = procs[interleaved][index_bps]; - } - if_debug1m('b', penum->memory, "[b]unpack=%d\n", bps); + penum->unpack = procs[interleaved][index_bps]; + + if_debug1m('b', mem, "[b]unpack=%d\n", bps); /* Set up pixel0 for image class procedures. */ penum->dda.pixel0 = penum->dda.strip; + penum->skip_next_line = NULL; for (i = 0; i < gx_image_class_table_count; ++i) if ((penum->render = gx_image_class_table[i](penum)) != 0) break; + penum->dev = dev; /* Restore this (in case it was changed to cdev or rtdev) */ if (i == gx_image_class_table_count) { /* No available class can handle this image. */ - gx_default_end_image(dev, (gx_image_enum_common_t *) penum, - false); return_error(gs_error_rangecheck); } } - if (penum->clip_image && pcpath) { /* Set up the clipping device. */ - gx_device_clip *cdev = - gs_alloc_struct(mem, gx_device_clip, - &st_device_clip, "image clipper"); - - if (cdev == 0) { - gx_default_end_image(dev, - (gx_image_enum_common_t *) penum, - false); - return_error(gs_error_VMerror); - } - gx_make_clip_device_in_heap(cdev, pcpath, dev, mem); - penum->clip_dev = cdev; - } - if (penum->use_rop) { /* Set up the RasterOp source device. */ - gx_device_rop_texture *rtdev; - - code = gx_alloc_rop_texture_device(&rtdev, mem, - "image RasterOp"); - if (code < 0) { - gx_default_end_image(dev, (gx_image_enum_common_t *) penum, - false); - return code; - } - gx_make_rop_texture_device(rtdev, - (penum->clip_dev != 0 ? - (gx_device *) penum->clip_dev : - dev), lop, pdcolor); - gx_device_retain((gx_device *)rtdev, true); - penum->rop_dev = rtdev; - } return 0; + +fail: + gs_free_object(mem, buffer, "image buffer"); + gs_free_object(mem, penum->clues, "gx_image_enum_begin"); + gs_free_object(mem, penum, "gx_begin_image1"); + return code; } /* If a drawing color is black or white, return 0 or 1 respectively, */ @@ -1070,7 +1180,7 @@ for (kk = 0; kk < num_des_comp; kk++) { conc[kk] = gx_color_value_from_byte(psrc[kk]); } - cmap_transfer(&(conc[0]), penum->pis, penum->dev); + cmap_transfer(&(conc[0]), penum->pgs, penum->dev); for (kk = 0; kk < num_des_comp; kk++) { psrc[kk] = gx_color_value_to_byte(conc[kk]); } @@ -1154,7 +1264,7 @@ for (kk = 0; kk < num_des_comp; kk++) { conc[kk] = gx_color_value_from_byte(byte_ptr[kk]); } - cmap_transfer(&(conc[0]), penum->pis, penum->dev); + cmap_transfer(&(conc[0]), penum->pgs, penum->dev); for (kk = 0; kk < num_des_comp; kk++) { byte_ptr[kk] = gx_color_value_to_byte(conc[kk]); } @@ -1208,13 +1318,13 @@ } /* Initialize the color mapping tables for a non-mask image. */ -static void +static int image_init_colors(gx_image_enum * penum, int bps, int spp, gs_image_format_t format, const float *decode /*[spp*2] */ , - const gs_imager_state * pis, gx_device * dev, + const gs_gstate * pgs, gx_device * dev, const gs_color_space * pcs, bool * pdcb) { - int ci, decode_type; + int ci, decode_type, code; static const float default_decode[] = { 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0 }; @@ -1304,20 +1414,28 @@ for (i = 15 - step; i > 0; i -= step) pmap->decode_lookup[i] = pmap->decode_base + i * (255.0 / 15) * pmap->decode_factor; - } else + pmap->inverted = 0; + } else { pmap->decoding = sd_compute; + pmap->inverted = 0; + } if (spp == 1) { /* and ci == 0 *//* Pre-map entries 0 and 255. */ gs_client_color cc; /* Image clues are used in this case */ cc.paint.values[0] = real_decode[0]; - (*pcs->type->remap_color) (&cc, pcs, penum->icolor0, - pis, dev, gs_color_select_source); + code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor0, + pgs, dev, gs_color_select_source); + if (code < 0) + return code; cc.paint.values[0] = real_decode[1]; - (*pcs->type->remap_color) (&cc, pcs, penum->icolor1, - pis, dev, gs_color_select_source); + code = (*pcs->type->remap_color) (&cc, pcs, penum->icolor1, + pgs, dev, gs_color_select_source); + if (code < 0) + return code; } } + return 0; } /* Construct a mapping table for sample values. */ /* map_size is 2, 4, 16, or 256. Note that 255 % (map_size - 1) == 0, */ @@ -1369,12 +1487,12 @@ /* Used to indicate for ICC procesing if we have decoding to do */ bool -gx_has_transfer(const gs_imager_state *pis, int num_comps) +gx_has_transfer(const gs_gstate *pgs, int num_comps) { int k; for (k = 0; k < num_comps; k++) { - if (pis->effective_transfer[k]->proc != gs_identity_transfer) { + if (pgs->effective_transfer[k]->proc != gs_identity_transfer) { return(true); } } diff -Nru ghostscript-9.10~dfsg/base/gxiscale.c ghostscript-9.25~dfsg+1/base/gxiscale.c --- ghostscript-9.10~dfsg/base/gxiscale.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxiscale.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -30,7 +30,7 @@ #include "gxdevice.h" #include "gxcmap.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdevmem.h" #include "gxcpath.h" #include "gximage.h" @@ -38,7 +38,6 @@ #include "siinterp.h" /* for spatial interpolation */ #include "siscale.h" /* for Mitchell filtering */ #include "sidscale.h" /* for special case downscale filter */ -#include "vdtrace.h" #include "gscindex.h" /* included for proper handling of index color spaces and keeping data in source color space */ #include "gxcolor2.h" /* define of float_color_to_byte_color */ @@ -47,6 +46,7 @@ #include "gsicc_manage.h" #include "gsicc.h" #include "gxdevsop.h" +#include /* For INT_MAX */ static void decode_sample_frac_to_float(gx_image_enum *penum, frac sample_value, gs_client_color *cc, int i); @@ -67,8 +67,110 @@ initialized and allocates buffer space if needed */ static irender_proc(image_render_interpolate); static irender_proc(image_render_interpolate_icc); +static irender_proc(image_render_interpolate_masked); +static irender_proc(image_render_interpolate_masked_hl); static irender_proc(image_render_interpolate_landscape); static irender_proc(image_render_interpolate_landscape_icc); +static irender_proc(image_render_interpolate_landscape_masked); +static irender_proc(image_render_interpolate_landscape_masked_hl); + +#if 0 // Unused now, but potentially useful in the future +static bool +is_high_level_device(gx_device *dev) +{ + char data[] = "HighLevelDevice"; + dev_param_req_t request; + gs_c_param_list list; + int highlevel = 0; + int code; + + gs_c_param_list_write(&list, dev->memory); + /* Stuff the data into a structure for passing to the spec_op */ + request.Param = data; + request.list = &list; + code = dev_proc(dev, dev_spec_op)(dev, gxdso_get_dev_param, &request, sizeof(dev_param_req_t)); + if (code < 0 && code != gs_error_undefined) { + gs_c_param_list_release(&list); + return 0; + } + gs_c_param_list_read(&list); + code = param_read_bool((gs_param_list *)&list, + "HighLevelDevice", + &highlevel); + gs_c_param_list_release(&list); + if (code < 0) + return 0; + + return highlevel; +} +#endif + +static bool +device_allows_imagemask_interpolation(gx_device *dev) +{ + char data[] = "NoInterpolateImagemasks"; + dev_param_req_t request; + gs_c_param_list list; + int nointerpolate = 0; + int code; + + gs_c_param_list_write(&list, dev->memory); + /* Stuff the data into a structure for passing to the spec_op */ + request.Param = data; + request.list = &list; + code = dev_proc(dev, dev_spec_op)(dev, gxdso_get_dev_param, &request, sizeof(dev_param_req_t)); + if (code < 0 && code != gs_error_undefined) { + gs_c_param_list_release(&list); + return 0; + } + gs_c_param_list_read(&list); + code = param_read_bool((gs_param_list *)&list, + "NoInterpolateImagemasks", + &nointerpolate); + gs_c_param_list_release(&list); + if (code < 0) + return 0; + + return !nointerpolate; +} + +#define DC_IS_NULL(pdc)\ + (gx_dc_is_pure(pdc) && (pdc)->colors.pure == gx_no_color_index) + +/* Returns < 0 for error, 0 for pure color, 1 for high level */ +static int mask_suitable_for_interpolation(gx_image_enum *penum) +{ + gx_device_color * const pdc1 = penum->icolor1; + int code; + int high_level_color = 1; + + if (gx_device_must_halftone(penum->dev)) { + /* We don't interpolate when going to 1bpp outputs */ + return -1; + } else if (gx_dc_is_pure(pdc1) && (pdc1)->colors.pure != gx_no_color_index && + dev_proc(penum->dev, copy_alpha) != NULL && + dev_proc(penum->dev, copy_alpha) != gx_no_copy_alpha) { + /* We have a 'pure' color, and a valid copy_alpha. We can work with that. */ + high_level_color = 0; + } else if (dev_proc(penum->dev, copy_alpha_hl_color) == gx_default_no_copy_alpha_hl_color) { + /* No copy_alpha_hl_color. We're out of luck. */ + return -1; + } else if ((code = gx_color_load(pdc1, penum->pgs, penum->dev)) < 0) { + /* Otherwise we'll need to load the color value. If this gives an + * error, we can't cope. */ + return -1; + } else if (!gx_dc_is_devn(pdc1)) { + /* If it's not a devn color, then we're really out of luck. */ + return -1; + } + + /* Never turn this on for devices that disallow it (primarily + * high level devices) */ + if (!device_allows_imagemask_interpolation(penum->dev)) + return -1; + + return high_level_color; +} irender_proc_t gs_image_class_0_interpolate(gx_image_enum * penum) @@ -84,46 +186,94 @@ int num_des_comps; cmm_dev_profile_t *dev_profile; int code; - - if (!penum->interpolate) + gx_color_polarity_t pol = GX_CINFO_POLARITY_UNKNOWN; + int mask_col_high_level = 0; + int interpolate_control = penum->dev->interpolate_control; + int abs_interp_limit = max(1, any_abs(interpolate_control)); + int limited_WidthOut, limited_HeightOut; + + if (interpolate_control < 0) + penum->interpolate = interp_on; /* not the same as "interp_force" -- threshold still used */ + if (interpolate_control == interp_off || penum->interpolate == interp_off) { + penum->interpolate = interp_off; + return 0; + } + if (penum->masked && (mask_col_high_level = mask_suitable_for_interpolation(penum)) < 0) { + penum->interpolate = interp_off; return 0; + } if (penum->use_mask_color || (penum->posture != image_portrait && penum->posture != image_landscape) || - penum->masked || penum->alpha) { + penum->alpha) { /* We can't handle these cases yet. Punt. */ - penum->interpolate = false; + penum->interpolate = interp_off; return 0; } if (penum->Width == 0 || penum->Height == 0) { - penum->interpolate = false; /* No need to interpolate and */ + penum->interpolate = interp_off; /* No need to interpolate and */ return 0; /* causes division by 0 if we try. */ } - if ( pcs->cmm_icc_profile_data != NULL ) { - use_icc = true; - } - if ( pcs->type->index == gs_color_space_index_Indexed) { - if ( pcs->base_space->cmm_icc_profile_data != NULL) { - use_icc = true; - } + if (penum->Width == 1 && penum->Height == 1) { + penum->interpolate = interp_off; /* No need to interpolate */ + return 0; } - if (!(penum->bps <= 8 || penum->bps == 16)) { - use_icc = false; + if (any_abs(penum->dst_width) < 0 || any_abs(penum->dst_height) < 0) + { + /* A calculation has overflowed. Bale */ + return 0; } - /* Do not allow mismatch in devices component output with the - profile output size. For example sep device with CMYK profile should - not go through the fast method */ - code = dev_proc(penum->dev, get_profile)(penum->dev, &dev_profile); - num_des_comps = gsicc_get_device_profile_comps(dev_profile); - if (num_des_comps != penum->dev->color_info.num_components) { - use_icc = false; + if (penum->x_extent.x == INT_MIN || penum->x_extent.x == INT_MAX || + penum->x_extent.y == INT_MIN || penum->x_extent.y == INT_MAX || + penum->y_extent.x == INT_MIN || penum->y_extent.x == INT_MAX || + penum->y_extent.y == INT_MIN || penum->y_extent.y == INT_MAX) + { + /* A calculation has overflowed. Bail */ + return 0; } - /* If the device has some unique color mapping procs due to its color space, - then we will need to use those and go through pixel by pixel instead - of blasting through buffers. This is true for example with many of - the color spaces for CUPs */ - if(!gx_device_uses_std_cmap_procs(penum->dev, penum->pis)) { + + if (penum->masked) { + abs_interp_limit = 1; /* ignore this for masked images for now */ use_icc = false; + num_des_comps = 1; + if (pcs) + pol = cs_polarity(pcs); + else + pol = GX_CINFO_POLARITY_ADDITIVE; + } else { + if (pcs == NULL) + return 0; /* can't handle this */ + if (pcs->cmm_icc_profile_data != NULL) { + use_icc = true; + } + if (pcs->type->index == gs_color_space_index_Indexed) { + if (pcs->base_space->cmm_icc_profile_data != NULL) { + use_icc = true; + } + } + if (!(penum->bps <= 8 || penum->bps == 16)) { + use_icc = false; + } + /* Do not allow mismatch in devices component output with the + profile output size. For example sep device with CMYK profile should + not go through the fast method */ + code = dev_proc(penum->dev, get_profile)(penum->dev, &dev_profile); + if (code) { + penum->interpolate = interp_off; + return 0; + } + num_des_comps = gsicc_get_device_profile_comps(dev_profile); + if (num_des_comps != penum->dev->color_info.num_components || + dev_profile->usefastcolor == true) { + use_icc = false; + } + /* If the device has some unique color mapping procs due to its color space, + then we will need to use those and go through pixel by pixel instead + of blasting through buffers. This is true for example with many of + the color spaces for CUPs */ + if(!gx_device_uses_std_cmap_procs(penum->dev, penum->pgs)) { + use_icc = false; + } } /* * USE_CONSERVATIVE_INTERPOLATION_RULES is normally NOT defined since @@ -144,21 +294,25 @@ if (penum->bps < 4 || penum->bps * penum->spp < 8 || (fabs(penum->matrix.xx) <= 5 && fabs(penum->matrix.yy <= 5)) ) { - penum->interpolate = false; + penum->interpolate = interp_off; return 0; } #endif - if (use_icc) { + iss.abs_interp_limit = abs_interp_limit; + if (penum->masked) { + iss.BitsPerComponentOut = 8; + iss.MaxValueOut = 0xff; + } else if (use_icc) { iss.BitsPerComponentOut = 16; iss.MaxValueOut = 0xffff; } else { iss.BitsPerComponentOut = sizeof(frac) * 8; iss.MaxValueOut = frac_1; } - iss.PatchWidthIn = penum->rrect.w; - iss.PatchHeightIn = penum->rrect.h; - iss.LeftMarginIn = penum->rrect.x - penum->rect.x; - iss.TopMargin = penum->rrect.y - penum->rect.y; + iss.PatchWidthIn = penum->drect.w; + iss.PatchHeightIn = penum->drect.h; + iss.LeftMarginIn = penum->drect.x - penum->rect.x; + iss.TopMarginIn = penum->drect.y - penum->rect.y; if (penum->posture == image_portrait) { fixed dw = any_abs(penum->dst_width); fixed dh = any_abs(penum->dst_height); @@ -172,15 +326,16 @@ dh / penum->Height)); iss.EntireWidthOut = fixed2int_pixround(dw); iss.EntireHeightOut = fixed2int_pixround(dh); + iss.TopMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y - penum->rect.y) * + dh / penum->Height)); + iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.h * + dh / penum->Height)) + - iss.TopMarginOut; iss.PatchWidthOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x + penum->rrect.w) * dw / penum->Width)) - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.x * dw / penum->Width)); - iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y + penum->rrect.h) * - dh / penum->Height)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.y * - dh / penum->Height)); - iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)iss.LeftMarginIn * + iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x - penum->rect.x) * dw / penum->Width)); } else { fixed dw = any_abs(penum->dst_width); @@ -195,19 +350,19 @@ dw / penum->Height)); iss.EntireWidthOut = fixed2int_pixround(dh); iss.EntireHeightOut = fixed2int_pixround(dw); + iss.TopMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y - penum->rect.y) * + dw / penum->Height)); + iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.h * + dw / penum->Height)) + - iss.TopMarginOut; iss.PatchWidthOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x + penum->rrect.w) * dh / penum->Width)) - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.x * dh / penum->Width)); - iss.PatchHeightOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.y + penum->rrect.h) * - dw / penum->Height)) - - fixed2int_pixround_perfect((fixed)((int64_t)penum->rrect.y * - dw / penum->Height)); - iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)iss.LeftMarginIn * + iss.LeftMarginOut = fixed2int_pixround_perfect((fixed)((int64_t)(penum->rrect.x - penum->rect.x) * dh / penum->Width)); } iss.PatchWidthOut = any_abs(iss.PatchWidthOut); - iss.PatchHeightOut = any_abs(iss.PatchHeightOut); if (iss.LeftMarginOut + iss.PatchWidthOut >= iss.WidthOut) { iss.LeftMarginOut = iss.WidthOut - iss.PatchWidthOut; if (iss.LeftMarginOut < 0) { @@ -222,25 +377,64 @@ iss.HeightIn = penum->rect.h; iss.WidthOut = any_abs(iss.WidthOut); iss.HeightOut = any_abs(iss.HeightOut); + limited_WidthOut = (iss.WidthOut + abs_interp_limit - 1)/abs_interp_limit; + limited_HeightOut = (iss.HeightOut + abs_interp_limit - 1)/abs_interp_limit; if ((penum->posture == image_portrait ? penum->dst_width : penum->dst_height) < 0) iss.LeftMarginOut = iss.WidthOut - iss.LeftMarginOut - iss.PatchWidthOut; /* For interpolator cores that don't set Active, have us always active */ iss.Active = 1; if (iss.EntireWidthOut == 0 || iss.EntireHeightOut == 0) { - penum->interpolate = false; + penum->interpolate = interp_off; return 0; } - /* If we are in an indexed space then we need to use the number of components - in the base space. Otherwise we use the number of components in the source space */ - if (pcs->type->index == gs_color_space_index_Indexed) { - /* Use the number of colors in the base space */ - iss.spp_decode = cs_num_components(pcs->base_space); + if (penum->masked) { + iss.spp_decode = 1; + } else { + /* If we are in an indexed space then we need to use the number of components + in the base space. Otherwise we use the number of components in the source space */ + if (pcs->type->index == gs_color_space_index_Indexed) { + /* Use the number of colors in the base space */ + iss.spp_decode = cs_num_components(pcs->base_space); + } else { + /* Use the number of colors that exist in the source space + as this is where we are doing our interpolation */ + iss.spp_decode = cs_num_components(pcs); + } + } + /* Set up the filter template. May be changed for "Special" downscaling */ +#ifdef USE_MITCHELL_FILTER + templat = &s_IScale_template; +#else + templat = &s_IIEncode_template; +#endif + + if ((iss.WidthOut < iss.WidthIn) && + (iss.HeightOut < iss.HeightIn) && /* downsampling */ + (pol != GX_CINFO_POLARITY_UNKNOWN) && + (dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_antidropout, NULL, 0) > 0)) { + /* Special case handling for when we are downsampling to a dithered + * device. The point of this non-linear downsampling is to preserve + * dark pixels from the source image to avoid dropout. The color + * polarity is used for this. */ + templat = &s_ISpecialDownScale_template; } else { - /* Use the number of colors that exist in the source space - as this is where we are doing our interpolation */ - iss.spp_decode = cs_num_components(pcs); + /* No interpolation unless we exceed the device selected minimum */ + int threshold = dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_threshold, NULL, 0); + + if ((iss.WidthOut == iss.WidthIn && iss.HeightOut == iss.HeightIn) || + ((penum->interpolate != interp_force) && + (threshold > 0) && + (iss.WidthOut < iss.WidthIn * threshold) && + (iss.HeightOut < iss.HeightIn * threshold))) { + penum->interpolate = interp_off; + return 0; /* don't interpolate if not scaled up enough */ + } } + /* The SpecialDownScale filter needs polarity, either ADDITIVE or SUBTRACTIVE */ + /* UNKNOWN case (such as for palette colors) has been handled above */ + iss.ColorPolarityAdditive = (pol == GX_CINFO_POLARITY_ADDITIVE); + if (iss.HeightOut > iss.EntireHeightIn && use_icc) { iss.early_cm = true; iss.spp_interp = num_des_comps; @@ -259,25 +453,23 @@ It is handed here to us in 8 bit form already decoded. */ iss.BitsPerComponentIn = 8; iss.MaxValueIn = 0xff; - /* If it is an index color space we will need to allocate for - the decoded data */ - if (pcs->type->index == gs_color_space_index_Indexed) { + if (penum->masked) { in_size = iss.WidthIn * iss.spp_decode; } else { - /* Non indexed case, we either use the data as - is, or allocate space if it is reversed in X */ + /* We either use the data as is, or allocate space if it is + reversed in X or if the colorspace requires it */ /* Do we need a buffer for reversing each scan line? */ bool reverse = (penum->posture == image_portrait ? penum->matrix.xx : penum->matrix.xy) < 0; in_size = (reverse ? iss.WidthIn * iss.spp_decode : 0); /* If it is not reversed, and we have 8 bit/color channel data then - no need to allocate extra as we will use the source directly */ - /* However, if we have a nonstandard encoding and are in - a device color space we will need to allocate - in that case also. We will maintain 8 bits but - do the decode and then interpolate. This is OK - for the linear decode */ - if (!penum->device_color && !gs_color_space_is_CIE(pcs)){ + we may not need to allocate extra as we will use the source directly. + However, if we have a nonstandard encoding and are in a device + color space we will need to allocate in that case also. We will + maintain 8 bits but do the decode and then interpolate. + This is OK for the linear decode + */ + if (!penum->device_color || pcs->type->index > gs_color_space_index_DeviceCMYK) { in_size = iss.WidthIn * iss.spp_decode; } } @@ -295,38 +487,13 @@ align_bitmap_mod); /* Size to allocate space to store the input as frac type */ } -#ifdef USE_MITCHELL_FILTER - templat = &s_IScale_template; -#else - templat = &s_IIEncode_template; -#endif - if ((iss.WidthOut < iss.WidthIn) && - (iss.HeightOut < iss.HeightIn) && /* downsampling */ - (penum->dev->color_info.polarity != GX_CINFO_POLARITY_UNKNOWN) && - (dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_antidropout, NULL, 0) > 0)) { - /* Special case handling for when we are downsampling (to a dithered - * device. The point of this non-linear downsampling is to preserve - * dark pixels from the source image to avoid dropout. The color - * polarity is used for this. */ - templat = &s_ISpecialDownScale_template; - } else { - int threshold = dev_proc(penum->dev, dev_spec_op)(penum->dev, gxdso_interpolate_threshold, NULL, 0); - if ((threshold > 0) && - (iss.WidthOut < iss.WidthIn * threshold) && - (iss.HeightOut < iss.HeightIn * threshold)) { - penum->interpolate = false; - return 0; /* no interpolation / downsampling */ - } - } - /* The SpecialDownScale filter needs polarity, either ADDITIVE or SUBTRACTIVE */ - /* UNKNOWN case (such as for palette colors) has been handled above */ - iss.ColorPolarityAdditive = - penum->dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE; - /* Allocate a buffer for one source/destination line. */ + /* Allocate a buffer for one source/destination line. */ + /* NB: The out_size is for full device res, regardless of abs_interp_limit */ + /* since we will expand into that area in the x-loop */ { - uint out_size = - iss.WidthOut * max(iss.spp_interp * (iss.BitsPerComponentOut / 8), - arch_sizeof_color_index); + uint out_size = iss.WidthOut * max(iss.spp_interp * ((iss.BitsPerComponentOut) / 8), + ARCH_SIZEOF_COLOR_INDEX); + /* Allocate based upon frac size (as BitsPerComponentOut=16) output scan line input plus output. The outsize may have an adjustment for word boundary on it. Need to account for that now */ @@ -343,7 +510,7 @@ gs_free_object(mem, pss, "image scale state"); gs_free_object(mem, line, "image scale src+dst line"); /* Try again without interpolation. */ - penum->interpolate = false; + penum->interpolate = interp_off; return 0; } penum->line = line; /* Set to the input and output buffer */ @@ -373,8 +540,24 @@ (fixed)((int64_t)x0 * penum->dst_height / penum->Width)); } + /* If the InterpolationControl specifies interpolation to less than full device res */ + /* Set up a scaling DDA to control scaling back to desired image size. */ + if (abs_interp_limit > 1) { + dda_init(pss->params.scale_dda.x, 0, iss.WidthOut, limited_WidthOut); + dda_init(pss->params.scale_dda.y, 0, iss.HeightOut, limited_HeightOut); + } if_debug0m('b', penum->memory, "[b]render=interpolate\n"); - if (use_icc) { + if (penum->masked) { + if (!mask_col_high_level) { + return (penum->posture == image_portrait ? + &image_render_interpolate_masked : + &image_render_interpolate_landscape_masked); + } else { + return (penum->posture == image_portrait ? + &image_render_interpolate_masked_hl : + &image_render_interpolate_landscape_masked_hl); + } + } else if (use_icc) { /* Set up the link now */ const gs_color_space *pcs; gsicc_rendering_param_t rendering_params; @@ -390,11 +573,11 @@ } } /* Define the rendering intents */ - rendering_params.black_point_comp = penum->pis->blackptcomp; + rendering_params.black_point_comp = penum->pgs->blackptcomp; rendering_params.graphics_type_tag = GS_IMAGE_TAG; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = penum->pis->renderingintent; + rendering_params.rendering_intent = penum->pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; if (gs_color_space_is_PSCIE(penum->pcs) && penum->pcs->icc_equivalent != NULL) { pcs = penum->pcs->icc_equivalent; @@ -409,16 +592,16 @@ penum->icc_setup.is_lab = pcs->cmm_icc_profile_data->islab; if (penum->icc_setup.is_lab) penum->icc_setup.need_decode = false; penum->icc_setup.must_halftone = gx_device_must_halftone(penum->dev); - penum->icc_setup.has_transfer = - gx_has_transfer(penum->pis, num_des_comps); + penum->icc_setup.has_transfer = + gx_has_transfer(penum->pgs, num_des_comps); if (penum->icc_link == NULL) { - penum->icc_link = gsicc_get_link(penum->pis, penum->dev, pcs, NULL, + penum->icc_link = gsicc_get_link(penum->pgs, penum->dev, pcs, NULL, &rendering_params, penum->memory); } /* We need to make sure that we do the proper unpacking proc if we are doing 16 bit */ if (penum->bps == 16) { - penum->unpack = sample_unpackicc_16_proc; + penum->unpack = sample_unpackicc_16; } return (penum->posture == image_portrait ? &image_render_interpolate_icc : @@ -437,27 +620,37 @@ application of color management. */ static void initial_decode(gx_image_enum * penum, const byte * buffer, int data_x, int h, - bool need_decode, stream_cursor_read *stream_r, bool is_icc) + stream_cursor_read *stream_r, bool is_icc) { stream_image_scale_state *pss = penum->scaler; - const gs_imager_state *pis = penum->pis; const gs_color_space *pcs = penum->pcs; - gs_logical_operation_t lop = penum->log_op; int spp_decode = pss->params.spp_decode; - stream_cursor_write w; - unsigned char index_space; byte *out = penum->line; - int reversed = (penum->posture == image_portrait ? penum->matrix.xx : penum->matrix.xy) < 0; + bool need_decode; + int reversed = + (penum->posture == image_portrait ? penum->matrix.xx : penum->matrix.xy) < 0; + /* If cs is neither a device color nor a CIE color then for an image case + it is going to be deviceN, sep, or index. */ + bool is_devn_sep_index = + (!(penum->device_color) && !gs_color_space_is_CIE(pcs)); + + /* Determine if we need to perform any decode procedures */ + if (is_icc) { + /* In icc case, decode upfront occurs if specified by icc setup or if + cs is neither a device color nor a CIE color (i.e. if it's DeviceN, + Index or Separation) The color space cannot be a pattern for an image */ + need_decode = (penum->icc_setup.need_decode || is_devn_sep_index); + } else + need_decode = is_devn_sep_index; if (h != 0) { /* Convert the unpacked data to concrete values in the source buffer. */ int sizeofPixelIn = pss->params.BitsPerComponentIn / 8; uint row_size = pss->params.WidthIn * spp_decode * sizeofPixelIn; /* raw input data */ - const int raw_size = (pcs->type->index == gs_color_space_index_Indexed ? + const int raw_size = (pcs != NULL && pcs->type->index == gs_color_space_index_Indexed ? 1 : spp_decode); const unsigned char *bdata = buffer + data_x * raw_size * sizeofPixelIn; - index_space = 0; /* We have the following cases to worry about 1) Device 8 bit color but not indexed (e.g. ICC). Apply CMM after interpolation if needed. @@ -469,7 +662,7 @@ will then be in same state as 3. */ if (sizeofPixelIn == 1) { - if (pcs->type->index != gs_color_space_index_Indexed) { + if (pcs == NULL || pcs->type->index != gs_color_space_index_Indexed) { /* An issue here is that we may not be "device color" due to how the data is encoded. Need to check for that case here */ /* Decide here if we need to decode or not. Essentially, as @@ -483,7 +676,7 @@ /* 8-bit color values, possibly device indep. or device depend., not indexed. Decode range was [0 1] */ if (!reversed) { - /* Use the input data directly. sets up data in the + /* Use the input data directly. sets up data in the stream buffer structure */ stream_r->ptr = bdata - 1; } else { @@ -492,12 +685,10 @@ byte *q = out; int i; - for (i = 0; i < pss->params.WidthIn; + for (i = 0; i < pss->params.WidthIn; p -= spp_decode, q += spp_decode, ++i) memcpy(q, p, spp_decode); stream_r->ptr = out - 1; - out += round_up(pss->params.WidthIn * - spp_decode, align_bitmap_mod); } } else { /* We need to do some decoding. Data will remain in 8 bits @@ -525,8 +716,6 @@ } pdata += dpd; } - out += round_up(pss->params.WidthIn * spp_decode, - align_bitmap_mod); } } else { /* indexed 8 bit color values, possibly a device indep. or @@ -545,7 +734,6 @@ max_range = (penum->map[0].decode_factor < 0 ? penum->map[0].decode_base : penum->map[0].decode_base + 255.0 * penum->map[0].decode_factor); - index_space = 1; /* flip the horizontal direction if indicated by the matrix value */ if (reversed) { pdata += (pss->params.WidthIn - 1) * dpd; @@ -588,19 +776,13 @@ pdata += dpd; /* Can't have just ++ since we could be going backwards */ } - /* We need to set the output to the end of the input buffer - moving it to the next desired word boundary. This must - be accounted for in the memory allocation of - gs_image_class_0_interpolate */ - out += round_up(pss->params.WidthIn * spp_decode, - align_bitmap_mod); } } else { /* More than 8-bits/color values */ /* Even in this case we need to worry about an indexed color space. We need to get to the base color space for the interpolation and then if necessary do the remap to the device space */ - if (pcs->type->index != gs_color_space_index_Indexed) { + if (pcs == NULL || pcs->type->index != gs_color_space_index_Indexed) { int bps = penum->bps; int dc = penum->spp; const byte *pdata = bdata; @@ -626,28 +808,26 @@ stream_r->ptr = (byte *) pdata - 1; } } else { - for (i = 0; i < pss->params.WidthIn; i++, - psrc += spp_decode) { - /* Lets get directly to a frac type loaded into psrc, - and do the interpolation in the source space. Then we - will do the appropriate remap function after - interpolation. */ - for (j = 0; j < dc; ++j) { - DECODE_FRAC_FRAC(((const frac *)pdata)[j], psrc[j], j); - } - pdata += dpd; + if (sizeof(frac) * dc == dpd) { + stream_r->ptr = (byte *) pdata - 1; + } else { + for (i = 0; i < pss->params.WidthIn; i++, + psrc += spp_decode) { + for (j = 0; j < dc; ++j) { + psrc[j] = ((const frac *)pdata)[j]; + } + pdata += dpd; #ifdef DEBUG - if (gs_debug_c('B')) { - int ci; + if (gs_debug_c('B')) { + int ci; - for (ci = 0; ci < spp_decode; ++ci) - dmprintf2(penum->memory, "%c%04x", (ci == 0 ? ' ' : ','), psrc[ci]); - } + for (ci = 0; ci < spp_decode; ++ci) + dmprintf2(penum->memory, "%c%04x", (ci == 0 ? ' ' : ','), psrc[ci]); + } #endif + } } } - out += round_up(pss->params.WidthIn * spp_decode * sizeof(frac), - align_bitmap_mod); if_debug0m('B', penum->memory, "\n"); } else { /* indexed and more than 8bps. Need to get to the base space */ @@ -659,7 +839,6 @@ int dpd = dc * (bps <= 8 ? 1 : sizeof(frac)); float decode_value; - index_space = 1; /* flip the horizontal direction if indicated by the matrix value */ if (reversed) { pdata += (pss->params.WidthIn - 1) * dpd; @@ -678,59 +857,318 @@ gs_cspace_indexed_lookup_frac(pcs, decode_value,psrc); pdata += dpd; } - /* We need to set the output to the end of the input buffer - moving it to the next desired word boundary. This must - be accounted for in the memory allocation of - gs_image_class_0_interpolate */ - out += round_up(pss->params.WidthIn * spp_decode, - align_bitmap_mod); } /* end of else on indexed */ } /* end of else on more than 8 bps */ stream_r->limit = stream_r->ptr + row_size; } else { /* h == 0 */ stream_r->ptr = 0, stream_r->limit = 0; - index_space = 0; } } static int +handle_device_color(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + + return (*pcs->type->remap_concrete_color) + (pcs, psrc, devc, pgs, dev, gs_color_select_source, dev_profile); +} + +/* LAB colors are normally decoded with a decode array + * of [0 100 -128 127 -128 127 ]. The color management + * however, expects this decode array NOT to have been + * applied. + * + * It would be possible for an LAB image to be given a + * non-standard decode array, in which case, we should + * take account of that. The easiest way is to apply the + * decode array as given, and then 'undo' the standard + * one. + */ +static int +handle_labicc_color8(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + + decode_sample_frac_to_float(penum, psrc[0], &cc, 0); + decode_sample_frac_to_float(penum, psrc[1], &cc, 1); + decode_sample_frac_to_float(penum, psrc[2], &cc, 2); + cc.paint.values[0] /= 100.0; + cc.paint.values[1] = (cc.paint.values[1] + 128) / 255.0; + cc.paint.values[2] = (cc.paint.values[2] + 128) / 255.0; + return gx_remap_ICC_imagelab(&cc, pcs, devc, pgs, dev, gs_color_select_source); +} + +static int +handle_labicc_color16(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + + decode_sample_frac_to_float(penum, psrc[0], &cc, 0); + decode_sample_frac_to_float(penum, psrc[1], &cc, 1); + decode_sample_frac_to_float(penum, psrc[2], &cc, 2); + cc.paint.values[0] *= 0x7ff8 / 25500.0f; + cc.paint.values[1] = (cc.paint.values[1] + 128) * 0x7ff8 / 65025.0; + cc.paint.values[2] = (cc.paint.values[2] + 128) * 0x7ff8 / 65025.0; + return gx_remap_ICC_imagelab(&cc, pcs, devc, pgs, dev, gs_color_select_source); +} + +static int +handle_lab_color8(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + + decode_sample_frac_to_float(penum, psrc[0], &cc, 0); + decode_sample_frac_to_float(penum, psrc[1], &cc, 1); + decode_sample_frac_to_float(penum, psrc[2], &cc, 2); + cc.paint.values[0] /= 100.0; + cc.paint.values[1] = (cc.paint.values[1] + 128) / 255.0; + cc.paint.values[2] = (cc.paint.values[2] + 128) / 255.0; + return (pcs->type->remap_color) + (&cc, pcs, devc, pgs, dev, gs_color_select_source); +} + +static int +handle_lab_color16(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + + decode_sample_frac_to_float(penum, psrc[0], &cc, 0); + decode_sample_frac_to_float(penum, psrc[1], &cc, 1); + decode_sample_frac_to_float(penum, psrc[2], &cc, 2); + cc.paint.values[0] *= 0x7ff8 / 25500.0f; + cc.paint.values[1] = (cc.paint.values[1] + 128) * 0x7ff8 / 65025.0; + cc.paint.values[2] = (cc.paint.values[2] + 128) * 0x7ff8 / 65025.0; + return (pcs->type->remap_color) + (&cc, pcs, devc, pgs, dev, gs_color_select_source); +} + +static int +handle_labicc_color2_idx(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + int j; + int num_components = gs_color_space_num_components(pcs); + + /* If we were indexed, dont use the decode procedure for the index + values just get to float directly */ + for (j = 0; j < num_components; ++j) + cc.paint.values[j] = frac2float(psrc[j]); + /* If the source colors are LAB then use the mapping that does not + rescale the source colors */ + return gx_remap_ICC_imagelab(&cc, pcs, devc, pgs, dev, + gs_color_select_source); +} + +static int +handle_remap_color_idx(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + int j; + int num_components = gs_color_space_num_components(pcs); + + for (j = 0; j < num_components; ++j) + cc.paint.values[j] = frac2float(psrc[j]); + + return (pcs->type->remap_color) + (&cc, pcs, devc, pgs, dev, gs_color_select_source); +} + +static int +handle_labicc_color2(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + int j; + int num_components = gs_color_space_num_components(pcs); + + for (j = 0; j < num_components; ++j) + decode_sample_frac_to_float(penum, psrc[j], &cc, j); + /* If the source colors are LAB then use the mapping that does not + rescale the source colors */ + return gx_remap_ICC_imagelab(&cc, pcs, devc, pgs, dev, + gs_color_select_source); +} + +static int +handle_remap_color(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs) +{ + const gs_gstate *pgs = penum->pgs; + gs_client_color cc; + int j; + int num_components = gs_color_space_num_components(pcs); + + for (j = 0; j < num_components; ++j) + decode_sample_frac_to_float(penum, psrc[j], &cc, j); + + return (pcs->type->remap_color) + (&cc, pcs, devc, pgs, dev, gs_color_select_source); +} + +typedef int (color_handler_fn)(gx_image_enum *penum, const frac *psrc, + gx_device_color *devc, gx_device *dev, + const cmm_dev_profile_t *dev_profile, + const gs_color_space *pcs); + +static color_handler_fn * +get_color_handler(gx_image_enum *penum, int spp_decode, + bool islab, const cmm_dev_profile_t *dev_profile, + const gs_color_space **pconc) +{ + const gs_color_space *pconcs; + const gs_gstate *pgs = penum->pgs; + const gs_color_space *pcs = penum->pcs; + bool device_color = false; + bool is_index_space; + + if (pcs == NULL) + return NULL; /* Must be masked */ + + is_index_space = (pcs->type->index == gs_color_space_index_Indexed); + /* If we are in a non device space then work from the pcs not from the + concrete space also handle index case, where base case was device type */ + if (pcs->type->index == gs_color_space_index_Indexed) + pcs = pcs->base_space; + pconcs = cs_concrete_space(pcs, pgs); + if (pconcs && pconcs->cmm_icc_profile_data != NULL) { + if (pconcs->cmm_icc_profile_data != NULL && dev_profile->usefastcolor == false) { + device_color = false; + } else { + device_color = (pconcs == pcs); + } + } + if (device_color) { + *pconc = pconcs; + return handle_device_color; + } + + *pconc = pcs; + /* If we are device dependent we need to get back to float prior to remap.*/ + if (islab) { + if (gs_color_space_is_ICC(pcs) && + pcs->cmm_icc_profile_data != NULL && + pcs->cmm_icc_profile_data->islab) + return penum->bps <= 8 ? handle_labicc_color8 : handle_labicc_color16; + else + return penum->bps <= 8 ? handle_lab_color8 : handle_lab_color16; + } else if (is_index_space) { + if (gs_color_space_is_ICC(pcs) && + pcs->cmm_icc_profile_data != NULL && + pcs->cmm_icc_profile_data->islab) + return handle_labicc_color2_idx; + else + return handle_remap_color_idx; + } else { + if (gs_color_space_is_ICC(pcs) && + pcs->cmm_icc_profile_data != NULL && + pcs->cmm_icc_profile_data->islab) + return handle_labicc_color2; + else + return handle_remap_color; + } +} + +/* returns the expanded width using the dda.x */ +static int +interpolate_scaled_expanded_width(int delta_x, stream_image_scale_state *pss) +{ + gx_dda_fixed_point tmp_dda = pss->params.scale_dda; + int start_x = dda_current(tmp_dda.x); + + do { + dda_next(tmp_dda.x); + } while (--delta_x > 0); + + return dda_current(tmp_dda.x) - start_x; +} + +/* returns the expanded height using the dda.y */ +static int +interpolate_scaled_expanded_height(int delta_y, stream_image_scale_state *pss) +{ + gx_dda_fixed_point tmp_dda = pss->params.scale_dda; + int start_y = dda_current(tmp_dda.y); + + do { + dda_next(tmp_dda.y); + } while (--delta_y > 0); + + return dda_current(tmp_dda.y) - start_y; +} + +static int image_render_interpolate(gx_image_enum * penum, const byte * buffer, int data_x, uint iw, int h, gx_device * dev) { stream_image_scale_state *pss = penum->scaler; - const gs_imager_state *pis = penum->pis; const gs_color_space *pcs = penum->pcs; gs_logical_operation_t lop = penum->log_op; int spp_decode = pss->params.spp_decode; stream_cursor_read stream_r; stream_cursor_write stream_w; - bool is_index_space; byte *out = penum->line; bool islab = false; - bool need_decode; + int abs_interp_limit = pss->params.abs_interp_limit; + int limited_PatchWidthOut = (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit; + const gs_color_space *pconc; + cmm_dev_profile_t *dev_profile; + int code = dev_proc(penum->dev, get_profile)(penum->dev, &dev_profile); - if (pcs->cmm_icc_profile_data != NULL) { + if (code < 0) + return code; + + if (!penum->masked && pcs->cmm_icc_profile_data != NULL) { islab = pcs->cmm_icc_profile_data->islab; } /* Perform any decode procedure if needed */ - need_decode = !(penum->device_color || gs_color_space_is_CIE(pcs) || islab); - initial_decode(penum, buffer, data_x, h, need_decode, &stream_r, false); - is_index_space = (pcs->type->index == gs_color_space_index_Indexed); + initial_decode(penum, buffer, data_x, h, &stream_r, false); /* * Process input and/or collect output. By construction, the pixels are - * 1-for-1 with the device, but the Y coordinate might be inverted. + * 1-for-1 with the device if the abs(interpolate_control) is 1 but the + * Y coordinate might be inverted. */ { int xo = penum->xyi.x; int yo = penum->xyi.y; - int width = pss->params.WidthOut; + int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit; int sizeofPixelOut = pss->params.BitsPerComponentOut / 8; int dy; - const gs_color_space *pconcs; - const gs_color_space *pactual_cs; int bpp = dev->color_info.depth; uint raster = bitmap_raster(width * bpp); - bool device_color; + color_handler_fn *color_handler = NULL; if (penum->matrix.yy > 0) dy = 1; @@ -741,11 +1179,16 @@ int x; const frac *psrc; gx_device_color devc; - int status, code; + int status; + byte *l_dptr = out; + int l_dbit = 0; + byte l_dbyte = 0; + int l_xprev = (xo); + int scaled_x_prev = 0; + gx_dda_fixed save_x_dda = pss->params.scale_dda.x; - DECLARE_LINE_ACCUM_COPY(out, bpp, xo); - stream_w.limit = out + width * - max(spp_decode * sizeofPixelOut, arch_sizeof_color_index) - 1; + stream_w.limit = out + pss->params.WidthOut * + max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1; stream_w.ptr = stream_w.limit - width * spp_decode * sizeofPixelOut; psrc = (const frac *)(stream_w.ptr + 1); /* This is where the rescale takes place; this will consume the @@ -758,97 +1201,85 @@ if (status < 0 && status != EOFC) return_error(gs_error_ioerror); if (stream_w.ptr == stream_w.limit) { - int xe = xo + pss->params.PatchWidthOut; + int xe = xo + limited_PatchWidthOut; + int scaled_w = 0; /* accumulate scaled up width */ + int scaled_h = interpolate_scaled_expanded_height(1, pss); + int scaled_y = yo + (dy * dda_current(pss->params.scale_dda.y)); /* Are we active? (i.e. in the render rectangle) */ if (!pss->params.Active) goto inactive; if_debug1m('B', penum->memory, "[B]Interpolated row %d:\n[B]", penum->line_xy); - psrc += pss->params.LeftMarginOut * spp_decode; + psrc += ((pss->params.LeftMarginOut + abs_interp_limit - 1) / abs_interp_limit) * spp_decode; + + if (color_handler == NULL) + color_handler = get_color_handler(penum, spp_decode, islab, dev_profile, &pconc); for (x = xo; x < xe;) { + if (color_handler != NULL) { #ifdef DEBUG - if (gs_debug_c('B')) { - int ci; + if (gs_debug_c('B')) { + int ci; - for (ci = 0; ci < spp_decode; ++ci) - dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), - psrc[ci]); - } -#endif - /* if we are in a non device space then work - from the pcs not from the concrete space - also handle index case, where base case was device type */ - if (pcs->type->index == gs_color_space_index_Indexed) { - pactual_cs = pcs->base_space; - } else { - pactual_cs = pcs; - } - pconcs = cs_concrete_space(pactual_cs, pis); - if (pconcs->cmm_icc_profile_data != NULL) { - device_color = false; - } else { - device_color = (pconcs == pactual_cs); - } - if (device_color) { - /* Use the underlying concrete space remap */ - code = (*pconcs->type->remap_concrete_color) - (psrc, pconcs, &devc, pis, dev, gs_color_select_source); - } else { - /* if we are device dependent we need to get back to - float prior to remap. This stuff needs to be - reworked as part of the ICC flow update. - In such a flow, we will want the interpolation - algorithm output likely to be 8 bit (if the input - were 8 bit) and hit that buffer of values directly - with the linked transform */ - gs_client_color cc; - int j; - int num_components = - gs_color_space_num_components(pactual_cs); - - for (j = 0; j < num_components; ++j) { - /* If we were indexed, dont use the decode procedure - for the index values just get to float directly */ - if (is_index_space || islab) { - cc.paint.values[j] = frac2float(psrc[j]); - } else { - decode_sample_frac_to_float(penum, psrc[j], &cc, j); - } - } - /* If the source colors are LAB then use the mapping - that does not rescale the source colors */ - if (gs_color_space_is_ICC(pactual_cs) && - pactual_cs->cmm_icc_profile_data != NULL && - pactual_cs->cmm_icc_profile_data->islab) { - code = gx_remap_ICC_imagelab (&cc, pactual_cs, &devc, - pis, dev, - gs_color_select_source); - } else { - code = (pactual_cs->type->remap_color) - (&cc, pactual_cs, &devc, pis, dev, - gs_color_select_source); + for (ci = 0; ci < spp_decode; ++ci) + dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), + psrc[ci]); } +#endif + code = color_handler(penum, psrc, &devc, dev, dev_profile, pconc); + if (code < 0) + return code; } - if (code < 0) - return code; if (color_is_pure(&devc)) { - /* Just pack colors into a scan line. */ gx_color_index color = devc.colors.pure; + int expand = 1; + + if (abs_interp_limit > 1) { + expand = interpolate_scaled_expanded_width(1, pss); + } + /* Just pack colors into a scan line. */ /* Skip runs quickly for the common cases. */ switch (spp_decode) { case 1: do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + }; x++, psrc += 1; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.x); + expand = interpolate_scaled_expanded_width(1, pss); + } else + expand = 1; } while (x < xe && psrc[-1] == psrc[0]); break; case 3: do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + }; x++, psrc += 3; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.x); + expand = interpolate_scaled_expanded_width(1, pss); + } else + expand = 1; } while (x < xe && psrc[-3] == psrc[0] && psrc[-2] == psrc[1] && @@ -856,33 +1287,225 @@ break; case 4: do { - LINE_ACCUM(color, bpp); + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + }; x++, psrc += 4; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.x); + expand = interpolate_scaled_expanded_width(1, pss); + } else + expand = 1; } while (x < xe && psrc[-4] == psrc[0] && psrc[-3] == psrc[1] && psrc[-2] == psrc[2] && psrc[-1] == psrc[3]); break; - default: - LINE_ACCUM(color, bpp); + default: /* no run length check for these spp cases */ + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + }; x++, psrc += spp_decode; + if (abs_interp_limit > 1) + dda_next(pss->params.scale_dda.x); } } else { - int rcode; + int rcode, rep = 0; + + /* do _COPY in case any pure colors were accumulated above */ + if ( x > l_xprev ) { + sample_store_flush(l_dptr, l_dbit, l_dbyte); + if (abs_interp_limit <= 1) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } else { + /* scale up in X and Y */ + int scaled_x = xo + scaled_x_prev; + int i = scaled_h; + int iy = scaled_y; + + for (; i > 0; --i) { + code = (*dev_proc(dev, copy_color)) + (dev, out, scaled_x_prev, raster, + gx_no_bitmap_id, scaled_x, iy, scaled_w, 1); + if (code < 0) + return code; + iy += dy; + } + scaled_x_prev = dda_current(pss->params.scale_dda.x); + } + } + /* as above, see if we can accumulate any runs */ + switch (spp_decode) { + case 1: + do { + rep++, psrc += 1; + } while ((rep + x) < xe && + psrc[-1] == psrc[0]); + break; + case 3: + do { + rep++, psrc += 3; + } while ((rep + x) < xe && + psrc[-3] == psrc[0] && + psrc[-2] == psrc[1] && + psrc[-1] == psrc[2]); + break; + case 4: + do { + rep++, psrc += 4; + } while ((rep + x) < xe && + psrc[-4] == psrc[0] && + psrc[-3] == psrc[1] && + psrc[-2] == psrc[2] && + psrc[-1] == psrc[3]); + break; + default: + rep = 1; + psrc += spp_decode; + break; + } + if (abs_interp_limit <= 1) { + scaled_w = rep; + rcode = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop); + if (rcode < 0) + return rcode; + } else { + int scaled_x = xo + scaled_x_prev; - LINE_ACCUM_COPY(dev, out, bpp, xo, x, raster, ry); - rcode = gx_fill_rectangle_device_rop(x, ry, 1, 1, - &devc, dev, lop); - if (rcode < 0) - return rcode; - LINE_ACCUM_SKIP(bpp); - l_xprev = x + 1; - x++, psrc += spp_decode; + scaled_w = interpolate_scaled_expanded_width(rep, pss); + rcode = gx_fill_rectangle_device_rop(scaled_x, scaled_y, scaled_w, scaled_h, + &devc, dev, lop); + if (rcode < 0) + return rcode; + dda_advance(pss->params.scale_dda.x, rep); + scaled_x_prev = dda_current(pss->params.scale_dda.x); + } + while (scaled_w-- > 0) + sample_store_skip_next(&l_dptr, &l_dbit, bpp, &l_dbyte); + scaled_w = 0; + l_xprev = x + rep; + x += rep; } - } - LINE_ACCUM_COPY(dev, out, bpp, xo, x, raster, ry); - /*if_debug1m('w', dev->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ + } /* End on x loop */ + if ( x > l_xprev ) { + sample_store_flush(l_dptr, l_dbit, l_dbyte); + if (abs_interp_limit <= 1) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } else { + /* scale up in X and Y */ + int scaled_x = xo + scaled_x_prev; + + for (; scaled_h > 0; --scaled_h) { + code = (*dev_proc(dev, copy_color)) + (dev, out, scaled_x_prev, raster, + gx_no_bitmap_id, scaled_x, scaled_y, scaled_w, 1); + if (code < 0) + return code; + scaled_y += dy; + } + } + } + /*if_debug1m('w', dev->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ +inactive: + penum->line_xy++; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.y); + pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */ + } + if_debug0m('B', dev->memory, "\n"); + } + if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC) + break; + } + } + return (h == 0 ? 0 : 1); +} + +static int +image_render_interpolate_masked(gx_image_enum * penum, const byte * buffer, + int data_x, uint iw, int h, gx_device * dev) +{ + stream_image_scale_state *pss = penum->scaler; + stream_cursor_read stream_r; + stream_cursor_write stream_w; + byte *out = penum->line; + gx_color_index color = penum->icolor1->colors.pure; + + /* Perform any decode procedure if needed */ + initial_decode(penum, buffer, data_x, h, &stream_r, false); + /* + * Process input and/or collect output. By construction, the pixels are + * 1-for-1 with the device, but the Y coordinate might be inverted. + */ + { + int xo = penum->xyi.x; + int yo = penum->xyi.y; + int width = pss->params.WidthOut; + int dy; + int bpp = dev->color_info.depth; + uint raster = bitmap_raster(width * bpp); + + if (penum->matrix.yy > 0) + dy = 1; + else + dy = -1, yo--; + for (;;) { + int ry = yo + penum->line_xy * dy; + const byte *psrc; + int status, code; + + stream_w.limit = out + width - 1; + stream_w.ptr = stream_w.limit - width; + psrc = stream_w.ptr + 1; + /* This is where the rescale takes place; this will consume the + * data from stream_r, and post processed data into stream_w. The + * data in stream_w may be bogus if we are outside the active + * region, and this will be indicated by pss->params.Active being + * set to false. */ + status = (*pss->templat->process) + ((stream_state *) pss, &stream_r, &stream_w, h == 0); + if (status < 0 && status != EOFC) + return_error(gs_error_ioerror); + if (stream_w.ptr == stream_w.limit) { + int xe = xo + pss->params.PatchWidthOut; + + /* Are we active? (i.e. in the render rectangle) */ + if (!pss->params.Active) + goto inactive; + if_debug1m('B', penum->memory, "[B]Interpolated mask row %d:\n[B]", + penum->line_xy); + psrc += pss->params.LeftMarginOut; + code = (*dev_proc(dev, copy_alpha)) + (dev, psrc, 0, raster, + gx_no_bitmap_id, xo, ry, xe-xo, 1, + color, 8); + if ( code < 0 ) + return code; inactive: penum->line_xy++; if_debug0m('B', dev->memory, "\n"); @@ -894,6 +1517,550 @@ return (h == 0 ? 0 : 1); } +static int +image_render_interpolate_masked_hl(gx_image_enum * penum, const byte * buffer, + int data_x, uint iw, int h, gx_device * dev) +{ + stream_image_scale_state *pss = penum->scaler; + stream_cursor_read stream_r; + stream_cursor_write stream_w; + byte *out = penum->line; + + /* Perform any decode procedure if needed */ + initial_decode(penum, buffer, data_x, h, &stream_r, false); + /* + * Process input and/or collect output. By construction, the pixels are + * 1-for-1 with the device, but the Y coordinate might be inverted. + */ + { + int xo = penum->xyi.x; + int yo = penum->xyi.y; + int width = pss->params.WidthOut; + int dy; + int bpp = dev->color_info.depth; + uint raster = bitmap_raster(width * bpp); + + if (penum->matrix.yy > 0) + dy = 1; + else + dy = -1, yo--; + for (;;) { + int ry = yo + penum->line_xy * dy; + const byte *psrc; + int status, code; + + stream_w.limit = out + width - 1; + stream_w.ptr = stream_w.limit - width; + psrc = stream_w.ptr + 1; + /* This is where the rescale takes place; this will consume the + * data from stream_r, and post processed data into stream_w. The + * data in stream_w may be bogus if we are outside the active + * region, and this will be indicated by pss->params.Active being + * set to false. */ + status = (*pss->templat->process) + ((stream_state *) pss, &stream_r, &stream_w, h == 0); + if (status < 0 && status != EOFC) + return_error(gs_error_ioerror); + if (stream_w.ptr == stream_w.limit) { + int xe = xo + pss->params.PatchWidthOut; + + /* Are we active? (i.e. in the render rectangle) */ + if (!pss->params.Active) + goto inactive; + if_debug1m('B', penum->memory, "[B]Interpolated mask row %d:\n[B]", + penum->line_xy); + psrc += pss->params.LeftMarginOut; + code = (*dev_proc(dev, copy_alpha_hl_color)) + (dev, psrc, 0, raster, + gx_no_bitmap_id, xo, ry, xe-xo, 1, + penum->icolor1, 8); + if ( code < 0 ) + return code; +inactive: + penum->line_xy++; + if_debug0m('B', dev->memory, "\n"); + } + if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC) + break; + } + } + return (h == 0 ? 0 : 1); +} + +static void +get_device_color(gx_image_enum * penum, unsigned short *p_cm_interp, +gx_device_color *devc, gx_color_index *color, gx_device * dev) +{ + bool must_halftone = penum->icc_setup.must_halftone; + bool has_transfer = penum->icc_setup.has_transfer; + + if (must_halftone || has_transfer) { + /* We need to do the tranfer function and/or the halftoning */ + cmap_transfer_halftone(p_cm_interp, devc, penum->pgs, dev, + has_transfer, must_halftone, gs_color_select_source); + } else { + /* encode as a color index. avoid all the cv to frac to cv conversions */ + *color = dev_proc(dev, encode_color)(dev, p_cm_interp); + /* check if the encoding was successful; we presume failure is rare */ + if (*color != gx_no_color_index) + color_set_pure(devc, *color); + } +} + +typedef int (*irii_core_fn)(gx_image_enum * penum, int xo, int xe, int spp_cm, unsigned short *p_cm_interp, gx_device *dev, int abs_interp_limit, int bpp, int raster, int yo, int dy, gs_logical_operation_t lop); + +static inline int +irii_inner_template(gx_image_enum * penum, int xo, int xe, int spp_cm, unsigned short *p_cm_interp, gx_device *dev, int abs_interp_limit, int bpp, int raster, int yo, int dy, gs_logical_operation_t lop) +{ + int x; + gx_device_color devc; + gx_color_index color; + stream_image_scale_state *pss = penum->scaler; + int scaled_w = 0; /* accumulate scaled up width */ + byte *out = penum->line; + byte *l_dptr = out; + int l_dbit = 0; + byte l_dbyte = 0; + int l_xprev = (xo); + int scaled_x_prev = 0; + int code; + int ry = yo + penum->line_xy * dy; + gx_dda_fixed save_x_dda = pss->params.scale_dda.x; + int scaled_h = interpolate_scaled_expanded_height(1, pss); + int scaled_y = yo + (dy * dda_current(pss->params.scale_dda.y)); + + for (x = xo; x < xe;) { + +#ifdef DEBUG + if (gs_debug_c('B')) { + int ci; + + for (ci = 0; ci < spp_cm; ++ci) + dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), + p_cm_interp[ci]); + } +#endif + /* Get the device color */ + get_device_color(penum, p_cm_interp, &devc, &color, dev); + if (color_is_pure(&devc)) { + gx_color_index color = devc.colors.pure; + int expand = 1; + + if (abs_interp_limit > 1) { + expand = interpolate_scaled_expanded_width(1, pss); + } + /* Just pack colors into a scan line. */ + /* Skip runs quickly for the common cases. */ + switch (spp_cm) { + case 1: + do { + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + } + x++, p_cm_interp += 1; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.x); + expand = interpolate_scaled_expanded_width(1, pss); + } else + expand = 1; + } while (x < xe && p_cm_interp[-1] == p_cm_interp[0]); + break; + case 3: + do { + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + } + x++, p_cm_interp += 3; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.x); + expand = interpolate_scaled_expanded_width(1, pss); + } else + expand = 1; + } while (x < xe && p_cm_interp[-3] == p_cm_interp[0] && + p_cm_interp[-2] == p_cm_interp[1] && + p_cm_interp[-1] == p_cm_interp[2]); + break; + case 4: + do { + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + } + x++, p_cm_interp += 4; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.x); + expand = interpolate_scaled_expanded_width(1, pss); + } else + expand = 1; + } while (x < xe && p_cm_interp[-4] == p_cm_interp[0] && + p_cm_interp[-3] == p_cm_interp[1] && + p_cm_interp[-2] == p_cm_interp[2] && + p_cm_interp[-1] == p_cm_interp[3]); + break; + default: + scaled_w += expand; + while (expand-- > 0) { + if (sizeof(color) > 4) { + if (sample_store_next64(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } else { + if (sample_store_next32(color, &l_dptr, &l_dbit, bpp, &l_dbyte) < 0) + return_error(gs_error_rangecheck); + } + }; + x++, p_cm_interp += spp_cm; + if (abs_interp_limit > 1) + dda_next(pss->params.scale_dda.x); + } + } else { + int rcode, rep = 0; + + /* do _COPY in case any pure colors were accumulated above*/ + if ( x > l_xprev ) { + sample_store_flush(l_dptr, l_dbit, l_dbyte); + if (abs_interp_limit <= 1) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } else { + /* scale up in X and Y */ + int scaled_x = xo + scaled_x_prev; + int i = scaled_h; + int iy = scaled_y; + + for (; i > 0; --i) { + code = (*dev_proc(dev, copy_color)) + (dev, out, scaled_x_prev, raster, + gx_no_bitmap_id, scaled_x, iy, scaled_w, 1); + if (code < 0) + return code; + iy += dy; + } + scaled_x_prev = dda_current(pss->params.scale_dda.x); + } + } + /* as above, see if we can accumulate any runs */ + switch (spp_cm) { + case 1: + do { + rep++, p_cm_interp += 1; + } while ((rep + x) < xe && p_cm_interp[-1] == p_cm_interp[0]); + break; + case 3: + do { + rep++, p_cm_interp += 3; + } while ((rep + x) < xe && p_cm_interp[-3] == p_cm_interp[0] && + p_cm_interp[-2] == p_cm_interp[1] && + p_cm_interp[-1] == p_cm_interp[2]); + break; + case 4: + do { + rep++, p_cm_interp += 4; + } while ((rep + x) < xe && p_cm_interp[-4] == p_cm_interp[0] && + p_cm_interp[-3] == p_cm_interp[1] && + p_cm_interp[-2] == p_cm_interp[2] && + p_cm_interp[-1] == p_cm_interp[3]); + break; + default: + rep = 1, p_cm_interp += spp_cm; + break; + } + if (abs_interp_limit <= 1) { + scaled_w = rep; + rcode = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop); + if (rcode < 0) + return rcode; + } else { + int scaled_x = xo + scaled_x_prev; + + scaled_w = interpolate_scaled_expanded_width(rep, pss); + rcode = gx_fill_rectangle_device_rop(scaled_x, scaled_y, scaled_w, scaled_h, + &devc, dev, lop); + if (rcode < 0) + return rcode; + dda_advance(pss->params.scale_dda.x, rep); + scaled_x_prev = dda_current(pss->params.scale_dda.x); + } + while (scaled_w-- > 0) + sample_store_skip_next(&l_dptr, &l_dbit, bpp, &l_dbyte); + scaled_w = 0; + x += rep; + l_xprev = x; + } + } /* End on x loop */ + if ( x > l_xprev ) { + sample_store_flush(l_dptr, l_dbit, l_dbyte); + if (abs_interp_limit <= 1) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } else { + /* scale up in X and Y */ + int scaled_x = xo + scaled_x_prev; + + for (; scaled_h > 0; --scaled_h) { + code = (*dev_proc(dev, copy_color)) + (dev, out, scaled_x_prev, raster, + gx_no_bitmap_id, scaled_x, scaled_y, scaled_w, 1); + if (code < 0) + return code; + scaled_y += dy; + } + } + } + if (abs_interp_limit > 1) { + pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */ + } + /*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ + return 0; +} + +static int irii_inner_32bpp_4spp_1abs(gx_image_enum * penum, int xo, int xe, int spp_cm, unsigned short *p_cm_interp, gx_device *dev, int abs_interp_limit, int bpp, int raster, int yo, int dy, gs_logical_operation_t lop) +{ + int x; + gx_device_color devc; + gx_color_index color; + byte *out = penum->line; + byte *l_dptr = out; + int l_xprev = (xo); + int code; + int ry = yo + penum->line_xy * dy; + + for (x = xo; x < xe;) { + +#ifdef DEBUG + if (gs_debug_c('B')) { + int ci; + + for (ci = 0; ci < 3; ++ci) + dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), + p_cm_interp[ci]); + } +#endif + /* Get the device color */ + get_device_color(penum, p_cm_interp, &devc, &color, dev); + if (color_is_pure(&devc)) { + gx_color_index color = devc.colors.pure; + + /* Just pack colors into a scan line. */ + /* Skip runs quickly for the common cases. */ + do { + *l_dptr++ = (byte)(color >> 24); + *l_dptr++ = (byte)(color >> 16); + *l_dptr++ = (byte)(color >> 8); + *l_dptr++ = (byte)(color); + x++, p_cm_interp += 4; + } while (x < xe && p_cm_interp[-4] == p_cm_interp[0] && + p_cm_interp[-3] == p_cm_interp[1] && + p_cm_interp[-2] == p_cm_interp[2] && + p_cm_interp[-1] == p_cm_interp[3]); + } + else { + int rep = 0; + + /* do _COPY in case any pure colors were accumulated above*/ + if (x > l_xprev) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } + /* as above, see if we can accumulate any runs */ + do { + rep++, p_cm_interp += 4; + } while ((rep + x) < xe && p_cm_interp[-4] == p_cm_interp[0] && + p_cm_interp[-3] == p_cm_interp[1] && + p_cm_interp[-2] == p_cm_interp[2] && + p_cm_interp[-1] == p_cm_interp[3]); + code = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop); + if (code < 0) + return code; + x += rep; + l_xprev = x; + l_dptr += 4 * rep; + } + } /* End on x loop */ + if (x > l_xprev) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } + /*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ + return 0; +} + +static int irii_inner_24bpp_3spp_1abs(gx_image_enum * penum, int xo, int xe, int spp_cm, unsigned short *p_cm_interp, gx_device *dev, int abs_interp_limit, int bpp, int raster, int yo, int dy, gs_logical_operation_t lop) +{ + int x; + gx_device_color devc; + gx_color_index color; + byte *out = penum->line; + byte *l_dptr = out; + int l_xprev = (xo); + int code; + int ry = yo + penum->line_xy * dy; + + for (x = xo; x < xe;) { +#ifdef DEBUG + if (gs_debug_c('B')) { + int ci; + + for (ci = 0; ci < 3; ++ci) + dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), + p_cm_interp[ci]); + } +#endif + /* Get the device color */ + get_device_color(penum, p_cm_interp, &devc, &color, dev); + if (color_is_pure(&devc)) { + gx_color_index color = devc.colors.pure; + + /* Just pack colors into a scan line. */ + /* Skip runs quickly for the common cases. */ + do { + *l_dptr++ = (byte)(color >> 16); + *l_dptr++ = (byte)(color >> 8); + *l_dptr++ = (byte)(color); + x++, p_cm_interp += 3; + } while (x < xe && p_cm_interp[-3] == p_cm_interp[0] && + p_cm_interp[-2] == p_cm_interp[1] && + p_cm_interp[-1] == p_cm_interp[2]); + } + else { + int rep = 0; + + /* do _COPY in case any pure colors were accumulated above*/ + if (x > l_xprev) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } + /* as above, see if we can accumulate any runs */ + do { + rep++, p_cm_interp += 3; + } while ((rep + x) < xe && p_cm_interp[-3] == p_cm_interp[0] && + p_cm_interp[-2] == p_cm_interp[1] && + p_cm_interp[-1] == p_cm_interp[2]); + code = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop); + if (code < 0) + return code; + x += rep; + l_xprev = x; + l_dptr += 3 * rep; + } + } /* End on x loop */ + if (x > l_xprev) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } + /*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ + return 0; +} + +static int irii_inner_8bpp_1spp_1abs(gx_image_enum * penum, int xo, int xe, int spp_cm, unsigned short *p_cm_interp, gx_device *dev, int abs_interp_limit, int bpp, int raster, int yo, int dy, gs_logical_operation_t lop) +{ + int x; + gx_device_color devc; + gx_color_index color; + byte *out = penum->line; + byte *l_dptr = out; + int l_xprev = (xo); + int code; + int ry = yo + penum->line_xy * dy; + + for (x = xo; x < xe;) { +#ifdef DEBUG + if (gs_debug_c('B')) { + int ci; + + for (ci = 0; ci < 3; ++ci) + dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), + p_cm_interp[ci]); + } +#endif + /* Get the device color */ + get_device_color(penum, p_cm_interp, &devc, &color, dev); + if (color_is_pure(&devc)) { + gx_color_index color = devc.colors.pure; + + /* Just pack colors into a scan line. */ + /* Skip runs quickly for the common cases. */ + do { + *l_dptr++ = (byte)(color); + x++, p_cm_interp++; + } while (x < xe && p_cm_interp[-1] == p_cm_interp[0]); + } + else { + int rep = 0; + + /* do _COPY in case any pure colors were accumulated above*/ + if (x > l_xprev) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } + /* as above, see if we can accumulate any runs */ + do { + rep++, p_cm_interp++; + } while ((rep + x) < xe && p_cm_interp[-1] == p_cm_interp[0]); + code = gx_fill_rectangle_device_rop(x, ry, rep, 1, &devc, dev, lop); + if (code < 0) + return code; + x += rep; + l_xprev = x; + l_dptr += rep; + } + } /* End on x loop */ + if (x > l_xprev) { + code = (*dev_proc(dev, copy_color)) + (dev, out, l_xprev - xo, raster, + gx_no_bitmap_id, l_xprev, ry, x - l_xprev, 1); + if (code < 0) + return code; + } + /*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ + return 0; +} + +static int irii_inner_generic(gx_image_enum * penum, int xo, int xe, int spp_cm, unsigned short *p_cm_interp, gx_device *dev, int abs_interp_limit, int bpp, int raster, int yo, int dy, gs_logical_operation_t lop) +{ + return irii_inner_template(penum, xo, xe, spp_cm, p_cm_interp, dev, abs_interp_limit, bpp, raster, yo, dy, lop); +} + /* Interpolation with ICC based source spaces. This is done seperately to enable optimization and avoid the multiple tranformations that occur in the above code */ @@ -902,25 +2069,18 @@ int data_x, uint iw, int h, gx_device * dev) { stream_image_scale_state *pss = penum->scaler; - const gs_imager_state *pis = penum->pis; - const gs_color_space *pcs = penum->pcs; + const gs_gstate *pgs = penum->pgs; gs_logical_operation_t lop = penum->log_op; byte *out = penum->line; - bool must_halftone = penum->icc_setup.must_halftone; - bool has_transfer = penum->icc_setup.has_transfer; stream_cursor_read stream_r; stream_cursor_write stream_w; - bool need_decode; + int abs_interp_limit = pss->params.abs_interp_limit; + int limited_PatchWidthOut = (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit; if (penum->icc_link == NULL) { return gs_rethrow(-1, "ICC Link not created during gs_image_class_0_interpolate"); } - /* Go ahead and take apart any indexed color space or do the decode - so that we can then perform the interpolation or color management */ - need_decode = !((penum->device_color || penum->icc_setup.is_lab) && - (penum->icc_setup.need_decode == 0) || - gs_color_space_is_CIE(pcs)); - initial_decode(penum, buffer, data_x, h, need_decode, &stream_r, true); + initial_decode(penum, buffer, data_x, h, &stream_r, true); /* * Process input and/or collect output. By construction, the pixels are * 1-for-1 with the device, but the Y coordinate might be inverted. @@ -929,7 +2089,7 @@ { int xo = penum->xyi.x; int yo = penum->xyi.y; - int width = pss->params.WidthOut; + int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit; int width_in = pss->params.WidthIn; int sizeofPixelOut = pss->params.BitsPerComponentOut / 8; int dy; @@ -943,23 +2103,34 @@ int spp_cm; gsicc_bufferdesc_t input_buff_desc; gsicc_bufferdesc_t output_buff_desc; - gx_color_index color; int code; cmm_dev_profile_t *dev_profile; int num_bytes_decode = pss->params.BitsPerComponentIn / 8; + irii_core_fn irii_core; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code) + return code; spp_cm = gsicc_get_device_profile_comps(dev_profile); if (penum->matrix.yy > 0) dy = 1; else dy = -1, yo--; + if (spp_cm == 4 && abs_interp_limit == 1 && bpp == 32) + irii_core = &irii_inner_32bpp_4spp_1abs; + else if (spp_cm == 3 && abs_interp_limit == 1 && bpp == 24) + irii_core = &irii_inner_24bpp_3spp_1abs; + else if (spp_cm == 1 && abs_interp_limit == 1 && bpp == 8) + irii_core = &irii_inner_8bpp_1spp_1abs; + else + irii_core = &irii_inner_generic; + /* If it makes sense (if enlarging), do early CM */ if (pss->params.early_cm && !penum->icc_link->is_identity && stream_r.ptr != stream_r.limit) { /* Get the buffers set up. */ p_cm_buff = - (byte *) gs_alloc_bytes(pis->memory, + (byte *) gs_alloc_bytes(pgs->memory, num_bytes_decode * width_in * spp_cm, "image_render_interpolate_icc"); /* Set up the buffer descriptors. We keep the bytes the same */ @@ -981,28 +2152,24 @@ /* CM after interpolation (or none). Just set up the buffers if needed. 16 bit operations if CM takes place. */ if (!penum->icc_link->is_identity) { - p_cm_buff = (byte *) gs_alloc_bytes(pis->memory, + p_cm_buff = (byte *) gs_alloc_bytes(pgs->memory, sizeof(unsigned short) * width * spp_cm, "image_render_interpolate_icc"); /* Set up the buffer descriptors. */ gsicc_init_buffer(&input_buff_desc, spp_decode, 2, false, false, false, 0, width * spp_decode, - 1, pss->params.PatchWidthOut); + 1, limited_PatchWidthOut); gsicc_init_buffer(&output_buff_desc, spp_cm, 2, false, false, false, 0, width * spp_cm, - 1, pss->params.PatchWidthOut); + 1, limited_PatchWidthOut); } } for (;;) { - int ry = yo + penum->line_xy * dy; - int x; const unsigned short *pinterp; - gx_device_color devc; int status; - DECLARE_LINE_ACCUM_COPY(out, bpp, xo); - stream_w.limit = out + width * - max(spp_interp * sizeofPixelOut, arch_sizeof_color_index) - 1; + stream_w.limit = out + pss->params.WidthOut * + max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1; stream_w.ptr = stream_w.limit - width * spp_interp * sizeofPixelOut; pinterp = (const unsigned short *)(stream_w.ptr + 1); /* This is where the rescale takes place; this will consume the @@ -1015,7 +2182,7 @@ if (status < 0 && status != EOFC) return_error(gs_error_ioerror); if (stream_w.ptr == stream_w.limit) { - int xe = xo + pss->params.PatchWidthOut; + int xe = xo + limited_PatchWidthOut; /* Are we active? (i.e. in the render rectangle) */ if (!pss->params.Active) @@ -1027,94 +2194,26 @@ if (penum->icc_link->is_identity || pss->params.early_cm) { /* Fastest case. No CM needed */ p_cm_interp = (unsigned short *) pinterp; - p_cm_interp += pss->params.LeftMarginOut * spp_cm; + p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm; } else { /* Transform */ - pinterp += pss->params.LeftMarginOut * spp_decode; + pinterp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_decode; p_cm_interp = (unsigned short *) p_cm_buff; - p_cm_interp += pss->params.LeftMarginOut * spp_cm; + p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm; (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, &output_buff_desc, (void*) pinterp, (void*) p_cm_interp); } - for (x = xo; x < xe;) { -#ifdef DEBUG - if (gs_debug_c('B')) { - int ci; - - for (ci = 0; ci < spp_cm; ++ci) - dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), - p_cm_interp[ci]); - } -#endif - /* Get the device color */ - /* Now we can do an encoding directly or we have to apply transfer - and or halftoning */ - if (must_halftone || has_transfer) { - /* We need to do the tranfer function and/or the halftoning */ - cmap_transfer_halftone(p_cm_interp, &devc, pis, dev, - has_transfer, must_halftone, gs_color_select_source); - } else { - /* encode as a color index. avoid all the cv to frac to cv - conversions */ - color = dev_proc(dev, encode_color)(dev, p_cm_interp); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(&devc, color); - } - if (color_is_pure(&devc)) { - /* Just pack colors into a scan line. */ - gx_color_index color = devc.colors.pure; - /* Skip runs quickly for the common cases. */ - switch (spp_cm) { - case 1: - do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, p_cm_interp += 1; - } while (x < xe && p_cm_interp[-1] == p_cm_interp[0]); - break; - case 3: - do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, p_cm_interp += 3; - } while (x < xe && p_cm_interp[-3] == p_cm_interp[0] && - p_cm_interp[-2] == p_cm_interp[1] && - p_cm_interp[-1] == p_cm_interp[2]); - break; - case 4: - do { - LINE_ACCUM(color, bpp); - x++, p_cm_interp += 4; - } while (x < xe && p_cm_interp[-4] == p_cm_interp[0] && - p_cm_interp[-3] == p_cm_interp[1] && - p_cm_interp[-2] == p_cm_interp[2] && - p_cm_interp[-1] == p_cm_interp[3]); - break; - default: - LINE_ACCUM(color, bpp); - x++, p_cm_interp += spp_cm; - } - } else { - int rcode; - - LINE_ACCUM_COPY(dev, out, bpp, xo, x, raster, ry); - rcode = gx_fill_rectangle_device_rop(x, ry, - 1, 1, &devc, dev, lop); - if (rcode < 0) - return rcode; - LINE_ACCUM_SKIP(bpp); - l_xprev = x + 1; - x++, p_cm_interp += spp_cm; - } - } /* End on x loop */ - LINE_ACCUM_COPY(dev, out, bpp, xo, x, raster, ry); - /*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ + code = irii_core(penum, xo, xe, spp_cm, p_cm_interp, dev, abs_interp_limit, bpp, raster, yo, dy, lop); + if (code < 0) + return code; inactive: penum->line_xy++; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.y); + } if_debug0m('B', penum->memory, "\n"); } if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC) @@ -1122,7 +2221,7 @@ } /* Free cm buffer, if it was used */ if (p_cm_buff != NULL) { - gs_free_object(pis->memory, (byte *)p_cm_buff, + gs_free_object(pgs->memory, (byte *)p_cm_buff, "image_render_interpolate_icc"); } } @@ -1136,24 +2235,26 @@ gx_device * dev) { stream_image_scale_state *pss = penum->scaler; - const gs_imager_state *pis = penum->pis; const gs_color_space *pcs = penum->pcs; gs_logical_operation_t lop = penum->log_op; int spp_decode = pss->params.spp_decode; stream_cursor_read stream_r; stream_cursor_write stream_w; - bool is_index_space; byte *out = penum->line; bool islab = false; - bool need_decode; + int abs_interp_limit = pss->params.abs_interp_limit; + const gs_color_space *pconc; + cmm_dev_profile_t *dev_profile; + int code = dev_proc(penum->dev, get_profile)(penum->dev, &dev_profile); + + if (code < 0) + return code; if (pcs->cmm_icc_profile_data != NULL) { islab = pcs->cmm_icc_profile_data->islab; } /* Perform any decode procedure if needed */ - need_decode = !(penum->device_color || gs_color_space_is_CIE(pcs) || islab); - initial_decode(penum, buffer, data_x, h, need_decode, &stream_r, false); - is_index_space = (pcs->type->index == gs_color_space_index_Indexed); + initial_decode(penum, buffer, data_x, h, &stream_r, false); /* * Process input and/or collect output. By construction, the pixels are * 1-for-1 with the device, but the Y coordinate might be inverted. @@ -1161,15 +2262,10 @@ { int xo = penum->xyi.y; int yo = penum->xyi.x; - int width = pss->params.WidthOut; + int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit; int sizeofPixelOut = pss->params.BitsPerComponentOut / 8; int dy; - const gs_color_space *pconcs; - const gs_color_space *pactual_cs; - int bpp = dev->color_info.depth; - uint raster = (bpp+7)>>3; - int bpp_rep = 8/bpp; - bool device_color; + color_handler_fn *color_handler = NULL; if (penum->matrix.yx > 0) dy = 1; @@ -1180,11 +2276,15 @@ int x; const frac *psrc; gx_device_color devc; - int status, code; + int status; + int scaled_w = 0; + gx_dda_fixed save_x_dda; - DECLARE_LINE_ACCUM_COPY(out, bpp, xo); + if (abs_interp_limit > 1) { + save_x_dda = pss->params.scale_dda.x; + } stream_w.limit = out + width * - max(spp_decode * sizeofPixelOut, arch_sizeof_color_index) - 1; + max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1; stream_w.ptr = stream_w.limit - width * spp_decode * sizeofPixelOut; psrc = (const frac *)(stream_w.ptr + 1); /* This is where the rescale takes place; this will consume the @@ -1197,180 +2297,246 @@ if (status < 0 && status != EOFC) return_error(gs_error_ioerror); if (stream_w.ptr == stream_w.limit) { - int xe = xo + pss->params.PatchWidthOut; + int xe = xo + (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit; + int scaled_h = interpolate_scaled_expanded_height(1, pss); + int scaled_y = yo + (dy * dda_current(pss->params.scale_dda.y)) - + ((dy < 0) ? (scaled_h - 1) : 0); /* Are we active? (i.e. in the render rectangle) */ if (!pss->params.Active) goto inactive; if_debug1m('B', penum->memory, "[B]Interpolated (rotated) row %d:\n[B]", penum->line_xy); - psrc += pss->params.LeftMarginOut * spp_decode; + psrc += (pss->params.LeftMarginOut / abs_interp_limit) * spp_decode; + if (color_handler == NULL) + color_handler = get_color_handler(penum, spp_decode, islab, dev_profile, &pconc); for (x = xo; x < xe;) { + if (color_handler != NULL) { #ifdef DEBUG - if (gs_debug_c('B')) { - int ci; + if (gs_debug_c('B')) { + int ci; - for (ci = 0; ci < spp_decode; ++ci) - dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), - psrc[ci]); - } + for (ci = 0; ci < spp_decode; ++ci) + dmprintf2(dev->memory, "%c%04x", (ci == 0 ? ' ' : ','), + psrc[ci]); + } #endif - /* if we are in a non device space then work - from the pcs not from the concrete space - also handle index case, where base case was device type */ - if (pcs->type->index == gs_color_space_index_Indexed) { - pactual_cs = pcs->base_space; - } else { - pactual_cs = pcs; - } - pconcs = cs_concrete_space(pactual_cs, pis); - if (pconcs->cmm_icc_profile_data != NULL) { - device_color = false; - } else { - device_color = (pconcs == pactual_cs); + code = color_handler(penum, psrc, &devc, dev, dev_profile, pconc); + if (code < 0) + return code; } - if (device_color) { - /* Use the underlying concrete space remap */ - code = (*pconcs->type->remap_concrete_color) - (psrc, pconcs, &devc, pis, dev, gs_color_select_source); - } else { - /* if we are device dependent we need to get back to - float prior to remap. This stuff needs to be - reworked as part of the ICC flow update. - In such a flow, we will want the interpolation - algorithm output likely to be 8 bit (if the input - were 8 bit) and hit that buffer of values directly - with the linked transform */ - gs_client_color cc; - int j; - int num_components = - gs_color_space_num_components(pactual_cs); - - for (j = 0; j < num_components; ++j) { - /* If we were indexed, dont use the decode procedure - for the index values just get to float directly */ - if (is_index_space || islab) { - cc.paint.values[j] = frac2float(psrc[j]); - } else { - decode_sample_frac_to_float(penum, psrc[j], &cc, j); - } + /* We scan for vertical runs of pixels, even if they end up + * being split up in most cases within copy_color_unaligned anyway. */ + { + int rcode; + int rep = 0; + + /* as above, see if we can accumulate any runs */ + switch (spp_decode) { + case 1: + do { + rep++, psrc += 1; + } while ((rep + x) < xe && + psrc[-1] == psrc[0]); + break; + case 3: + do { + rep++, psrc += 3; + } while ((rep + x) < xe && + psrc[-3] == psrc[0] && + psrc[-2] == psrc[1] && + psrc[-1] == psrc[2]); + break; + case 4: + do { + rep++, psrc += 4; + } while ((rep + x) < xe && + psrc[-4] == psrc[0] && + psrc[-3] == psrc[1] && + psrc[-2] == psrc[2] && + psrc[-1] == psrc[3]); + break; + default: + rep = 1; + psrc += spp_decode; + break; } - /* If the source colors are LAB then use the mapping - that does not rescale the source colors */ - if (gs_color_space_is_ICC(pactual_cs) && - pactual_cs->cmm_icc_profile_data != NULL && - pactual_cs->cmm_icc_profile_data->islab) { - code = gx_remap_ICC_imagelab (&cc, pactual_cs, &devc, - pis, dev, - gs_color_select_source); + if (abs_interp_limit <= 1) { + rcode = gx_fill_rectangle_device_rop(ry, x, 1, rep, &devc, dev, lop); + if (rcode < 0) + return rcode; } else { - code = (pactual_cs->type->remap_color) - (&cc, pactual_cs, &devc, pis, dev, - gs_color_select_source); + int scaled_x = xo + dda_current(pss->params.scale_dda.x); + + scaled_w = interpolate_scaled_expanded_width(rep, pss); + rcode = gx_fill_rectangle_device_rop(scaled_y, scaled_x, scaled_h, scaled_w, + &devc, dev, lop); + if (rcode < 0) + return rcode; + dda_advance(pss->params.scale_dda.x, rep); } + x += rep; } + } + /*if_debug1m('w', dev->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ +inactive: + penum->line_xy++; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.y); + pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */ + } + if_debug0m('B', dev->memory, "\n"); + } + if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC) + break; + } + } + return (h == 0 ? 0 : 1); +} + +static int +image_render_interpolate_landscape_masked(gx_image_enum * penum, + const byte * buffer, + int data_x, uint iw, int h, + gx_device * dev) +{ + stream_image_scale_state *pss = penum->scaler; + int spp_decode = pss->params.spp_decode; + stream_cursor_read stream_r; + stream_cursor_write stream_w; + byte *out = penum->line; + gx_color_index color = penum->icolor1->colors.pure; + + /* Perform any decode procedure if needed. Probably only reversal + * of the data in this case. */ + initial_decode(penum, buffer, data_x, h, &stream_r, false); + /* + * Process input and/or collect output. By construction, the pixels are + * 1-for-1 with the device, but the Y coordinate might be inverted. + */ + { + int xo = penum->xyi.y; + int yo = penum->xyi.x; + int width = pss->params.WidthOut; + int sizeofPixelOut = pss->params.BitsPerComponentOut / 8; + int dy; + + if (penum->matrix.yx > 0) + dy = 1; + else + dy = -1, yo--; + for (;;) { + int ry = yo + penum->line_xy * dy; + int x; + const byte *psrc; + int status, code; + + stream_w.limit = out + width * + max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1; + stream_w.ptr = stream_w.limit - width * spp_decode * sizeofPixelOut; + psrc = stream_w.ptr + 1; + /* This is where the rescale takes place; this will consume the + * data from stream_r, and post processed data into stream_w. The + * data in stream_w may be bogus if we are outside the active + * region, and this will be indicated by pss->params.Active being + * set to false. */ + status = (*pss->templat->process) + ((stream_state *) pss, &stream_r, &stream_w, h == 0); + if (status < 0 && status != EOFC) + return_error(gs_error_ioerror); + if (stream_w.ptr == stream_w.limit) { + int xe = xo + pss->params.PatchWidthOut; + + /* Are we active? (i.e. in the render rectangle) */ + if (!pss->params.Active) + goto inactive; + if_debug1m('B', penum->memory, "[B]Interpolated masked (rotated) row %d:\n[B]", + penum->line_xy); + psrc += pss->params.LeftMarginOut * spp_decode; + for (x = xo; x < xe; x++) { + code = (*dev_proc(dev, copy_alpha))(dev, psrc, 0, 0, + gx_no_bitmap_id, ry, x, 1, 1, color, 8); if (code < 0) return code; - if (color_is_pure(&devc)) { - /* Just pack colors into a scan line. */ - gx_color_index color = devc.colors.pure; - if (bpp >= 8) { - /* Skip runs quickly for the common cases. */ - switch (spp_decode) { - case 1: - do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, psrc += 1; - } while (x < xe && psrc[-1] == psrc[0]); - break; - case 3: - do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, psrc += 3; - } while (x < xe && - psrc[-3] == psrc[0] && - psrc[-2] == psrc[1] && - psrc[-1] == psrc[2]); - break; - case 4: - do { - LINE_ACCUM(color, bpp); - x++, psrc += 4; - } while (x < xe && - psrc[-4] == psrc[0] && - psrc[-3] == psrc[1] && - psrc[-2] == psrc[2] && - psrc[-1] == psrc[3]); - break; - default: - LINE_ACCUM(color, bpp); - x++, psrc += spp_decode; - } - } else { - /* Skip runs quickly for the common cases. */ - switch (spp_decode) { - case 1: - do { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, psrc += 1; - } while (x < xe && psrc[-1] == psrc[0]); - break; - case 3: - do { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, psrc += 3; - } while (x < xe && - psrc[-3] == psrc[0] && - psrc[-2] == psrc[1] && - psrc[-1] == psrc[2]); - break; - case 4: - do { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - x++, psrc += 4; - } while (x < xe && - psrc[-4] == psrc[0] && - psrc[-3] == psrc[1] && - psrc[-2] == psrc[2] && - psrc[-1] == psrc[3]); - break; - default: - { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - x++, psrc += spp_decode; - } - } - } - } else { - int rcode; + psrc += spp_decode; + } + /*if_debug1m('w', dev->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ +inactive: + penum->line_xy++; + if_debug0m('B', dev->memory, "\n"); + } + if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC) + break; + } + } + return (h == 0 ? 0 : 1); +} - LINE_ACCUM_COPY_TRANS(dev, out, bpp, xo, x, raster, ry); - rcode = gx_fill_rectangle_device_rop(ry, x, 1, 1, - &devc, dev, lop); - if (rcode < 0) - return rcode; - LINE_ACCUM_SKIP(bpp); - l_xprev = x + 1; - x++, psrc += spp_decode; - } +static int +image_render_interpolate_landscape_masked_hl(gx_image_enum * penum, + const byte * buffer, + int data_x, uint iw, int h, + gx_device * dev) +{ + stream_image_scale_state *pss = penum->scaler; + int spp_decode = pss->params.spp_decode; + stream_cursor_read stream_r; + stream_cursor_write stream_w; + byte *out = penum->line; + + /* Perform any decode procedure if needed. Probably only reversal + * of the data in this case. */ + initial_decode(penum, buffer, data_x, h, &stream_r, false); + /* + * Process input and/or collect output. By construction, the pixels are + * 1-for-1 with the device, but the Y coordinate might be inverted. + */ + { + int xo = penum->xyi.y; + int yo = penum->xyi.x; + int width = pss->params.WidthOut; + int sizeofPixelOut = pss->params.BitsPerComponentOut / 8; + int dy; + + if (penum->matrix.yx > 0) + dy = 1; + else + dy = -1, yo--; + for (;;) { + int ry = yo + penum->line_xy * dy; + int x; + const byte *psrc; + int status, code; + + stream_w.limit = out + width * + max(spp_decode * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1; + stream_w.ptr = stream_w.limit - width * spp_decode * sizeofPixelOut; + psrc = stream_w.ptr + 1; + /* This is where the rescale takes place; this will consume the + * data from stream_r, and post processed data into stream_w. The + * data in stream_w may be bogus if we are outside the active + * region, and this will be indicated by pss->params.Active being + * set to false. */ + status = (*pss->templat->process) + ((stream_state *) pss, &stream_r, &stream_w, h == 0); + if (status < 0 && status != EOFC) + return_error(gs_error_ioerror); + if (stream_w.ptr == stream_w.limit) { + int xe = xo + pss->params.PatchWidthOut; + + /* Are we active? (i.e. in the render rectangle) */ + if (!pss->params.Active) + goto inactive; + if_debug1m('B', penum->memory, "[B]Interpolated masked (rotated) row %d:\n[B]", + penum->line_xy); + psrc += pss->params.LeftMarginOut * spp_decode; + for (x = xo; x < xe; x++) { + code = (*dev_proc(dev, copy_alpha_hl_color))(dev, psrc, 0, 0, + gx_no_bitmap_id, ry, x, 1, 1, penum->icolor1, 8); + if (code < 0) + return code; + psrc += spp_decode; } - LINE_ACCUM_COPY_TRANS(dev, out, bpp, xo, x, raster, ry); /*if_debug1m('w', dev->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ inactive: penum->line_xy++; @@ -1393,31 +2559,17 @@ gx_device * dev) { stream_image_scale_state *pss = penum->scaler; - const gs_imager_state *pis = penum->pis; - const gs_color_space *pcs = penum->pcs; + const gs_gstate *pgs = penum->pgs; gs_logical_operation_t lop = penum->log_op; byte *out = penum->line; - bool must_halftone = penum->icc_setup.must_halftone; - bool has_transfer = penum->icc_setup.has_transfer; stream_cursor_read stream_r; stream_cursor_write stream_w; - bool need_decode; + int abs_interp_limit = pss->params.abs_interp_limit; if (penum->icc_link == NULL) { return gs_rethrow(-1, "ICC Link not created during gs_image_class_0_interpolate"); } - /* Go ahead and take apart any indexed color space or do the decode - so that we can then perform the interpolation or color management */ - /* We need to perform an extra decode step if: - * we have a non-lab non-device color. - * OR the icc stuff tells us we need to. - * OR gs_color_space_is_CIE(pcs) == 0 (i.e. we have indexed/sep or devn) - * FIXME: Understand this! Michael says change the second || to && maybe. - */ - need_decode = !((penum->device_color || penum->icc_setup.is_lab) && - (penum->icc_setup.need_decode == 0) || - gs_color_space_is_CIE(pcs)); - initial_decode(penum, buffer, data_x, h, need_decode, &stream_r, true); + initial_decode(penum, buffer, data_x, h, &stream_r, true); /* * Process input and/or collect output. By construction, the pixels are * 1-for-1 with the device, but the Y coordinate might be inverted. @@ -1426,13 +2578,10 @@ { int xo = penum->xyi.y; int yo = penum->xyi.x; - int width = pss->params.WidthOut; + int width = (pss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit; int width_in = pss->params.WidthIn; int sizeofPixelOut = pss->params.BitsPerComponentOut / 8; int dy; - int bpp = dev->color_info.depth; - uint raster = (bpp+7)>>3; - int bpp_rep = 8/bpp; unsigned short *p_cm_interp; byte *p_cm_buff = NULL; byte *psrc; @@ -1447,6 +2596,10 @@ int num_bytes_decode = pss->params.BitsPerComponentIn / 8; code = dev_proc(dev, get_profile)(dev, &dev_profile); + if (code) { + penum->interpolate = interp_off; + return 0; + } spp_cm = gsicc_get_device_profile_comps(dev_profile); if (penum->matrix.yx > 0) dy = 1; @@ -1456,8 +2609,8 @@ if (pss->params.early_cm && !penum->icc_link->is_identity && stream_r.ptr != stream_r.limit) { /* Get the buffers set up. */ - p_cm_buff = - (byte *) gs_alloc_bytes(pis->memory, + p_cm_buff = + (byte *) gs_alloc_bytes(pgs->memory, num_bytes_decode * width_in * spp_cm, "image_render_interpolate_icc"); /* Set up the buffer descriptors. We keep the bytes the same */ @@ -1476,10 +2629,10 @@ stream_r.ptr = p_cm_buff - 1; stream_r.limit = stream_r.ptr + num_bytes_decode * width_in * spp_cm; } else { - /* CM after interpolation (or none). Just set up the buffers + /* CM after interpolation (or none). Just set up the buffers if needed. 16 bit operations if CM takes place. */ if (!penum->icc_link->is_identity) { - p_cm_buff = (byte *) gs_alloc_bytes(pis->memory, + p_cm_buff = (byte *) gs_alloc_bytes(pgs->memory, sizeof(unsigned short) * width * spp_cm, "image_render_interpolate_icc"); /* Set up the buffer descriptors. */ @@ -1497,10 +2650,14 @@ const unsigned short *pinterp; gx_device_color devc; int status; + int scaled_w = 0; + gx_dda_fixed save_x_dda; - DECLARE_LINE_ACCUM_COPY(out, bpp, xo); + if (abs_interp_limit > 1) { + save_x_dda = pss->params.scale_dda.x; + } stream_w.limit = out + width * - max(spp_interp * sizeofPixelOut, arch_sizeof_color_index) - 1; + max(spp_interp * sizeofPixelOut, ARCH_SIZEOF_COLOR_INDEX) - 1; stream_w.ptr = stream_w.limit - width * spp_interp * sizeofPixelOut; pinterp = (const unsigned short *)(stream_w.ptr + 1); /* This is where the rescale takes place; this will consume the @@ -1513,14 +2670,17 @@ if (status < 0 && status != EOFC) return_error(gs_error_ioerror); if (stream_w.ptr == stream_w.limit) { - int xe = xo + pss->params.PatchWidthOut; + int xe = xo + (pss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit; + int scaled_h = interpolate_scaled_expanded_height(1, pss); + int scaled_y = yo + (dy * dda_current(pss->params.scale_dda.y)) - + ((dy < 0) ? (scaled_h - 1) : 0); /* Are we active? (i.e. in the render rectangle) */ if (!pss->params.Active) goto inactive; if_debug1m('B', penum->memory, "[B]Interpolated row %d:\n[B]", penum->line_xy); - /* Take care of CM on the entire interpolated row, if we + /* Take care of CM on the entire interpolated row, if we did not already do CM */ if (penum->icc_link->is_identity || pss->params.early_cm) { /* Fastest case. No CM needed */ @@ -1528,13 +2688,13 @@ } else { /* Transform */ p_cm_interp = (unsigned short *) p_cm_buff; - (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, + (penum->icc_link->procs.map_buffer)(dev, penum->icc_link, &input_buff_desc, - &output_buff_desc, + &output_buff_desc, (void*) pinterp, (void*) p_cm_interp); } - p_cm_interp += pss->params.LeftMarginOut * spp_cm; + p_cm_interp += (pss->params.LeftMarginOut / abs_interp_limit) * spp_cm; for (x = xo; x < xe;) { #ifdef DEBUG if (gs_debug_c('B')) { @@ -1546,120 +2706,63 @@ } #endif /* Get the device color */ - /* Now we can do an encoding directly or we have to apply transfer - and or halftoning */ - if (must_halftone || has_transfer) { - /* We need to do the tranfer function and/or the halftoning */ - cmap_transfer_halftone(p_cm_interp, &devc, pis, dev, - has_transfer, must_halftone, gs_color_select_source); - } else { - /* encode as a color index. avoid all the cv to frac to cv - conversions */ - color = dev_proc(dev, encode_color)(dev, p_cm_interp); - /* check if the encoding was successful; we presume failure is rare */ - if (color != gx_no_color_index) - color_set_pure(&devc, color); - } - if (color_is_pure(&devc)) { - /* Just pack colors into a scan line. */ - gx_color_index color = devc.colors.pure; - if (bpp >= 8) - { - /* Skip runs quickly for the common cases. */ - switch (spp_cm) { - case 1: - do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, p_cm_interp += 1; - } while (x < xe && p_cm_interp[-1] == p_cm_interp[0]); - break; - case 3: - do { - LINE_ACCUM(color, bpp); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, p_cm_interp += 3; - } while (x < xe && p_cm_interp[-3] == p_cm_interp[0] && - p_cm_interp[-2] == p_cm_interp[1] && - p_cm_interp[-1] == p_cm_interp[2]); - break; - case 4: - do { - LINE_ACCUM(color, bpp); - x++, p_cm_interp += 4; - } while (x < xe && p_cm_interp[-4] == p_cm_interp[0] && - p_cm_interp[-3] == p_cm_interp[1] && - p_cm_interp[-2] == p_cm_interp[2] && - p_cm_interp[-1] == p_cm_interp[3]); - break; - default: - LINE_ACCUM(color, bpp); - x++, p_cm_interp += spp_cm; - } - } else { - /* Skip runs quickly for the common cases. */ - switch (spp_cm) { - case 1: - do { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, p_cm_interp += 1; - } while (x < xe && p_cm_interp[-1] == p_cm_interp[0]); - break; - case 3: - do { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - vd_pixel(int2fixed(x), int2fixed(ry), color); - x++, p_cm_interp += 3; - } while (x < xe && p_cm_interp[-3] == p_cm_interp[0] && - p_cm_interp[-2] == p_cm_interp[1] && - p_cm_interp[-1] == p_cm_interp[2]); - break; - case 4: - do { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - x++, p_cm_interp += 4; - } while (x < xe && p_cm_interp[-4] == p_cm_interp[0] && - p_cm_interp[-3] == p_cm_interp[1] && - p_cm_interp[-2] == p_cm_interp[2] && - p_cm_interp[-1] == p_cm_interp[3]); - break; - default: - { - int count = bpp_rep; - do { - LINE_ACCUM(color, bpp); - } while (--count); - x++, p_cm_interp += spp_cm; - } - } - } - } else { + get_device_color(penum, p_cm_interp, &devc, &color, dev); + /* We scan for vertical runs of pixels, even if they end up + * being split up in most cases within copy_color_unaligned anyway. */ + { int rcode; + int rep = 0; - LINE_ACCUM_COPY_TRANS(dev, out, bpp, xo, x, raster, ry); - rcode = gx_fill_rectangle_device_rop(ry, x, 1, 1, - &devc, dev, lop); - if (rcode < 0) - return rcode; - LINE_ACCUM_SKIP(bpp); - l_xprev = x + 1; - x++, p_cm_interp += spp_cm; + switch (spp_cm) { + case 1: + do { + rep++, p_cm_interp += 1; + } while ((rep + x) < xe && p_cm_interp[-1] == p_cm_interp[0]); + break; + case 3: + do { + rep++, p_cm_interp += 3; + } while ((rep + x) < xe && p_cm_interp[-3] == p_cm_interp[0] && + p_cm_interp[-2] == p_cm_interp[1] && + p_cm_interp[-1] == p_cm_interp[2]); + break; + case 4: + do { + rep++, p_cm_interp += 4; + } while ((rep + x) < xe && p_cm_interp[-4] == p_cm_interp[0] && + p_cm_interp[-3] == p_cm_interp[1] && + p_cm_interp[-2] == p_cm_interp[2] && + p_cm_interp[-1] == p_cm_interp[3]); + break; + default: + rep = 1, p_cm_interp += spp_cm; + break; + } + + if (abs_interp_limit <= 1) { + rcode = gx_fill_rectangle_device_rop(ry, x, 1, rep, &devc, dev, lop); + if (rcode < 0) + return rcode; + } else { + int scaled_x = xo + dda_current(pss->params.scale_dda.x); + + scaled_w = interpolate_scaled_expanded_width(rep, pss); + rcode = gx_fill_rectangle_device_rop(scaled_y, scaled_x, scaled_h, scaled_w, + &devc, dev, lop); + if (rcode < 0) + return rcode; + dda_advance(pss->params.scale_dda.x, rep); + } + x += rep; } } /* End on x loop */ - LINE_ACCUM_COPY_TRANS(dev, out, bpp, xo, x, raster, ry); /*if_debug1m('w', penum->memory, "[w]Y=%d:\n", ry);*/ /* See siscale.c about 'w'. */ inactive: penum->line_xy++; + if (abs_interp_limit > 1) { + dda_next(pss->params.scale_dda.y); + pss->params.scale_dda.x = save_x_dda; /* reset X to start of line */ + } if_debug0m('B', penum->memory, "\n"); } if ((status == 0 && stream_r.ptr == stream_r.limit) || status == EOFC) @@ -1667,7 +2770,7 @@ } /* Free cm buffer, if it was used */ if (p_cm_buff != NULL) { - gs_free_object(pis->memory, (byte *)p_cm_buff, + gs_free_object(pgs->memory, (byte *)p_cm_buff, "image_render_interpolate_icc"); } } diff -Nru ghostscript-9.10~dfsg/base/gxistate.h ghostscript-9.25~dfsg+1/base/gxistate.h --- ghostscript-9.10~dfsg/base/gxistate.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxistate.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,340 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Imager state definition */ - -#ifndef gxistate_INCLUDED -# define gxistate_INCLUDED - -#include "gscsel.h" -#include "gsrefct.h" -#include "gsropt.h" -#include "gstparam.h" -#include "gxcvalue.h" -#include "gxcmap.h" -#include "gxfixed.h" -#include "gxline.h" -#include "gxmatrix.h" -#include "gxtmap.h" -#include "gscspace.h" -#include "gstrans.h" -#include "gsnamecl.h" -#include "gscms.h" - -/* - Define the subset of the PostScript graphics state that the imager library - API needs. The intended division between the two state structures is that - the imager state contain only information that (1) is not part of the - parameters for individual drawing commands at the gx_ interface (i.e., - will likely be different for each drawing call), and (2) is not an - artifact of the PostScript language (i.e., doesn't need to burden the - structure when it is being used for other imaging, specifically for - imaging a command list). While this criterion is somewhat fuzzy, it leads - us to INCLUDE the following state elements: - line parameters: cap, join, miter limit, dash pattern - transformation matrix (CTM) - logical operation: RasterOp, transparency - color modification: alpha, rendering algorithm - transparency information: - blend mode - (opacity + shape) (alpha + cached mask) - text knockout flag - rendering stack - overprint control: overprint flag, mode, and effective mode - rendering tweaks: flatness, fill adjustment, stroke adjust flag, - accurate curves flag, shading smoothness - color rendering information: - halftone, halftone phases - transfer functions - black generation, undercolor removal - CIE rendering tables - halftone and pattern caches - shared (constant) device color spaces - We EXCLUDE the following for reason #1 (drawing command parameters): - path - clipping path and stack - color specification: color, color space, substitute color spaces - font - device - We EXCLUDE the following for reason #2 (specific to PostScript): - graphics state stack - default CTM - clipping path stack - In retrospect, perhaps the device should have been included in the - imager state, but we don't think this change is worth the trouble now. - */ - -/* - * Define the color rendering state information. - * This should be a separate object (or at least a substructure), - * but making this change would require editing too much code. - */ - -/* Opaque types referenced by the color rendering state. */ -#ifndef gs_halftone_DEFINED -# define gs_halftone_DEFINED -typedef struct gs_halftone_s gs_halftone; -#endif -#ifndef gx_device_color_DEFINED -# define gx_device_color_DEFINED -typedef struct gx_device_color_s gx_device_color; -#endif -#ifndef gx_device_halftone_DEFINED -# define gx_device_halftone_DEFINED -typedef struct gx_device_halftone_s gx_device_halftone; -#endif -#ifndef gs_color_space_DEFINED -# define gs_color_space_DEFINED -typedef struct gs_color_space_s gs_color_space; -#endif - -/* - * We need some special memory management for the components of a - * c.r. state, as indicated by the following notations on the elements: - * (RC) means the element is reference-counted. - * (Shared) means the element is shared among an arbitrary number of - * c.r. states and is never freed. - * (Owned) means exactly one c.r. state references the element, - * and it is guaranteed that no references to it will outlive - * the c.r. state itself. - */ - -/* Define the interior structure of a transfer function. */ -typedef struct gx_transfer_s { - int red_component_num; - gx_transfer_map *red; /* (RC) */ - int green_component_num; - gx_transfer_map *green; /* (RC) */ - int blue_component_num; - gx_transfer_map *blue; /* (RC) */ - int gray_component_num; - gx_transfer_map *gray; /* (RC) */ -} gx_transfer; - -#define gs_color_rendering_state_common\ -\ - /* Halftone screen: */\ -\ - gs_halftone *halftone; /* (RC) */\ - gs_int_point screen_phase[gs_color_select_count];\ - /* dev_ht depends on halftone and device resolution. */\ - gx_device_halftone *dev_ht; /* (RC) */\ -\ - /* Color (device-dependent): */\ -\ - struct gs_cie_render_s *cie_render; /* (RC) may be 0 */\ - bool cie_to_xyz; /* flag for conversion to XYZ, no CRD req'd */\ - gx_transfer_map *black_generation; /* (RC) may be 0 */\ - gx_transfer_map *undercolor_removal; /* (RC) may be 0 */\ - /* set_transfer holds the transfer functions specified by */\ - /* set[color]transfer; effective_transfer includes the */\ - /* effects of overrides by TransferFunctions in halftone */\ - /* dictionaries. (In Level 1 systems, set_transfer and */\ - /* effective_transfer are always the same.) */\ - gx_transfer set_transfer; /* members are (RC) */\ - gx_transfer_map *effective_transfer[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* see below */\ -\ - /* Color caches: */\ -\ - /* cie_joint_caches depend on cie_render and */\ - /* the color space. */\ - struct gx_cie_joint_caches_s *cie_joint_caches; /* (RC) */\ - /* cmap_procs depend on the device's color_info. */\ - const struct gx_color_map_procs_s *cmap_procs; /* static */\ - /* DeviceN component map for current color space */\ - gs_devicen_color_map color_component_map;\ - /* The contents of pattern_cache depend on the */\ - /* the color space and the device's color_info and */\ - /* resolution. */\ - struct gx_pattern_cache_s *pattern_cache; /* (Shared) by all gstates */\ -\ - /* Simple color spaces, stored here for easy access from */ \ - /* gx_concrete_space_CIE */ \ - gs_color_space *devicergb_cs;\ - gs_color_space *devicecmyk_cs;\ -\ - /* Stores for cached values which correspond to whichever */\ - /* color isn't in force at the moment */\ - struct gx_cie_joint_caches_s *cie_joint_caches_alt;\ - gs_devicen_color_map color_component_map_alt - -/* - * Enumerate the reference-counted pointers in a c.r. state. Note that - * effective_transfer doesn't contribute to the reference count: it points - * either to the same objects as set_transfer, or to objects in a halftone - * structure that someone else worries about. - */ -#define gs_cr_state_do_rc_ptrs(m)\ - m(halftone) m(dev_ht) m(cie_render)\ - m(black_generation) m(undercolor_removal)\ - m(set_transfer.red) m(set_transfer.green)\ - m(set_transfer.blue) m(set_transfer.gray)\ - m(cie_joint_caches)\ - m(devicergb_cs) m(devicecmyk_cs)\ - m(cie_joint_caches_alt) - -/* Enumerate the pointers in a c.r. state. */ -#define gs_cr_state_do_ptrs(m)\ - m(0,halftone) m(1,dev_ht)\ - m(2,cie_render) m(3,black_generation) m(4,undercolor_removal)\ - m(5,set_transfer.red) m(6,set_transfer.green)\ - m(7,set_transfer.blue) m(8,set_transfer.gray)\ - m(9,cie_joint_caches) m(10,pattern_cache)\ - m(11,devicergb_cs) m(12,devicecmyk_cs)\ - m(13,cie_joint_caches_alt) - /* - * We handle effective_transfer specially in gsistate.c since its pointers - * are not enumerated for garbage collection but they are are relocated. - */ -/* - * This count does not include the effective_transfer pointers since they - * are not enumerated for GC. - */ -#define st_cr_state_num_ptrs 14 - -#ifndef gs_devicen_color_map_DEFINED -# define gs_devicen_color_map_DEFINED -typedef struct gs_devicen_color_map_s gs_devicen_color_map; -#endif - -struct gs_devicen_color_map_s { - bool use_alt_cspace; - separation_type sep_type; - uint num_components; /* Input - Duplicate of value in gs_device_n_params */ - uint num_colorants; /* Number of colorants - output */ - gs_id cspace_id; /* Used to verify color space and map match */ - int color_map[GS_CLIENT_COLOR_MAX_COMPONENTS]; -}; - - -/* These flags are used to keep track of qQ - combinations surrounding a graphic state - change that includes a softmask setting. - The transparency compositor must be notified - when a Q event occurs following a softmask */ - -typedef struct gs_xstate_trans_flags { - bool xstate_pending; - bool xstate_change; -} gs_xstate_trans_flags_t; - -/* Define the imager state structure itself. */ -/* - * Note that the ctm member is a gs_matrix_fixed. As such, it cannot be - * used directly as the argument for procedures like gs_point_transform. - * Instead, one must use the ctm_only macro, e.g., &ctm_only(pis) rather - * than &pis->ctm. - */ -#define gs_imager_state_common\ - bool is_gstate; /* is this imager state part of gstate ? */\ - gs_memory_t *memory;\ - void *client_data;\ - gx_line_params line_params;\ - bool hpgl_path_mode;\ - gs_matrix_fixed ctm;\ - bool current_point_valid;\ - gs_point current_point;\ - gs_point subpath_start;\ - bool clamp_coordinates;\ - gs_logical_operation_t log_op;\ - gx_color_value alpha;\ - gs_blend_mode_t blend_mode;\ - gs_transparency_source_t opacity, shape;\ - gs_xstate_trans_flags_t trans_flags;\ - gs_id soft_mask_id;\ - bool text_knockout;\ - uint text_rendering_mode;\ - bool has_transparency; /* used to keep from doing shading fills in device color space */\ - gx_device *trans_device; /* trans device has all mappings to group color space */\ - bool overprint;\ - int overprint_mode;\ - int effective_overprint_mode;\ - bool overprint_alt;\ - int overprint_mode_alt;\ - int effective_overprint_mode_alt;\ - float flatness;\ - gs_fixed_point fill_adjust; /* A path expansion for fill; -1 = dropout prevention*/\ - bool stroke_adjust;\ - bool accurate_curves;\ - bool have_pattern_streams;\ - float smoothness;\ - int renderingintent; /* See gsstate.c */\ - bool blackptcomp;\ - gsicc_manager_t *icc_manager; /* ICC color manager, profile */\ - gsicc_link_cache_t *icc_link_cache; /* ICC linked transforms */\ - gsicc_profile_cache_t *icc_profile_cache; /* ICC profiles from PS. */\ - CUSTOM_COLOR_PTR /* Pointer to custom color callback struct */\ - const gx_color_map_procs *\ - (*get_cmap_procs)(const gs_imager_state *, const gx_device *);\ - gs_color_rendering_state_common -#define st_imager_state_num_ptrs\ - (st_line_params_num_ptrs + st_cr_state_num_ptrs + 5) -/* Access macros */ -#define ctm_only(pis) (*(const gs_matrix *)&(pis)->ctm) -#define ctm_only_writable(pis) (*(gs_matrix *)&(pis)->ctm) -#define set_ctm_only(pis, mat) (*(gs_matrix *)&(pis)->ctm = (mat)) -#define gs_init_rop(pis) ((pis)->log_op = lop_default) -#define gs_currentflat_inline(pis) ((pis)->flatness) -#define gs_currentlineparams_inline(pis) (&(pis)->line_params) -#define gs_current_logical_op_inline(pis) ((pis)->log_op) -#define gs_set_logical_op_inline(pis, lop) ((pis)->log_op = (lop)) - -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; -#endif - -struct gs_imager_state_s { - gs_imager_state_common; -}; - -/* Initialization for gs_imager_state */ -#define gs_imager_state_initial(scale, is_gstate)\ - is_gstate, 0, 0, { gx_line_params_initial }, 0,\ - { (float)(scale), 0.0, 0.0, (float)(-(scale)), 0.0, 0.0 },\ - false, {0, 0}, {0, 0}, false, \ - lop_default, gx_max_color_value, BLEND_MODE_Compatible,\ -{ 1.0 }, { 1.0 }, {0, 0}, 0, 0/*false*/, 0, 0, 0, 0/*false*/, 0, 0, 0/*false*/, 0, 0, 1.0, \ - { fixed_half, fixed_half }, 0/*false*/, 0/*false*/, 0/*false*/, 1.0,\ - 1, 1/* bpt true */, 0, 0, 0, INIT_CUSTOM_COLOR_PTR /* 'Custom color' callback pointer */ \ - gx_default_get_cmap_procs - -/* The imager state structure is public only for subclassing. */ -#define public_st_imager_state() /* in gsistate.c */\ - gs_public_st_composite(st_imager_state, gs_imager_state, "gs_imager_state",\ - imager_state_enum_ptrs, imager_state_reloc_ptrs) - -/* Initialize an imager state, other than the parts covered by */ -/* gs_imager_state_initial. */ -int gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem); - -/* Make a temporary copy of a gs_imager_state. Note that this does not */ -/* do all the necessary reference counting, etc. */ -gs_imager_state * - gs_imager_state_copy(const gs_imager_state * pis, gs_memory_t * mem); - -/* Increment reference counts to note that an imager state has been copied. */ -void gs_imager_state_copied(gs_imager_state * pis); - -/* Adjust reference counts before assigning one imager state to another. */ -void gs_imager_state_pre_assign(gs_imager_state *to, - const gs_imager_state *from); - -/* Release an imager state. */ -void gs_imager_state_release(gs_imager_state * pis); -int gs_currentscreenphase_pis(const gs_imager_state *, gs_int_point *, gs_color_select_t); - -#endif /* gxistate_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxline.h ghostscript-9.25~dfsg+1/base/gxline.h --- ghostscript-9.10~dfsg/base/gxline.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxline.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -61,14 +61,14 @@ ((plp)->half_width = fabs(wid) / 2) #define gx_current_line_width(plp)\ ((plp)->half_width * 2) -int gx_set_miter_limit(gx_line_params *, floatp); +int gx_set_miter_limit(gx_line_params *, double); #define gx_current_miter_limit(plp)\ ((plp)->miter_limit) -int gx_set_dash(gx_dash_params *, const float *, uint, floatp, gs_memory_t *); +int gx_set_dash(gx_dash_params *, const float *, uint, double, gs_memory_t *); #define gx_set_dash_adapt(pdp, adpt) ((pdp)->adapt = (adpt)) -int gx_set_dot_length(gx_line_params *, floatp, bool); +int gx_set_dot_length(gx_line_params *, double, bool); /* See gsline.c for the computation of miter_check. */ #define gx_line_params_initial\ diff -Nru ghostscript-9.10~dfsg/base/gxlum.h ghostscript-9.25~dfsg+1/base/gxlum.h --- ghostscript-9.10~dfsg/base/gxlum.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxlum.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxmatrix.h ghostscript-9.25~dfsg+1/base/gxmatrix.h --- ghostscript-9.10~dfsg/base/gxmatrix.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxmatrix.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -47,13 +47,13 @@ int gs_matrix_fixed_from_matrix(gs_matrix_fixed *, const gs_matrix *); /* Coordinate transformations to fixed point. */ -int gs_point_transform2fixed(const gs_matrix_fixed *, floatp, floatp, +int gs_point_transform2fixed(const gs_matrix_fixed *, double, double, gs_fixed_point *); -int gs_distance_transform2fixed(const gs_matrix_fixed *, floatp, floatp, +int gs_distance_transform2fixed(const gs_matrix_fixed *, double, double, gs_fixed_point *); #if PRECISE_CURRENTPOINT int gs_point_transform2fixed_rounding(const gs_matrix_fixed * pmat, - floatp x, floatp y, gs_fixed_point * ppt); + double x, double y, gs_fixed_point * ppt); #endif /* diff -Nru ghostscript-9.10~dfsg/base/gxmclip.c ghostscript-9.25~dfsg+1/base/gxmclip.c --- ghostscript-9.10~dfsg/base/gxmclip.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxmclip.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxmclip.h ghostscript-9.25~dfsg+1/base/gxmclip.h --- ghostscript-9.10~dfsg/base/gxmclip.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxmclip.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -34,9 +34,9 @@ * stack frame. */ -#define tile_clip_buffer_request 16384 /* enough for 2400 dpi up to 54" wide */ +#define tile_clip_buffer_request 32768 /* enough for 2400 dpi up to 109" wide */ #define tile_clip_buffer_size\ - ((tile_clip_buffer_request / arch_sizeof_long) * arch_sizeof_long) + ((tile_clip_buffer_request / ARCH_SIZEOF_LONG) * ARCH_SIZEOF_LONG) typedef struct gx_device_mask_clip_s { gx_device_forward_common; /* target is set by client */ gx_strip_bitmap tiles; @@ -46,7 +46,7 @@ /* Ensure that the buffer is long-aligned. */ union _b { byte bytes[tile_clip_buffer_size]; - ulong longs[tile_clip_buffer_size / arch_sizeof_long]; + ulong longs[tile_clip_buffer_size / ARCH_SIZEOF_LONG]; } buffer; } gx_device_mask_clip; diff -Nru ghostscript-9.10~dfsg/base/gxobj.h ghostscript-9.25~dfsg+1/base/gxobj.h --- ghostscript-9.10~dfsg/base/gxobj.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxobj.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -80,19 +80,19 @@ * The back pointer's meaning depends on whether the object is * free (unmarked) or in use (marked): * - In free objects, the back pointer is an offset from the object - * header back to a chunk_head_t structure that contains the location - * to which all the data in this chunk will get moved; the reloc field + * header back to a clump_head_t structure that contains the location + * to which all the data in this clump will get moved; the reloc field * contains the amount by which the following run of useful objects * will be relocated downwards. * - In useful objects, the back pointer is an offset from the object * back to the previous free object; the reloc field is not used (it * overlays the type field). - * These two cases can be distinguished when scanning a chunk linearly, - * but when simply examining an object via a pointer, the chunk pointer + * These two cases can be distinguished when scanning a clump linearly, + * but when simply examining an object via a pointer, the clump pointer * is also needed. */ #define obj_flag_bits 1 -#define obj_mb_bits (arch_sizeof_int * 8 - obj_flag_bits) +#define obj_mb_bits (ARCH_SIZEOF_INT * 8 - obj_flag_bits) #define o_unmarked (((uint)1 << obj_mb_bits) - 1) #define o_set_unmarked(pp)\ ((pp)->o_smark = o_unmarked) @@ -199,16 +199,16 @@ /* * Define the header that free objects point back to when relocating. - * Every chunk, including inner chunks, has one of these. + * Every clump, including inner clumps, has one of these. */ -typedef struct chunk_head_s { +typedef struct clump_head_s { byte *dest; /* destination for objects */ -#if obj_align_mod > arch_sizeof_ptr - byte *_pad[obj_align_mod / arch_sizeof_ptr - 1]; +#if obj_align_mod > ARCH_SIZEOF_PTR + byte *_pad[obj_align_mod / ARCH_SIZEOF_PTR - 1]; #endif obj_header_t free; /* header for a free object, */ /* in case the first real object */ /* is in use */ -} chunk_head_t; +} clump_head_t; #endif /* gxobj_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxoprect.c ghostscript-9.25~dfsg+1/base/gxoprect.c --- ghostscript-9.10~dfsg/base/gxoprect.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxoprect.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -187,9 +187,7 @@ int gx_overprint_generic_fill_rectangle( gx_device * tdev, - bool blendspot, gx_color_index drawn_comps, - ushort k_value, int x, int y, int w, @@ -232,7 +230,7 @@ /* allocate space for a scanline of color indices */ pcolor_buff = (gx_color_index *) gs_alloc_bytes( mem, - w * arch_sizeof_color_index, + w * ARCH_SIZEOF_COLOR_INDEX, "overprint generic fill rectangle" ); if (pcolor_buff == 0) return gs_note_error(gs_error_VMerror); @@ -322,28 +320,9 @@ if ((code = dev_proc(tdev, decode_color)(tdev, *cp, dest_cvals)) < 0) break; - if (k_value > 0) { - /* Have to run through all 3 components */ - for (j = 0, comps = drawn_comps; j < 3; j++, comps >>= 1) { + for (j = 0, comps = drawn_comps; comps != 0; ++j, comps >>= 1) { if ((comps & 0x1) != 0) dest_cvals[j] = src_cvals[j]; - else { - int temp = (dest_cvals[j] * (256 - k_value)); - dest_cvals[j] = temp >> 8; - } - } - } else { - if (blendspot) { - for (j = 0, comps = drawn_comps; comps != 0; ++j, comps >>= 1) { - if ((comps & 0x1) != 0) - dest_cvals[j] = src_cvals[j]; - } - } else { - for (j = 0, comps = drawn_comps; comps != 0; ++j, comps >>= 1) { - if ((comps & 0x1) != 0) - dest_cvals[j] = src_cvals[j]; - } - } } *cp = dev_proc(tdev, encode_color)(tdev, dest_cvals); } @@ -546,7 +525,6 @@ int gx_overprint_sep_fill_rectangle_2( gx_device * tdev, - bool blendspot, gx_color_index retain_mask, /* already swapped */ int x, int y, @@ -569,9 +547,9 @@ /* set up color and retain mask pointers */ pcolor = (byte *)&color; pmask = (byte *)&retain_mask; -#if arch_is_big_endian - pcolor += arch_sizeof_color_index - byte_depth; - pmask += arch_sizeof_color_index - byte_depth; +#if ARCH_IS_BIG_ENDIAN + pcolor += ARCH_SIZEOF_COLOR_INDEX - byte_depth; + pmask += ARCH_SIZEOF_COLOR_INDEX - byte_depth; #endif /* allocate a buffer for the returned data */ @@ -612,23 +590,10 @@ 0 ); if (code < 0) break; - if (blendspot) { - /* We need to blend the CMYK colorants as we are simulating - the overprint of a spot colorant with its equivalent CMYK - colorants */ - for (i = 0, j = 0; i < byte_w; i++, cp++) { - int temp = (255-*cp) * (255-pcolor[j]); - temp = temp >> 8; - *cp = (255-temp); - if (++j == byte_depth) - j = 0; - } - } else { - for (i = 0, j = 0; i < byte_w; i++, cp++) { - *cp = (*cp & pmask[j]) | pcolor[j]; - if (++j == byte_depth) - j = 0; - } + for (i = 0, j = 0; i < byte_w; i++, cp++) { + *cp = (*cp & pmask[j]) | pcolor[j]; + if (++j == byte_depth) + j = 0; } code = dev_proc(tdev, copy_color)( tdev, gb_buff, diff -Nru ghostscript-9.10~dfsg/base/gxoprect.h ghostscript-9.25~dfsg+1/base/gxoprect.h --- ghostscript-9.10~dfsg/base/gxoprect.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxoprect.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,9 +27,7 @@ */ extern int gx_overprint_generic_fill_rectangle( gx_device * tdev, - bool blendspot, gx_color_index drawn_comps, - ushort k_value, int x, int y, int w, @@ -64,7 +62,6 @@ extern int gx_overprint_sep_fill_rectangle_2( gx_device * tdev, - bool blendspot, gx_color_index retain_mask, /* already swapped */ int x, int y, diff -Nru ghostscript-9.10~dfsg/base/gxp1fill.c ghostscript-9.25~dfsg+1/base/gxp1fill.c --- ghostscript-9.10~dfsg/base/gxp1fill.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxp1fill.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -102,7 +102,7 @@ bool is_planar; ptfs->pdevc = pdevc; - is_planar = dev_proc(dev, dev_spec_op)(dev, gxdso_is_native_planar, NULL, 0) > 0; + is_planar = dev->is_planar; if (is_planar) { ptfs->num_planes = dev->color_info.num_components; } else { @@ -256,7 +256,7 @@ bool full_transfer = (w == ptfs->w0 && h == ptfs->h0); int code = 0; - if (source == NULL && lop_no_S_is_T(lop) && dev->procs.copy_planes != NULL && + if (source == NULL && lop_no_S_is_T(lop) && dev_proc(dev, copy_planes) != gx_default_copy_planes && ptfs->num_planes > 0) { code = (*dev_proc(ptfs->pcdev, copy_planes)) (ptfs->pcdev, data + bits->raster * yoff, xoff, @@ -329,16 +329,26 @@ crdev->offset_map = NULL; crdev->page_info.io_procs->rewind(crdev->page_info.bfile, false, NULL); crdev->page_info.io_procs->rewind(crdev->page_info.cfile, false, NULL); + clist_render_init(cdev); /* Check for and get ICC profile table */ - if (crdev->icc_table == NULL) + if (crdev->icc_table == NULL) { code = clist_read_icctable(crdev); + if (code < 0) + return code; + } /* Also allocate the icc cache for the clist reader */ if ( crdev->icc_cache_cl == NULL ) - crdev->icc_cache_cl = gsicc_cache_new(crdev->memory); + crdev->icc_cache_cl = gsicc_cache_new(crdev->memory->thread_safe_memory); if_debug0m('L', dev->memory, "Pattern clist playback begin\n"); code = clist_playback_file_bands(playback_action_render, crdev, &crdev->page_info, dev, 0, 0, ptfs->xoff - x, ptfs->yoff - y); if_debug0m('L', dev->memory, "Pattern clist playback end\n"); + /* FIXME: it would be preferable to have this persist, but as + * clist_render_init() sets it to NULL, we currently have to + * cleanup before returning. Set to NULL for safety + */ + rc_decrement(crdev->icc_cache_cl, "tile_pattern_clist"); + crdev->icc_cache_cl = NULL; return code; } @@ -683,9 +693,8 @@ /* We only go through blending during tiling, if there was overlap as defined by the step matrix and the bounding box */ - ptile->ttrans->pat_trans_fill(x, y, x+w, y+h, px, py, ptile, - fill_trans_buffer); + fill_trans_buffer); } } return 0; @@ -714,6 +723,7 @@ int mid_copy_width, right_copy_width; int tile_width = ptile->ttrans->width; int tile_height = ptile->ttrans->height; + int src_planes = fill_trans_buffer->n_chan + (fill_trans_buffer->has_tags ? 1 : 0); /* Update the bbox in the topmost stack entry to reflect the fact that we * have drawn into it. FIXME: This makes the groups too large! */ @@ -772,10 +782,12 @@ if (right_copy_width < 0) right_copy_width = 0; - for (kk = 0; kk < fill_trans_buffer->n_chan; kk++) { + for (kk = 0; kk < src_planes; kk++) { ptr_out = buff_out + kk * fill_trans_buffer->planestride; ptr_in = buff_in + kk * ptile->ttrans->planestride; + if (fill_trans_buffer->has_shape && kk == fill_trans_buffer->n_chan) + ptr_out += fill_trans_buffer->planestride; /* tag plane follows shape plane */ for (jj = 0; jj < h; jj++, ptr_out += fill_trans_buffer->rowstride) { @@ -837,6 +849,11 @@ int tile_width = ptile->ttrans->width; int tile_height = ptile->ttrans->height; int num_chan = ptile->ttrans->n_chan; /* Includes alpha */ + int tag_offset = fill_trans_buffer->n_chan + (fill_trans_buffer->has_shape ? 1 : 0); + pdf14_device *p14dev = (pdf14_device *) fill_trans_buffer->pdev14; + + if (fill_trans_buffer->has_tags == 0) + tag_offset = 0; /* Update the bbox in the topmost stack entry to reflect the fact that we * have drawn into it. FIXME: This makes the groups too large! */ @@ -900,15 +917,22 @@ } /* Blend */ - art_pdf_composite_pixel_alpha_8(dst, src, - ptile->ttrans->n_chan-1, - ptile->ttrans->blending_mode, - ptile->ttrans->blending_procs); + art_pdf_composite_pixel_alpha_8(dst, src, ptile->ttrans->n_chan-1, + ptile->blending_mode, ptile->ttrans->n_chan-1, + ptile->ttrans->blending_procs, p14dev); /* Store the color values */ for (kk = 0; kk < num_chan; kk++) { *(buff_ptr + kk * fill_trans_buffer->planestride) = dst[kk]; } + /* Now handle the blending of the tag. NB: dst tag_offset follows shape */ + if (tag_offset > 0) { + int src_tag = *(tile_ptr + num_chan * ptile->ttrans->planestride); + int dst_tag = *(buff_ptr + tag_offset * fill_trans_buffer->planestride); + + dst_tag |= src_tag; /* simple blend combines tags */ + *(buff_ptr + tag_offset * fill_trans_buffer->planestride) = dst_tag; + } } } @@ -946,16 +970,24 @@ phase.x = pdevc->phase.x; phase.y = pdevc->phase.y; +#if 0 + if_debug8m('v', ptile->ttrans->mem, + "[v]gx_dc_pat_trans_fill_rectangle, Fill: (%d, %d), %d x %d To Buffer: (%d, %d), %d x %d \n", + x, y, w, h, ptile->ttrans->fill_trans_buffer->rect.p.x, + ptile->ttrans->fill_trans_buffer->rect.p.y, + ptile->ttrans->fill_trans_buffer->rect.q.x - + ptile->ttrans->fill_trans_buffer->rect.p.x, + ptile->ttrans->fill_trans_buffer->rect.q.y - + ptile->ttrans->fill_trans_buffer->rect.p.y); +#endif code = gx_trans_pattern_fill_rect(x, y, x+w, y+h, ptile, ptile->ttrans->fill_trans_buffer, phase, dev, pdevc); - return code; } /* This fills the transparency buffer rectangles with a pattern buffer that includes transparency */ - int gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax, gx_color_tile *ptile, @@ -963,21 +995,20 @@ gs_int_point phase, gx_device *dev, const gx_device_color * pdevc) { - tile_fill_trans_state_t state_trans; tile_fill_state_t state_clist_trans; int code = 0; + int w = xmax - xmin; + int h = ymax - ymin; if (ptile == 0) /* null pattern */ return 0; - /* Fit fill */ - if ( (xmin | ymin) < 0 ) { - if ( xmin < 0 ) - xmin = 0; - if ( ymin < 0 ) - ymin = 0; - } + fit_fill_xywh(dev, xmin, ymin, w, h); + if (w < 0 || h < 0) + return 0; + xmax = w + xmin; + ymax = h + ymin; /* Initialize the fill state */ state_trans.phase.x = phase.x; @@ -1029,8 +1060,8 @@ tbits.size.x = crdev->width; tbits.size.y = crdev->height; if (code >= 0) - code = tile_by_steps(&state_clist_trans, xmin, ymin, xmax, - ymax, ptile, &tbits, tile_pattern_clist); + code = tile_by_steps(&state_clist_trans, xmin, ymin, xmax-xmin, + ymax-ymin, ptile, &tbits, tile_pattern_clist); if (code >= 0 && (state_clist_trans.cdev != NULL)) { tile_clip_free((gx_device_tile_clip *)state_clist_trans.cdev); @@ -1039,5 +1070,5 @@ } } - return(code); + return code; } diff -Nru ghostscript-9.10~dfsg/base/gxp1impl.h ghostscript-9.25~dfsg+1/base/gxp1impl.h --- ghostscript-9.10~dfsg/base/gxp1impl.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxp1impl.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -35,7 +35,7 @@ /* * Declare the Pattern color mapping procedures exported by gxpcmap.c. */ -int gx_pattern_load(gx_device_color *, const gs_imager_state *, +int gx_pattern_load(gx_device_color *, const gs_gstate *, gx_device *, gs_color_select_t); pattern_proc_remap_color(gs_pattern1_remap_color); diff -Nru ghostscript-9.10~dfsg/base/gxpageq.c ghostscript-9.25~dfsg+1/base/gxpageq.c --- ghostscript-9.10~dfsg/base/gxpageq.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpageq.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,359 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Page queue implementation */ - -/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */ - -#include "gx.h" -#include "gxdevice.h" -#include "gxclist.h" -#include "gxpageq.h" -#include "gserrors.h" -#include "gsstruct.h" - -/* Define the structure implementation for a page queue. */ -struct gx_page_queue_s { - gs_memory_t *memory; /* allocator used to allocate entries */ - gx_monitor_t *monitor; /* used to serialize access to this structure */ - int entry_count; /* # elements in page_queue */ - bool dequeue_in_progress; /* true between start/ & end_dequeue */ - gx_semaphore_t *render_req_sema; /* sema signalled when page queued */ - bool enable_render_done_signal; /* enable signals to render_done_sema */ - gx_semaphore_t *render_done_sema; /* semaphore signaled when (partial) page rendered */ - gx_page_queue_entry_t *last_in; /* if <> 0, Last-in queue entry */ - gx_page_queue_entry_t *first_in; /* if <> 0, First-in queue entry */ - gx_page_queue_entry_t *reserve_entry; /* spare allocation */ -}; - -/* - * Null initializer for entry page_info (used by gx_page_queue_add_page() ). - */ -static const gx_band_page_info_t null_page_info = { PAGE_INFO_NULL_VALUES }; - -#define private_st_gx_page_queue()\ - gs_private_st_ptrs4(st_gx_page_queue, gx_page_queue_t, "gx_page_queue",\ - gx_page_queue_enum_ptrs, gx_page_queue_reloc_ptrs,\ - monitor, first_in, last_in, reserve_entry); - -/* ------------------- Global Data ----------------------- */ - -/* Structure descriptor for GC */ -private_st_gx_page_queue_entry(); -private_st_gx_page_queue(); - -/* ------------ Forward Decl's --------------------------- */ -static gx_page_queue_entry_t * /* removed entry, 0 if none avail */ - gx_page_queue_remove_first( - gx_page_queue_t * queue /* page queue to retrieve from */ - ); - -/* --------------------Procedures------------------------- */ - -/* Allocate a page queue. */ -gx_page_queue_t * -gx_page_queue_alloc(gs_memory_t *mem) -{ - return gs_alloc_struct(mem, gx_page_queue_t, &st_gx_page_queue, - "gx_page_queue_alloc"); -} - -/* ------- page_queue_entry alloc/free --------- */ - -/* Allocate & init a gx_page_queue_entry */ -gx_page_queue_entry_t * /* rets ptr to allocated object, 0 if VM error */ -gx_page_queue_entry_alloc( - gx_page_queue_t * queue /* queue that entry is being alloc'd for */ -) -{ - gx_page_queue_entry_t *entry - = gs_alloc_struct(queue->memory, gx_page_queue_entry_t, - &st_gx_page_queue_entry, "gx_page_queue_entry_alloc"); - - if (entry != 0) { - entry->next = 0; - entry->queue = queue; - } - return entry; -} - -/* Free a gx_page_queue_entry allocated w/gx_page_queue_entry_alloc */ -void -gx_page_queue_entry_free( - gx_page_queue_entry_t * entry /* entry to free up */ -) -{ - gs_free_object(entry->queue->memory, entry, "gx_page_queue_entry_free"); -} - -/* Free the clist resources held by a gx_page_queue_entry_t */ -void -gx_page_queue_entry_free_page_info( - gx_page_queue_entry_t * entry /* entry to free up */ -) -{ - clist_close_page_info( &entry->page_info ); -} - -/* -------- page_queue init/dnit ---------- */ - -/* Initialize a gx_page_queue object */ -int /* -ve error code, or 0 */ -gx_page_queue_init( - gx_page_queue_t * queue, /* page queue to init */ - gs_memory_t * memory /* allocator for dynamic memory */ -) -{ - queue->memory = memory; - queue->monitor = gx_monitor_alloc(memory); /* alloc monitor to serialize */ - queue->entry_count = 0; - queue->dequeue_in_progress = false; - queue->render_req_sema = gx_semaphore_alloc(memory); - queue->enable_render_done_signal = false; - queue->render_done_sema = gx_semaphore_alloc(memory); - queue->first_in = queue->last_in = 0; - queue->reserve_entry = gx_page_queue_entry_alloc(queue); - - if (queue->monitor && queue->render_req_sema && queue->render_done_sema - && queue->reserve_entry) - return 0; - else { - gx_page_queue_dnit(queue); - return gs_error_VMerror; - } -} - -/* Dnitialize a gx_page_queue object */ -void -gx_page_queue_dnit( - gx_page_queue_t * queue /* page queue to dnit */ -) -{ - /* Deallocate any left-over queue entries */ - gx_page_queue_entry_t *entry; - - while ((entry = gx_page_queue_remove_first(queue)) != 0) { - gx_page_queue_entry_free_page_info(entry); - gx_page_queue_entry_free(entry); - } - - /* Free dynamic objects */ - if (queue->monitor) { - gx_monitor_free(queue->monitor); - queue->monitor = 0; - } - if (queue->render_req_sema) { - gx_semaphore_free(queue->render_req_sema); - queue->render_req_sema = 0; - } - if (queue->render_done_sema) { - gx_semaphore_free(queue->render_done_sema); - queue->render_done_sema = 0; - } - if (queue->reserve_entry) { - gx_page_queue_entry_free(queue->reserve_entry); - queue->reserve_entry = 0; - } -} - -/* -------- low-level queue add/remove ---------- */ - -/* Retrieve & remove firstin queue entry */ -static gx_page_queue_entry_t * /* removed entry, 0 if none avail */ -gx_page_queue_remove_first( - gx_page_queue_t * queue /* page queue to retrieve from */ -) -{ - gx_page_queue_entry_t *entry = 0; /* assume failure */ - - /* Enter monitor */ - gx_monitor_enter(queue->monitor); - - /* Get the goods */ - if (queue->entry_count) { - entry = queue->first_in; - queue->first_in = entry->next; - if (queue->last_in == entry) - queue->last_in = 0; - --queue->entry_count; - } - /* exit monitor */ - gx_monitor_leave(queue->monitor); - - return entry; -} - -/* Add entry to queue at end */ -static void -gx_page_queue_add_last( - gx_page_queue_entry_t * entry /* entry to add */ -) -{ - gx_page_queue_t *queue = entry->queue; - - /* Enter monitor */ - gx_monitor_enter(queue->monitor); - - /* Add the goods */ - entry->next = 0; - if (queue->last_in != 0) - queue->last_in->next = entry; - queue->last_in = entry; - if (queue->first_in == 0) - queue->first_in = entry; - ++queue->entry_count; - - /* exit monitor */ - gx_monitor_leave(queue->monitor); -} - -/* --------- low-level synchronization ---------- */ - -/* Wait for a single page to finish rendering (if any pending) */ -int /* rets 0 if no pages were waiting for rendering, 1 if actually waited */ -gx_page_queue_wait_one_page( - gx_page_queue_t * queue /* queue to wait on */ -) -{ - int code; - - gx_monitor_enter(queue->monitor); - if (!queue->entry_count && !queue->dequeue_in_progress) { - code = 0; - gx_monitor_leave(queue->monitor); - } else { - /* request acknowledgement on render done */ - queue->enable_render_done_signal = true; - - /* exit monitor & wait for acknowlegement */ - gx_monitor_leave(queue->monitor); - gx_semaphore_wait(queue->render_done_sema); - code = 1; - } - return code; -} - -/* Wait for page queue to become empty */ -void -gx_page_queue_wait_until_empty( - gx_page_queue_t * queue /* page queue to wait on */ -) -{ - while (gx_page_queue_wait_one_page(queue)); -} - -/* ----------- Synchronized page_queue get/put routines ------ */ - -/* Add an entry to page queue for rendering w/sync to renderer */ -void -gx_page_queue_enqueue( - gx_page_queue_entry_t * entry /* entry to add */ -) -{ - gx_page_queue_t *queue = entry->queue; - - /* Add the goods to queue, & signal it */ - gx_page_queue_add_last(entry); - gx_semaphore_signal(queue->render_req_sema); -} - -/* Add page to a page queue */ -/* Even if an error is returned, entry will have been added to queue! */ -int /* rets 0 ok, gs_error_VMerror if error */ -gx_page_queue_add_page(gx_device_clist_writer *const pcwdev, - gx_page_queue_t * queue, /* page queue to add to */ - gx_page_queue_action_t action, /* action code to queue */ - const gx_band_page_info_t * page_info, /* bandinfo incl. bandlist (or 0) */ - int page_count /* see comments in gdevprna.c */ -) -{ - int code = 0; - - /* Allocate a new page queue entry */ - gx_page_queue_entry_t *entry - = gx_page_queue_entry_alloc(queue); - - if (!entry) { - /* Use reserve page queue entry */ - gx_monitor_enter(queue->monitor); /* not strictly necessary */ - entry = queue->reserve_entry; - queue->reserve_entry = 0; - gx_monitor_leave(queue->monitor); - } - /* Fill in page queue entry with info from device */ - entry->action = action; - if (page_info != 0) - entry->page_info = *page_info; - else { - entry->page_info = null_page_info; - entry->page_info.io_procs = pcwdev->page_info.io_procs; - } - entry->num_copies = page_count; - - /* Stick onto page queue & signal */ - gx_page_queue_enqueue(entry); - - /* If a new reserve entry is needed, wait till enough mem is avail */ - while (!queue->reserve_entry) { - queue->reserve_entry = gx_page_queue_entry_alloc(queue); - if (!queue->reserve_entry && !gx_page_queue_wait_one_page(queue)) { - /* Should never happen: all pages rendered & still can't get memory: give up! */ - code = gs_note_error(gs_error_Fatal); - break; - } - } - return code; -} - -/* Wait for & get next page queue entry */ -gx_page_queue_entry_t * /* removed entry */ -gx_page_queue_start_dequeue( - gx_page_queue_t * queue /* page queue to retrieve from */ -) -{ - gx_semaphore_wait(queue->render_req_sema); - queue->dequeue_in_progress = true; - return gx_page_queue_remove_first(queue); -} - -/* After rendering page gotten w/gx_page_queue_dequeue, call this to ack */ -void -gx_page_queue_finish_dequeue( - gx_page_queue_entry_t * entry /* entry that was retrieved to delete */ -) -{ - gx_page_queue_t *queue = entry->queue; - - gx_monitor_enter(queue->monitor); - if (queue->enable_render_done_signal) { - queue->enable_render_done_signal = false; - gx_semaphore_signal(queue->render_done_sema); - } - queue->dequeue_in_progress = false; - - /* - * Delete the previously-allocated entry, do inside monitor in case - * this is the reserve entry & is the only memory in the universe; - * in that case gx_page_queue_add_page won't be looking for this - * until the monitor is exited. - * In this implementation of the page queue, clist and queue entries - * are managed together, so free the clist just before freeing the entry. - */ - gx_page_queue_entry_free_page_info(entry); - gx_page_queue_entry_free(entry); - - gx_monitor_leave(queue->monitor); -} diff -Nru ghostscript-9.10~dfsg/base/gxpageq.h ghostscript-9.25~dfsg+1/base/gxpageq.h --- ghostscript-9.10~dfsg/base/gxpageq.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpageq.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,269 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Page queue implementation */ - -/* Initial version 2/1/98 by John Desrosiers (soho@crl.com) */ -/* 7/17/98 L. Peter Deutsch (ghost@aladdin.com) edited to conform to - Ghostscript coding standards */ -/* 8/7/98 ghost@aladdin.com fixed bugs in #define st_... statements */ -/* 11/3/98 ghost@aladdin.com further updates for coding standards, - moves definition of page queue structure to gxpageq.c */ -/* 12/1/98 soho@crl.com - Upgraded gx_page_queue_action_t comments */ - -#ifndef gxpageq_INCLUDED -# define gxpageq_INCLUDED - -#include "gsmemory.h" -#include "gxband.h" -#include "gxsync.h" - -/* --------------- Data type definitions --------------------- */ - -/* Action codes for each page queue entry. Each page that the interpreter - emits to the page queue can actually be broken down into a sequence of - one or more page queue entries. The general form for a given page's - sequence of page queue entries can be expressed as: - [PARTIAL_PAGE]... [COPY_PAGE [PARTIAL_PAGE]...]... FULL_PAGE - where elements in square brackets are optional, and ellipses show - repetition. NOTE that a single ACTION_TERMINATE (followed by nothing) can - also show up at any point in the page queue in lieu of page descriptions. - - PARTIAL_PAGE: The interpreter emits a partial page when the bandlist is - too small to contain a page's full representation. Partial pages will - be emitted in out-of-memory situations *only* after the interpreter - has determined that no further page queue entries are in the page - queue, indicating that no further memory can be reclaimed by merely - waiting for queued pages to render and free their associated bandlist. - - Note that num_copies is undefined for partial pages: the actual - number of pages to render will only be known when ...COPY_PAGE - or FULL_PAGE is emitted. - - Partial pages are never imaged. - - FULL_PAGE: The interpreter emits a full page when a page description - is complete (e.g. showpage), or trashed (e.g. setpagedevice). The - page's complete description consists of the FULL_PAGE plus all - PARTIAL_PAGEs that immediately precede it in the page queue (and - possibly preceding COPY_PAGEs) all the way back to the previous - FULL_PAGE (or up to the beginning of queue entries). - - In the case of a trashed page, the page count will be 0. The page - queue may choose to not render the 0-count FULL_PAGE queue entry - for efficiency. If they have not been rendered, the page queue - may choose to also discard (and/or not render) any PARTIAL_PAGEs - leading up to the trashed page. The page queue must however take - care to not discard any entries leading up to a COPY_PAGE with - a non-0 page count that may precede the FULL_PAGE, since COPY_PAGE - must be rendered in that case. In any event, a 0-count page will - not be imaged. - - In the case of a complete page, the page count will be 0 or greater. - The 0-count page is equivalent to a trashed page -- see above. The - renderer must ensure that all PARTIAL_PAGEs and COPY_PAGEs leading - up to the FULL_PAGE are rendered sequentially before rendering - and imaging the FULL_PAGE. - - COPY_PAGE: is similar to FULL_PAGE above, except that COPY_PAGE must - keep the rendered results, instead of clearing them. COPY_PAGE - differs from a partial page in that the page must be imaged, as well - as rasterized. This is to support PostScript language "copypage" - semantics. - - Note that a 0 page count here does not absolve the renderer from - rendering the page queue entries (unless all subsequent COPY_PAGEs - the the FULL_PAGE for this page also have a 0 page count), since - the results of COPY_PAGE must be available for subsequent pages. - - TERMINATE: This entry can appear at any time in the page queue. It - will be the last entry to ever appear in the queue. The semantics - of this entry require all prior non-zero-count COPY_PAGEs and - FULL_PAGEs to be imaged. Any trailing PARTIAL_PAGEs may optionally - be rendered, but should not be imaged. - */ -typedef enum { - GX_PAGE_QUEUE_ACTION_PARTIAL_PAGE, - GX_PAGE_QUEUE_ACTION_FULL_PAGE, - GX_PAGE_QUEUE_ACTION_COPY_PAGE, - GX_PAGE_QUEUE_ACTION_TERMINATE -} gx_page_queue_action_t; - -/* - * Define the structure used to manage a page queue. - * A page queue is a monitor-locked FIFO which holds completed command - * list files ready for rendering. - */ -#ifndef gx_page_queue_DEFINED -# define gx_page_queue_DEFINED -typedef struct gx_page_queue_s gx_page_queue_t; -#endif - -/* - * Define a page queue entry object. - */ -typedef struct gx_page_queue_entry_s gx_page_queue_entry_t; -struct gx_page_queue_entry_s { - gx_band_page_info_t page_info; - gx_page_queue_action_t action; /* action code */ - int num_copies; /* number of copies to render, only defined */ - /* if action == ...FULL_PAGE or ...COPY_PAGE */ - gx_page_queue_entry_t *next; /* link to next in queue */ - gx_page_queue_t *queue; /* link to queue the entry is in */ -}; - -#define private_st_gx_page_queue_entry()\ - gs_private_st_ptrs2(st_gx_page_queue_entry, gx_page_queue_entry_t,\ - "gx_page_queue_entry",\ - gx_page_queue_entry_enum_ptrs, gx_page_queue_entry_reloc_ptrs,\ - next, queue) - -/* -------------- Public Procedure Declaraions --------------------- */ - -/* Allocate a page queue. */ -gx_page_queue_t *gx_page_queue_alloc(gs_memory_t *mem); - -/* - * Allocate and initialize a page queue entry. - * All page queue entries must be allocated by this routine. - */ -/* rets ptr to allocated object, 0 if VM error */ -gx_page_queue_entry_t * -gx_page_queue_entry_alloc( - gx_page_queue_t * queue /* queue that entry is being alloc'd for */ - ); - -/* - * Free a page queue entry. - * All page queue entries must be destroyed by this routine. - */ -void gx_page_queue_entry_free( - gx_page_queue_entry_t * entry /* entry to free up */ - ); - -/* - * Free the page_info resources held by the pageq entry. Used to free - * pages' clist, typically after rendering. Note that this routine is NOT - * called implicitly by gx_page_queue_entry_free, since page clist may be - * managed separately from page queue entries. However, unless you are - * managing clist separately, you must call this routine before freeing the - * pageq entry itself (via gx_page_queue_entry_free), or you will leak - * memory (lots). - */ -void gx_page_queue_entry_free_page_info( - gx_page_queue_entry_t * entry /* entry to free up */ - ); - -/* - * Initialize a page queue; this must be done before it can be used. - * This routine allocates & inits various necessary structures and will - * fail if insufficient memory is available. - */ -/* -ve error code, or 0 */ -int gx_page_queue_init( - gx_page_queue_t * queue, /* page queue to init */ - gs_memory_t * memory /* allocator for dynamic memory */ - ); - -/* - * Destroy a page queue which was initialized by gx_page_queue_init. - * Any page queue entries in the queue are released and destroyed; - * dynamic allocations are released. - */ -void gx_page_queue_dnit( - gx_page_queue_t * queue /* page queue to dnit */ - ); - -/* - * If there are any pages in queue, wait until one of them finishes - * rendering. Typically called by writer's out-of-memory error handlers - * that want to wait until some memory has been freed. - */ -/* rets 0 if no pages were waiting for rendering, 1 if actually waited */ -int gx_page_queue_wait_one_page( - gx_page_queue_t * queue /* queue to wait on */ - ); - -/* - * Wait until all (if any) pages in queue have finished rendering. Typically - * called by writer operations which need to drain the page queue before - * continuing. - */ -void gx_page_queue_wait_until_empty( - gx_page_queue_t * queue /* page queue to wait on */ - ); - -/* - * Add a pageq queue entry to the end of the page queue. If an unsatisfied - * reader thread has an outstanding gx_page_queue_start_deque(), wake it up. - */ -void gx_page_queue_enqueue( - gx_page_queue_entry_t * entry /* entry to add */ - ); - -/* - * Allocate & construct a pageq entry, then add to the end of the pageq as - * in gx_page_queue_enqueue. If unable to allocate a new pageq entry, uses - * the pre-allocated reserve entry held in the pageq. When using the reserve - * pageq entry, wait until enough pages have been rendered to allocate a new - * reserve for next time -- this should always succeed & returns eFatal if not. - * Unless the reserve was used, does not wait for any rendering to complete. - * Typically called by writer when it has a (partial) page ready for rendering. - */ -/* rets 0 ok, gs_error_Fatal if error */ -int gx_page_queue_add_page( - gx_device_clist_writer *const pcwdev, - gx_page_queue_t * queue, /* page queue to add to */ - gx_page_queue_action_t action, /* action code to queue */ - const gx_band_page_info_t * page_info, /* bandinfo incl. bandlist */ - int page_count /* # of copies to print if final "print," */ - /* 0 if partial page, -1 if cancel */ - ); - -/* - * Retrieve the least-recently added queue entry from the pageq. If no - * entry is available, waits on a signal from gx_page_queue_enqueue. Must - * eventually be followed by a call to gx_page_queue_finish_dequeue for the - * same pageq entry. - * Even though the pageq is actually removed from the pageq, a mark is made in - * the pageq to indicate that the pageq is not "empty" until the - * gx_page_queue_finish_dequeue; this is for the benefit of - * gx_page_queue_wait_???, since the completing the current page's rendering - * may free more memory. - * Typically called by renderer thread loop, which looks like: - do { - gx_page_queue_start_deqeueue(...); - render_retrieved_entry(...); - gx_page_queue_finish_dequeue(...); - } while (some condition); - */ -gx_page_queue_entry_t * /* removed entry */ -gx_page_queue_start_dequeue( - gx_page_queue_t * queue /* page queue to retrieve from */ - ); - -/* - * Free the pageq entry and its associated band list data, then signal any - * waiting threads. Typically used to indicate completion of rendering the - * pageq entry. Note that this is different from gx_page_queue_entry_free, - * which does not free the band list data (a separate call of - * gx_page_queue_entry_free_page_info is required). - */ -void gx_page_queue_finish_dequeue( - gx_page_queue_entry_t * entry /* entry that was retrieved to delete */ - ); - -#endif /*!defined(gxpageq_INCLUDED) */ diff -Nru ghostscript-9.10~dfsg/base/gxpaint.c ghostscript-9.25~dfsg+1/base/gxpaint.c --- ghostscript-9.10~dfsg/base/gxpaint.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpaint.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,7 +23,7 @@ #include "gxpath.h" #include "gxfont.h" -static bool caching_an_outline_font(const gs_state * pgs) +static bool caching_an_outline_font(const gs_gstate * pgs) { return pgs->in_cachedevice > 1 && pgs->font != NULL && @@ -35,7 +35,7 @@ /* Fill a path. */ int -gx_fill_path(gx_path * ppath, gx_device_color * pdevc, gs_state * pgs, +gx_fill_path(gx_path * ppath, gx_device_color * pdevc, gs_gstate * pgs, int rule, fixed adjust_x, fixed adjust_y) { gx_device *dev = gs_currentdevice_inline(pgs); @@ -50,12 +50,12 @@ params.adjust.y = adjust_y; params.flatness = (caching_an_outline_font(pgs) ? 0.0 : pgs->flatness); return (*dev_proc(dev, fill_path)) - (dev, (const gs_imager_state *)pgs, ppath, ¶ms, pdevc, pcpath); + (dev, (const gs_gstate *)pgs, ppath, ¶ms, pdevc, pcpath); } /* Stroke a path for drawing or saving. */ int -gx_stroke_fill(gx_path * ppath, gs_state * pgs) +gx_stroke_fill(gx_path * ppath, gs_gstate * pgs) { gx_device *dev = gs_currentdevice_inline(pgs); gx_clip_path *pcpath; @@ -67,31 +67,31 @@ params.flatness = (caching_an_outline_font(pgs) ? 0.0 : pgs->flatness); params.traditional = false; return (*dev_proc(dev, stroke_path)) - (dev, (const gs_imager_state *)pgs, ppath, ¶ms, + (dev, (const gs_gstate *)pgs, ppath, ¶ms, gs_currentdevicecolor_inline(pgs), pcpath); } int gx_stroke_add(gx_path * ppath, gx_path * to_path, - const gs_state * pgs, bool traditional) + const gs_gstate * pgs, bool traditional) { gx_stroke_params params; params.flatness = (caching_an_outline_font(pgs) ? 0.0 : pgs->flatness); params.traditional = traditional; return gx_stroke_path_only(ppath, to_path, pgs->device, - (const gs_imager_state *)pgs, + (const gs_gstate *)pgs, ¶ms, NULL, NULL); } int -gx_imager_stroke_add(gx_path *ppath, gx_path *to_path, - gx_device *dev, const gs_imager_state *pis) +gx_gstate_stroke_add(gx_path *ppath, gx_path *to_path, + gx_device *dev, const gs_gstate *pgs) { gx_stroke_params params; - params.flatness = pis->flatness; + params.flatness = pgs->flatness; params.traditional = false; - return gx_stroke_path_only(ppath, to_path, dev, pis, + return gx_stroke_path_only(ppath, to_path, dev, pgs, ¶ms, NULL, NULL); } diff -Nru ghostscript-9.10~dfsg/base/gxpaint.h ghostscript-9.25~dfsg+1/base/gxpaint.h --- ghostscript-9.10~dfsg/base/gxpaint.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpaint.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,14 +20,14 @@ #ifndef gxpaint_INCLUDED # define gxpaint_INCLUDED -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #ifndef gx_device_DEFINED @@ -47,16 +47,16 @@ * They are implemented in gxpaint.c. */ -int gx_fill_path(gx_path * ppath, gx_device_color * pdevc, gs_state * pgs, +int gx_fill_path(gx_path * ppath, gx_device_color * pdevc, gs_gstate * pgs, int rule, fixed adjust_x, fixed adjust_y); -int gx_stroke_fill(gx_path * ppath, gs_state * pgs); -int gx_stroke_add(gx_path *ppath, gx_path *to_path, const gs_state * pgs, bool traditional); +int gx_stroke_fill(gx_path * ppath, gs_gstate * pgs); +int gx_stroke_add(gx_path *ppath, gx_path *to_path, const gs_gstate * pgs, bool traditional); /* - * gx_imager_stroke_add needs a device for the sake of absolute-length + * gx_gstate_stroke_add needs a device for the sake of absolute-length * dots (and for no other reason). */ -int gx_imager_stroke_add(gx_path *ppath, gx_path *to_path, - gx_device *dev, const gs_imager_state *pis); +int gx_gstate_stroke_add(gx_path *ppath, gx_path *to_path, + gx_device *dev, const gs_gstate *pgs); /* ------ Imager procedures ------ */ @@ -76,12 +76,12 @@ * amount if the miter limit is large. If this matters, use strokepath + * pathbbox. */ -int gx_stroke_path_expansion(const gs_imager_state *pis, +int gx_stroke_path_expansion(const gs_gstate *pgs, const gx_path *ppath, gs_fixed_point *ppt); /* Backward compatibility */ -#define gx_stroke_expansion(pis, ppt)\ - gx_stroke_path_expansion(pis, (const gx_path *)0, ppt) +#define gx_stroke_expansion(pgs, ppt)\ + gx_stroke_path_expansion(pgs, (const gx_path *)0, ppt) /* * The following procedures do not need a graphics state. @@ -99,8 +99,8 @@ float flatness; }; -#define gx_fill_path_only(ppath, dev, pis, params, pdevc, pcpath)\ - (*dev_proc(dev, fill_path))(dev, pis, ppath, params, pdevc, pcpath) +#define gx_fill_path_only(ppath, dev, pgs, params, pdevc, pcpath)\ + (*dev_proc(dev, fill_path))(dev, pgs, ppath, params, pdevc, pcpath) /* Define the parameters passed to the imager's stroke routine. */ #ifndef gx_stroke_params_DEFINED @@ -113,7 +113,7 @@ }; int gx_stroke_path_only(gx_path * ppath, gx_path * to_path, gx_device * dev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_stroke_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath); diff -Nru ghostscript-9.10~dfsg/base/gxpath2.c ghostscript-9.25~dfsg+1/base/gxpath2.c --- ghostscript-9.10~dfsg/base/gxpath2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpath2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -179,50 +179,104 @@ const subpath ** ppnext) { const segment *pseg1, *pseg2, *pseg3, *pseg4; - gx_path_rectangular_type type; + gx_path_rectangular_type type = prt_none; + fixed x0 = pseg0->pt.x, y0 = pseg0->pt.y; + fixed x1, y1, x2, y2, x3, y3; + + pseg1 = (const segment *)pseg0; + do { + pseg1 = pseg1->next; + if (pseg1 == NULL) + return prt_none; + x1 = pseg1->pt.x; + y1 = pseg1->pt.y; + if (pseg1->type == s_curve) { + if (gx_curve_is_really_point(x0, y0, pseg1)) + continue; /* Ignore this one and try again */ + if (gx_curve_is_really_line(x0, y0, pseg1)) + break; /* That'll do! */ + return prt_none; + } else if (pseg1->type != s_line && pseg1->type != s_gap) + return prt_none; + } while (x1 == x0 && y1 == y0); - if (pseg0->curve_count == 0 && - (pseg1 = pseg0->next) != 0 && - (pseg2 = pseg1->next) != 0 && - (pseg3 = pseg2->next) != 0 - ) { - if ((pseg4 = pseg3->next) == 0 || pseg4->type == s_start) - type = prt_open; /* M, L, L, L */ - else if (pseg4->type != s_line && pseg4->type != s_gap) /* must be s_line_close */ - type = prt_closed; /* M, L, L, L, C */ - else if (pseg4->pt.x != pseg0->pt.x || - pseg4->pt.y != pseg0->pt.y - ) + pseg2 = pseg1; + do { + pseg2 = pseg2->next; + if (pseg2 == NULL) return prt_none; - else if (pseg4->next == 0 || pseg4->next->type == s_start) - type = prt_fake_closed; /* Mo, L, L, L, Lo */ - else if (pseg4->next->type != s_line && pseg4->next->type != s_gap) /* must be s_line_close */ - type = prt_closed; /* Mo, L, L, L, Lo, C */ - else + x2 = pseg2->pt.x; + y2 = pseg2->pt.y; + if (pseg2->type == s_curve) { + if (gx_curve_is_really_point(x1, y1, pseg2)) + continue; /* Ignore this one and try again */ + if (gx_curve_is_really_line(x1, y1, pseg2)) + break; /* That'll do! */ return prt_none; - { - fixed x0 = pseg0->pt.x, y0 = pseg0->pt.y; - fixed x2 = pseg2->pt.x, y2 = pseg2->pt.y; - - if ((x0 == pseg1->pt.x && pseg1->pt.y == y2 && - x2 == pseg3->pt.x && pseg3->pt.y == y0) || - (x0 == pseg3->pt.x && pseg3->pt.y == y2 && - x2 == pseg1->pt.x && pseg1->pt.y == y0) - ) { /* Path is a rectangle. Return the bounding box. */ - if (x0 < x2) - pbox->p.x = x0, pbox->q.x = x2; - else - pbox->p.x = x2, pbox->q.x = x0; - if (y0 < y2) - pbox->p.y = y0, pbox->q.y = y2; - else - pbox->p.y = y2, pbox->q.y = y0; - while (pseg4 != 0 && pseg4->type != s_start) - pseg4 = pseg4->next; - *ppnext = (const subpath *)pseg4; - return type; - } + } else if (pseg2->type != s_line && pseg2->type != s_gap) + return prt_none; + } while (x2 == x1 && y2 == y1); + + pseg3 = pseg2; + do { + pseg3 = pseg3->next; + if (pseg3 == NULL) + return prt_none; + x3 = pseg3->pt.x; + y3 = pseg3->pt.y; + if (pseg3->type == s_curve) { + if (gx_curve_is_really_point(x2, y2, pseg3)) + continue; /* Ignore this one and try again */ + if (gx_curve_is_really_line(x2, y2, pseg3)) + break; /* That'll do! */ + return prt_none; + } else if (pseg3->type != s_line && pseg3->type != s_gap) + return prt_none; + } while (x3 == x2 && y3 == y2); + + pseg4 = pseg3; + do { + pseg4 = pseg4->next; + if (pseg4 == NULL || pseg4->type == s_start) { + type = prt_open; /* M, L, L, L */ + goto type_known; + } + if (pseg4->type == s_curve) { + if (gx_curve_is_really_point(x3, y3, pseg4)) + continue; /* Ignore this one and try again */ + if (gx_curve_is_really_line(x3, y3, pseg4)) + break; /* That'll do! */ + return prt_none; + } else if (pseg4->type == s_line_close) { + type = prt_closed; /* M, L, L, L, C */ + goto type_known; } + } while (pseg4->pt.x == x3 && pseg4->pt.y == y3); + + if (pseg4->pt.x != pseg0->pt.x || pseg4->pt.y != pseg0->pt.y) + return prt_none; + else if (pseg4->next == NULL || pseg4->next->type == s_start) + type = prt_fake_closed; /* Mo, L, L, L, L, Mo */ + else + return prt_none; + +type_known: + + if ((x0 == x1 && y1 == y2 && x2 == x3 && y3 == y0) || + (x0 == x3 && y3 == y2 && x2 == x1 && y1 == y0)) { + /* Path is a rectangle. Return the bounding box. */ + if (x0 < x2) + pbox->p.x = x0, pbox->q.x = x2; + else + pbox->p.x = x2, pbox->q.x = x0; + if (y0 < y2) + pbox->p.y = y0, pbox->q.y = y2; + else + pbox->p.y = y2, pbox->q.y = y0; + while (pseg4 != 0 && pseg4->type != s_start) + pseg4 = pseg4->next; + *ppnext = (const subpath *)pseg4; + return type; } return prt_none; } @@ -262,6 +316,7 @@ update_xy(pcseg->p1); update_xy(pcseg->p2); #undef pcseg + /* fall through */ default: update_xy(pseg->pt); } @@ -322,6 +377,7 @@ case s_curve: SCALE_XY(((curve_segment *)pseg)->p1); SCALE_XY(((curve_segment *)pseg)->p2); + /* fall through */ default: SCALE_XY(pseg->pt); } diff -Nru ghostscript-9.10~dfsg/base/gxpath.c ghostscript-9.25~dfsg+1/base/gxpath.c --- ghostscript-9.10~dfsg/base/gxpath.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpath.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,7 +20,6 @@ #include "gsstruct.h" #include "gxfixed.h" #include "gzpath.h" -#include "vdtrace.h" /* These routines all assume that all points are */ /* already in device coordinates, and in fixed representation. */ @@ -236,9 +235,8 @@ ppath->local_segments.contents.subpath_current = 0; ppath->segments = 0; path_update_newpath(ppath); - ppath->bbox.p.x = ppath->bbox.q.x = 0; - ppath->bbox.p.y = ppath->bbox.q.y = 0; ppath->bbox_set = 0; + ppath->bbox.p.x = ppath->bbox.p.y = ppath->bbox.q.x = ppath->bbox.q.y = 0; ppath->bbox_accurate = 1; ppath->memory = NULL; /* Won't allocate anything. */ ppath->allocation = path_allocated_on_stack; @@ -444,9 +442,9 @@ int code = path_alloc_segments(&ppath->segments, ppath->memory, "gx_path_new"); + rc_decrement(psegs, "gx_path_new"); if (code < 0) return code; - rc_decrement(psegs, "gx_path_new"); } else { rc_free_path_segments_local(psegs->rc.memory, psegs, "gx_path_new"); } @@ -795,15 +793,10 @@ */ int gx_path_add_partial_arc_notes(gx_path * ppath, -fixed x3, fixed y3, fixed xt, fixed yt, floatp fraction, segment_notes notes) +fixed x3, fixed y3, fixed xt, fixed yt, double fraction, segment_notes notes) { fixed x0 = ppath->position.x, y0 = ppath->position.y; - vd_curveto(x0 + (fixed) ((xt - x0) * fraction), - y0 + (fixed) ((yt - y0) * fraction), - x3 + (fixed) ((xt - x3) * fraction), - y3 + (fixed) ((yt - y3) * fraction), - x3, y3); return gx_path_add_curve_notes(ppath, x0 + (fixed) ((xt - x0) * fraction), y0 + (fixed) ((yt - y0) * fraction), diff -Nru ghostscript-9.10~dfsg/base/gxpath.h ghostscript-9.25~dfsg+1/base/gxpath.h --- ghostscript-9.10~dfsg/base/gxpath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -161,7 +161,7 @@ gx_path_add_rectangle(gx_path *, fixed, fixed, fixed, fixed), gx_path_add_char_path(gx_path *, gx_path *, gs_char_path_mode), gx_path_add_curve_notes(gx_path *, fixed, fixed, fixed, fixed, fixed, fixed, segment_notes), - gx_path_add_partial_arc_notes(gx_path *, fixed, fixed, fixed, fixed, floatp, segment_notes), + gx_path_add_partial_arc_notes(gx_path *, fixed, fixed, fixed, fixed, double, segment_notes), gx_path_add_path(gx_path *, gx_path *), gx_path_close_subpath_notes(gx_path *, segment_notes), /* We have to remove the 'subpath' from the following name */ @@ -205,7 +205,7 @@ /* Path accessors */ -gx_path *gx_current_path(const gs_state *); +gx_path *gx_current_path(const gs_gstate *); int gx_path_current_point(const gx_path *, gs_fixed_point *), gx_path_bbox(gx_path *, gs_fixed_rect *), gx_path_bbox_set(gx_path *, gs_fixed_rect *); @@ -231,32 +231,54 @@ #define gx_path_is_null_inline(ppath)\ (gx_path_is_void(ppath) && !path_position_valid(ppath)) +/* Macro to test if a curve is actually a line (i.e. that + * both control points are at one end or the other). + * (Yes, there are cases where the curve can be a line + * where this does not apply, but they are not trivial to + * to test for) + */ +#define gx_curve_is_really_line(x0, y0, seg) \ + (((((curve_segment *)seg)->p1.x == x0 && \ + ((curve_segment *)seg)->p1.y == y0) || \ + (((curve_segment *)seg)->p1.x == (seg)->pt.x && \ + ((curve_segment *)seg)->p1.y == (seg)->pt.y)) && \ + ((((curve_segment *)seg)->p2.x == x0 && \ + ((curve_segment *)seg)->p2.y == y0) || \ + (((curve_segment *)seg)->p2.x == (seg)->pt.x && \ + ((curve_segment *)seg)->p2.y == (seg)->pt.y))) + +/* Macro to test if a curve is actually a point (i.e. that + * start/end and both control points are coincident). + */ +#define gx_curve_is_really_point(x0, y0, seg) \ + (x0 == (seg)->pt.y && y0 == (seg)->pt.y && \ + ((curve_segment *)seg)->p1.x == x0 && \ + ((curve_segment *)seg)->p1.y == y0 && \ + ((curve_segment *)seg)->p2.x == x0 && \ + ((curve_segment *)seg)->p2.y == y0) + /* Path transformers */ -/* The imager state is only needed when flattening for stroke. */ -#ifndef gs_imager_state_DEFINED -# define gs_imager_state_DEFINED -typedef struct gs_imager_state_s gs_imager_state; +/* The gs_gstate is only needed when flattening for stroke. */ +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif int gx_path_copy_reducing(const gx_path * ppath_old, gx_path * ppath_new, - fixed fixed_flatness, const gs_imager_state *pis, + fixed fixed_flatness, const gs_gstate *pgs, gx_path_copy_options options); #define gx_path_copy(old, new)\ gx_path_copy_reducing(old, new, max_fixed, NULL, pco_none) -#define gx_path_add_flattened(old, new, flatness)\ - gx_path_copy_reducing(old, new, float2fixed(flatness), NULL, pco_none) #define gx_path_add_flattened_accurate(old, new, flatness, accurate)\ gx_path_copy_reducing(old, new, float2fixed(flatness), NULL,\ (accurate ? pco_accurate : pco_none)) -#define gx_path_add_flattened_for_stroke(old, new, flatness, pis)\ - gx_path_copy_reducing(old, new, float2fixed(flatness), pis,\ - (pis->accurate_curves ?\ +#define gx_path_add_flattened_for_stroke(old, new, flatness, pgs)\ + gx_path_copy_reducing(old, new, float2fixed(flatness), pgs,\ + (pgs->accurate_curves ?\ pco_accurate | pco_for_stroke : pco_for_stroke)) -#define gx_path_add_monotonized(old, new)\ - gx_path_copy_reducing(old, new, max_fixed, NULL, pco_monotonize) int gx_path_add_dash_expansion(const gx_path * /*old*/, gx_path * /*new*/, - const gs_imager_state *), + const gs_gstate *), gx_path_copy_reversed(const gx_path * /*old*/, gx_path * /*new*/), gx_path_append_reversed(const gx_path * /*orig*/, gx_path * /*rev*/), gx_path_translate(gx_path *, fixed, fixed), @@ -277,8 +299,8 @@ bool gx_path_enum_backup(gs_path_enum *); /* An auxiliary function to add a path point with a specified transformation. */ -int gs_moveto_aux(gs_imager_state *pis, gx_path *ppath, floatp x, floatp y); -int gx_setcurrentpoint_from_path(gs_imager_state *pis, gx_path *path); +int gs_moveto_aux(gs_gstate *pgs, gx_path *ppath, double x, double y); +int gx_setcurrentpoint_from_path(gs_gstate *pgs, gx_path *path); /* Path optimization for the filling algorithm. */ @@ -293,11 +315,11 @@ #endif /* Graphics state clipping */ -int gx_clip_to_rectangle(gs_state *, gs_fixed_rect *); -int gx_clip_to_path(gs_state *); -int gx_default_clip_box(const gs_state *, gs_fixed_rect *); -int gx_effective_clip_path(gs_state *, gx_clip_path **); -int gx_curr_bbox(gs_state * pgs, gs_rect *bbox, gs_bbox_comp_t comp_type); +int gx_clip_to_rectangle(gs_gstate *, gs_fixed_rect *); +int gx_clip_to_path(gs_gstate *); +int gx_default_clip_box(const gs_gstate *, gs_fixed_rect *); +int gx_effective_clip_path(gs_gstate *, gx_clip_path **); +int gx_curr_bbox(gs_gstate * pgs, gs_rect *bbox, gs_bbox_comp_t comp_type); /* Opaque type for a clip list. */ @@ -356,16 +378,17 @@ int gx_cpath_reset(gx_clip_path *), /* from_rectangle ((0,0),(0,0)) */ gx_cpath_from_rectangle(gx_clip_path *, gs_fixed_rect *), - gx_cpath_clip(gs_state *, gx_clip_path *, /*const*/ gx_path *, int), + gx_cpath_clip(gs_gstate *, gx_clip_path *, /*const*/ gx_path *, int), gx_cpath_intersect(gx_clip_path *, /*const*/ gx_path *, int, - gs_imager_state *), + gs_gstate *), gx_cpath_intersect_with_params(gx_clip_path *pcpath, /*const*/ gx_path *ppath_orig, - int rule, gs_imager_state *pis, const gx_fill_params * params), + int rule, gs_gstate *pgs, const gx_fill_params * params), gx_cpath_scale_exp2_shared(gx_clip_path *pcpath, int log2_scale_x, int log2_scale_y, bool list_shared, bool segments_shared), gx_cpath_to_path(gx_clip_path *, gx_path *), gx_cpath_to_path_synthesize(const gx_clip_path * pcpath, gx_path * ppath); +int gx_cpath_ensure_path_list(gx_clip_path *pcpath); bool gx_cpath_inner_box(const gx_clip_path *, gs_fixed_rect *), gx_cpath_outer_box(const gx_clip_path *, gs_fixed_rect *), diff -Nru ghostscript-9.10~dfsg/base/gxpcache.h ghostscript-9.25~dfsg+1/base/gxpcache.h --- ghostscript-9.10~dfsg/base/gxpcache.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpcache.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxpcmap.c ghostscript-9.25~dfsg+1/base/gxpcmap.c --- ghostscript-9.10~dfsg/base/gxpcmap.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpcmap.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -38,6 +38,8 @@ #include "gxdevsop.h" #include "gdevmpla.h" #include "gdevp14.h" +#include "gxgetbit.h" +#include "gscoord.h" #if RAW_PATTERN_DUMP unsigned int global_pat_index = 0; @@ -51,7 +53,7 @@ uint gx_pat_cache_default_tiles(void) { -#if arch_small_memory +#if ARCH_SMALL_MEMORY return max_cached_patterns_SMALL; #else #ifdef DEBUG @@ -65,7 +67,7 @@ ulong gx_pat_cache_default_bits(void) { -#if arch_small_memory +#if ARCH_SMALL_MEMORY return max_pattern_bits_SMALL; #else #ifdef DEBUG @@ -95,11 +97,13 @@ static dev_proc_copy_planes(pattern_accum_copy_planes); static dev_proc_get_bits_rectangle(pattern_accum_get_bits_rectangle); static dev_proc_fill_rectangle_hl_color(pattern_accum_fill_rectangle_hl_color); +/* not static for use by clist_dev_spec_op with pattern-clist */ +dev_proc_dev_spec_op(pattern_accum_dev_spec_op); /* The device descriptor */ static const gx_device_pattern_accum gs_pattern_accum_device = -{std_device_std_body_open(gx_device_pattern_accum, 0, - "pattern accumulator", +{std_device_std_body_type_open(gx_device_pattern_accum, 0, + "pattern accumulator", &st_device_pattern_accum, 0, 0, 72, 72), { /* NOTE: all drawing procedures must be defaulted, not forwarded. */ @@ -168,7 +172,7 @@ NULL, /* push_transparency_state */ NULL, /* pop_transparency_state */ NULL, /* put_image */ - NULL, /* dev_spec_op */ + pattern_accum_dev_spec_op, /* dev_spec_op */ pattern_accum_copy_planes, /* copy_planes */ NULL, /* get_profile */ NULL, /* set_graphics_type_tag */ @@ -179,12 +183,6 @@ 0, 0, 0, 0 /* bitmap_memory, bits, mask, instance */ }; -static int -dummy_free_up_bandlist_memory(gx_device *cldev, bool b) -{ - return 0; -} - int pattern_clist_open_device(gx_device *dev) { @@ -215,55 +213,58 @@ /* be needed in the pattern cache). If we end up using the clist, this is only */ /* a guess -- we use the tile size which will _probably_ be too large. */ static int -gx_pattern_size_estimate(gs_pattern1_instance_t *pinst, int has_tags) +gx_pattern_size_estimate(gs_pattern1_instance_t *pinst, bool has_tags) { gx_device *tdev = pinst->saved->device; int depth = (pinst->templat.PaintType == 2 ? 1 : tdev->color_info.depth); int64_t raster; int64_t size; + if (pinst->size.x == 0 || pinst->size.y == 0) + return 0; + if (pinst->templat.uses_transparency) { - raster = (pinst->size.x * ((depth/8) + 1 + has_tags)); - size = raster > max_int / pinst->size.y ? (max_int & ~0xFFFF) : raster * pinst->size.y; + /* if the device has tags, add in an extra tag byte for the pdf14 compositor */ + raster = ((int64_t)pinst->size.x * ((depth/8) + 1 + (has_tags ? 1 : 0))); } else { - raster = (pinst->size.x * depth + 7) / 8; - size = raster * pinst->size.y; + raster = ((int64_t)pinst->size.x * depth + 7) / 8; } + size = raster > max_int / pinst->size.y ? (max_int & ~0xFFFF) : raster * pinst->size.y; if (size > (int64_t)max_int) - size = (int64_t)max_int; + size = (max_int & ~0xFFFF); return (int)size; } -#ifndef MaxPatternBitmap_DEFAULT -# define MaxPatternBitmap_DEFAULT (8*1024*1024) /* reasonable on most modern hosts */ -#endif - static void gx_pattern_accum_finalize_cw(gx_device * dev) { gx_device_clist_writer *cwdev = (gx_device_clist_writer *)dev; rc_decrement_only(cwdev->target, "gx_pattern_accum_finalize_cw"); } +bool gx_device_is_pattern_accum(gx_device *dev) +{ + return dev_proc(dev, open_device) == pattern_accum_open; +} + +bool gx_device_is_pattern_clist(gx_device *dev) +{ + return dev_proc(dev, open_device) == pattern_clist_open_device; +} + /* Allocate a pattern accumulator, with an initial refct of 0. */ gx_device_forward * gx_pattern_accum_alloc(gs_memory_t * mem, gs_memory_t * storage_memory, gs_pattern1_instance_t *pinst, client_name_t cname) { gx_device *tdev = pinst->saved->device; - int has_tags = tdev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS; + bool has_tags = device_encodes_tags(tdev); int size = gx_pattern_size_estimate(pinst, has_tags); gx_device_forward *fdev; int force_no_clist = 0; int max_pattern_bitmap = tdev->MaxPatternBitmap == 0 ? MaxPatternBitmap_DEFAULT : tdev->MaxPatternBitmap; - int ret; - ret = dev_proc(tdev, dev_spec_op)(tdev, gxdso_is_native_planar, NULL, 0); - if (ret > 0) { - pinst->is_planar = ret; - } else { - pinst->is_planar = false; - } + pinst->is_planar = tdev->is_planar; /* * If the target device can accumulate a pattern stream and the language * client supports high level patterns (ps and pdf only) we don't need a @@ -302,100 +303,37 @@ } else { gx_device_buf_procs_t buf_procs = {dummy_create_buf_device, dummy_size_buf_device, dummy_setup_buf_device, dummy_destroy_buf_device}; - gx_device_clist *cdev = gs_alloc_struct(mem, gx_device_clist, - &st_device_clist, cname); - gx_device_clist_writer *cwdev = (gx_device_clist_writer *)cdev; - const int data_size = 1024*32; - byte *data; + gx_device_clist *cdev; + gx_device_clist_writer *cwdev; + const int data_size = 1024*128; + gx_band_params_t band_params = { 0 }; + byte *data = gs_alloc_bytes(storage_memory->non_gc_memory, data_size, cname); - if (cdev == 0) + if (data == NULL) return 0; - /* We're not shure how big area do we need here. - Definitely we need 1 state in 'states'. - Not sure whether we need to create tile_cache, etc.. - Note it is allocated in non-gc memory, - because the garbager descriptor for - gx_device_clist do not enumerate 'data' - and its subfields, assuming they do not relocate. - We place command list files to non-gc memory - due to same reason. - */ - data = gs_alloc_bytes(storage_memory->non_gc_memory, data_size, cname); - if (data == NULL) { - gs_free_object(mem, cdev, cname); + pinst->is_clist = true; + /* NB: band_params.page_uses_transparency is set in clist_make_accum_device */ + band_params.BandWidth = pinst->size.x; + band_params.BandHeight = pinst->size.y; + band_params.BandBufferSpace = 0; + + cdev = clist_make_accum_device(tdev, "pattern-clist", data, data_size, + &buf_procs, &band_params, true, /* use_memory_clist */ + pinst->templat.uses_transparency, pinst); + if (cdev == 0) { + gs_free_object(storage_memory->non_gc_memory, data, cname); return 0; } - pinst->is_clist = true; - memset(cdev, 0, sizeof(*cdev)); - cwdev->params_size = sizeof(gx_device_clist); - cwdev->static_procs = NULL; - cwdev->dname = "pattern-clist"; - cwdev->memory = mem; - cwdev->stype = &st_device_clist; - cwdev->stype_is_dynamic = false; + cwdev = (gx_device_clist_writer *)cdev; cwdev->finalize = gx_pattern_accum_finalize_cw; - rc_init(cwdev, mem, 1); - cwdev->retained = true; - cwdev->is_open = false; - cwdev->max_fill_band = 0; - cwdev->color_info = tdev->color_info; - cwdev->cached_colors = tdev->cached_colors; - cwdev->width = pinst->size.x; - cwdev->height = pinst->size.y; - cwdev->LeadingEdge = tdev->LeadingEdge; - cwdev->is_planar = pinst->is_planar; - /* Fields left zeroed : - float MediaSize[2]; - float ImagingBBox[4]; - bool ImagingBBox_set; - */ - cwdev->HWResolution[0] = tdev->HWResolution[0]; - cwdev->HWResolution[1] = tdev->HWResolution[1]; - /* Fields left zeroed : - float MarginsHWResolution[2]; - float Margins[2]; - float HWMargins[4]; - long PageCount; - long ShowpageCount; - int NumCopies; - bool NumCopies_set; - bool IgnoreNumCopies; - */ - cwdev->icc_cache_cl = NULL; - cwdev->icc_table = NULL; - cwdev->UseCIEColor = tdev->UseCIEColor; - cwdev->LockSafetyParams = true; - /* gx_page_device_procs page_procs; */ - cwdev->procs = gs_clist_device_procs; - cwdev->procs.open_device = pattern_clist_open_device; - gx_device_copy_color_params((gx_device *)cwdev, tdev); - rc_assign(cwdev->target, tdev, "gx_pattern_accum_alloc"); - clist_init_io_procs(cdev, true); - cwdev->data = data; - cwdev->data_size = data_size; - cwdev->buf_procs = buf_procs; - if ( pinst->templat.uses_transparency) { - cwdev->band_params.page_uses_transparency = true; - cwdev->page_uses_transparency = true; - } else { - cwdev->band_params.page_uses_transparency = false; - cwdev->page_uses_transparency = false; - } - cwdev->band_params.BandWidth = pinst->size.x; - cwdev->band_params.BandHeight = pinst->size.y; - cwdev->band_params.BandBufferSpace = 0; - cwdev->do_not_open_or_close_bandfiles = false; - cwdev->bandlist_memory = storage_memory->non_gc_memory; - cwdev->free_up_bandlist_memory = dummy_free_up_bandlist_memory; - cwdev->disable_mask = 0; - cwdev->pinst = pinst; - set_dev_proc(cwdev, get_clipping_box, gx_default_get_clipping_box); - set_dev_proc(cwdev, get_profile, gx_forward_get_profile); - set_dev_proc(cwdev, set_graphics_type_tag, gx_forward_set_graphics_type_tag); - cwdev->graphics_type_tag = tdev->graphics_type_tag; /* initialize to same as target */ + set_dev_proc(cwdev, open_device, pattern_clist_open_device); fdev = (gx_device_forward *)cdev; } - check_device_separable((gx_device *)fdev); + fdev->log2_align_mod = tdev->log2_align_mod; + fdev->pad = tdev->pad; + fdev->is_planar = tdev->is_planar; + fdev->graphics_type_tag = tdev->graphics_type_tag; + fdev->interpolate_control = tdev->interpolate_control; gx_device_forward_fill_in_procs(fdev); return fdev; } @@ -501,7 +439,6 @@ if (bits == 0) code = gs_note_error(gs_error_VMerror); else { - int depth; gs_make_mem_device(bits, gdev_mem_device_for_bits(padev->color_info.depth), mem, -1, target); @@ -509,12 +446,12 @@ #undef PDSET bits->color_info = padev->color_info; bits->bitmap_memory = mem; - depth = dev_proc(target, dev_spec_op)(target, gxdso_is_native_planar, NULL, 0); - if (depth > 0) + if (target->is_planar > 0) { gx_render_plane_t planes[GX_DEVICE_COLOR_MAX_COMPONENTS]; - int num_comp = padev->color_info.num_components; - int i; + uchar num_comp = padev->color_info.num_components; + uchar i; + int depth = target->color_info.depth / target->color_info.num_components; for (i = 0; i < num_comp; i++) { planes[i].shift = depth * (num_comp - 1 - i); @@ -527,6 +464,12 @@ code = (*dev_proc(bits, open_device)) ((gx_device *) bits); gx_device_set_target((gx_device_forward *)padev, (gx_device *)bits); + /* The update_spot_equivalent_color proc for the bits device + should forward to the real target device. This will ensure + that the target device can get equivalent CMYK values for + spot colors if we are using a separation device and the spot + color occurs only in patterns on the page. */ + bits->procs.update_spot_equivalent_colors = gx_forward_update_spot_equivalent_colors; } } } @@ -596,15 +539,19 @@ /* _hl_color */ static int pattern_accum_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, - const gs_imager_state *pis, - const gx_drawing_color *pdcolor, + const gs_gstate *pgs, + const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) { gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev; + int code; - if (padev->bits) - (*dev_proc(padev->target, fill_rectangle_hl_color)) - (padev->target, rect, pis, pdcolor, pcpath); + if (padev->bits) { + code = (*dev_proc(padev->target, fill_rectangle_hl_color)) + (padev->target, rect, pgs, pdcolor, pcpath); + if (code < 0) + return code; + } if (padev->mask) { int x, y, w, h; @@ -616,8 +563,7 @@ return (*dev_proc(padev->mask, fill_rectangle)) ((gx_device *) padev->mask, x, y, w, h, (gx_color_index) 1); } - else - return 0; + return 0; } /* Fill a rectangle */ @@ -703,6 +649,115 @@ return 0; } +static int +blank_unmasked_bits(gx_device * mask, + int polarity, + int num_comps, + int depth, + const gs_int_rect *prect, + gs_get_bits_params_t *p) +{ + static const int required_options = GB_COLORS_NATIVE + | GB_ALPHA_NONE + | GB_RETURN_COPY + | GB_ALIGN_STANDARD + | GB_OFFSET_0 + | GB_RASTER_STANDARD; + int raster = p->raster; + byte *min; + int x0 = prect->p.x; + int y0 = prect->p.y; + int x, y; + int w = prect->q.x - x0; + int h = prect->q.y - y0; + int code = 0; + byte *ptr; + int blank = (polarity == GX_CINFO_POLARITY_ADDITIVE ? 255 : 0); + + if ((p->options & required_options) != required_options) + return_error(gs_error_rangecheck); + + min = gs_alloc_bytes(mask->memory, (w+7)>>3, "blank_unmasked_bits"); + if (min == NULL) + return_error(gs_error_VMerror); + + if (p->options & GB_PACKING_CHUNKY) + { + if ((depth & 7) != 0 || depth > 64) + return_error(gs_error_rangecheck); + ptr = p->data[0]; + depth >>= 3; + raster -= w*depth; + for (y = 0; y < h; y++) + { + byte *mine; + code = dev_proc(mask, get_bits)(mask, y+y0, min, &mine); + if (code < 0) + goto fail; + for (x = 0; x < w; x++) + { + int xx = x+x0; + if (((mine[xx>>3]>>(x&7)) & 1) == 0) { + switch (depth) + { + case 8: + *ptr++ = blank; + case 7: + *ptr++ = blank; + case 6: + *ptr++ = blank; + case 5: + *ptr++ = blank; + case 4: + *ptr++ = blank; + case 3: + *ptr++ = blank; + case 2: + *ptr++ = blank; + case 1: + *ptr++ = blank; + break; + } + } else { + ptr += depth; + } + } + ptr += raster; + } + } else { + if (depth/num_comps != 8) + return_error(gs_error_rangecheck); + for (y = 0; y < h; y++) + { + int c; + byte *mine; + code = dev_proc(mask, get_bits)(mask, y+y0, min, &mine); + if (code < 0) + goto fail; + for (c = 0; c < num_comps; c++) + { + if (p->data[c] == NULL) + continue; + ptr = p->data[c] + raster * y; + for (x = 0; x < w; x++) + { + int xx = x+x0; + if (((mine[xx>>3]>>(x&7)) & 1) == 0) { + *ptr++ = blank; + } else { + ptr++; + } + } + } + } + } + +fail: + gs_free_object(mask->memory, min, "blank_unmasked_bits"); + + return code; +} + /* Read back a rectangle of bits. */ /****** SHOULD USE MASK TO DEFINE UNREAD AREA *****/ static int @@ -710,16 +765,31 @@ gs_get_bits_params_t * params, gs_int_rect ** unread) { gx_device_pattern_accum *const padev = (gx_device_pattern_accum *) dev; - const gs_pattern1_instance_t *pinst = padev->instance; + int code; + gs_get_bits_params_t params2 = *params; - if (padev->bits) - return (*dev_proc(padev->target, get_bits_rectangle)) - (padev->target, prect, params, unread); + if (padev->bits) { + if (padev->mask) + params2.options &= ~GB_RETURN_POINTER; + code = (*dev_proc(padev->target, get_bits_rectangle)) + (padev->target, prect, ¶ms2, unread); + /* If we have a mask, then unmarked pixels of the bits + * will be undefined. Strictly speaking it makes no + * sense for us to return any value here, but the only + * caller of this currently is the overprint code, which + * uses the the values to parrot back to us. Let's + * make sure they are set to the default 'empty' values. + */ + if (code >= 0 && padev->mask) + code = blank_unmasked_bits((gx_device *)padev->mask, + padev->target->color_info.polarity, + padev->target->color_info.num_components, + padev->target->color_info.depth, + prect, ¶ms2); + return code; + } - if (pinst->templat.PaintType == 2) - return 0; - else - return_error(gs_error_Fatal); /* shouldn't happen */ + return_error(gs_error_Fatal); /* shouldn't happen */ } /* ------ Color space implementation ------ */ @@ -767,8 +837,23 @@ /* Clear the pointers to pacify the GC. */ uid_set_invalid(&tiles->uid); tiles->bits_used = 0; +#ifdef PACIFY_VALGRIND + /* The following memsets are required to avoid a valgrind warning + * in: + * gs -I./gs/lib -sOutputFile=out.pgm -dMaxBitmap=10000 + * -sDEVICE=pgmraw -r300 -Z: -sDEFAULTPAPERSIZE=letter + * -dNOPAUSE -dBATCH -K2000000 -dClusterJob -dJOBSERVER + * tests_private/ps/ps3cet/11-14.PS + * Setting the individual elements of the structures directly is + * not enough, which leads me to believe that we are writing the + * entire structs out, padding and all. + */ + memset(&tiles->tbits, 0, sizeof(tiles->tbits)); + memset(&tiles->tmask, 0, sizeof(tiles->tmask)); +#else tiles->tbits.data = 0; tiles->tmask.data = 0; +#endif tiles->index = i; tiles->cdev = NULL; tiles->ttrans = NULL; @@ -778,17 +863,17 @@ } /* Ensure that an imager has a Pattern cache. */ static int -ensure_pattern_cache(gs_imager_state * pis) +ensure_pattern_cache(gs_gstate * pgs) { - if (pis->pattern_cache == 0) { + if (pgs->pattern_cache == 0) { gx_pattern_cache *pcache = - gx_pattern_alloc_cache(pis->memory, + gx_pattern_alloc_cache(pgs->memory, gx_pat_cache_default_tiles(), gx_pat_cache_default_bits()); if (pcache == 0) return_error(gs_error_VMerror); - pis->pattern_cache = pcache; + pgs->pattern_cache = pcache; } return 0; } @@ -805,12 +890,12 @@ /* Get and set the Pattern cache in a gstate. */ gx_pattern_cache * -gstate_pattern_cache(gs_state * pgs) +gstate_pattern_cache(gs_gstate * pgs) { return pgs->pattern_cache; } void -gstate_set_pattern_cache(gs_state * pgs, gx_pattern_cache * pcache) +gstate_set_pattern_cache(gs_gstate * pgs, gx_pattern_cache * pcache) { pgs->pattern_cache = pcache; } @@ -843,17 +928,24 @@ dev_proc(&ctile->cdev->common, close_device)((gx_device *)&ctile->cdev->common); /* Free up the icc based stuff in the clist device. I am puzzled why the other objects are not released */ - clist_icc_freetable(ctile->cdev->common.icc_table, + clist_free_icc_table(ctile->cdev->common.icc_table, ctile->cdev->common.memory); + ctile->cdev->common.icc_table = NULL; rc_decrement(ctile->cdev->common.icc_cache_cl, "gx_pattern_cache_free_entry"); + ctile->cdev->common.icc_cache_cl = NULL; + ctile->cdev->writer.pinst = NULL; + gs_free_object(ctile->cdev->common.memory->non_gc_memory, ctile->cdev->common.cache_chunk, "free tile cache for clist"); + ctile->cdev->common.cache_chunk = 0; temp_device = (gx_device *)ctile->cdev; gx_device_retain(temp_device, false); ctile->cdev = NULL; } if (ctile->ttrans != NULL) { - + if_debug2m('v', mem, + "[v*] Freeing trans pattern from cache, uid = %ld id = %ld \n", + ctile->uid.id, ctile->id); if ( ctile->ttrans->pdev14 == NULL) { /* This can happen if we came from the clist */ if (ctile->ttrans->mem != NULL) @@ -889,15 +981,15 @@ /* enough space is available (or nothing left to free). */ /* This will allow 1 oversized entry */ void -gx_pattern_cache_ensure_space(gs_imager_state * pis, int needed) +gx_pattern_cache_ensure_space(gs_gstate * pgs, int needed) { - int code = ensure_pattern_cache(pis); + int code = ensure_pattern_cache(pgs); gx_pattern_cache *pcache; if (code < 0) return; /* no cache -- just exit */ - pcache = pis->pattern_cache; + pcache = pgs->pattern_cache; /* If too large then start freeing entries */ /* By starting at 'next', we attempt to first free the oldest entries */ @@ -910,9 +1002,9 @@ /* Export updating the pattern_cache bits_used and tiles_used for clist reading */ void -gx_pattern_cache_update_used(gs_imager_state *pis, ulong used) +gx_pattern_cache_update_used(gs_gstate *pgs, ulong used) { - gx_pattern_cache *pcache = pis->pattern_cache; + gx_pattern_cache *pcache = pgs->pattern_cache; pcache->bits_used += used; pcache->tiles_used++; @@ -926,7 +1018,7 @@ */ static void make_bitmap(gx_strip_bitmap *, const gx_device_memory *, gx_bitmap_id); int -gx_pattern_cache_add_entry(gs_imager_state * pis, +gx_pattern_cache_add_entry(gs_gstate * pgs, gx_device_forward * fdev, gx_color_tile ** pctile) { gx_pattern_cache *pcache; @@ -934,7 +1026,7 @@ ulong used = 0, mask_used = 0, trans_used = 0; gx_bitmap_id id; gx_color_tile *ctile; - int code = ensure_pattern_cache(pis); + int code = ensure_pattern_cache(pgs); extern dev_proc_open_device(pattern_clist_open_device); gx_device_memory *mmask = NULL; gx_device_memory *mbits = NULL; @@ -943,9 +1035,9 @@ if (code < 0) return code; - pcache = pis->pattern_cache; + pcache = pgs->pattern_cache; - if (fdev->procs.open_device != pattern_clist_open_device) { + if (dev_proc(fdev, open_device) != pattern_clist_open_device) { gx_device_pattern_accum *padev = (gx_device_pattern_accum *)fdev; mbits = padev->bits; @@ -1016,9 +1108,13 @@ ctile->is_simple = pinst->is_simple; ctile->has_overlap = pinst->has_overlap; ctile->is_dummy = false; - if (fdev->procs.open_device != pattern_clist_open_device) { + if (pinst->templat.uses_transparency) + ctile->blending_mode = ((pdf14_device *)(pgs->device))->blend_mode; + else + ctile->blending_mode = 0; + if (dev_proc(fdev, open_device) != pattern_clist_open_device) { if (mbits != 0) { - make_bitmap(&ctile->tbits, mbits, gs_next_ids(pis->memory, 1)); + make_bitmap(&ctile->tbits, mbits, gs_next_ids(pgs->memory, 1)); mbits->bitmap_memory = 0; /* don't free the bits */ } else ctile->tbits.data = 0; @@ -1028,6 +1124,9 @@ } else ctile->tmask.data = 0; if (trans != 0) { + if_debug2m('v', pgs->memory, + "[v*] Adding trans pattern to cache, uid = %ld id = %ld \n", + ctile->uid.id, ctile->id); ctile->ttrans = trans; } @@ -1043,15 +1142,6 @@ ctile->tmask.size.x = 0; ctile->tmask.size.y = 0; ctile->cdev = cdev; -#if 0 /* Don't free - tile cache is used by clist reader. */ - gs_free_object(cwdev->bandlist_memory, cwdev->data, "gx_pattern_cache_add_entry"); - cwdev->data = NULL; - cwdev->states = NULL; - cwdev->cbuf = NULL; - cwdev->cnext = NULL; - cwdev->cend = NULL; - cwdev->ccl = NULL; -#endif /* Prevent freeing files on pattern_paint_cleanup : */ cwdev->do_not_open_or_close_bandfiles = true; } @@ -1060,7 +1150,7 @@ * going in and coming out of the cache. Therefore we store the used * figure in the tile so we always remove the same amount. */ ctile->bits_used = used; - gx_pattern_cache_update_used(pis, used); + gx_pattern_cache_update_used(pgs, used); *pctile = ctile; return 0; @@ -1068,17 +1158,17 @@ /* Get entry for reading a pattern from clist. */ int -gx_pattern_cache_get_entry(gs_imager_state * pis, gs_id id, gx_color_tile ** pctile) +gx_pattern_cache_get_entry(gs_gstate * pgs, gs_id id, gx_color_tile ** pctile) { gx_pattern_cache *pcache; gx_color_tile *ctile; - int code = ensure_pattern_cache(pis); + int code = ensure_pattern_cache(pgs); if (code < 0) return code; - pcache = pis->pattern_cache; + pcache = pgs->pattern_cache; ctile = &pcache->tiles[id % pcache->num_tiles]; - gx_pattern_cache_free_entry(pis->pattern_cache, ctile); + gx_pattern_cache_free_entry(pgs->pattern_cache, ctile); ctile->id = id; *pctile = ctile; return 0; @@ -1093,17 +1183,17 @@ /* Add a dummy Pattern cache entry. Stubs a pattern tile for interpreter when device handles high level patterns. */ int -gx_pattern_cache_add_dummy_entry(gs_imager_state *pis, +gx_pattern_cache_add_dummy_entry(gs_gstate *pgs, gs_pattern1_instance_t *pinst, int depth) { gx_color_tile *ctile; gx_pattern_cache *pcache; gx_bitmap_id id = pinst->id; - int code = ensure_pattern_cache(pis); + int code = ensure_pattern_cache(pgs); if (code < 0) return code; - pcache = pis->pattern_cache; + pcache = pgs->pattern_cache; ctile = &pcache->tiles[id % pcache->num_tiles]; gx_pattern_cache_free_entry(pcache, ctile); ctile->id = id; @@ -1145,14 +1235,14 @@ byte *curr_ptr = Buffer; int plane_offset; - is_planar = dev_proc(mdev, dev_spec_op)(mdev, gxdso_is_native_planar, NULL, 0) > 0; + is_planar = mdev->is_planar; max_bands = ( n_chan < 57 ? n_chan : 56); /* Photoshop handles at most 56 bands */ if (is_planar) { - gs_sprintf(full_file_name,"%d)PATTERN_PLANE_%dx%dx%d.raw",global_pat_index, - width,height,max_bands); + gs_sprintf(full_file_name, "%d)PATTERN_PLANE_%dx%dx%d.raw", global_pat_index, + mdev->raster, height, max_bands); } else { - gs_sprintf(full_file_name,"%d)PATTERN_CHUNK_%dx%dx%d.raw",global_pat_index, - width,height,max_bands); + gs_sprintf(full_file_name, "%d)PATTERN_CHUNK_%dx%dx%d.raw", global_pat_index, + width, height, max_bands); } fid = gp_fopen(full_file_name,"wb"); if (depth >= 8) { @@ -1160,14 +1250,14 @@ if (is_planar) { for (m = 0; m < max_bands; m++) { curr_ptr = mdev->line_ptrs[m*mdev->height]; - fwrite(curr_ptr,1,height*width,fid); + fwrite(curr_ptr, 1, mdev->height * mdev->raster, fid); } } else { /* Just dump it like it is */ - fwrite(Buffer,1,max_bands*height*width,fid); + fwrite(Buffer, 1, max_bands * height * width, fid); } } else { - /* Binary Data. Lets get to 8 bit for debugging. We have to + /* Binary Data. Lets get to 8 bit for debugging. We have to worry about planar vs. chunky. Note this assumes 1 bit data only. */ if (is_planar) { @@ -1189,17 +1279,17 @@ for (k = 0; k < width; k++) { for (m = 0; m < max_bands; m++) { /* index current byte */ - byte_number = - (int) ceil((( (float) k * (float) max_bands + + byte_number = + (int) ceil((( (float) k * (float) max_bands + (float) m + 1.0) / 8.0)) - 1; /* get byte of interest */ - current_byte = + current_byte = curr_ptr[j*(mdev->raster) + byte_number]; /* get bit position */ - bit_position = + bit_position = 7 - (k * max_bands + m - byte_number * 8); /* extract and create byte */ - output_val = + output_val = ((current_byte >> bit_position) & 0x1) * 255; fwrite(&output_val,1,1,fid); } @@ -1221,7 +1311,7 @@ pbm->rep_height = pbm->size.y = mdev->height; pbm->id = id; pbm->rep_shift = pbm->shift = 0; - pbm->num_planes = (mdev->num_planes > 1 ? mdev->num_planes : 1); + pbm->num_planes = (mdev->is_planar ? mdev->color_info.num_components : 1); /* Lets dump this for debug purposes */ @@ -1258,7 +1348,7 @@ /* blank the pattern accumulator device assumed to be in the graphics state */ int -gx_erase_colored_pattern(gs_state *pgs) +gx_erase_colored_pattern(gs_gstate *pgs) { int code; gx_device_pattern_accum *pdev = (gx_device_pattern_accum *)gs_currentdevice(pgs); @@ -1268,12 +1358,19 @@ if ((code = gs_setgray(pgs, 1.0)) >= 0) { gs_rect rect; gx_device_memory *mask; + static const gs_matrix identity = { 1, 0, 0, 1, 0, 0 }; + pgs->log_op = lop_default; rect.p.x = 0.0; rect.p.y = 0.0; rect.q.x = (double)pdev->width; rect.q.y = (double)pdev->height; + code = gs_setmatrix(pgs, &identity); + if (code < 0) { + gs_grestore_only(pgs); + return code; + } /* we don't want the fill rectangle device call to use the mask */ mask = pdev->mask; @@ -1281,56 +1378,63 @@ code = gs_rectfill(pgs, &rect, 1); /* restore the mask */ pdev->mask = mask; - if (code < 0) + if (code < 0) { + gs_grestore_only(pgs); return code; + } } /* we don't need wraparound here */ - return gs_grestore_only(pgs); + gs_grestore_only(pgs); + return code; } /* Reload a (non-null) Pattern color into the cache. */ /* *pdc is already set, except for colors.pattern.p_tile and mask.m_tile. */ int -gx_pattern_load(gx_device_color * pdc, const gs_imager_state * pis, +gx_pattern_load(gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { gx_device_forward *adev = NULL; gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)pdc->ccolor.pattern; - gs_state *saved; + gs_gstate *saved; gx_color_tile *ctile; - gs_memory_t *mem = pis->memory; - int has_tags = dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS; + gs_memory_t *mem = pgs->memory; + bool has_tags = device_encodes_tags(dev); int code; - if (pis->pattern_cache == NULL) - if ((code = ensure_pattern_cache((gs_imager_state *) pis))< 0) /* break const for call */ + if (pgs->pattern_cache == NULL) + if ((code = ensure_pattern_cache((gs_gstate *) pgs))< 0) /* break const for call */ return code; - if (gx_pattern_cache_lookup(pdc, pis, dev, select)) + if (gx_pattern_cache_lookup(pdc, pgs, dev, select)) return 0; /* Get enough space in the cache for this pattern (estimated if it is a clist) */ - gx_pattern_cache_ensure_space((gs_imager_state *)pis, gx_pattern_size_estimate(pinst, has_tags)); + gx_pattern_cache_ensure_space((gs_gstate *)pgs, gx_pattern_size_estimate(pinst, has_tags)); /* * Note that adev is an internal device, so it will be freed when the * last reference to it from a graphics state is deleted. */ - adev = gx_pattern_accum_alloc(mem, pis->pattern_cache->memory, pinst, "gx_pattern_load"); + adev = gx_pattern_accum_alloc(mem, pgs->pattern_cache->memory, pinst, "gx_pattern_load"); if (adev == 0) return_error(gs_error_VMerror); gx_device_set_target((gx_device_forward *)adev, dev); code = dev_proc(adev, open_device)((gx_device *)adev); - if (code < 0) - goto fail; - saved = gs_gstate(pinst->saved); + if (code < 0) { + gs_free_object(mem, adev, "gx_pattern_load"); + return code; + } + saved = gs_gstate_copy(pinst->saved, pinst->saved->memory); if (saved == 0) { code = gs_note_error(gs_error_VMerror); goto fail; } if (saved->pattern_cache == 0) - saved->pattern_cache = pis->pattern_cache; - gs_setdevice_no_init(saved, (gx_device *)adev); + saved->pattern_cache = pgs->pattern_cache; + code = gs_setdevice_no_init(saved, (gx_device *)adev); + if (code < 0) + goto fail; if (pinst->templat.uses_transparency) { if_debug0m('v', mem, "gx_pattern_load: pushing the pdf14 compositor device into this graphics state\n"); if ((code = gs_push_pdf14trans_device(saved, true)) < 0) @@ -1344,30 +1448,41 @@ make a similar change in zpcolor.c where much of this pattern code is duplicated to support high level stream patterns. */ - if (pinst->templat.PaintType == 1 && !(pinst->is_clist)) + if (pinst->templat.PaintType == 1 && !(pinst->is_clist) + && dev_proc(pinst->saved->device, dev_spec_op)(pinst->saved->device, gxdso_pattern_can_accum, NULL, 0) == 0) if ((code = gx_erase_colored_pattern(saved)) < 0) - return code; + goto fail; } code = (*pinst->templat.PaintProc)(&pdc->ccolor, saved); if (code < 0) { + if (dev_proc(adev, open_device) == pattern_accum_open) { + // free pattern cache data that never got added to the dictionary + gx_device_pattern_accum *padev = (gx_device_pattern_accum *) adev; + if ((padev->bits != NULL) && (padev->bits->base != NULL)) { + gs_free_object(padev->bits->memory, padev->bits->base, "mem_open"); + } + } /* RJW: At this point, in the non transparency case, * saved->device == adev. So unretain it, close it, and the - * gs_state_free(saved) will remove it. In the transparency case, + * gs_gstate_free(saved) will remove it. In the transparency case, * saved->device = the pdf14 device. So we need to unretain it, - * close adev, and finally close saved->device - * (which frees adev). */ + * close adev, and finally close saved->device. + */ gx_device_retain(saved->device, false); /* device no longer retained */ if (pinst->templat.uses_transparency) { - if (pinst->is_clist == 0) + if (pinst->is_clist == 0) { gs_free_object(((gx_device_pattern_accum *)adev)->bitmap_memory, ((gx_device_pattern_accum *)adev)->transbuff, "gx_pattern_load"); + } dev_proc(adev, close_device)((gx_device *)adev); + /* adev was the target of the pdf14 device, so also is no longer retained */ + gx_device_retain((gx_device *)adev, false); /* device no longer retained */ } dev_proc(saved->device, close_device)((gx_device *)saved->device); /* Freeing the state should now free the device which may be the pdf14 compositor. */ - gs_state_free(saved); + gs_gstate_free_chain(saved); return code; } if (pinst->templat.uses_transparency) { @@ -1376,12 +1491,12 @@ return code; */ if (pinst->is_clist) { /* Send the compositor command to close the PDF14 device */ - code = (gs_pop_pdf14trans_device(saved, true) < 0); + code = gs_pop_pdf14trans_device(saved, true); if (code < 0) return code; } else { /* Not a clist, get PDF14 buffer information */ - code = + code = pdf14_get_buffer_information(saved->device, ((gx_device_pattern_accum*)adev)->transbuff, saved->memory, @@ -1393,16 +1508,16 @@ } } /* We REALLY don't like the following cast.... */ - code = gx_pattern_cache_add_entry((gs_imager_state *)pis, + code = gx_pattern_cache_add_entry((gs_gstate *)pgs, adev, &ctile); if (code >= 0) { - if (!gx_pattern_cache_lookup(pdc, pis, dev, select)) { + if (!gx_pattern_cache_lookup(pdc, pgs, dev, select)) { mlprintf(mem, "Pattern cache lookup failed after insertion!\n"); code = gs_note_error(gs_error_Fatal); } } #ifdef DEBUG - if (gs_debug_c('B') && adev->procs.open_device == pattern_accum_open) { + if (gs_debug_c('B') && dev_proc(adev, open_device) == pattern_accum_open) { gx_device_pattern_accum *pdev = (gx_device_pattern_accum *)adev; if (pdev->mask) @@ -1420,16 +1535,25 @@ /* data iff they are still needed. */ dev_proc(adev, close_device)((gx_device *)adev); /* Free the chain of gstates. Freeing the state will free the device. */ - gs_state_free_chain(saved); + gs_gstate_free_chain(saved); return code; + fail: - if (adev->procs.open_device == pattern_clist_open_device) { + if (dev_proc(adev, open_device) == pattern_accum_open) { + // free pattern cache data that never got added to the dictionary + gx_device_pattern_accum *padev = (gx_device_pattern_accum *) adev; + if ((padev->bits != NULL) && (padev->bits->base != NULL)) { + gs_free_object(padev->bits->memory, padev->bits->base, "mem_open"); + } + } + if (dev_proc(adev, open_device) == pattern_clist_open_device) { gx_device_clist *cdev = (gx_device_clist *)adev; gs_free_object(cdev->writer.bandlist_memory, cdev->common.data, "gx_pattern_load"); cdev->common.data = 0; } - gs_free_object(mem, adev, "gx_pattern_load"); + dev_proc(adev, close_device)((gx_device *)adev); + gs_gstate_free_chain(saved); return code; } @@ -1437,7 +1561,7 @@ cs_proc_remap_color(gx_remap_Pattern); /* check the prototype */ int gs_pattern1_remap_color(const gs_client_color * pc, const gs_color_space * pcs, - gx_device_color * pdc, const gs_imager_state * pis, + gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev, gs_color_select_t select) { gs_pattern1_instance_t *pinst = (gs_pattern1_instance_t *)pc->pattern; @@ -1452,8 +1576,11 @@ return 0; } if (pinst->templat.PaintType == 2) { /* uncolored */ - code = (pcs->base_space->type->remap_color) - (pc, pcs->base_space, pdc, pis, dev, select); + if (pcs->base_space) + code = (pcs->base_space->type->remap_color) + (pc, pcs->base_space, pdc, pgs, dev, select); + else + code = gs_note_error(gs_error_unregistered); if (code < 0) return code; if (pdc->type == gx_dc_type_pure) @@ -1470,5 +1597,29 @@ color_set_null_pattern(pdc); pdc->mask.id = pinst->id; pdc->mask.m_tile = 0; - return gx_pattern_load(pdc, pis, dev, select); + return gx_pattern_load(pdc, pgs, dev, select); +} + +int +pattern_accum_dev_spec_op(gx_device *dev, int dso, void *data, int size) +{ + gx_device_pattern_accum *const padev = (gx_device_pattern_accum *)dev; + const gs_pattern1_instance_t *pinst = padev->instance; + gx_device *target = + (padev->target == 0 ? gs_currentdevice(pinst->saved) : + padev->target); + + if (dso == gxdso_in_pattern_accumulator) + return (pinst->templat.PaintType == 2 ? 2 : 1); + if (dso == gxdso_get_dev_param) { + dev_param_req_t *request = (dev_param_req_t *)data; + gs_param_list * plist = (gs_param_list *)request->list; + bool bool_true = 1; + + if (strcmp(request->Param, "NoInterpolateImagemasks") == 0) { + return param_write_bool(plist, "NoInterpolateImagemasks", &bool_true); + } + } + + return dev_proc(target, dev_spec_op)(target, dso, data, size); } diff -Nru ghostscript-9.10~dfsg/base/gxpcolor.h ghostscript-9.25~dfsg+1/base/gxpcolor.h --- ghostscript-9.10~dfsg/base/gxpcolor.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpcolor.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -66,7 +66,7 @@ #define pattern_proc_make_pattern(proc)\ int proc(gs_client_color *, const gs_pattern_template_t *,\ - const gs_matrix *, gs_state *, gs_memory_t *) + const gs_matrix *, gs_gstate *, gs_memory_t *) pattern_proc_make_pattern((*make_pattern)); @@ -96,7 +96,7 @@ * pattern instance specifies a color space. */ #define pattern_proc_set_color(proc)\ - int proc(const gs_client_color *, gs_state *) + int proc(const gs_client_color *, gs_gstate *) pattern_proc_set_color((*set_color)); @@ -115,7 +115,7 @@ * saved graphics state, and fill in the common members. */ int gs_make_pattern_common(gs_client_color *, const gs_pattern_template_t *, - const gs_matrix *, gs_state *, gs_memory_t *, + const gs_matrix *, gs_gstate *, gs_memory_t *, gs_memory_type_ptr_t); /* Declare the freeing procedure for Pattern instances. */ @@ -130,7 +130,7 @@ * device color type. */ extern const gx_device_color_type_t - gx_dc_pattern, gx_dc_pure_masked, gx_dc_binary_masked, + gx_dc_pattern, gx_dc_pure_masked, gx_dc_binary_masked, gx_dc_colored_masked, gx_dc_devn_masked; #ifndef gx_dc_type_pattern @@ -168,11 +168,11 @@ int planestride; int n_chan; /* number of pixel planes including alpha */ bool has_shape; /* extra plane inserted */ + bool has_tags; /* and yet another plane for the tag */ int width; /* Complete plane width/height; rect may be a subset of this */ int height; const pdf14_nonseparable_blending_procs_t *blending_procs; bool is_additive; - gs_blend_mode_t blending_mode; gs_int_rect *dirty; void (* pat_trans_fill)(int xmin, int ymin, int xmax, int ymax, int px, int py, const gx_color_tile *ptile, @@ -215,6 +215,7 @@ /* (i.e., the mask is all 1's) */ gx_pattern_trans_t *ttrans; /* !=0 if has trans. in this case tbits == 0 */ + gs_blend_mode_t blending_mode; /* used if the pattern has transparency */ gx_device_clist *cdev; /* not NULL if the graphics is a command list. */ byte is_simple; /* true if xstep/ystep = tile size */ @@ -225,10 +226,10 @@ /* The following is neither key nor value. */ uint index; /* the index of the tile within */ bool trans_group_popped; /* Used to avoid multiple group pops in image mask fills */ - bool is_planar; /* Has to be stored here due to the device - change that can occur when the tile is + bool is_planar; /* Has to be stored here due to the device + change that can occur when the tile is created and when it is written in the clist - when we are writing to a transparency + when we are writing to a transparency device which, is not planar but the target is */ /* the cache (for GC) */ @@ -257,8 +258,8 @@ void gx_pattern_cache_free(gx_pattern_cache *pcache); /* Get or set the Pattern cache in a gstate. */ -gx_pattern_cache *gstate_pattern_cache(gs_state *); -void gstate_set_pattern_cache(gs_state *, gx_pattern_cache *); +gx_pattern_cache *gstate_pattern_cache(gs_gstate *); +void gstate_set_pattern_cache(gs_gstate *, gx_pattern_cache *); /* * Define a device for accumulating the rendering of a Pattern. @@ -295,32 +296,35 @@ gs_memory_t * stoarge_memory, gs_pattern1_instance_t *pinst, client_name_t cname); +/* Return true if pattern accumulator device (not pattern-clist) */ +bool gx_device_is_pattern_accum(gx_device *dev); + /* Given the size of a new pattern tile, free entries from the cache until */ /* enough space is available (or nothing left to free). */ /* This will allow 1 oversized entry */ -void gx_pattern_cache_ensure_space(gs_imager_state * pis, int needed); +void gx_pattern_cache_ensure_space(gs_gstate * pgs, int needed); -void gx_pattern_cache_update_used(gs_imager_state *pis, ulong used); +void gx_pattern_cache_update_used(gs_gstate *pgs, ulong used); /* Update cache tile space */ -void gx_pattern_cache_update_space(gs_imager_state * pis, int64_t used); +void gx_pattern_cache_update_space(gs_gstate * pgs, int64_t used); /* Add an accumulated pattern to the cache. */ /* Note that this does not free any of the data in the accumulator */ /* device, but it may zero out the bitmap_memory pointers to prevent */ /* the accumulated bitmaps from being freed when the device is closed. */ -int gx_pattern_cache_add_entry(gs_imager_state *, gx_device_forward *, +int gx_pattern_cache_add_entry(gs_gstate *, gx_device_forward *, gx_color_tile **); /* Add a dummy Pattern cache entry. Stubs a pattern tile for interpreter when device handles high level patterns. */ -int gx_pattern_cache_add_dummy_entry(gs_imager_state *pis, gs_pattern1_instance_t *pinst, +int gx_pattern_cache_add_dummy_entry(gs_gstate *pgs, gs_pattern1_instance_t *pinst, int depth); /* Get entry for reading a pattern from clist. */ -int gx_pattern_cache_get_entry(gs_imager_state * pis, gs_id id, gx_color_tile ** pctile); +int gx_pattern_cache_get_entry(gs_gstate * pgs, gs_id id, gx_color_tile ** pctile); /* Look up a pattern color in the cache. */ -bool gx_pattern_cache_lookup(gx_device_color *, const gs_imager_state *, +bool gx_pattern_cache_lookup(gx_device_color *, const gs_gstate *, gx_device *, gs_color_select_t); /* Purge selected entries from the pattern cache. */ @@ -330,7 +334,11 @@ bool gx_pattern_tile_is_clist(gx_color_tile *ptile); +/* Return true if pattern-clist device (not pattern accumulator) */ +bool gx_device_is_pattern_clist(gx_device *dev); + dev_proc_open_device(pattern_clist_open_device); +dev_proc_dev_spec_op(pattern_accum_dev_spec_op); /* Code to fill a pdf14 transparency rectangles with a pattern trans buffer object */ int gx_trans_pattern_fill_rect(int xmin, int ymin, int xmax, int ymax, @@ -350,9 +358,9 @@ it would be best to avoid doing it if not needed. */ void tile_rect_trans_blend(int xmin, int ymin, int xmax, int ymax, int px, int py, const gx_color_tile *ptile, - gx_pattern_trans_t *fill_trans_buffer); + gx_pattern_trans_t *fill_trans_buffer); /* File a colored pattern with white */ -int gx_erase_colored_pattern(gs_state *pgs); +int gx_erase_colored_pattern(gs_gstate *pgs); #endif /* gxpcolor_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxpcopy.c ghostscript-9.25~dfsg+1/base/gxpcopy.c --- ghostscript-9.10~dfsg/base/gxpcopy.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpcopy.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,9 +20,8 @@ #include "gserrors.h" #include "gxfixed.h" #include "gxfarith.h" -#include "gxistate.h" /* for access to line params */ +#include "gxgstate.h" /* for access to line params */ #include "gzpath.h" -#include "vdtrace.h" /* Forward declarations */ static void adjust_point_to_tangent(segment *, const segment *, @@ -85,7 +84,7 @@ /* If the copy fails, free the new path. */ int gx_path_copy_reducing(const gx_path *ppath_old, gx_path *ppath, - fixed fixed_flatness, const gs_imager_state *pis, + fixed fixed_flatness, const gs_gstate *pgs, gx_path_copy_options options) { const segment *pseg; @@ -105,22 +104,20 @@ #endif if (options & pco_for_stroke) { /* Precompute the maximum expansion of the bounding box. */ - double width = pis->line_params.half_width; + double width = pgs->line_params.half_width; expansion.x = - float2fixed((fabs(pis->ctm.xx) + fabs(pis->ctm.yx)) * width) * 2; + float2fixed((fabs(pgs->ctm.xx) + fabs(pgs->ctm.yx)) * width) * 2; expansion.y = - float2fixed((fabs(pis->ctm.xy) + fabs(pis->ctm.yy)) * width) * 2; + float2fixed((fabs(pgs->ctm.xy) + fabs(pgs->ctm.yy)) * width) * 2; } else expansion.x = expansion.y = 0; /* Quiet gcc warning. */ - vd_setcolor(RGB(255,255,0)); pseg = (const segment *)(ppath_old->first_subpath); while (pseg) { switch (pseg->type) { case s_start: code = gx_path_add_point(ppath, pseg->pt.x, pseg->pt.y); - vd_moveto(pseg->pt.x, pseg->pt.y); break; case s_curve: { @@ -204,7 +201,6 @@ notes); if (code < 0) break; - vd_lineto(x0, y0); start = ppath->current_subpath->last; notes |= sn_not_first; cseg = *pc; @@ -216,7 +212,6 @@ * they line up with the tangents. */ end = ppath->current_subpath->last; - vd_lineto(ppath->position.x, ppath->position.y); if ((code = gx_path_add_line_notes(ppath, ppath->position.x, ppath->position.y, @@ -247,7 +242,6 @@ break; code = gx_path_add_line_notes(ppath, pseg->pt.x, pseg->pt.y, pseg->notes); - vd_lineto(pseg->pt.x, pseg->pt.y); break; case s_gap: code = break_gap_if_long(ppath, pseg); @@ -255,7 +249,6 @@ break; code = gx_path_add_gap_notes(ppath, pseg->pt.x, pseg->pt.y, pseg->notes); - vd_lineto(pseg->pt.x, pseg->pt.y); break; case s_dash: { @@ -270,7 +263,6 @@ if (code < 0) break; code = gx_path_close_subpath(ppath); - vd_closepath; break; default: /* can't happen */ code = gs_note_error(gs_error_unregistered); @@ -281,9 +273,14 @@ } pseg = pseg->next; } - if (path_last_is_moveto(ppath_old)) - gx_path_add_point(ppath, ppath_old->position.x, + if (path_last_is_moveto(ppath_old)) { + code = gx_path_add_point(ppath, ppath_old->position.x, ppath_old->position.y); + if (code < 0) { + gx_path_new(ppath); + return code; + } + } if (ppath_old->bbox_set) { if (ppath->bbox_set) { ppath->bbox.p.x = min(ppath_old->bbox.p.x, ppath->bbox.p.x); @@ -465,8 +462,8 @@ { fixed x0 = ppath->position.x, y0 = ppath->position.y; segment_notes notes = pc->notes; - double t[4], tt = 1, tp; - int c[4]; + double t[5], tt = 1, tp; + int c[5]; int n0, n1, n, i, j, k = 0; fixed ax, bx, cx, ay, by, cy, v01, v12; fixed px, py, qx, qy, rx, ry, sx, sy; diff -Nru ghostscript-9.10~dfsg/base/gxpdash.c ghostscript-9.25~dfsg+1/base/gxpdash.c --- ghostscript-9.10~dfsg/base/gxpdash.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpdash.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,7 +21,7 @@ #include "gscoord.h" #include "gxfixed.h" #include "gxarith.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gsline.h" #include "gzline.h" #include "gzpath.h" @@ -29,14 +29,14 @@ /* Expand a dashed path into explicit segments. */ /* The path contains no curves. */ static int subpath_expand_dashes(const subpath *, gx_path *, - const gs_imager_state *, + const gs_gstate *, const gx_dash_params *); int gx_path_add_dash_expansion(const gx_path * ppath_old, gx_path * ppath, - const gs_imager_state * pis) + const gs_gstate * pgs) { const subpath *psub; - const gx_dash_params *dash = &gs_currentlineparams(pis)->dash; + const gx_dash_params *dash = &gs_currentlineparams(pgs)->dash; int code = 0; if (dash->pattern_size == 0) @@ -44,13 +44,13 @@ for (psub = ppath_old->first_subpath; psub != 0 && code >= 0; psub = (const subpath *)psub->last->next ) - code = subpath_expand_dashes(psub, ppath, pis, dash); + code = subpath_expand_dashes(psub, ppath, pgs, dash); return code; } static int subpath_expand_dashes(const subpath * psub, gx_path * ppath, - const gs_imager_state * pis, const gx_dash_params * dash) + const gs_gstate * pgs, const gx_dash_params * dash) { const float *pattern = dash->pattern; int count, index; @@ -62,7 +62,7 @@ int wrap = (dash->init_ink_on && psub->is_closed ? -1 : 0); int drawing = wrap; segment_notes notes = ~sn_not_first; - const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis); + const gx_line_params *pgs_lp = gs_currentlineparams_inline(pgs); bool zero_length = true; int code; gs_line_cap cap; @@ -116,9 +116,14 @@ zero_length = false; dx = udx, dy = udy; /* scaled as fixed */ - gs_imager_idtransform(pis, dx, dy, &d); + code = gs_gstate_idtransform(pgs, dx, dy, &d); + if (code < 0) { + d.x = 0; d.y = 0; + /* Swallow the error */ + code = 0; + } length = hypot(d.x, d.y) * (1.0 / fixed_1); - if (gs_imager_currentdashadapt(pis)) { + if (gs_gstate_currentdashadapt(pgs)) { double reps = length / dash->pattern_length; scale = reps / ceil(reps); diff -Nru ghostscript-9.10~dfsg/base/gxpflat.c ghostscript-9.25~dfsg+1/base/gxpflat.c --- ghostscript-9.10~dfsg/base/gxpflat.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxpflat.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,7 +22,6 @@ #include "gxfixed.h" #include "gzpath.h" #include "memory_.h" -#include "vdtrace.h" /* ---------------- Curve flattening ---------------- */ @@ -144,7 +143,8 @@ if (!gs_debug_c('3')) return; for (i = 0; i < count; i++) - if_debug2('3', "[3]out x=%ld y=%ld\n", points[i].x, points[i].y); + if_debug2('3', "[3]out x=%ld y=%ld\n", + (long)points[i].x, (long)points[i].y); #endif } @@ -202,7 +202,6 @@ &self->ay, &self->by, &self->cy, k)) return false; self->curve = true; - vd_curve(self->x0, self->y0, x1, y1, x2, y2, self->x3, self->y3, 0, RGB(255, 255, 255)); self->k = k; #ifndef GS_THREADSAFE # ifdef DEBUG @@ -271,13 +270,10 @@ static inline bool check_diff_overflow(fixed v0, fixed v1) { - if (v0 < v1) { - if (v1 - v0 < 0) - return true; - } else { - if (v0 - v1 < 0) - return true; - } + if (v1 > 0) + return (v0 < min_fixed + v1); + else if (v1 < 0) + return (v0 > max_fixed + v1); return false; } @@ -415,9 +411,8 @@ if_debug5('3', "[3]%s x=%g, y=%g x=%ld y=%ld\n", (((x ^ self->x0) | (y ^ self->y0)) & float2fixed(-0.5) ? "add" : "skip"), - fixed2float(x), fixed2float(y), x, y); + fixed2float(x), fixed2float(y), (long)x, (long)y); self->lx1 = x, self->ly1 = y; - vd_bar(self->lx0, self->ly0, self->lx1, self->ly1, 1, RGB(0, 255, 0)); return true; } else { --self->i; @@ -438,19 +433,18 @@ if_debug5('3', "[3]%s x=%g, y=%g x=%ld y=%ld\n", (((x ^ self->lx0) | (y ^ self->ly0)) & float2fixed(-0.5) ? "add" : "skip"), - fixed2float(x), fixed2float(y), x, y); + fixed2float(x), fixed2float(y), (long)x, (long)y); # undef accum self->lx1 = self->x = x; self->ly1 = self->y = y; - vd_bar(self->lx0, self->ly0, self->lx1, self->ly1, 1, RGB(0, 255, 0)); return true; } last: self->lx1 = self->x3; self->ly1 = self->y3; if_debug4('3', "[3]last x=%g, y=%g x=%ld y=%ld\n", - fixed2float(self->lx1), fixed2float(self->ly1), self->lx1, self->ly1); - vd_bar(self->lx0, self->ly0, self->lx1, self->ly1, 1, RGB(0, 255, 0)); + fixed2float(self->lx1), fixed2float(self->ly1), + (long)self->lx1, (long)self->ly1); return false; } @@ -492,7 +486,6 @@ self->i++; self->lx0 = self->x0; self->ly0 = self->y0; - vd_bar(self->lx0, self->ly0, self->lx1, self->ly1, 1, RGB(0, 0, 255)); return false; } gx_flattened_iterator__unaccum(self); @@ -501,13 +494,13 @@ if_debug5('3', "[3]%s x=%g, y=%g x=%ld y=%ld\n", (((self->x ^ self->lx1) | (self->y ^ self->ly1)) & float2fixed(-0.5) ? "add" : "skip"), - fixed2float(self->x), fixed2float(self->y), self->x, self->y); + fixed2float(self->x), fixed2float(self->y), + (long)self->x, (long)self->y); gx_flattened_iterator__print_state(self); # endif last = (self->i == (1 << self->k) - 1); self->lx0 = self->x; self->ly0 = self->y; - vd_bar(self->lx0, self->ly0, self->lx1, self->ly1, 1, RGB(0, 0, 255)); if (last) if (self->lx0 != self->x0 || self->ly0 != self->y0) return_error(gs_error_unregistered); /* Must not happen. */ @@ -534,20 +527,16 @@ generate_segments(gx_path * ppath, const gs_fixed_point *points, int count, segment_notes notes) { - /* vd_moveto(ppath->position.x, ppath->position.y); */ if (notes & sn_not_first) { - /* vd_lineto_multi(points, count); */ print_points(points, count); return gx_path_add_lines_notes(ppath, points, count, notes); } else { int code; - /* vd_lineto(points[0].x, points[0].y); */ print_points(points, 1); code = gx_path_add_line_notes(ppath, points[0].x, points[0].y, notes); if (code < 0) return code; - /* vd_lineto_multi(points + 1, count - 1); */ print_points(points + 1, count - 1); return gx_path_add_lines_notes(ppath, points + 1, count - 1, notes | sn_not_first); } diff -Nru ghostscript-9.10~dfsg/base/gxrplane.h ghostscript-9.25~dfsg+1/base/gxrplane.h --- ghostscript-9.10~dfsg/base/gxrplane.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxrplane.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxsample.c ghostscript-9.25~dfsg+1/base/gxsample.c --- ghostscript-9.10~dfsg/base/gxsample.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxsample.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -41,7 +41,7 @@ # define ffL16 0x00ff0000U # define ffL24 0xff000000U #else -#if arch_sizeof_long == 4 +#if ARCH_SIZEOF_LONG == 4 /* * The compiler evaluates long expressions mod 2^32. Even very picky * compilers allow assigning signed longs to unsigned longs, so we use @@ -61,14 +61,14 @@ # define ffL24 0xff000000L #endif #endif -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN const bits32 lookup4x1to32_identity[16] = { map4tox(0, 0xff, ffL8, ffL16, ffL24) }; const bits32 lookup4x1to32_inverted[16] = { map4tox(n0L, 0xff, ffL8, ffL16, ffL24) }; -#else /* !arch_is_big_endian */ +#else /* !ARCH_IS_BIG_ENDIAN */ const bits32 lookup4x1to32_identity[16] = { map4tox(0, ffL24, ffL16, ffL8, 0xff) }; diff -Nru ghostscript-9.10~dfsg/base/gxsample.h ghostscript-9.25~dfsg+1/base/gxsample.h --- ghostscript-9.10~dfsg/base/gxsample.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxsample.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -80,4 +80,9 @@ SAMPLE_UNPACK_PROC(sample_unpack_4_interleaved); SAMPLE_UNPACK_PROC(sample_unpack_8_interleaved); +/* The following don't have interleaved variants */ +SAMPLE_UNPACK_PROC(sample_unpack_12); +SAMPLE_UNPACK_PROC(sample_unpack_16); +SAMPLE_UNPACK_PROC(sample_unpackicc_16); + #endif /* gxsample_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxsamplp.h ghostscript-9.25~dfsg+1/base/gxsamplp.h --- ghostscript-9.10~dfsg/base/gxsamplp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxsamplp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxscanc.c ghostscript-9.25~dfsg+1/base/gxscanc.c --- ghostscript-9.10~dfsg/base/gxscanc.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxscanc.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,4140 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Path stroking procedures for Ghostscript library */ +#include "math_.h" +#include "memory_.h" +#include "string_.h" +#include "gx.h" +#include "gpcheck.h" +#include "gserrors.h" +#include "gsdcolor.h" +#include "gsptype1.h" +#include "gxfixed.h" +#include "gxfarith.h" +#include "gxmatrix.h" +#include "gscoord.h" +#include "gsdevice.h" +#include "gxdevice.h" +#include "gxhttile.h" +#include "gxgstate.h" +#include "gzline.h" +#include "gzpath.h" +#include "gzcpath.h" +#include "gxpaint.h" +#include "gxscanc.h" +#include "gxfill.h" +#include "gxdcolor.h" +#include "assert_.h" +#include /* for qsort */ +#include /* For INT_MAX */ + +/* Overview of the scan conversion algorithm. + * + * The normal scan conversion algorithm runs through a path, converting + * it into a sequence of edges. It then runs through those edges from + * top to bottom keeping a list of which ones are "active", and ordering + * them so that it can read out a list of intersection points from left + * to right across any given scanline (or scan "band" when working with + * trapezoids). + * + * This scan conversion algorithm avoids the need to maintain an active + * line list, and to repeatedly re-sort lines. It is thus faster, at + * the cost of using more memory, and not being able to cope with + * trapezoids. + * + * Conceptually, the idea is to make an (initially empty) table. Each + * row of the table holds the set of intersection data for a given + * scanline. We therefore just need to run through the path once, + * decomposing it to a sequence of edges. We then step along each edge + * adding intersection information into each row of the table as we go. + * Each piece of intersection information includes the point at which + * the edge crosses the scanline, and the direction in which it does so + * (up or down). + * + * At the end of this process, we can then sort each rows data, and + * simply 'fill in' the scanline according to the winding rule. + * + * This copes well with 'centre of a pixel' fill modes, but 'any part + * of a pixel' requires some extra work. Let's describe 'centre of a + * pixel' first. + * + * Assume we have a path with n segments in, and a bbox that crosses + * a region x wide, y high. + * + * 1) Create a table, A, 1 int entry per scan line. Run through the path, + * segment by segment counting how many intersections occur on each + * scanline. (O(y * n)) + * + * 2) Create a table, B, with as many entries per scanline as determined in + * the table A. (O(y * n)) + * + * [Each entry is a (xcoord,direction) tuple. xcoord = the xcoord where + * an edge crosses the horizontal line through the middle of the pixel. + * direction = 0 if the edge is rising, 1 if falling.] + * + * 3) Run through the path segment by segment, inserting entries for each + * scanline intersection in table B. (O(y * n)) + * + * 4) Sort the scanline intersections of table B (on left,right,direction). + * (O(y * n log n) for current code) + * + * 5) Filter the scanline intersections according to the winding rule. + * (O(y * n)) + * + * 6) Fill rectangles according to each set of scanline intersections. + * (O(y * n)) + * + * So worst case complexity (when every segment crosses every scanline) is + * O(y * n log n). + * + * NOTE: If we use a binary comparison based sort, then the best we can manage + * is n log n for step 4. If we use a radix based sort, we can get O(n). + * Consider this if we ever need it. + * + * In order to cope with 'any part of a pixel' it no longer suffices + * to keep a single intersection point for each scanline intersection. + * Instead we keep the interval of a scanline that the edge intersects. + * Thus each entry is a (left,right,direction) tuple. left = the + * leftmost point at which this edge intersects this scanline. right = + * the rightmost point at which this edge intersects this scanline. + * direction = 0 for rising edges, 1 for falling edges. + * + * The rest of the algorithm is unchanged, apart from additional care + * being required when filling the scanlines to allow for the fact + * that edges are no longer point intersections. + * + * The first set of routines (gx_scan_convert and gx_fill_edgebuffer) + * implement the "pixel centre" covered routines by drawing rectangle + * high scanlines at a time. The second set of routines + * (gx_scan_convert_app and gx_fill_edgebuffer_app) is the equivalent, + * for "Any Part of Pixel" covered. + * + * The third and fourth are the same things, but using trapezoids + * that can be multiple scanlines high rather than scanlines. + * + * In order to do trapezoid extraction, we extend the edge intersection + * information to be (left,right,id,direction) (for the "centre pixel" + * variants) and (left,left_id,right,right_id,direction) (for the "any + * part of a pixel" variants). The 'id' is a int that is guaranteed + * unique for each flattened line in path. + * + * If we spot that each scanlines data has the same set of ids in the + * same order, then we can 'collate' them into a trapezoid. + */ + +/* NOTE: code in this file assumes that fixed and int can be used + * interchangably. */ + +#undef DEBUG_SCAN_CONVERTER +#undef DEBUG_OUTPUT_SC_AS_PS + +typedef int64_t fixed64; + +enum +{ + DIRN_UNSET = -1, + DIRN_UP = 0, + DIRN_DOWN = 1 +}; + +/* Centre of a pixel routines */ + +static int intcmp(const void *a, const void *b) +{ + return *((int*)a) - *((int *)b); +} + +#if defined(DEBUG_SCAN_CONVERTER) +int debugging_scan_converter = 1; + +static void +gx_edgebuffer_print(gx_edgebuffer * edgebuffer) +{ + int i; + + dlprintf1("Edgebuffer %x\n", edgebuffer); + dlprintf4("xmin=%x xmax=%x base=%x height=%x\n", + edgebuffer->xmin, edgebuffer->xmax, edgebuffer->base, edgebuffer->height); + for (i=0; i < edgebuffer->height; i++) { + int offset = edgebuffer->index[i]; + int *row = &edgebuffer->table[offset]; + int count = *row++; + dlprintf3("%d @ %d: %d =", i, offset, count); + while (count-- > 0) { + int v = *row++; + dlprintf2(" %x:%d", v&~1, v&1); + } + dlprintf("\n"); + } +} +#endif + +#ifdef DEBUG_OUTPUT_SC_AS_PS +static void coord(const char *str, fixed x, fixed y) +{ + if (x > 0) + dlprintf1(" 16#%x ", x); + else + dlprintf1("0 16#%x sub ", -x); + if (y > 0) + dlprintf1(" 16#%x ", y); + else + dlprintf1("0 16#%x sub ", -y); + dlprintf1("%s %%PS\n", str); +} +#endif + +static void mark_line(fixed sx, fixed sy, fixed ex, fixed ey, int base_y, int height, int *table, int *index) +{ + int64_t delta; + int iy, ih; + fixed clip_sy, clip_ey; + int dirn = DIRN_UP; + int *row; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf6("Marking line from %x,%x to %x,%x (%x,%x)\n", sx, sy, ex, ey, fixed2int(sy + fixed_half-1) - base_y, fixed2int(ey + fixed_half-1) - base_y); +#endif +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 0 0 0 setrgbcolor %%PS\n"); + coord("moveto", sx, sy); + coord("lineto", ex, ey); + dlprintf("stroke %%PS\n"); +#endif + + if (fixed2int(sy + fixed_half-1) == fixed2int(ey + fixed_half-1)) + return; + if (sy > ey) { + int t; + t = sy; sy = ey; ey = t; + t = sx; sx = ex; ex = t; + dirn = DIRN_DOWN; + } + /* Lines go from sy to ey, closed at the start, open at the end. */ + /* We clip them to a region to make them closed at both ends. */ + /* Thus the first scanline marked (>= sy) is: */ + clip_sy = ((sy + fixed_half - 1) & ~(fixed_1-1)) | fixed_half; + /* The last scanline marked (< ey) is: */ + clip_ey = ((ey - fixed_half - 1) & ~(fixed_1-1)) | fixed_half; + /* Now allow for banding */ + if (clip_sy < int2fixed(base_y) + fixed_half) + clip_sy = int2fixed(base_y) + fixed_half; + if (ey <= clip_sy) + return; + if (clip_ey > int2fixed(base_y + height - 1) + fixed_half) + clip_ey = int2fixed(base_y + height - 1) + fixed_half; + if (sy > clip_ey) + return; + delta = (int64_t)clip_sy - (int64_t)sy; + if (delta > 0) + { + int64_t dx = (int64_t)ex - (int64_t)sx; + int64_t dy = (int64_t)ey - (int64_t)sy; + int advance = (int)((dx * delta + (dy>>1)) / dy); + sx += advance; + sy += delta; + } + delta = (int64_t)ey - (int64_t)clip_ey; + if (delta > 0) + { + int64_t dx = (int64_t)ex - (int64_t)sx; + int64_t dy = (int64_t)ey - (int64_t)sy; + int advance = (int)((dx * delta + (dy>>1)) / dy); + ex -= advance; + ey -= delta; + } + ex -= sx; + ey -= sy; + ih = fixed2int(ey); + assert(ih >= 0); + iy = fixed2int(sy) - base_y; +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf2(" iy=%x ih=%x\n", iy, ih); +#endif + assert(iy >= 0 && iy < height); + /* We always cross at least one scanline */ + row = &table[index[iy]]; + *row = (*row)+1; /* Increment the count */ + row[*row] = (sx&~1) | dirn; + if (ih == 0) + return; + if (ex >= 0) { + int x_inc, n_inc, f; + + /* We want to change sx by ex in ih steps. So each step, we add + * ex/ih to sx. That's x_inc + n_inc/ih. + */ + x_inc = ex/ih; + n_inc = ex-(x_inc*ih); + f = ih>>1; + delta = ih; + do { + int count; + iy++; + sx += x_inc; + f -= n_inc; + if (f < 0) { + f += ih; + sx++; + } + assert(iy >= 0 && iy < height); + row = &table[index[iy]]; + count = *row = (*row)+1; /* Increment the count */ + row[count] = (sx&~1) | dirn; + } while (--delta); + } else { + int x_dec, n_dec, f; + + ex = -ex; + /* We want to change sx by ex in ih steps. So each step, we subtract + * ex/ih from sx. That's x_dec + n_dec/ih. + */ + x_dec = ex/ih; + n_dec = ex-(x_dec*ih); + f = ih>>1; + delta = ih; + do { + int count; + iy++; + sx -= x_dec; + f -= n_dec; + if (f < 0) { + f += ih; + sx--; + } + assert(iy >= 0 && iy < height); + row = &table[index[iy]]; + count = *row = (*row)+1; /* Increment the count */ + row[count] = (sx&~1) | dirn; + } while (--delta); + } +} + +static void mark_curve(fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, fixed base_y, fixed height, int *table, int *index, int depth) +{ + fixed ax = (sx + c1x)>>1; + fixed ay = (sy + c1y)>>1; + fixed bx = (c1x + c2x)>>1; + fixed by = (c1y + c2y)>>1; + fixed cx = (c2x + ex)>>1; + fixed cy = (c2y + ey)>>1; + fixed dx = (ax + bx)>>1; + fixed dy = (ay + by)>>1; + fixed fx = (bx + cx)>>1; + fixed fy = (by + cy)>>1; + fixed gx = (dx + fx)>>1; + fixed gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) + mark_line(sx, sy, ex, ey, base_y, height, table, index); + else { + depth--; + mark_curve(sx, sy, ax, ay, dx, dy, gx, gy, base_y, height, table, index, depth); + mark_curve(gx, gy, fx, fy, cx, cy, ex, ey, base_y, height, table, index, depth); + } +} + +static void mark_curve_big(fixed64 sx, fixed64 sy, fixed64 c1x, fixed64 c1y, fixed64 c2x, fixed64 c2y, fixed64 ex, fixed64 ey, fixed base_y, fixed height, int *table, int *index, int depth) +{ + fixed64 ax = (sx + c1x)>>1; + fixed64 ay = (sy + c1y)>>1; + fixed64 bx = (c1x + c2x)>>1; + fixed64 by = (c1y + c2y)>>1; + fixed64 cx = (c2x + ex)>>1; + fixed64 cy = (c2y + ey)>>1; + fixed64 dx = (ax + bx)>>1; + fixed64 dy = (ay + by)>>1; + fixed64 fx = (bx + cx)>>1; + fixed64 fy = (by + cy)>>1; + fixed64 gx = (dx + fx)>>1; + fixed64 gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) + mark_line((fixed)sx, (fixed)sy, (fixed)ex, (fixed)ey, base_y, height, table, index); + else { + depth--; + mark_curve_big(sx, sy, ax, ay, dx, dy, gx, gy, base_y, height, table, index, depth); + mark_curve_big(gx, gy, fx, fy, cx, cy, ex, ey, base_y, height, table, index, depth); + } +} + +static void mark_curve_top(fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, fixed base_y, fixed height, int *table, int *index, int depth) +{ + fixed test = (sx^(sx<<1))|(sy^(sy<<1))|(c1x^(c1x<<1))|(c1y^(c1y<<1))|(c2x^(c2x<<1))|(c2y^(c2y<<1))|(ex^(ex<<1))|(ey^(ey<<1)); + + if (test < 0) + mark_curve_big(sx, sy, c1x, c1y, c2x, c2y, ex, ey, base_y, height, table, index, depth); + else + mark_curve(sx, sy, c1x, c1y, c2x, c2y, ex, ey, base_y, height, table, index, depth); +} + +static int make_bbox(gx_path * path, + const gs_fixed_rect * clip, + gs_fixed_rect * ibox, + fixed adjust) +{ + gs_fixed_rect bbox; + int code; + + /* Find the bbox - fixed */ + code = gx_path_bbox(path, &bbox); + if (code < 0) + return code; + + if (clip) { + if (bbox.p.y < clip->p.y) + bbox.p.y = clip->p.y; + if (bbox.q.y > clip->q.y) + bbox.q.y = clip->q.y; + } + + /* Convert to bbox - int */ + ibox->p.x = fixed2int(bbox.p.x-adjust); + ibox->p.y = fixed2int(bbox.p.y-adjust); + ibox->q.x = fixed2int(bbox.q.x-adjust+fixed_1); + ibox->q.y = fixed2int(bbox.q.y-adjust+fixed_1); + + return 0; +} + +static inline int +make_table_template(gx_device * pdev, + gx_path * path, + gs_fixed_rect * ibox, + int intersection_size, + int adjust, + int * scanlinesp, + int ** indexp, + int ** tablep) +{ + int scanlines; + const subpath * gs_restrict psub; + int * gs_restrict index; + int * gs_restrict table; + int i; + int64_t offset; + int delta; + fixed base_y; + + *scanlinesp = 0; + *indexp = NULL; + *tablep = NULL; + + if (pdev->max_fill_band != 0) + ibox->p.y &= ~(pdev->max_fill_band-1); + base_y = ibox->p.y; + + /* Previously we took adjust as a fixed distance to add to miny/maxy + * to allow for the expansion due to 'any part of a pixel'. This causes + * problems with over/underflow near INT_MAX/INT_MIN, so instead we + * take adjust as boolean telling us whether to expand y by 1 or not, and + * then adjust the assignments into the index as appropriate. This + * solves Bug 697970. */ + + /* Step 1: Make us a table */ + scanlines = ibox->q.y-base_y; + /* +1+adjust simplifies the loop below */ + index = (int *)gs_alloc_bytes(pdev->memory, + (scanlines+1+adjust) * sizeof(*index), + "scanc index buffer"); + if (index == NULL) + return_error(gs_error_VMerror); + + /* Step 1 continued: Blank the index */ + memset(index, 0, (scanlines+1)*sizeof(int)); + + /* Step 1 continued: Run through the path, filling in the index */ + for (psub = path->first_subpath; psub != 0;) { + const segment * gs_restrict pseg = (const segment *)psub; + fixed ey = pseg->pt.y; + fixed iy = ey; + int iey = fixed2int(iy) - base_y; + + assert(pseg->type == s_start); + + /* Allow for 2 extra intersections on the start scanline. + * This copes with the 'zero height rectangle' case. */ + if (iey >= 0 && iey < scanlines) + { + index[iey] += 2; + if (iey+1 < scanlines) + index[iey+1] -= 2; + } + + while ((pseg = pseg->next) != 0 && + pseg->type != s_start + ) { + fixed sy = ey; + ey = pseg->pt.y; + + switch (pseg->type) { + default: + case s_start: /* Should never happen */ + case s_dash: /* We should never be seeing a dash here */ + assert("This should never happen" == NULL); + break; + case s_curve: { + const curve_segment *const gs_restrict pcur = (const curve_segment *)pseg; + fixed c1y = pcur->p1.y; + fixed c2y = pcur->p2.y; + fixed maxy = sy, miny = sy; + int imaxy, iminy; + if (miny > c1y) + miny = c1y; + if (miny > c2y) + miny = c2y; + if (miny > ey) + miny = ey; + if (maxy < c1y) + maxy = c1y; + if (maxy < c2y) + maxy = c2y; + if (maxy < ey) + maxy = ey; +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf2("Curve (%x->%x) ", miny, maxy); +#endif + iminy = fixed2int(miny) - base_y; + if (iminy <= 0) + iminy = 0; + else + iminy -= adjust; + if (iminy < scanlines) { + imaxy = fixed2int(maxy) - base_y; + if (imaxy >= 0) { +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf1("+%x ", iminy); +#endif + index[iminy]+=3; + if (imaxy < scanlines) { +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf1("-%x ", imaxy+1); +#endif + index[imaxy+1+adjust]-=3; + } + } + } +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf("\n"); +#endif + break; + } + case s_gap: + case s_line: + case s_line_close: { + fixed miny, maxy; + int imaxy, iminy; + if (sy == ey) { +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf("Line (Horiz)\n"); +#endif + break; + } + if (sy < ey) + miny = sy, maxy = ey; + else + miny = ey, maxy = sy; +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf2("Line (%x->%x) ", miny, maxy); +#endif + iminy = fixed2int(miny) - base_y; + if (iminy <= 0) + iminy = 0; + else + iminy -= adjust; + if (iminy < scanlines) { + imaxy = fixed2int(maxy) - base_y; + if (imaxy >= 0) { +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf1("+%x ", iminy); +#endif + index[iminy]++; + if (imaxy < scanlines) { +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf1("-%x ", imaxy+1); +#endif + index[imaxy+1+adjust]--; + } + } + } +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf("\n"); +#endif + break; + } + } + } + + /* And close any segments that need it */ + if (ey != iy) { + fixed miny, maxy; + int imaxy, iminy; + if (iy < ey) + miny = iy, maxy = ey; + else + miny = ey, maxy = iy; +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf2("Close (%x->%x) ", miny, maxy); +#endif + iminy = fixed2int(miny) - base_y; + if (iminy <= 0) + iminy = 0; + else + iminy -= adjust; + if (iminy < scanlines) { + imaxy = fixed2int(maxy) - base_y; + if (imaxy >= 0) { +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf1("+%x ", iminy); +#endif + index[iminy]++; + if (imaxy < scanlines) { +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf1("-%x ", imaxy+1); +#endif + index[imaxy+1+adjust]--; + } + } + } +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf("\n"); +#endif + } +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf("\n"); +#endif + psub = (const subpath *)pseg; + } + + /* Step 1 continued: index now contains a list of deltas (how the + * number of intersects on line x differs from the number on line x-1). + * First convert them to be the real number of intersects on that line. + * Sum these values to get us the total nunber of intersects. Then + * convert the table to be a list of offsets into the real intersect + * buffer. */ + offset = 0; + delta = 0; + for (i=0; i < scanlines+adjust; i++) { + delta += intersection_size*index[i]; /* delta = Num ints on this scanline. */ + index[i] = offset; /* Offset into table for this lines data. */ + offset += delta+1; /* Adjust offset for next line. */ + } + offset *= sizeof(*table); + if (offset != (int64_t)(uint)offset) + { + gs_free_object(pdev->memory, index, "scanc index buffer"); + return_error(gs_error_VMerror); + } + + /* End of step 1: index[i] = offset into table 2 for scanline i's + * intersection data. offset = Total number of int entries required for + * table. */ + + /* Step 2: Collect the real intersections */ + table = (int *)gs_alloc_bytes(pdev->memory, offset, + "scanc intersects buffer"); + if (table == NULL) { + gs_free_object(pdev->memory, index, "scanc index buffer"); + return_error(gs_error_VMerror); + } + + /* Step 2 continued: initialise table's data; each scanlines data starts + * with a count of the number of intersects so far, followed by a record + * of the intersect points on this scanline. */ + for (i=0; i < scanlines; i++) { + table[index[i]] = 0; + } + + *scanlinesp = scanlines; + *tablep = table; + *indexp = index; + + return 0; +} + +static int make_table(gx_device * pdev, + gx_path * path, + gs_fixed_rect * ibox, + int * scanlines, + int ** index, + int ** table) +{ + return make_table_template(pdev, path, ibox, 1, 1, scanlines, index, table); +} + +int gx_scan_convert(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict clip, + gx_edgebuffer * gs_restrict edgebuffer, + fixed fixed_flat) +{ + gs_fixed_rect ibox; + int scanlines; + const subpath *psub; + int *index; + int *table; + int i; + int code; + + edgebuffer->index = NULL; + edgebuffer->table = NULL; + + /* Bale out if no actual path. We see this with the clist */ + if (path->first_subpath == NULL) + return 0; + + code = make_bbox(path, clip, &ibox, fixed_half); + if (code < 0) + return code; + + if (ibox.q.y <= ibox.p.y) + return 0; + + code = make_table(pdev, path, &ibox, &scanlines, &index, &table); + if (code < 0) + return code; + + /* Step 2 continued: Now we run through the path, filling in the real + * values. */ + for (psub = path->first_subpath; psub != 0;) { + const segment *pseg = (const segment *)psub; + fixed ex = pseg->pt.x; + fixed ey = pseg->pt.y; + fixed ix = ex; + fixed iy = ey; + + while ((pseg = pseg->next) != 0 && + pseg->type != s_start + ) { + fixed sx = ex; + fixed sy = ey; + ex = pseg->pt.x; + ey = pseg->pt.y; + + switch (pseg->type) { + default: + case s_start: /* Should never happen */ + case s_dash: /* We should never be seeing a dash here */ + assert("This should never happen" == NULL); + break; + case s_curve: { + const curve_segment *const pcur = (const curve_segment *)pseg; + int k = gx_curve_log2_samples(sx, sy, pcur, fixed_flat); + + mark_curve_top(sx, sy, pcur->p1.x, pcur->p1.y, pcur->p2.x, pcur->p2.y, ex, ey, ibox.p.y, scanlines, table, index, k); + break; + } + case s_gap: + case s_line: + case s_line_close: + if (sy != ey) + mark_line(sx, sy, ex, ey, ibox.p.y, scanlines, table, index); + break; + } + } + /* And close any open segments */ + if (iy != ey) + mark_line(ex, ey, ix, iy, ibox.p.y, scanlines, table, index); + psub = (const subpath *)pseg; + } + + /* Step 2 complete: We now have a complete list of intersection data in + * table, indexed by index. */ + + edgebuffer->base = ibox.p.y; + edgebuffer->height = scanlines; + edgebuffer->xmin = ibox.p.x; + edgebuffer->xmax = ibox.q.x; + edgebuffer->index = index; + edgebuffer->table = table; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before sorting:\n"); + gx_edgebuffer_print(edgebuffer); + } +#endif + + /* Step 3: Sort the intersects on x */ + for (i=0; i < scanlines; i++) { + int *row = &table[index[i]]; + int rowlen = *row++; + + /* Bubblesort short runs, qsort longer ones. */ + /* FIXME: Check "6" below */ + if (rowlen <= 6) { + int j, k; + for (j = 0; j < rowlen-1; j++) { + int t = row[j]; + for (k = j+1; k < rowlen; k++) { + int s = row[k]; + if (t > s) + row[k] = t, t = row[j] = s; + } + } + } else + qsort(row, rowlen, sizeof(int), intcmp); + } + + return 0; +} + +/* Step 5: Filter the intersections according to the rules */ +int +gx_filter_edgebuffer(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule) +{ + int i; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before filtering:\n"); + gx_edgebuffer_print(edgebuffer); + } +#endif + + for (i=0; i < edgebuffer->height; i++) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int *rowstart = row; + int rowlen = *row++; + int *rowout = row; + + while (rowlen > 0) + { + int left, right; + + if (rule == gx_rule_even_odd) { + /* Even Odd */ + left = (*row++)&~1; + right = (*row++)&~1; + rowlen -= 2; + } else { + /* Non-Zero */ + int w; + + left = *row++; + w = ((left&1)-1) | (left&1); + rowlen--; + do { + right = *row++; + rowlen--; + w += ((right&1)-1) | (right&1); + } while (w != 0); + left &= ~1; + right &= ~1; + } + + if (right > left) { + *rowout++ = left; + *rowout++ = right; + } + } + *rowstart = (rowout-rowstart)-1; + } + return 0; +} + +/* Step 6: Fill the edgebuffer */ +int +gx_fill_edgebuffer(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op) +{ + int i, code; + + for (i=0; i < edgebuffer->height; i++) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int rowlen = *row++; + + while (rowlen > 0) { + int left, right; + + left = *row++; + right = *row++; + rowlen -= 2; + left = fixed2int(left + fixed_half); + right = fixed2int(right + fixed_half); + right -= left; + if (right > 0) { +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 1 0.5 0 setrgbcolor %% orange %%PS\n"); + coord("moveto", int2fixed(left), int2fixed(edgebuffer->base+i)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+i)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+i+1)); + coord("lineto", int2fixed(left), int2fixed(edgebuffer->base+i+1)); + dlprintf("closepath stroke %%PS\n"); +#endif + if (log_op < 0) + code = dev_proc(pdev, fill_rectangle)(pdev, left, edgebuffer->base+i, right, 1, pdevc->colors.pure); + else + code = gx_fill_rectangle_device_rop(left, edgebuffer->base+i, right, 1, pdevc, pdev, (gs_logical_operation_t)log_op); + if (code < 0) + return code; + } + } + } + return 0; +} + +/* Any part of a pixel routines */ + +static int edgecmp(const void *a, const void *b) +{ + int left = ((int*)a)[0]; + int right = ((int*)b)[0]; + left -= right; + if (left) + return left; + return ((int*)a)[1] - ((int*)b)[1]; +} + +#ifdef DEBUG_SCAN_CONVERTER +static void +gx_edgebuffer_print_app(gx_edgebuffer * edgebuffer) +{ + int i; + int borked = 0; + + if (!debugging_scan_converter) + return; + + dlprintf1("Edgebuffer %x\n", edgebuffer); + dlprintf4("xmin=%x xmax=%x base=%x height=%x\n", + edgebuffer->xmin, edgebuffer->xmax, edgebuffer->base, edgebuffer->height); + for (i=0; i < edgebuffer->height; i++) { + int offset = edgebuffer->index[i]; + int *row = &edgebuffer->table[offset]; + int count = *row++; + int c = count; + int wind = 0; + dlprintf3("%x @ %d: %d =", i, offset, count); + while (count-- > 0) { + int left = *row++; + int right = *row++; + int w = -(left&1) | 1; + wind += w; + dlprintf3(" (%x,%x)%c", left&~1, right, left&1 ? 'v' : '^'); + } + if (wind != 0 || c & 1) { + dlprintf(" <- BROKEN"); + borked = 1; + } + dlprintf("\n"); + } + if (borked) { + borked = borked; /* Breakpoint here */ + } +} +#endif + +typedef struct +{ + fixed left; + fixed right; + fixed y; + signed char d; /* 0 up (or horiz), 1 down, -1 uninited */ + unsigned char first; + unsigned char saved; + + fixed save_left; + fixed save_right; + int save_iy; + int save_d; + + int scanlines; + int *table; + int *index; + int base; +} cursor; + +static inline void +cursor_output(cursor * gs_restrict cr, int iy) +{ + int *row; + int count; + + if (iy >= 0 && iy < cr->scanlines) { + if (cr->first) { + /* Save it for later in case we join up */ + cr->save_left = cr->left; + cr->save_right = cr->right; + cr->save_iy = iy; + cr->save_d = cr->d; + cr->saved = 1; + } else { + /* Enter it into the table */ + assert(cr->d != DIRN_UNSET); + + row = &cr->table[cr->index[iy]]; + *row = count = (*row)+1; /* Increment the count */ + row[2 * count - 1] = (cr->left&~1) | cr->d; + row[2 * count ] = cr->right; + } + } + cr->first = 0; +} + +static inline void +cursor_output_inrange(cursor * gs_restrict cr, int iy) +{ + int *row; + int count; + + assert(iy >= 0 && iy < cr->scanlines); + if (cr->first) { + /* Save it for later in case we join up */ + cr->save_left = cr->left; + cr->save_right = cr->right; + cr->save_iy = iy; + cr->save_d = cr->d; + cr->saved = 1; + } else { + /* Enter it into the table */ + assert(cr->d != DIRN_UNSET); + + row = &cr->table[cr->index[iy]]; + *row = count = (*row)+1; /* Increment the count */ + row[2 * count - 1] = (cr->left&~1) | cr->d; + row[2 * count ] = cr->right; + } + cr->first = 0; +} + +/* Step the cursor in y, allowing for maybe crossing a scanline */ +static inline void +cursor_step(cursor * gs_restrict cr, fixed dy, fixed x) +{ + int new_iy; + int iy = fixed2int(cr->y) - cr->base; + + cr->y += dy; + new_iy = fixed2int(cr->y) - cr->base; + if (new_iy != iy) { + cursor_output(cr, iy); + cr->left = x; + cr->right = x; + } else { + if (x < cr->left) + cr->left = x; + if (x > cr->right) + cr->right = x; + } +} + +/* Step the cursor in y, never by enough to cross a scanline. */ +static inline void +cursor_never_step_vertical(cursor * gs_restrict cr, fixed dy, fixed x) +{ + assert(fixed2int(cr->y+dy) == fixed2int(cr->y)); + + cr->y += dy; +} + +/* Step the cursor in y, never by enough to cross a scanline, + * knowing that we are moving left, and that the right edge + * has already been accounted for. */ +static inline void +cursor_never_step_left(cursor * gs_restrict cr, fixed dy, fixed x) +{ + assert(fixed2int(cr->y+dy) == fixed2int(cr->y)); + + if (x < cr->left) + cr->left = x; + cr->y += dy; +} + +/* Step the cursor in y, never by enough to cross a scanline, + * knowing that we are moving right, and that the left edge + * has already been accounted for. */ +static inline void +cursor_never_step_right(cursor * gs_restrict cr, fixed dy, fixed x) +{ + assert(fixed2int(cr->y+dy) == fixed2int(cr->y)); + + if (x > cr->right) + cr->right = x; + cr->y += dy; +} + +/* Step the cursor in y, always by enough to cross a scanline. */ +static inline void +cursor_always_step(cursor * gs_restrict cr, fixed dy, fixed x) +{ + int iy = fixed2int(cr->y) - cr->base; + + cursor_output(cr, iy); + cr->y += dy; + cr->left = x; + cr->right = x; +} + +/* Step the cursor in y, always by enough to cross a scanline, as + * part of a vertical line, knowing that we are moving from a + * position guaranteed to be in the valid y range. */ +static inline void +cursor_always_step_inrange_vertical(cursor * gs_restrict cr, fixed dy, fixed x) +{ + int iy = fixed2int(cr->y) - cr->base; + + cursor_output(cr, iy); + cr->y += dy; +} + +/* Step the cursor in y, always by enough to cross a scanline, as + * part of a left moving line, knowing that we are moving from a + * position guaranteed to be in the valid y range. */ +static inline void +cursor_always_inrange_step_left(cursor * gs_restrict cr, fixed dy, fixed x) +{ + int iy = fixed2int(cr->y) - cr->base; + + cr->y += dy; + cursor_output_inrange(cr, iy); + cr->right = x; +} + +/* Step the cursor in y, always by enough to cross a scanline, as + * part of a right moving line, knowing that we are moving from a + * position guaranteed to be in the valid y range. */ +static inline void +cursor_always_inrange_step_right(cursor * gs_restrict cr, fixed dy, fixed x) +{ + int iy = fixed2int(cr->y) - cr->base; + + cr->y += dy; + cursor_output_inrange(cr, iy); + cr->left = x; +} + +static inline void cursor_init(cursor * gs_restrict cr, fixed y, fixed x) +{ + assert(y >= int2fixed(cr->base) && y <= int2fixed(cr->base + cr->scanlines)); + + cr->y = y; + cr->left = x; + cr->right = x; + cr->d = DIRN_UNSET; +} + +static inline void cursor_left_merge(cursor * gs_restrict cr, fixed x) +{ + if (x < cr->left) + cr->left = x; +} + +static inline void cursor_left(cursor * gs_restrict cr, fixed x) +{ + cr->left = x; +} + +static inline void cursor_right_merge(cursor * gs_restrict cr, fixed x) +{ + if (x > cr->right) + cr->right = x; +} + +static inline void cursor_right(cursor * gs_restrict cr, fixed x) +{ + cr->right = x; +} + +static inline void cursor_down(cursor * gs_restrict cr, fixed x) +{ + if (cr->d == DIRN_UP) + { + cursor_output(cr, fixed2int(cr->y) - cr->base); + cr->left = x; + cr->right = x; + } + cr->d = DIRN_DOWN; +} + +static inline void cursor_up(cursor * gs_restrict cr, fixed x) +{ + if (cr->d == DIRN_DOWN) + { + cursor_output(cr, fixed2int(cr->y) - cr->base); + cr->left = x; + cr->right = x; + } + cr->d = DIRN_UP; +} + +static inline void +cursor_flush(cursor * gs_restrict cr, fixed x) +{ + int iy; + + /* This should only happen if we were entirely out of bounds, + * or if everything was within a zero height horizontal + * rectangle from the start point. */ + if (cr->first) { + int iy = fixed2int(cr->y) - cr->base; + if (iy >= 0 && iy < cr->scanlines) { + int *row = &cr->table[cr->index[iy]]; + int count = *row = (*row)+2; /* Increment the count */ + row[2 * count - 3] = (cr->left & ~1) | DIRN_UP; + row[2 * count - 2] = (cr->right & ~1); + row[2 * count - 1] = (cr->right & ~1) | DIRN_DOWN; + row[2 * count ] = cr->right; + } + return; + } + + /* Merge save into current if we can */ + iy = fixed2int(cr->y) - cr->base; + if (cr->saved && iy == cr->save_iy && + (cr->d == cr->save_d || cr->save_d == DIRN_UNSET)) { + if (cr->left > cr->save_left) + cr->left = cr->save_left; + if (cr->right < cr->save_right) + cr->right = cr->save_right; + cursor_output(cr, iy); + return; + } + + /* Merge not possible */ + cursor_output(cr, iy); + if (cr->saved) { + cr->left = cr->save_left; + cr->right = cr->save_right; + assert(cr->save_d != DIRN_UNSET); + if (cr->save_d != DIRN_UNSET) + cr->d = cr->save_d; + cursor_output(cr, cr->save_iy); + } +} + +static void mark_line_app(cursor * gs_restrict cr, fixed sx, fixed sy, fixed ex, fixed ey) +{ + int isy, iey; + fixed saved_sy = sy; + fixed saved_ex = ex; + fixed saved_ey = ey; + int truncated; + + if (sx == ex && sy == ey) + return; + + isy = fixed2int(sy) - cr->base; + iey = fixed2int(ey) - cr->base; +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf6("Marking line (app) from %x,%x to %x,%x (%x,%x)\n", sx, sy, ex, ey, isy, iey); +#endif +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 0 0 0 setrgbcolor %%PS\n"); + coord("moveto", sx, sy); + coord("lineto", ex, ey); + dlprintf("stroke %%PS\n"); +#endif + + assert(cr->y == sy && cr->left <= sx && cr->right >= sx && cr->d >= DIRN_UNSET && cr->d <= DIRN_DOWN); + + if (isy < iey) { + /* Rising line */ + if (iey < 0 || isy >= cr->scanlines) { + /* All line is outside. */ + cr->y = ey; + cr->left = ex; + cr->right = ex; + cr->first = 0; + return; + } + if (isy < 0) { + /* Move sy up */ + int64_t y = (int64_t)ey - (int64_t)sy; + fixed new_sy = int2fixed(cr->base); + int64_t dy = (int64_t)new_sy - (int64_t)sy; + sx += (int)((((int64_t)(ex-sx))*dy + y/2)/y); + sy = new_sy; + cursor_init(cr, sy, sx); + isy = 0; + } + truncated = iey > cr->scanlines; + if (truncated) { + /* Move ey down */ + int64_t y = ey - sy; + fixed new_ey = int2fixed(cr->base + cr->scanlines); + int64_t dy = (int64_t)ey - (int64_t)new_ey; + saved_ex = ex; + saved_ey = ey; + ex -= (int)((((int64_t)(ex-sx))*dy + y/2)/y); + ey = new_ey; + iey = cr->scanlines; + } + } else { + /* Falling line */ + if (isy < 0 || iey >= cr->scanlines) { + /* All line is outside. */ + cr->y = ey; + cr->left = ex; + cr->right = ex; + cr->first = 0; + return; + } + truncated = iey < 0; + if (truncated) { + /* Move ey up */ + int64_t y = (int64_t)ey - (int64_t)sy; + fixed new_ey = int2fixed(cr->base); + int64_t dy = (int64_t)ey - (int64_t)new_ey; + ex -= (int)((((int64_t)(ex-sx))*dy + y/2)/y); + ey = new_ey; + iey = 0; + } + if (isy >= cr->scanlines) { + /* Move sy down */ + int64_t y = (int64_t)ey - (int64_t)sy; + fixed new_sy = int2fixed(cr->base + cr->scanlines); + int64_t dy = (int64_t)new_sy - (int64_t)sy; + sx += (int)((((int64_t)(ex-sx))*dy + y/2)/y); + sy = new_sy; + cursor_init(cr, sy, sx); + isy = cr->scanlines; + } + } + + assert(cr->left <= sx); + assert(cr->right >= sx); + assert(cr->y == sy); + + /* A note: The code below used to be of the form: + * if (isy == iey) ... deal with horizontal lines + * else if (ey > sy) { + * fixed y_steps = ey - sy; + * ... deal with rising lines ... + * } else { + * fixed y_steps = ey - sy; + * ... deal with falling lines + * } + * but that lead to problems, for instance, an example seen + * has sx=2aa8e, sy=8aee7, ex=7ffc1686, ey=8003e97a. + * Thus isy=84f, iey=ff80038a. We can see that ey < sy, but + * sy - ey < 0! + * We therefore rejig our code so that the choice between + * cases is done based on the sign of y_steps rather than + * the relative size of ey and sy. + */ + + /* First, deal with lines that don't change scanline. + * This accommodates horizontal lines. */ + if (isy == iey) { + if (saved_sy == saved_ey) { + /* Horizontal line. Don't change cr->d, don't flush. */ + } else if (saved_sy > saved_ey) { + /* Falling line, flush if previous was rising */ + cursor_down(cr, sx); + } else { + /* Rising line, flush if previous was falling */ + cursor_up(cr, sx); + } + if (sx <= ex) { + cursor_left_merge(cr, sx); + cursor_right_merge(cr, ex); + } else { + cursor_left_merge(cr, ex); + cursor_right_merge(cr, sx); + } + cr->y = ey; + if (sy > saved_ey) + goto endFalling; + } else if (iey > isy) { + /* We want to change from sy to ey, which are guaranteed to be on + * different scanlines. We do this in 3 phases. + * Phase 1 gets us from sy to the next scanline boundary. + * Phase 2 gets us all the way to the last scanline boundary. + * Phase 3 gets us from the last scanline boundary to ey. + */ + /* We want to change from sy to ey, which are guaranteed to be on + * different scanlines. We do this in 3 phases. + * Phase 1 gets us from sy to the next scanline boundary. (We may exit after phase 1). + * Phase 2 gets us all the way to the last scanline boundary. (This may be a null operation) + * Phase 3 gets us from the last scanline boundary to ey. (We are guaranteed to have output the cursor at least once before phase 3). + */ + int phase1_y_steps = (-sy) & (fixed_1 - 1); + int phase3_y_steps = ey & (fixed_1 - 1); + ufixed y_steps = (ufixed)ey - (ufixed)sy; + + cursor_up(cr, sx); + + if (sx == ex) { + /* Vertical line. (Rising) */ + + /* Phase 1: */ + cursor_left_merge(cr, sx); + cursor_right_merge(cr, sx); + if (phase1_y_steps) { + /* If phase 1 will move us into a new scanline, then we must + * flush it before we move. */ + cursor_step(cr, phase1_y_steps, sx); + sy += phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto end; + } + + /* Phase 3: precalculation */ + y_steps -= phase3_y_steps; + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps > 0) { + cursor_always_step(cr, fixed_1, sx); + y_steps--; + while (y_steps) { + cursor_always_step_inrange_vertical(cr, fixed_1, sx); + y_steps--; + } + } + + /* Phase 3 */ + assert(cr->left == sx && cr->right == sx); + cr->y += phase3_y_steps; + } else if (sx < ex) { + /* Lines increasing in x. (Rightwards, rising) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = ex - sx; + + /* Phase 1: */ + cursor_left_merge(cr, sx); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + sx += phase1_x_steps; + cursor_right_merge(cr, sx); + x_steps -= phase1_x_steps; + cursor_step(cr, phase1_y_steps, sx); + sy += phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto end; + } + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we add x_steps/y_steps to sx. That's x_inc + n_inc/y_steps. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + /* Special casing the first iteration, allows us to simplify + * the following loop. */ + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right_merge(cr, sx); + cursor_always_step(cr, fixed_1, sx); + y_steps--; + + while (y_steps) { + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right(cr, sx); + cursor_always_inrange_step_right(cr, fixed_1, sx); + y_steps--; + }; + } + + /* Phase 3 */ + assert(cr->left <= ex && cr->right >= sx); + cursor_right(cr, ex); + cr->y += phase3_y_steps; + } else { + /* Lines decreasing in x. (Leftwards, rising) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = sx - ex; + + /* Phase 1: */ + cursor_right_merge(cr, sx); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + x_steps -= phase1_x_steps; + sx -= phase1_x_steps; + cursor_left_merge(cr, sx); + cursor_step(cr, phase1_y_steps, sx); + sy += phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto end; + } + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we sub x_steps/y_steps from sx. That's x_inc + n_inc/ey. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + /* Special casing the first iteration, allows us to simplify + * the following loop. */ + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left_merge(cr, sx); + cursor_always_step(cr, fixed_1, sx); + y_steps--; + + while (y_steps) { + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left(cr, sx); + cursor_always_inrange_step_left(cr, fixed_1, sx); + y_steps--; + } + } + + /* Phase 3 */ + assert(cr->right >= ex && cr->left <= sx); + cursor_left(cr, ex); + cr->y += phase3_y_steps; + } + } else { + /* So lines decreasing in y. */ + /* We want to change from sy to ey, which are guaranteed to be on + * different scanlines. We do this in 3 phases. + * Phase 1 gets us from sy to the next scanline boundary. This never causes an output. + * Phase 2 gets us all the way to the last scanline boundary. This is guaranteed to cause an output. + * Phase 3 gets us from the last scanline boundary to ey. We are guaranteed to have outputted by now. + */ + int phase1_y_steps = sy & (fixed_1 - 1); + int phase3_y_steps = (-ey) & (fixed_1 - 1); + ufixed y_steps = (ufixed)sy - (ufixed)ey; + + cursor_down(cr, sx); + + if (sx == ex) { + /* Vertical line. (Falling) */ + + /* Phase 1: */ + cursor_left_merge(cr, sx); + cursor_right_merge(cr, sx); + if (phase1_y_steps) { + /* Phase 1 in a falling line never moves us into a new scanline. */ + cursor_never_step_vertical(cr, -phase1_y_steps, sx); + sy -= phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto endFalling; + } + + /* Phase 3: precalculation */ + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + cursor_always_step(cr, -fixed_1, sx); + y_steps--; + while (y_steps) { + cursor_always_step_inrange_vertical(cr, -fixed_1, sx); + y_steps--; + } + } + + /* Phase 3 */ + if (phase3_y_steps > 0) { + cursor_step(cr, -phase3_y_steps, sx); + assert(cr->left == sx && cr->right == sx); + } + } else if (sx < ex) { + /* Lines increasing in x. (Rightwards, falling) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = ex - sx; + + /* Phase 1: */ + cursor_left_merge(cr, sx); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + x_steps -= phase1_x_steps; + sx += phase1_x_steps; + /* Phase 1 in a falling line never moves us into a new scanline. */ + cursor_never_step_right(cr, -phase1_y_steps, sx); + sy -= phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto endFalling; + } else + cursor_right_merge(cr, sx); + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we add x_steps/y_steps to sx. That's x_inc + n_inc/ey. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + cursor_always_step(cr, -fixed_1, sx); + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right(cr, sx); + y_steps--; + + while (y_steps) { + cursor_always_inrange_step_right(cr, -fixed_1, sx); + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right(cr, sx); + y_steps--; + } + } + + /* Phase 3 */ + if (phase3_y_steps > 0) { + cursor_step(cr, -phase3_y_steps, sx); + cursor_right(cr, ex); + assert(cr->left == sx && cr->right == ex); + } + } else { + /* Lines decreasing in x. (Falling) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = sx - ex; + + /* Phase 1: */ + cursor_right_merge(cr, sx); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + x_steps -= phase1_x_steps; + sx -= phase1_x_steps; + /* Phase 1 in a falling line never moves us into a new scanline. */ + cursor_never_step_left(cr, -phase1_y_steps, sx); + sy -= phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto endFalling; + } else + cursor_left_merge(cr, sx); + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we sub x_steps/y_steps from sx. That's x_inc + n_inc/ey. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + cursor_always_step(cr, -fixed_1, sx); + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left(cr, sx); + y_steps--; + + while (y_steps) { + cursor_always_inrange_step_left(cr, -fixed_1, sx); + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left(cr, sx); + y_steps--; + } + } + + /* Phase 3 */ + if (phase3_y_steps > 0) { + cursor_step(cr, -phase3_y_steps, sx); + cursor_left(cr, ex); + assert(cr->left == ex && cr->right == sx); + } + } +endFalling: + if (truncated) + cursor_output(cr, fixed2int(cr->y) - cr->base); + } + +end: + if (truncated) { + cr->left = saved_ex; + cr->right = saved_ex; + cr->y = saved_ey; + } +} + +static void mark_curve_app(cursor *cr, fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, int depth) +{ + int ax = (sx + c1x)>>1; + int ay = (sy + c1y)>>1; + int bx = (c1x + c2x)>>1; + int by = (c1y + c2y)>>1; + int cx = (c2x + ex)>>1; + int cy = (c2y + ey)>>1; + int dx = (ax + bx)>>1; + int dy = (ay + by)>>1; + int fx = (bx + cx)>>1; + int fy = (by + cy)>>1; + int gx = (dx + fx)>>1; + int gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) + mark_line_app(cr, sx, sy, ex, ey); + else { + depth--; + mark_curve_app(cr, sx, sy, ax, ay, dx, dy, gx, gy, depth); + mark_curve_app(cr, gx, gy, fx, fy, cx, cy, ex, ey, depth); + } +} + +static void mark_curve_big_app(cursor *cr, fixed64 sx, fixed64 sy, fixed64 c1x, fixed64 c1y, fixed64 c2x, fixed64 c2y, fixed64 ex, fixed64 ey, int depth) +{ + fixed64 ax = (sx + c1x)>>1; + fixed64 ay = (sy + c1y)>>1; + fixed64 bx = (c1x + c2x)>>1; + fixed64 by = (c1y + c2y)>>1; + fixed64 cx = (c2x + ex)>>1; + fixed64 cy = (c2y + ey)>>1; + fixed64 dx = (ax + bx)>>1; + fixed64 dy = (ay + by)>>1; + fixed64 fx = (bx + cx)>>1; + fixed64 fy = (by + cy)>>1; + fixed64 gx = (dx + fx)>>1; + fixed64 gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) + mark_line_app(cr, (fixed)sx, (fixed)sy, (fixed)ex, (fixed)ey); + else { + depth--; + mark_curve_big_app(cr, sx, sy, ax, ay, dx, dy, gx, gy, depth); + mark_curve_big_app(cr, gx, gy, fx, fy, cx, cy, ex, ey, depth); + } +} + +static void mark_curve_top_app(cursor *cr, fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, int depth) +{ + fixed test = (sx^(sx<<1))|(sy^(sy<<1))|(c1x^(c1x<<1))|(c1y^(c1y<<1))|(c2x^(c2x<<1))|(c2y^(c2y<<1))|(ex^(ex<<1))|(ey^(ey<<1)); + + if (test < 0) + mark_curve_big_app(cr, sx, sy, c1x, c1y, c2x, c2y, ex, ey, depth); + else + mark_curve_app(cr, sx, sy, c1x, c1y, c2x, c2y, ex, ey, depth); +} + +static int make_table_app(gx_device * pdev, + gx_path * path, + gs_fixed_rect * ibox, + int * scanlines, + int ** index, + int ** table) +{ + return make_table_template(pdev, path, ibox, 2, 0, scanlines, index, table); +} + +int gx_scan_convert_app(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict clip, + gx_edgebuffer * gs_restrict edgebuffer, + fixed fixed_flat) +{ + gs_fixed_rect ibox; + int scanlines; + const subpath *psub; + int *index; + int *table; + int i; + cursor cr; + int code; + + edgebuffer->index = NULL; + edgebuffer->table = NULL; + + /* Bale out if no actual path. We see this with the clist */ + if (path->first_subpath == NULL) + return 0; + + code = make_bbox(path, clip, &ibox, 0); + if (code < 0) + return code; + + if (ibox.q.y <= ibox.p.y) + return 0; + + code = make_table_app(pdev, path, &ibox, &scanlines, &index, &table); + if (code < 0) + return code; + + /* Step 2 continued: Now we run through the path, filling in the real + * values. */ + cr.scanlines = scanlines; + cr.index = index; + cr.table = table; + cr.base = ibox.p.y; + for (psub = path->first_subpath; psub != 0;) { + const segment *pseg = (const segment *)psub; + fixed ex = pseg->pt.x; + fixed ey = pseg->pt.y; + fixed ix = ex; + fixed iy = ey; + fixed sx, sy; + + cr.left = cr.right = ex; + cr.y = ey; + cr.d = DIRN_UNSET; + cr.first = 1; + cr.saved = 0; + + while ((pseg = pseg->next) != 0 && + pseg->type != s_start + ) { + sx = ex; + sy = ey; + ex = pseg->pt.x; + ey = pseg->pt.y; + + switch (pseg->type) { + default: + case s_start: /* Should never happen */ + case s_dash: /* We should never be seeing a dash here */ + assert("This should never happen" == NULL); + break; + case s_curve: { + const curve_segment *const pcur = (const curve_segment *)pseg; + int k = gx_curve_log2_samples(sx, sy, pcur, fixed_flat); + + mark_curve_top_app(&cr, sx, sy, pcur->p1.x, pcur->p1.y, pcur->p2.x, pcur->p2.y, ex, ey, k); + break; + } + case s_gap: + case s_line: + case s_line_close: + mark_line_app(&cr, sx, sy, ex, ey); + break; + } + } + /* And close any open segments */ + mark_line_app(&cr, ex, ey, ix, iy); + cursor_flush(&cr, ex); + psub = (const subpath *)pseg; + } + + /* Step 2 complete: We now have a complete list of intersection data in + * table, indexed by index. */ + + edgebuffer->base = ibox.p.y; + edgebuffer->height = scanlines; + edgebuffer->xmin = ibox.p.x; + edgebuffer->xmax = ibox.q.x; + edgebuffer->index = index; + edgebuffer->table = table; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before sorting:\n"); + gx_edgebuffer_print_app(edgebuffer); + } +#endif + + /* Step 3: Sort the intersects on x */ + for (i=0; i < scanlines; i++) { + int *row = &table[index[i]]; + int rowlen = *row++; + + /* Bubblesort short runs, qsort longer ones. */ + /* FIXME: Verify the figure 6 below */ + if (rowlen <= 6) { + int j, k; + for (j = 0; j < rowlen-1; j++) { + int * gs_restrict t = &row[j<<1]; + for (k = j+1; k < rowlen; k++) { + int * gs_restrict s = &row[k<<1]; + int tmp; + if (t[0] < s[0]) + continue; + if (t[0] > s[0]) + goto swap01; + if (t[1] <= s[1]) + continue; + if (0) { +swap01: + tmp = t[0], t[0] = s[0], s[0] = tmp; + } + tmp = t[1], t[1] = s[1], s[1] = tmp; + } + } + } else + qsort(row, rowlen, 2*sizeof(int), edgecmp); + } + + return 0; +} + +/* Step 5: Filter the intersections according to the rules */ +int +gx_filter_edgebuffer_app(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule) +{ + int i; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before filtering:\n"); + gx_edgebuffer_print_app(edgebuffer); + } +#endif + + for (i=0; i < edgebuffer->height; i++) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int rowlen = *row++; + int *rowstart = row; + int *rowout = row; + int ll, lr, rl, rr, wind, marked_to; + + /* Avoid double setting pixels, by keeping where we have marked to. */ + marked_to = INT_MIN; + while (rowlen > 0) { + if (rule == gx_rule_even_odd) { + /* Even Odd */ + ll = (*row++)&~1; + lr = *row; + row += 2; + rowlen-=2; + + /* We will fill solidly from ll to at least lr, possibly further */ + assert(rowlen >= 0); + rr = (*row++); + if (rr > lr) + lr = rr; + } else { + /* Non-Zero */ + int w; + + ll = *row++; + lr = *row++; + wind = -(ll&1) | 1; + ll &= ~1; + rowlen--; + + assert(rowlen > 0); + do { + rl = *row++; + rr = *row++; + w = -(rl&1) | 1; + rl &= ~1; + rowlen--; + if (rr > lr) + lr = rr; + wind += w; + if (wind == 0) + break; + } while (rowlen > 0); + } + + if (marked_to >= lr) + continue; + + if (marked_to >= ll) { + if (rowout == rowstart) + ll = marked_to; + else { + rowout -= 2; + ll = *rowout; + } + } + + if (lr >= ll) { + *rowout++ = ll; + *rowout++ = lr; + marked_to = lr; + } + } + rowstart[-1] = rowout - rowstart; + } + return 0; +} + +/* Step 6: Fill */ +int +gx_fill_edgebuffer_app(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op) +{ + int i, code; + + for (i=0; i < edgebuffer->height; i++) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int rowlen = *row++; + int left, right; + + while (rowlen > 0) { + left = *row++; + right = *row++; + left = fixed2int(left); + right = fixed2int(right + fixed_1 - 1); + rowlen -= 2; + + right -= left; + if (right > 0) { + if (log_op < 0) + code = dev_proc(pdev, fill_rectangle)(pdev, left, edgebuffer->base+i, right, 1, pdevc->colors.pure); + else + code = gx_fill_rectangle_device_rop(left, edgebuffer->base+i, right, 1, pdevc, pdev, (gs_logical_operation_t)log_op); + if (code < 0) + return code; + } + } + } + return 0; +} + +/* Centre of a pixel trapezoid routines */ + +static int intcmp_tr(const void *a, const void *b) +{ + int left = ((int*)a)[0]; + int right = ((int*)b)[0]; + if (left != right) + return left - right; + return ((int*)a)[1] - ((int*)b)[1]; +} + +#ifdef DEBUG_SCAN_CONVERTER +static void +gx_edgebuffer_print_tr(gx_edgebuffer * edgebuffer) +{ + int i; + + if (!debugging_scan_converter) + return; + + dlprintf1("Edgebuffer %x\n", edgebuffer); + dlprintf4("xmin=%x xmax=%x base=%x height=%x\n", + edgebuffer->xmin, edgebuffer->xmax, edgebuffer->base, edgebuffer->height); + for (i=0; i < edgebuffer->height; i++) + { + int offset = edgebuffer->index[i]; + int *row = &edgebuffer->table[offset]; + int count = *row++; + dlprintf3("%d @ %d: %d =", i, offset, count); + while (count-- > 0) { + int e = *row++; + int id = *row++; + dlprintf3(" %x%c%d", e, id&1 ? 'v' : '^', id>>1); + } + dlprintf("\n"); + } +} +#endif + +static void mark_line_tr(fixed sx, fixed sy, fixed ex, fixed ey, int base_y, int height, int *table, int *index, int id) +{ + int64_t delta; + int iy, ih; + fixed clip_sy, clip_ey; + int dirn = DIRN_UP; + int *row; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf6("Marking line (tr) from %x,%x to %x,%x (%x,%x)\n", sx, sy, ex, ey, fixed2int(sy + fixed_half-1) - base_y, fixed2int(ey + fixed_half-1) - base_y); +#endif +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 0 0 0 setrgbcolor %%PS\n"); + coord("moveto", sx, sy); + coord("lineto", ex, ey); + dlprintf("stroke %%PS\n"); +#endif + + if (fixed2int(sy + fixed_half-1) == fixed2int(ey + fixed_half-1)) + return; + if (sy > ey) { + int t; + t = sy; sy = ey; ey = t; + t = sx; sx = ex; ex = t; + dirn = DIRN_DOWN; + } + /* Lines go from sy to ey, closed at the start, open at the end. */ + /* We clip them to a region to make them closed at both ends. */ + /* Thus the first scanline marked (>= sy) is: */ + clip_sy = ((sy + fixed_half - 1) & ~(fixed_1-1)) | fixed_half; + /* The last scanline marked (< ey) is: */ + clip_ey = ((ey - fixed_half - 1) & ~(fixed_1-1)) | fixed_half; + /* Now allow for banding */ + if (clip_sy < int2fixed(base_y) + fixed_half) + clip_sy = int2fixed(base_y) + fixed_half; + if (ey <= clip_sy) + return; + if (clip_ey > int2fixed(base_y + height - 1) + fixed_half) + clip_ey = int2fixed(base_y + height - 1) + fixed_half; + if (sy > clip_ey) + return; + delta = (int64_t)clip_sy - (int64_t)sy; + if (delta > 0) + { + int64_t dx = (int64_t)ex - (int64_t)sx; + int64_t dy = (int64_t)ey - (int64_t)sy; + int advance = (int)((dx * delta + (dy>>1)) / dy); + sx += advance; + sy += delta; + } + delta = (int64_t)ey - (int64_t)clip_ey; + if (delta > 0) + { + int64_t dx = (int64_t)ex - (int64_t)sx; + int64_t dy = (int64_t)ey - (int64_t)sy; + int advance = (int)((dx * delta + (dy>>1)) / dy); + ex -= advance; + ey -= delta; + } + ex -= sx; + ey -= sy; + ih = fixed2int(ey); + assert(ih >= 0); + iy = fixed2int(sy) - base_y; +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf2(" iy=%x ih=%x\n", iy, ih); +#endif + assert(iy >= 0 && iy < height); + id = (id<<1) | dirn; + /* We always cross at least one scanline */ + row = &table[index[iy]]; + *row = (*row)+1; /* Increment the count */ + row[*row * 2 - 1] = sx; + row[*row * 2 ] = id; + if (ih == 0) + return; + if (ex >= 0) { + int x_inc, n_inc, f; + + /* We want to change sx by ex in ih steps. So each step, we add + * ex/ih to sx. That's x_inc + n_inc/ih. + */ + x_inc = ex/ih; + n_inc = ex-(x_inc*ih); + f = ih>>1; + delta = ih; + do { + int count; + iy++; + sx += x_inc; + f -= n_inc; + if (f < 0) { + f += ih; + sx++; + } + assert(iy >= 0 && iy < height); + row = &table[index[iy]]; + count = *row = (*row)+1; /* Increment the count */ + row[count * 2 - 1] = sx; + row[count * 2 ] = id; + } + while (--delta); + } else { + int x_dec, n_dec, f; + + ex = -ex; + /* We want to change sx by ex in ih steps. So each step, we subtract + * ex/ih from sx. That's x_dec + n_dec/ih. + */ + x_dec = ex/ih; + n_dec = ex-(x_dec*ih); + f = ih>>1; + delta = ih; + do { + int count; + iy++; + sx -= x_dec; + f -= n_dec; + if (f < 0) { + f += ih; + sx--; + } + assert(iy >= 0 && iy < height); + row = &table[index[iy]]; + count = *row = (*row)+1; /* Increment the count */ + row[count * 2 - 1] = sx; + row[count * 2 ] = id; + } + while (--delta); + } +} + +static void mark_curve_tr(fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, fixed base_y, fixed height, int *table, int *index, int *id, int depth) +{ + fixed ax = (sx + c1x)>>1; + fixed ay = (sy + c1y)>>1; + fixed bx = (c1x + c2x)>>1; + fixed by = (c1y + c2y)>>1; + fixed cx = (c2x + ex)>>1; + fixed cy = (c2y + ey)>>1; + fixed dx = (ax + bx)>>1; + fixed dy = (ay + by)>>1; + fixed fx = (bx + cx)>>1; + fixed fy = (by + cy)>>1; + fixed gx = (dx + fx)>>1; + fixed gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) { + *id += 1; + mark_line_tr(sx, sy, ex, ey, base_y, height, table, index, *id); + } else { + depth--; + mark_curve_tr(sx, sy, ax, ay, dx, dy, gx, gy, base_y, height, table, index, id, depth); + mark_curve_tr(gx, gy, fx, fy, cx, cy, ex, ey, base_y, height, table, index, id, depth); + } +} + +static void mark_curve_big_tr(fixed64 sx, fixed64 sy, fixed64 c1x, fixed64 c1y, fixed64 c2x, fixed64 c2y, fixed64 ex, fixed64 ey, fixed base_y, fixed height, int *table, int *index, int *id, int depth) +{ + fixed64 ax = (sx + c1x)>>1; + fixed64 ay = (sy + c1y)>>1; + fixed64 bx = (c1x + c2x)>>1; + fixed64 by = (c1y + c2y)>>1; + fixed64 cx = (c2x + ex)>>1; + fixed64 cy = (c2y + ey)>>1; + fixed64 dx = (ax + bx)>>1; + fixed64 dy = (ay + by)>>1; + fixed64 fx = (bx + cx)>>1; + fixed64 fy = (by + cy)>>1; + fixed64 gx = (dx + fx)>>1; + fixed64 gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) { + *id += 1; + mark_line_tr((fixed)sx, (fixed)sy, (fixed)ex, (fixed)ey, base_y, height, table, index, *id); + } else { + depth--; + mark_curve_big_tr(sx, sy, ax, ay, dx, dy, gx, gy, base_y, height, table, index, id, depth); + mark_curve_big_tr(gx, gy, fx, fy, cx, cy, ex, ey, base_y, height, table, index, id, depth); + } +} + +static void mark_curve_top_tr(fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, fixed base_y, fixed height, int *table, int *index, int *id, int depth) +{ + fixed test = (sx^(sx<<1))|(sy^(sy<<1))|(c1x^(c1x<<1))|(c1y^(c1y<<1))|(c2x^(c2x<<1))|(c2y^(c2y<<1))|(ex^(ex<<1))|(ey^(ey<<1)); + + if (test < 0) + mark_curve_big_tr(sx, sy, c1x, c1y, c2x, c2y, ex, ey, base_y, height, table, index, id, depth); + else + mark_curve_tr(sx, sy, c1x, c1y, c2x, c2y, ex, ey, base_y, height, table, index, id, depth); +} + +static int make_table_tr(gx_device * pdev, + gx_path * path, + gs_fixed_rect * ibox, + int * scanlines, + int ** index, + int ** table) +{ + return make_table_template(pdev, path, ibox, 2, 1, scanlines, index, table); +} + +int gx_scan_convert_tr(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict clip, + gx_edgebuffer * gs_restrict edgebuffer, + fixed fixed_flat) +{ + gs_fixed_rect ibox; + int scanlines; + const subpath *psub; + int *index; + int *table; + int i; + int code; + int id = 0; + + edgebuffer->index = NULL; + edgebuffer->table = NULL; + + /* Bale out if no actual path. We see this with the clist */ + if (path->first_subpath == NULL) + return 0; + + code = make_bbox(path, clip, &ibox, fixed_half); + if (code < 0) + return code; + + if (ibox.q.y <= ibox.p.y) + return 0; + + code = make_table_tr(pdev, path, &ibox, &scanlines, &index, &table); + if (code < 0) + return code; + + /* Step 3: Now we run through the path, filling in the real + * values. */ + for (psub = path->first_subpath; psub != 0;) { + const segment *pseg = (const segment *)psub; + fixed ex = pseg->pt.x; + fixed ey = pseg->pt.y; + fixed ix = ex; + fixed iy = ey; + + while ((pseg = pseg->next) != 0 && + pseg->type != s_start + ) { + fixed sx = ex; + fixed sy = ey; + ex = pseg->pt.x; + ey = pseg->pt.y; + + switch (pseg->type) { + default: + case s_start: /* Should never happen */ + case s_dash: /* We should never be seeing a dash here */ + assert("This should never happen" == NULL); + break; + case s_curve: { + const curve_segment *const pcur = (const curve_segment *)pseg; + int k = gx_curve_log2_samples(sx, sy, pcur, fixed_flat); + + mark_curve_top_tr(sx, sy, pcur->p1.x, pcur->p1.y, pcur->p2.x, pcur->p2.y, ex, ey, ibox.p.y, scanlines, table, index, &id, k); + break; + } + case s_gap: + case s_line: + case s_line_close: + if (sy != ey) + mark_line_tr(sx, sy, ex, ey, ibox.p.y, scanlines, table, index, ++id); + break; + } + } + /* And close any open segments */ + if (iy != ey) + mark_line_tr(ex, ey, ix, iy, ibox.p.y, scanlines, table, index, ++id); + psub = (const subpath *)pseg; + } + + /* Step 2 complete: We now have a complete list of intersection data in + * table, indexed by index. */ + + edgebuffer->base = ibox.p.y; + edgebuffer->height = scanlines; + edgebuffer->xmin = ibox.p.x; + edgebuffer->xmax = ibox.q.x; + edgebuffer->index = index; + edgebuffer->table = table; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before sorting:\n"); + gx_edgebuffer_print_tr(edgebuffer); + } +#endif + + /* Step 4: Sort the intersects on x */ + for (i=0; i < scanlines; i++) { + int *row = &table[index[i]]; + int rowlen = *row++; + + /* Bubblesort short runs, qsort longer ones. */ + /* FIXME: Verify the figure 6 below */ + if (rowlen <= 6) { + int j, k; + for (j = 0; j < rowlen-1; j++) { + int * gs_restrict t = &row[j<<1]; + for (k = j+1; k < rowlen; k++) { + int * gs_restrict s = &row[k<<1]; + int tmp; + if (t[0] < s[0]) + continue; + if (t[0] == s[0]) { + if (t[1] <= s[1]) + continue; + } else + tmp = t[0], t[0] = s[0], s[0] = tmp; + tmp = t[1], t[1] = s[1], s[1] = tmp; + } + } + } else + qsort(row, rowlen, 2*sizeof(int), intcmp_tr); + } + + return 0; +} + +/* Step 5: Filter the intersections according to the rules */ +int +gx_filter_edgebuffer_tr(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule) +{ + int i; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before filtering\n"); + gx_edgebuffer_print_tr(edgebuffer); + } +#endif + + for (i=0; i < edgebuffer->height; i++) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int rowlen = *row++; + int *rowstart = row; + int *rowout = row; + + while (rowlen > 0) { + int left, lid, right, rid; + + if (rule == gx_rule_even_odd) { + /* Even Odd */ + left = *row++; + lid = *row++; + right = *row++; + rid = *row++; + rowlen -= 2; + } else { + /* Non-Zero */ + int w; + + left = *row++; + lid = *row++; + w = ((lid&1)-1) | 1; + rowlen--; + do { + right = *row++; + rid = *row++; + rowlen--; + w += ((rid&1)-1) | 1; + } while (w != 0); + } + + if (right > left) { + *rowout++ = left; + *rowout++ = lid; + *rowout++ = right; + *rowout++ = rid; + } + } + rowstart[-1] = (rowout-rowstart)>>1; + } + return 0; +} + +/* Step 6: Fill the edgebuffer */ +int +gx_fill_edgebuffer_tr(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op) +{ + int i, j, code; + int mfb = pdev->max_fill_band; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before filling\n"); + gx_edgebuffer_print_tr(edgebuffer); + } +#endif + + for (i=0; i < edgebuffer->height; ) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int rowlen = *row++; + int *row2; + int *rowptr; + int *row2ptr; + int y_band_max; + + if (mfb) { + y_band_max = (i & ~(mfb-1)) + mfb; + if (y_band_max > edgebuffer->height) + y_band_max = edgebuffer->height; + } else { + y_band_max = edgebuffer->height; + } + + /* See how many scanlines match i */ + for (j = i+1; j < y_band_max; j++) { + int row2len; + + row2 = &edgebuffer->table[edgebuffer->index[j]]; + row2len = *row2++; + row2ptr = row2; + rowptr = row; + + if (rowlen != row2len) + break; + while (row2len > 0) { + if ((rowptr[1]&~1) != (row2ptr[1]&~1)) + goto rowdifferent; + rowptr += 2; + row2ptr += 2; + row2len--; + } + } +rowdifferent:{} + + /* So j is the first scanline that doesn't match i */ + + if (j == i+1) { + while (rowlen > 0) { + int left, right; + + left = row[0]; + right = row[2]; + row += 4; + rowlen -= 2; + + left = fixed2int(left + fixed_half); + right = fixed2int(right + fixed_half); + right -= left; + if (right > 0) { +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 1 0 1 setrgbcolor %% purple %%PS\n"); + coord("moveto", int2fixed(left), int2fixed(edgebuffer->base+i)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+i)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+i+1)); + coord("lineto", int2fixed(left), int2fixed(edgebuffer->base+i+1)); + dlprintf("closepath stroke %%PS\n"); +#endif + if (log_op < 0) + code = dev_proc(pdev, fill_rectangle)(pdev, left, edgebuffer->base+i, right, 1, pdevc->colors.pure); + else + code = gx_fill_rectangle_device_rop(left, edgebuffer->base+i, right, 1, pdevc, pdev, (gs_logical_operation_t)log_op); + if (code < 0) + return code; + } + } + } else { + gs_fixed_edge le; + gs_fixed_edge re; + +#ifdef DEBUG_OUTPUT_SC_AS_PS +#ifdef DEBUG_OUTPUT_SC_AS_PS_TRAPS_AS_RECTS + int k; + for (k = i; k < j; k++) + { + int row2len; + int left, right; + row2 = &edgebuffer->table[edgebuffer->index[k]]; + row2len = *row2++; + while (row2len > 0) { + left = row2[0]; + right = row2[2]; + row2 += 4; + row2len -= 2; + + left = fixed2int(left + fixed_half); + right = fixed2int(right + fixed_half); + right -= left; + if (right > 0) { + dlprintf("0.001 setlinewidth 1 0 0.5 setrgbcolor %%PS\n"); + coord("moveto", int2fixed(left), int2fixed(edgebuffer->base+k)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+k)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+k+1)); + coord("lineto", int2fixed(left), int2fixed(edgebuffer->base+k+1)); + dlprintf("closepath stroke %%PS\n"); + } + } + } +#endif +#endif + + le.start.y = re.start.y = int2fixed(edgebuffer->base+i) + fixed_half; + le.end.y = re.end.y = int2fixed(edgebuffer->base+j) - (fixed_half-1); + row2 = &edgebuffer->table[edgebuffer->index[j-1]+1]; + while (rowlen > 0) { + le.start.x = row[0]; + re.start.x = row[2]; + le.end.x = row2[0]; + re.end.x = row2[2]; + row += 4; + row2 += 4; + rowlen -= 2; + + assert(re.start.x >= le.start.x); + assert(re.end.x >= le.end.x); + +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 0 1 1 setrgbcolor %%cyan %%PS\n"); + coord("moveto", le.start.x, le.start.y); + coord("lineto", le.end.x, le.end.y); + coord("lineto", re.end.x, re.end.y); + coord("lineto", re.start.x, re.start.y); + dlprintf("closepath stroke %%PS\n"); +#endif + code = dev_proc(pdev, fill_trapezoid)( + pdev, + &le, + &re, + le.start.y, + le.end.y, + 0, /* bool swap_axes */ + pdevc, /*const gx_drawing_color *pdcolor */ + log_op); + if (code < 0) + return code; + } + } + + i = j; + } + return 0; +} + +/* Any part of a pixel trapezoid routines */ + +static int edgecmp_tr(const void *a, const void *b) +{ + int left = ((int*)a)[0]; + int right = ((int*)b)[0]; + if (left != right) + return left - right; + left = ((int*)a)[2] - ((int*)b)[2]; + if (left != 0) + return left; + left = ((int*)a)[1] - ((int*)b)[1]; + if (left != 0) + return left; + return ((int*)a)[3] - ((int*)b)[3]; +} + +#ifdef DEBUG_SCAN_CONVERTER +static void +gx_edgebuffer_print_filtered_tr_app(gx_edgebuffer * edgebuffer) +{ + int i; + + if (!debugging_scan_converter) + return; + + dlprintf1("Edgebuffer %x\n", edgebuffer); + dlprintf4("xmin=%x xmax=%x base=%x height=%x\n", + edgebuffer->xmin, edgebuffer->xmax, edgebuffer->base, edgebuffer->height); + for (i=0; i < edgebuffer->height; i++) + { + int offset = edgebuffer->index[i]; + int *row = &edgebuffer->table[offset]; + int count = *row++; + dlprintf3("%x @ %d: %d =", i, offset, count); + while (count-- > 0) { + int left = *row++; + int lid = *row++; + int right = *row++; + int rid = *row++; + dlprintf4(" (%x:%d,%x:%d)", left, lid, right, rid); + } + dlprintf("\n"); + } +} + +static void +gx_edgebuffer_print_tr_app(gx_edgebuffer * edgebuffer) +{ + int i; + int borked = 0; + + if (!debugging_scan_converter) + return; + + dlprintf1("Edgebuffer %x\n", edgebuffer); + dlprintf4("xmin=%x xmax=%x base=%x height=%x\n", + edgebuffer->xmin, edgebuffer->xmax, edgebuffer->base, edgebuffer->height); + for (i=0; i < edgebuffer->height; i++) + { + int offset = edgebuffer->index[i]; + int *row = &edgebuffer->table[offset]; + int count = *row++; + int c = count; + int wind = 0; + dlprintf3("%x @ %d: %d =", i, offset, count); + while (count-- > 0) { + int left = *row++; + int lid = *row++; + int right = *row++; + int rid = *row++; + int ww = lid & 1; + int w = -ww | 1; + lid >>= 1; + wind += w; + dlprintf5(" (%x:%d,%x:%d)%c", left, lid, right, rid, ww ? 'v' : '^'); + } + if (wind != 0 || c & 1) { + dlprintf(" <- BROKEN"); + borked = 1; + } + dlprintf("\n"); + } + if (borked) { + borked = borked; /* Breakpoint here */ + } +} +#endif + +typedef struct +{ + fixed left; + int lid; + fixed right; + int rid; + fixed y; + signed char d; /* 0 up (or horiz), 1 down, -1 uninited */ + unsigned char first; + unsigned char saved; + fixed save_left; + int save_lid; + fixed save_right; + int save_rid; + int save_iy; + int save_d; + + int scanlines; + int *table; + int *index; + int base; +} cursor_tr; + +static inline void +cursor_output_tr(cursor_tr * gs_restrict cr, int iy) +{ + int *row; + int count; + + if (iy >= 0 && iy < cr->scanlines) { + if (cr->first) { + /* Save it for later in case we join up */ + cr->save_left = cr->left; + cr->save_lid = cr->lid; + cr->save_right = cr->right; + cr->save_rid = cr->rid; + cr->save_iy = iy; + cr->save_d = cr->d; + cr->saved = 1; + } else { + /* Enter it into the table */ + assert(cr->d != DIRN_UNSET); + + row = &cr->table[cr->index[iy]]; + *row = count = (*row)+1; /* Increment the count */ + row[4 * count - 3] = cr->left; + row[4 * count - 2] = cr->d | (cr->lid<<1); + row[4 * count - 1] = cr->right; + row[4 * count ] = cr->rid; + } + } + cr->first = 0; +} + +static inline void +cursor_output_inrange_tr(cursor_tr * gs_restrict cr, int iy) +{ + int *row; + int count; + + assert(iy >= 0 && iy < cr->scanlines); + if (cr->first) { + /* Save it for later in case we join up */ + cr->save_left = cr->left; + cr->save_lid = cr->lid; + cr->save_right = cr->right; + cr->save_rid = cr->rid; + cr->save_iy = iy; + cr->save_d = cr->d; + cr->saved = 1; + } else { + /* Enter it into the table */ + assert(cr->d != DIRN_UNSET); + + row = &cr->table[cr->index[iy]]; + *row = count = (*row)+1; /* Increment the count */ + row[4 * count - 3] = cr->left; + row[4 * count - 2] = cr->d | (cr->lid<<1); + row[4 * count - 1] = cr->right; + row[4 * count ] = cr->rid; + } + cr->first = 0; +} + +/* Step the cursor in y, allowing for maybe crossing a scanline */ +static inline void +cursor_step_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + int new_iy; + int iy = fixed2int(cr->y) - cr->base; + + cr->y += dy; + new_iy = fixed2int(cr->y) - cr->base; + if (new_iy != iy) { + cursor_output_tr(cr, iy); + cr->left = x; + cr->lid = id; + cr->right = x; + cr->rid = id; + } else { + if (x < cr->left) + { + cr->left = x; + cr->lid = id; + } + if (x > cr->right) + { + cr->right = x; + cr->rid = id; + } + } +} + +/* Step the cursor in y, never by enough to cross a scanline. */ +static inline void +cursor_never_step_vertical_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + assert(fixed2int(cr->y+dy) == fixed2int(cr->y)); + + cr->y += dy; +} + +/* Step the cursor in y, never by enough to cross a scanline, + * knowing that we are moving left, and that the right edge + * has already been accounted for. */ +static inline void +cursor_never_step_left_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + assert(fixed2int(cr->y+dy) == fixed2int(cr->y)); + + if (x < cr->left) + { + cr->left = x; + cr->lid = id; + } + cr->y += dy; +} + +/* Step the cursor in y, never by enough to cross a scanline, + * knowing that we are moving right, and that the left edge + * has already been accounted for. */ +static inline void +cursor_never_step_right_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + assert(fixed2int(cr->y+dy) == fixed2int(cr->y)); + + if (x > cr->right) + { + cr->right = x; + cr->rid = id; + } + cr->y += dy; +} + +/* Step the cursor in y, always by enough to cross a scanline. */ +static inline void +cursor_always_step_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + int iy = fixed2int(cr->y) - cr->base; + + cursor_output_tr(cr, iy); + cr->y += dy; + cr->left = x; + cr->lid = id; + cr->right = x; + cr->rid = id; +} + +/* Step the cursor in y, always by enough to cross a scanline, as + * part of a vertical line, knowing that we are moving from a + * position guaranteed to be in the valid y range. */ +static inline void +cursor_always_step_inrange_vertical_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + int iy = fixed2int(cr->y) - cr->base; + + cursor_output_tr(cr, iy); + cr->y += dy; +} + +/* Step the cursor in y, always by enough to cross a scanline, as + * part of a left moving line, knowing that we are moving from a + * position guaranteed to be in the valid y range. */ +static inline void +cursor_always_inrange_step_left_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + int iy = fixed2int(cr->y) - cr->base; + + cr->y += dy; + cursor_output_inrange_tr(cr, iy); + cr->right = x; + cr->rid = id; +} + +/* Step the cursor in y, always by enough to cross a scanline, as + * part of a right moving line, knowing that we are moving from a + * position guaranteed to be in the valid y range. */ +static inline void +cursor_always_inrange_step_right_tr(cursor_tr * gs_restrict cr, fixed dy, fixed x, int id) +{ + int iy = fixed2int(cr->y) - cr->base; + + cr->y += dy; + cursor_output_inrange_tr(cr, iy); + cr->left = x; + cr->lid = id; +} + +static inline void cursor_init_tr(cursor_tr * gs_restrict cr, fixed y, fixed x, int id) +{ + assert(y >= int2fixed(cr->base) && y <= int2fixed(cr->base + cr->scanlines)); + + cr->y = y; + cr->left = x; + cr->lid = id; + cr->right = x; + cr->rid = id; + cr->d = DIRN_UNSET; +} + +static inline void cursor_left_merge_tr(cursor_tr * gs_restrict cr, fixed x, int id) +{ + if (x < cr->left) { + cr->left = x; + cr->lid = id; + } +} + +static inline void cursor_left_tr(cursor_tr * gs_restrict cr, fixed x, int id) +{ + cr->left = x; + cr->lid = id; +} + +static inline void cursor_right_merge_tr(cursor_tr * gs_restrict cr, fixed x, int id) +{ + if (x > cr->right) { + cr->right = x; + cr->rid = id; + } +} + +static inline void cursor_right_tr(cursor_tr * gs_restrict cr, fixed x, int id) +{ + cr->right = x; + cr->rid = id; +} + +static inline void cursor_down_tr(cursor_tr * gs_restrict cr, fixed x, int id) +{ + if (cr->d == DIRN_UP) + { + cursor_output_tr(cr, fixed2int(cr->y) - cr->base); + cr->left = x; + cr->lid = id; + cr->right = x; + cr->rid = id; + } + cr->d = DIRN_DOWN; +} + +static inline void cursor_up_tr(cursor_tr * gs_restrict cr, fixed x, int id) +{ + if (cr->d == DIRN_DOWN) + { + cursor_output_tr(cr, fixed2int(cr->y) - cr->base); + cr->left = x; + cr->lid = id; + cr->right = x; + cr->rid = id; + } + cr->d = DIRN_UP; +} + +static inline void +cursor_flush_tr(cursor_tr * gs_restrict cr, fixed x, int id) +{ + int iy; + + /* This should only happen if we were entirely out of bounds, + * or if everything was within a zero height horizontal + * rectangle from the start point. */ + if (cr->first) { + int iy = fixed2int(cr->y) - cr->base; + if (iy >= 0 && iy < cr->scanlines) { + int *row = &cr->table[cr->index[iy]]; + int count = *row = (*row)+2; /* Increment the count */ + row[4 * count - 7] = cr->left; + row[4 * count - 6] = DIRN_UP | (cr->lid<<1); + row[4 * count - 5] = cr->right; + row[4 * count - 4] = cr->rid; + row[4 * count - 3] = cr->right; + row[4 * count - 2] = DIRN_DOWN | (cr->rid<<1); + row[4 * count - 1] = cr->right; + row[4 * count ] = cr->rid; + } + return; + } + + /* Merge save into current if we can */ + iy = fixed2int(cr->y) - cr->base; + if (cr->saved && iy == cr->save_iy && + (cr->d == cr->save_d || cr->save_d == DIRN_UNSET)) { + if (cr->left > cr->save_left) { + cr->left = cr->save_left; + cr->lid = cr->save_lid; + } + if (cr->right < cr->save_right) { + cr->right = cr->save_right; + cr->rid = cr->save_rid; + } + cursor_output_tr(cr, iy); + return; + } + + /* Merge not possible */ + cursor_output_tr(cr, iy); + if (cr->saved) { + cr->left = cr->save_left; + cr->lid = cr->save_lid; + cr->right = cr->save_right; + cr->rid = cr->save_rid; + assert(cr->save_d != DIRN_UNSET); + if (cr->save_d != DIRN_UNSET) + cr->d = cr->save_d; + cursor_output_tr(cr, cr->save_iy); + } +} + +static void mark_line_tr_app(cursor_tr * gs_restrict cr, fixed sx, fixed sy, fixed ex, fixed ey, int id) +{ + int isy, iey; + fixed saved_sy = sy; + fixed saved_ex = ex; + fixed saved_ey = ey; + int truncated; + + if (sx == ex && sy == ey) + return; + + isy = fixed2int(sy) - cr->base; + iey = fixed2int(ey) - cr->base; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) + dlprintf6("Marking line (tr_app) from %x,%x to %x,%x (%x,%x)\n", sx, sy, ex, ey, isy, iey); +#endif +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 0 0 0 setrgbcolor %%PS\n"); + coord("moveto", sx, sy); + coord("lineto", ex, ey); + dlprintf("stroke %%PS\n"); +#endif + + assert(cr->y == sy && cr->left <= sx && cr->right >= sx && cr->d >= DIRN_UNSET && cr->d <= DIRN_DOWN); + + if (isy < iey) { + /* Rising line */ + if (iey < 0 || isy >= cr->scanlines) { + /* All line is outside. */ + cr->y = ey; + cr->left = ex; + cr->lid = id; + cr->right = ex; + cr->rid = id; + cr->first = 0; + return; + } + if (isy < 0) { + /* Move sy up */ + int64_t y = (int64_t)ey - (int64_t)sy; + fixed new_sy = int2fixed(cr->base); + int64_t dy = (int64_t)new_sy - (int64_t)sy; + sx += (int)((((int64_t)(ex-sx))*dy + y/2)/y); + sy = new_sy; + cursor_init_tr(cr, sy, sx, id); + isy = 0; + } + truncated = iey > cr->scanlines; + if (truncated) { + /* Move ey down */ + int64_t y = (int64_t)ey - (int64_t)sy; + fixed new_ey = int2fixed(cr->base + cr->scanlines); + int64_t dy = (int64_t)ey - (int64_t)new_ey; + saved_ex = ex; + saved_ey = ey; + ex -= (int)((((int64_t)(ex-sx))*dy + y/2)/y); + ey = new_ey; + iey = cr->scanlines; + } + } else { + /* Falling line */ + if (isy < 0 || iey >= cr->scanlines) { + /* All line is outside. */ + cr->y = ey; + cr->left = ex; + cr->lid = id; + cr->right = ex; + cr->rid = id; + cr->first = 0; + return; + } + truncated = iey < 0; + if (truncated) { + /* Move ey up */ + int64_t y = (int64_t)ey - (int64_t)sy; + fixed new_ey = int2fixed(cr->base); + int64_t dy = (int64_t)ey - (int64_t)new_ey; + ex -= (int)((((int64_t)(ex-sx))*dy + y/2)/y); + ey = new_ey; + iey = 0; + } + if (isy >= cr->scanlines) { + /* Move sy down */ + int64_t y = (int64_t)ey - (int64_t)sy; + fixed new_sy = int2fixed(cr->base + cr->scanlines); + int64_t dy = (int64_t)new_sy - (int64_t)sy; + sx += (int)((((int64_t)(ex-sx))*dy + y/2)/y); + sy = new_sy; + cursor_init_tr(cr, sy, sx, id); + isy = cr->scanlines; + } + } + + assert(cr->left <= sx); + assert(cr->right >= sx); + assert(cr->y == sy); + + /* A note: The code below used to be of the form: + * if (isy == iey) ... deal with horizontal lines + * else if (ey > sy) { + * fixed y_steps = ey - sy; + * ... deal with rising lines ... + * } else { + * fixed y_steps = ey - sy; + * ... deal with falling lines + * } + * but that lead to problems, for instance, an example seen + * has sx=2aa8e, sy=8aee7, ex=7ffc1686, ey=8003e97a. + * Thus isy=84f, iey=ff80038a. We can see that ey < sy, but + * sy - ey < 0! + * We therefore rejig our code so that the choice between + * cases is done based on the sign of y_steps rather than + * the relative size of ey and sy. + */ + + /* First, deal with lines that don't change scanline. + * This accommodates horizontal lines. */ + if (isy == iey) { + if (saved_sy == saved_ey) { + /* Horizontal line. Don't change cr->d, don't flush. */ + } else if (saved_sy > saved_ey) { + /* Falling line, flush if previous was rising */ + cursor_down_tr(cr, sx, id); + } else { + /* Rising line, flush if previous was falling */ + cursor_up_tr(cr, sx, id); + } + if (sx <= ex) { + cursor_left_merge_tr(cr, sx, id); + cursor_right_merge_tr(cr, ex, id); + } else { + cursor_left_merge_tr(cr, ex, id); + cursor_right_merge_tr(cr, sx, id); + } + cr->y = ey; + if (sy > saved_ey) + goto endFalling; + } else if (iey > isy) { + /* So lines increasing in y. */ + /* We want to change from sy to ey, which are guaranteed to be on + * different scanlines. We do this in 3 phases. + * Phase 1 gets us from sy to the next scanline boundary. (We may exit after phase 1). + * Phase 2 gets us all the way to the last scanline boundary. (This may be a null operation) + * Phase 3 gets us from the last scanline boundary to ey. (We are guaranteed to have output the cursor at least once before phase 3). + */ + int phase1_y_steps = (-sy) & (fixed_1 - 1); + int phase3_y_steps = ey & (fixed_1 - 1); + ufixed y_steps = (ufixed)ey - (ufixed)sy; + + cursor_up_tr(cr, sx, id); + + if (sx == ex) { + /* Vertical line. (Rising) */ + + /* Phase 1: */ + cursor_left_merge_tr(cr, sx, id); + cursor_right_merge_tr(cr, sx, id); + if (phase1_y_steps) { + /* If phase 1 will move us into a new scanline, then we must + * flush it before we move. */ + cursor_step_tr(cr, phase1_y_steps, sx, id); + sy += phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto end; + } + + /* Phase 3: precalculation */ + y_steps -= phase3_y_steps; + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps > 0) { + cursor_always_step_tr(cr, fixed_1, sx, id); + y_steps--; + while (y_steps) { + cursor_always_step_inrange_vertical_tr(cr, fixed_1, sx, id); + y_steps--; + } + } + + /* Phase 3 */ + assert(cr->left == sx && cr->right == sx && cr->lid == id && cr->rid == id); + cr->y += phase3_y_steps; + } else if (sx < ex) { + /* Lines increasing in x. (Rightwards, rising) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = ex - sx; + + /* Phase 1: */ + cursor_left_merge_tr(cr, sx, id); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + sx += phase1_x_steps; + cursor_right_merge_tr(cr, sx, id); + x_steps -= phase1_x_steps; + cursor_step_tr(cr, phase1_y_steps, sx, id); + sy += phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto end; + } + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we add x_steps/y_steps to sx. That's x_inc + n_inc/y_steps. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + /* Special casing the first iteration, allows us to simplify + * the following loop. */ + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right_merge_tr(cr, sx, id); + cursor_always_step_tr(cr, fixed_1, sx, id); + y_steps--; + + while (y_steps) { + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right_tr(cr, sx, id); + cursor_always_inrange_step_right_tr(cr, fixed_1, sx, id); + y_steps--; + }; + } + + /* Phase 3 */ + assert(cr->left <= ex && cr->lid == id && cr->right >= sx); + cursor_right_tr(cr, ex, id); + cr->y += phase3_y_steps; + } else { + /* Lines decreasing in x. (Leftwards, rising) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = sx - ex; + + /* Phase 1: */ + cursor_right_merge_tr(cr, sx, id); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + x_steps -= phase1_x_steps; + sx -= phase1_x_steps; + cursor_left_merge_tr(cr, sx, id); + cursor_step_tr(cr, phase1_y_steps, sx, id); + sy += phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto end; + } + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int((unsigned int)y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we sub x_steps/y_steps from sx. That's x_inc + n_inc/ey. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + /* Special casing the first iteration, allows us to simplify + * the following loop. */ + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left_merge_tr(cr, sx, id); + cursor_always_step_tr(cr, fixed_1, sx, id); + y_steps--; + + while (y_steps) { + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left_tr(cr, sx, id); + cursor_always_inrange_step_left_tr(cr, fixed_1, sx, id); + y_steps--; + } + } + + /* Phase 3 */ + assert(cr->right >= ex && cr->rid == id && cr->left <= sx); + cursor_left_tr(cr, ex, id); + cr->y += phase3_y_steps; + } + } else { + /* So lines decreasing in y. */ + /* We want to change from sy to ey, which are guaranteed to be on + * different scanlines. We do this in 3 phases. + * Phase 1 gets us from sy to the next scanline boundary. This never causes an output. + * Phase 2 gets us all the way to the last scanline boundary. This is guaranteed to cause an output. + * Phase 3 gets us from the last scanline boundary to ey. We are guaranteed to have outputted by now. + */ + int phase1_y_steps = sy & (fixed_1 - 1); + int phase3_y_steps = (-ey) & (fixed_1 - 1); + ufixed y_steps = (ufixed)sy - (ufixed)ey; + + cursor_down_tr(cr, sx, id); + + if (sx == ex) { + /* Vertical line. (Falling) */ + + /* Phase 1: */ + cursor_left_merge_tr(cr, sx, id); + cursor_right_merge_tr(cr, sx, id); + if (phase1_y_steps) { + /* Phase 1 in a falling line never moves us into a new scanline. */ + cursor_never_step_vertical_tr(cr, -phase1_y_steps, sx, id); + sy -= phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto endFalling; + } + + /* Phase 3: precalculation */ + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + cursor_always_step_tr(cr, -fixed_1, sx, id); + y_steps--; + while (y_steps) { + cursor_always_step_inrange_vertical_tr(cr, -fixed_1, sx, id); + y_steps--; + } + } + + /* Phase 3 */ + if (phase3_y_steps > 0) { + cursor_step_tr(cr, -phase3_y_steps, sx, id); + assert(cr->left == sx && cr->lid == id && cr->right == sx && cr->rid == id); + } + } else if (sx < ex) { + /* Lines increasing in x. (Rightwards, falling) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = ex - sx; + + /* Phase 1: */ + cursor_left_merge_tr(cr, sx, id); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + x_steps -= phase1_x_steps; + sx += phase1_x_steps; + /* Phase 1 in a falling line never moves us into a new scanline. */ + cursor_never_step_right_tr(cr, -phase1_y_steps, sx, id); + sy -= phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto endFalling; + } else + cursor_right_merge_tr(cr, sx, id); + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we add x_steps/y_steps to sx. That's x_inc + n_inc/ey. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + cursor_always_step_tr(cr, -fixed_1, sx, id); + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right_tr(cr, sx, id); + y_steps--; + + while (y_steps) { + cursor_always_inrange_step_right_tr(cr, -fixed_1, sx, id); + sx += x_inc; + f -= n_inc; + if (f < 0) + f += d, sx++; + cursor_right_tr(cr, sx, id); + y_steps--; + } + } + + /* Phase 3 */ + if (phase3_y_steps > 0) { + cursor_step_tr(cr, -phase3_y_steps, sx, id); + cursor_right_tr(cr, ex, id); + assert(cr->left == sx && cr->lid == id && cr->right == ex && cr->rid == id); + } + } else { + /* Lines decreasing in x. (Falling) */ + int phase1_x_steps, phase3_x_steps; + fixed x_steps = sx - ex; + + /* Phase 1: */ + cursor_right_merge_tr(cr, sx, id); + if (phase1_y_steps) { + phase1_x_steps = (int)(((int64_t)x_steps * phase1_y_steps + y_steps/2) / y_steps); + x_steps -= phase1_x_steps; + sx -= phase1_x_steps; + /* Phase 1 in a falling line never moves us into a new scanline. */ + cursor_never_step_left_tr(cr, -phase1_y_steps, sx, id); + sy -= phase1_y_steps; + y_steps -= phase1_y_steps; + if (y_steps == 0) + goto endFalling; + } else + cursor_left_merge_tr(cr, sx, id); + + /* Phase 3: precalculation */ + phase3_x_steps = (int)(((int64_t)x_steps * phase3_y_steps + y_steps/2) / y_steps); + x_steps -= phase3_x_steps; + y_steps -= phase3_y_steps; + assert((y_steps & (fixed_1 - 1)) == 0); + + /* Phase 2: */ + y_steps = fixed2int(y_steps); + assert(y_steps >= 0); + if (y_steps) { + /* We want to change sx by x_steps in y_steps steps. + * So each step, we sub x_steps/y_steps from sx. That's x_inc + n_inc/ey. */ + int x_inc = x_steps/y_steps; + int n_inc = x_steps - (x_inc * y_steps); + int f = y_steps/2; + int d = y_steps; + + cursor_always_step_tr(cr, -fixed_1, sx, id); + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left_tr(cr, sx, id); + y_steps--; + + while (y_steps) { + cursor_always_inrange_step_left_tr(cr, -fixed_1, sx, id); + sx -= x_inc; + f -= n_inc; + if (f < 0) + f += d, sx--; + cursor_left_tr(cr, sx, id); + y_steps--; + } + } + + /* Phase 3 */ + if (phase3_y_steps > 0) { + cursor_step_tr(cr, -phase3_y_steps, sx, id); + cursor_left_tr(cr, ex, id); + assert(cr->left == ex && cr->lid == id && cr->right == sx && cr->rid == id); + } + } +endFalling: + if (truncated) + { + cursor_output_tr(cr, fixed2int(cr->y) - cr->base); + } + } + +end: + if (truncated) { + cr->left = saved_ex; + cr->lid = id; + cr->right = saved_ex; + cr->rid = id; + cr->y = saved_ey; + } +} + +static void mark_curve_tr_app(cursor_tr * gs_restrict cr, fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, int depth, int * gs_restrict id) +{ + int ax = (sx + c1x)>>1; + int ay = (sy + c1y)>>1; + int bx = (c1x + c2x)>>1; + int by = (c1y + c2y)>>1; + int cx = (c2x + ex)>>1; + int cy = (c2y + ey)>>1; + int dx = (ax + bx)>>1; + int dy = (ay + by)>>1; + int fx = (bx + cx)>>1; + int fy = (by + cy)>>1; + int gx = (dx + fx)>>1; + int gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) { + *id += 1; + mark_line_tr_app(cr, sx, sy, ex, ey, *id); + } else { + depth--; + mark_curve_tr_app(cr, sx, sy, ax, ay, dx, dy, gx, gy, depth, id); + mark_curve_tr_app(cr, gx, gy, fx, fy, cx, cy, ex, ey, depth, id); + } +} + +static void mark_curve_big_tr_app(cursor_tr * gs_restrict cr, fixed64 sx, fixed64 sy, fixed64 c1x, fixed64 c1y, fixed64 c2x, fixed64 c2y, fixed64 ex, fixed64 ey, int depth, int * gs_restrict id) +{ + fixed64 ax = (sx + c1x)>>1; + fixed64 ay = (sy + c1y)>>1; + fixed64 bx = (c1x + c2x)>>1; + fixed64 by = (c1y + c2y)>>1; + fixed64 cx = (c2x + ex)>>1; + fixed64 cy = (c2y + ey)>>1; + fixed64 dx = (ax + bx)>>1; + fixed64 dy = (ay + by)>>1; + fixed64 fx = (bx + cx)>>1; + fixed64 fy = (by + cy)>>1; + fixed64 gx = (dx + fx)>>1; + fixed64 gy = (dy + fy)>>1; + + assert(depth >= 0); + if (depth == 0) { + *id += 1; + mark_line_tr_app(cr, (fixed)sx, (fixed)sy, (fixed)ex, (fixed)ey, *id); + } else { + depth--; + mark_curve_big_tr_app(cr, sx, sy, ax, ay, dx, dy, gx, gy, depth, id); + mark_curve_big_tr_app(cr, gx, gy, fx, fy, cx, cy, ex, ey, depth, id); + } +} + +static void mark_curve_top_tr_app(cursor_tr * gs_restrict cr, fixed sx, fixed sy, fixed c1x, fixed c1y, fixed c2x, fixed c2y, fixed ex, fixed ey, int depth, int * gs_restrict id) +{ + fixed test = (sx^(sx<<1))|(sy^(sy<<1))|(c1x^(c1x<<1))|(c1y^(c1y<<1))|(c2x^(c2x<<1))|(c2y^(c2y<<1))|(ex^(ex<<1))|(ey^(ey<<1)); + + if (test < 0) + mark_curve_big_tr_app(cr, sx, sy, c1x, c1y, c2x, c2y, ex, ey, depth, id); + else + mark_curve_tr_app(cr, sx, sy, c1x, c1y, c2x, c2y, ex, ey, depth, id); +} + +static int make_table_tr_app(gx_device * pdev, + gx_path * path, + gs_fixed_rect * ibox, + int * scanlines, + int ** index, + int ** table) +{ + return make_table_template(pdev, path, ibox, 4, 0, scanlines, index, table); +} + +int gx_scan_convert_tr_app(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict clip, + gx_edgebuffer * gs_restrict edgebuffer, + fixed fixed_flat) +{ + gs_fixed_rect ibox; + int scanlines; + const subpath *psub; + int *index; + int *table; + int i; + cursor_tr cr; + int code; + int id = 0; + + edgebuffer->index = NULL; + edgebuffer->table = NULL; + + /* Bale out if no actual path. We see this with the clist */ + if (path->first_subpath == NULL) + return 0; + + code = make_bbox(path, clip, &ibox, 0); + if (code < 0) + return code; + + if (ibox.q.y <= ibox.p.y) + return 0; + + code = make_table_tr_app(pdev, path, &ibox, &scanlines, &index, &table); + if (code < 0) + return code; + + /* Step 2 continued: Now we run through the path, filling in the real + * values. */ + cr.scanlines = scanlines; + cr.index = index; + cr.table = table; + cr.base = ibox.p.y; + for (psub = path->first_subpath; psub != 0;) { + const segment *pseg = (const segment *)psub; + fixed ex = pseg->pt.x; + fixed ey = pseg->pt.y; + fixed ix = ex; + fixed iy = ey; + fixed sx, sy; + + cr.left = cr.right = ex; + cr.lid = cr.rid = id+1; + cr.y = ey; + cr.d = DIRN_UNSET; + cr.first = 1; + cr.saved = 0; + + while ((pseg = pseg->next) != 0 && + pseg->type != s_start + ) { + sx = ex; + sy = ey; + ex = pseg->pt.x; + ey = pseg->pt.y; + + switch (pseg->type) { + default: + case s_start: /* Should never happen */ + case s_dash: /* We should never be seeing a dash here */ + assert("This should never happen" == NULL); + break; + case s_curve: { + const curve_segment *const pcur = (const curve_segment *)pseg; + int k = gx_curve_log2_samples(sx, sy, pcur, fixed_flat); + + mark_curve_top_tr_app(&cr, sx, sy, pcur->p1.x, pcur->p1.y, pcur->p2.x, pcur->p2.y, ex, ey, k, &id); + break; + } + case s_gap: + case s_line: + case s_line_close: + mark_line_tr_app(&cr, sx, sy, ex, ey, ++id); + break; + } + } + /* And close any open segments */ + mark_line_tr_app(&cr, ex, ey, ix, iy, ++id); + cursor_flush_tr(&cr, ex, id); + psub = (const subpath *)pseg; + } + + /* Step 2 complete: We now have a complete list of intersection data in + * table, indexed by index. */ + + edgebuffer->base = ibox.p.y; + edgebuffer->height = scanlines; + edgebuffer->xmin = ibox.p.x; + edgebuffer->xmax = ibox.q.x; + edgebuffer->index = index; + edgebuffer->table = table; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before sorting\n"); + gx_edgebuffer_print_tr_app(edgebuffer); + } +#endif + + /* Step 3: Sort the intersects on x */ + for (i=0; i < scanlines; i++) { + int *row = &table[index[i]]; + int rowlen = *row++; + + /* Bubblesort short runs, qsort longer ones. */ + /* Figure of '6' comes from testing */ + if (rowlen <= 6) { + int j, k; + for (j = 0; j < rowlen-1; j++) { + int * gs_restrict t = &row[j<<2]; + for (k = j+1; k < rowlen; k++) { + int * gs_restrict s = &row[k<<2]; + int tmp; + if (t[0] < s[0]) + continue; + if (t[0] > s[0]) + goto swap0213; + if (t[2] < s[2]) + continue; + if (t[2] > s[2]) + goto swap213; + if (t[1] < s[1]) + continue; + if (t[1] > s[1]) + goto swap13; + if (t[3] <= s[3]) + continue; + if (0) { +swap0213: + tmp = t[0], t[0] = s[0], s[0] = tmp; +swap213: + tmp = t[2], t[2] = s[2], s[2] = tmp; +swap13: + tmp = t[1], t[1] = s[1], s[1] = tmp; + } + tmp = t[3], t[3] = s[3], s[3] = tmp; + } + } + } else + qsort(row, rowlen, 4*sizeof(int), edgecmp_tr); + } + + return 0; +} + +/* Step 5: Filter the intersections according to the rules */ +int +gx_filter_edgebuffer_tr_app(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule) +{ + int i; + int marked_id = 0; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Before filtering:\n"); + gx_edgebuffer_print_tr_app(edgebuffer); + } +#endif + + for (i=0; i < edgebuffer->height; i++) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int rowlen = *row++; + int *rowstart = row; + int *rowout = row; + int ll, llid, lr, lrid, rlid, rr, rrid, wind, marked_to; + + /* Avoid double setting pixels, by keeping where we have marked to. */ + marked_to = INT_MIN; + while (rowlen > 0) { + if (rule == gx_rule_even_odd) { + /* Even Odd */ + ll = *row++; + llid = (*row++)>>1; + lr = *row++; + lrid = *row++; + rowlen--; + + /* We will fill solidly from ll to at least lr, possibly further */ + assert(rowlen > 0); + (void)row++; /* rl not needed here */ + (void)row++; + rr = *row++; + rrid = *row++; + rowlen--; + if (rr > lr) { + lr = rr; + lrid = rrid; + } + } else { + /* Non-Zero */ + int w; + + ll = *row++; + llid = *row++; + lr = *row++; + lrid = *row++; + wind = -(llid&1) | 1; + llid >>= 1; + rowlen--; + + assert(rowlen > 0); + do { + (void)row++; /* rl not needed */ + rlid = *row++; + rr = *row++; + rrid = *row++; + w = -(rlid&1) | 1; + rlid >>= 1; + rowlen--; + if (rr > lr) { + lr = rr; + lrid = rrid; + } + wind += w; + if (wind == 0) + break; + } while (rowlen > 0); + } + + if (lr < marked_to) + continue; + + if (marked_to >= ll) { + if (rowout == rowstart) { + ll = marked_to; + llid = --marked_id; + } else { + rowout -= 4; + ll = rowout[0]; + llid = rowout[1]; + } + } + + if (lr >= ll) { + *rowout++ = ll; + *rowout++ = llid; + *rowout++ = lr; + *rowout++ = lrid; + marked_to = lr; + } + } + rowstart[-1] = (rowout - rowstart)>>2; + } + return 0; +} + +/* Step 6: Fill */ +int +gx_fill_edgebuffer_tr_app(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op) +{ + int i, j, code; + int mfb = pdev->max_fill_band; + +#ifdef DEBUG_SCAN_CONVERTER + if (debugging_scan_converter) { + dlprintf("Filling:\n"); + gx_edgebuffer_print_filtered_tr_app(edgebuffer); + } +#endif + + for (i=0; i < edgebuffer->height; ) { + int *row = &edgebuffer->table[edgebuffer->index[i]]; + int rowlen = *row++; + int *row2; + int *rowptr; + int *row2ptr; + int y_band_max; + + if (mfb) { + y_band_max = (i & ~(mfb-1)) + mfb; + if (y_band_max > edgebuffer->height) + y_band_max = edgebuffer->height; + } else { + y_band_max = edgebuffer->height; + } + + /* See how many scanlines match i */ + for (j = i+1; j < y_band_max; j++) { + int row2len; + + row2 = &edgebuffer->table[edgebuffer->index[j]]; + row2len = *row2++; + row2ptr = row2; + rowptr = row; + + if (rowlen != row2len) + break; + while (row2len > 0) { + if (rowptr[1] != row2ptr[1] || rowptr[3] != row2ptr[3]) + goto rowdifferent; + rowptr += 4; + row2ptr += 4; + row2len--; + } + } +rowdifferent:{} + + /* So j is the first scanline that doesn't match i */ + + /* The first scanline is always sent as rectangles */ + while (rowlen > 0) { + int left = row[0]; + int right = row[2]; + row += 4; + left = fixed2int(left); + right = fixed2int(right + fixed_1 - 1); + rowlen--; + + right -= left; + if (right > 0) { +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 1 0 0 setrgbcolor %%red %%PS\n"); + coord("moveto", int2fixed(left), int2fixed(edgebuffer->base+i)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+i)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+i+1)); + coord("lineto", int2fixed(left), int2fixed(edgebuffer->base+i+1)); + dlprintf("closepath stroke %%PS\n"); +#endif + if (log_op < 0) + code = dev_proc(pdev, fill_rectangle)(pdev, left, edgebuffer->base+i, right, 1, pdevc->colors.pure); + else + code = gx_fill_rectangle_device_rop(left, edgebuffer->base+i, right, 1, pdevc, pdev, (gs_logical_operation_t)log_op); + if (code < 0) + return code; + } + } + + /* The middle section (all but the first and last + * scanlines) can be sent as a trapezoid. */ + if (i + 2 < j) { + gs_fixed_edge le; + gs_fixed_edge re; + fixed ybot = int2fixed(edgebuffer->base+i+1); + fixed ytop = int2fixed(edgebuffer->base+j-1); + int *row3, *row4; + int offset = 1; + row = &edgebuffer->table[edgebuffer->index[i]]; + row2 = &edgebuffer->table[edgebuffer->index[i+1]]; + row3 = &edgebuffer->table[edgebuffer->index[j-2]]; + row4 = &edgebuffer->table[edgebuffer->index[j-1]]; + rowlen = *row; + while (rowlen > 0) { + /* The fill rules used by fill_trap state that if a + * pixel centre is touched by a boundary, the pixel + * will be filled iff the boundary is horizontal and + * the filled region is above it, or the boundary is + * not horizontal, and the filled region is to the + * right of it. + * + * We need to fill "any part of a pixel", not just + * "centre covered", so we need to adjust our edges + * by half a pixel in both X and Y. + * + * X is relatively easy. We move the left edge back by + * just less than half, so ...00 goes to ...81 and + * therefore does not cause an extra pixel to get filled. + * + * Similarly, we move the right edge forward by half, so + * ...00 goes to ...80 and therefore does not cause an + * extra pixel to get filled. + * + * For y, we can adjust edges up or down as appropriate. + * We move up by half, so ...0 goes to ..80 and therefore + * does not cause an extra pixel to get filled. We move + * down by just less than a half so that ...0 goes to + * ...81 and therefore does not cause an extra pixel to + * get filled. + * + * We use ybot = ...80 and ytop = ...81 in the trap call + * so that it just covers the pixel centres. + */ + if (row[offset] <= row4[offset]) { + le.start.x = row2[offset] - (fixed_half-1); + le.end.x = row4[offset] - (fixed_half-1); + le.start.y = ybot + fixed_half; + le.end.y = ytop + fixed_half; + } else { + le.start.x = row [offset] - (fixed_half-1); + le.end.x = row3[offset] - (fixed_half-1); + le.start.y = ybot - (fixed_half-1); + le.end.y = ytop - (fixed_half-1); + } + if (row[offset+2] <= row4[offset+2]) { + re.start.x = row [offset+2] + fixed_half; + re.end.x = row3[offset+2] + fixed_half; + re.start.y = ybot - (fixed_half-1); + re.end.y = ytop - (fixed_half-1); + } else { + re.start.x = row2[offset+2] + fixed_half; + re.end.x = row4[offset+2] + fixed_half; + re.start.y = ybot + fixed_half; + re.end.y = ytop + fixed_half; + } + offset += 4; + rowlen--; + + assert(re.start.x >= le.start.x); + assert(re.end.x >= le.end.x); + assert(le.start.y <= ybot + fixed_half); + assert(re.start.y <= ybot + fixed_half); + assert(le.end.y >= ytop - (fixed_half - 1)); + assert(re.end.y >= ytop - (fixed_half - 1)); + +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 0 1 0 setrgbcolor %% green %%PS\n"); + coord("moveto", le.start.x, le.start.y); + coord("lineto", le.end.x, le.end.y); + coord("lineto", re.end.x, re.end.y); + coord("lineto", re.start.x, re.start.y); + dlprintf("closepath stroke %%PS\n"); +#endif + code = dev_proc(pdev, fill_trapezoid)( + pdev, + &le, + &re, + ybot + fixed_half, + ytop - (fixed_half - 1), + 0, /* bool swap_axes */ + pdevc, /*const gx_drawing_color *pdcolor */ + log_op); + if (code < 0) + return code; + } + } + + if (i + 1 < j) + { + /* The last scanline is always sent as rectangles */ + row = &edgebuffer->table[edgebuffer->index[j-1]]; + rowlen = *row++; + while (rowlen > 0) { + int left = row[0]; + int right = row[2]; + row += 4; + left = fixed2int(left); + right = fixed2int(right + fixed_1 - 1); + rowlen--; + + right -= left; + if (right > 0) { +#ifdef DEBUG_OUTPUT_SC_AS_PS + dlprintf("0.001 setlinewidth 0 0 1 setrgbcolor %% blue %%PS\n"); + coord("moveto", int2fixed(left), int2fixed(edgebuffer->base+j-1)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+j-1)); + coord("lineto", int2fixed(left+right), int2fixed(edgebuffer->base+j)); + coord("lineto", int2fixed(left), int2fixed(edgebuffer->base+j)); + dlprintf("closepath stroke %%PS\n"); +#endif + if (log_op < 0) + code = dev_proc(pdev, fill_rectangle)(pdev, left, edgebuffer->base+j-1, right, 1, pdevc->colors.pure); + else + code = gx_fill_rectangle_device_rop(left, edgebuffer->base+j-1, right, 1, pdevc, pdev, (gs_logical_operation_t)log_op); + if (code < 0) + return code; + } + } + } + i = j; + } + return 0; +} + + +void +gx_edgebuffer_init(gx_edgebuffer * edgebuffer) +{ + edgebuffer->base = 0; + edgebuffer->height = 0; + edgebuffer->index = NULL; + edgebuffer->table = NULL; +} + +void +gx_edgebuffer_fin(gx_device * pdev, + gx_edgebuffer * edgebuffer) +{ + gs_free_object(pdev->memory, edgebuffer->table, "scanc intersects buffer"); + gs_free_object(pdev->memory, edgebuffer->index, "scanc index buffer"); + edgebuffer->index = NULL; + edgebuffer->table = NULL; +} diff -Nru ghostscript-9.10~dfsg/base/gxscanc.h ghostscript-9.25~dfsg+1/base/gxscanc.h --- ghostscript-9.10~dfsg/base/gxscanc.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxscanc.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,127 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* $Id: gxpath.h 8022 2007-06-05 22:23:38Z giles $ */ +/* Fixed-point path procedures */ +/* Requires gxfixed.h */ + +#ifndef gxscanc_INCLUDED +# define gxscanc_INCLUDED + +#include "gxpath.h" +#include "gxdevice.h" + +/* The routines and types in this interface use */ +/* device, rather than user, coordinates, and fixed-point, */ +/* rather than floating, representation. */ + +#ifndef inline +#define inline __inline +#endif /* inline */ + +/* Opaque type for an edgebuffer */ +typedef struct gx_edgebuffer_s gx_edgebuffer; + +struct gx_edgebuffer_s { + int base; + int height; + int xmin; + int xmax; + int *index; + int *table; +}; + +/* "Pixel centre" scanline routines */ +int +gx_scan_convert(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict rect, + gx_edgebuffer * gs_restrict edgebuffer, + fixed flatness); + +int +gx_filter_edgebuffer(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule); + +int +gx_fill_edgebuffer(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op); + +/* "Any Part of a Pixel" (app) scanline routines */ +int +gx_scan_convert_app(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict rect, + gx_edgebuffer * gs_restrict edgebuffer, + fixed flatness); + +int +gx_filter_edgebuffer_app(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule); + +int +gx_fill_edgebuffer_app(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op); + +/* "Pixel centre" trapezoid routines */ +int +gx_scan_convert_tr(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict rect, + gx_edgebuffer * gs_restrict edgebuffer, + fixed flatness); + +int +gx_filter_edgebuffer_tr(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule); + +int +gx_fill_edgebuffer_tr(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op); + +/* "Any Part of a Pixel" (app) trapezoid routines */ +int +gx_scan_convert_tr_app(gx_device * gs_restrict pdev, + gx_path * gs_restrict path, + const gs_fixed_rect * gs_restrict rect, + gx_edgebuffer * gs_restrict edgebuffer, + fixed flatness); + +int +gx_filter_edgebuffer_tr_app(gx_device * gs_restrict pdev, + gx_edgebuffer * gs_restrict edgebuffer, + int rule); + +int +gx_fill_edgebuffer_tr_app(gx_device * gs_restrict pdev, + const gx_device_color * gs_restrict pdevc, + gx_edgebuffer * gs_restrict edgebuffer, + int log_op); + +/* Equivalent to filling it full of 0's */ +void gx_edgebuffer_init(gx_edgebuffer * edgebuffer); + +void gx_edgebuffer_fin(gx_device * pdev, + gx_edgebuffer * edgebuffer); + + +#endif /* gxscanc_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxshade1.c ghostscript-9.25~dfsg+1/base/gxshade1.c --- ghostscript-9.10~dfsg/base/gxshade1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxshade1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,18 +27,13 @@ #include "gxdcolor.h" #include "gxfarith.h" #include "gxfixed.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxpath.h" #include "gxshade.h" #include "gxdevcli.h" #include "gxshade4.h" -#include "vdtrace.h" #include "gsicc_cache.h" -#define VD_TRACE_AXIAL_PATCH 1 -#define VD_TRACE_RADIAL_PATCH 1 -#define VD_TRACE_FUNCTIONAL_PATCH 1 - /* ---------------- Function-based shading ---------------- */ typedef struct Fb_frame_s { /* A rudiment of old code. */ @@ -73,7 +68,7 @@ /* Transform a point with a fixed-point result. */ static void gs_point_transform2fixed_clamped(const gs_matrix_fixed * pmat, - floatp x, floatp y, gs_fixed_point * ppt) + double x, double y, gs_fixed_point * ppt) { gs_point fpt; @@ -90,12 +85,6 @@ Fb_frame_t * fp = &pfs->frame; int code; - if (VD_TRACE_FUNCTIONAL_PATCH && vd_allowed('s')) { - vd_get_dc('s'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - } memcpy(&pfs1, (shading_fill_state_t *)pfs, sizeof(shading_fill_state_t)); pfs1.Function = pfs->psh->params.Function; code = init_patch_fill_state(&pfs1); @@ -116,15 +105,13 @@ code = patch_fill(&pfs1, curve, NULL, NULL); if (term_patch_fill_state(&pfs1)) return_error(gs_error_unregistered); /* Must not happen. */ - if (VD_TRACE_FUNCTIONAL_PATCH && vd_allowed('s')) - vd_release_dc; return code; } int gs_shading_Fb_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_shading_Fb_t * const psh = (const gs_shading_Fb_t *)psh0; gs_matrix save_ctm; @@ -132,15 +119,15 @@ float x[2], y[2]; Fb_fill_state_t state; - code = shade_init_fill_state((shading_fill_state_t *) & state, psh0, dev, pis); + code = shade_init_fill_state((shading_fill_state_t *) & state, psh0, dev, pgs); if (code < 0) return code; state.psh = psh; /****** HACK FOR FIXED-POINT MATRIX MULTIPLY ******/ - gs_currentmatrix((gs_state *) pis, &save_ctm); - gs_concat((gs_state *) pis, &psh->params.Matrix); - state.ptm = pis->ctm; - gs_setmatrix((gs_state *) pis, &save_ctm); + gs_currentmatrix((gs_gstate *) pgs, &save_ctm); + gs_concat((gs_gstate *) pgs, &psh->params.Matrix); + state.ptm = pgs->ctm; + gs_setmatrix((gs_gstate *) pgs, &save_ctm); /* Compute the parameter X and Y ranges. */ { gs_rect pbox; @@ -196,11 +183,20 @@ double y1 = psh->params.Coords[1] + pfs->delta.y * pfs->v1; double h0 = pfs->u0, h1 = pfs->u1; patch_curve_t curve[4]; + int code; - gs_point_transform2fixed(&pfs1->pis->ctm, x0 + pfs->delta.y * h0, y0 - pfs->delta.x * h0, &curve[0].vertex.p); - gs_point_transform2fixed(&pfs1->pis->ctm, x1 + pfs->delta.y * h0, y1 - pfs->delta.x * h0, &curve[1].vertex.p); - gs_point_transform2fixed(&pfs1->pis->ctm, x1 + pfs->delta.y * h1, y1 - pfs->delta.x * h1, &curve[2].vertex.p); - gs_point_transform2fixed(&pfs1->pis->ctm, x0 + pfs->delta.y * h1, y0 - pfs->delta.x * h1, &curve[3].vertex.p); + code = gs_point_transform2fixed(&pfs1->pgs->ctm, x0 + pfs->delta.y * h0, y0 - pfs->delta.x * h0, &curve[0].vertex.p); + if (code < 0) + return code; + code = gs_point_transform2fixed(&pfs1->pgs->ctm, x1 + pfs->delta.y * h0, y1 - pfs->delta.x * h0, &curve[1].vertex.p); + if (code < 0) + return code; + code = gs_point_transform2fixed(&pfs1->pgs->ctm, x1 + pfs->delta.y * h1, y1 - pfs->delta.x * h1, &curve[2].vertex.p); + if (code < 0) + return code; + code = gs_point_transform2fixed(&pfs1->pgs->ctm, x0 + pfs->delta.y * h1, y0 - pfs->delta.x * h1, &curve[3].vertex.p); + if (code < 0) + return code; curve[0].vertex.cc[0] = pfs->t0; /* The element cc[1] is set to a dummy value against */ curve[1].vertex.cc[0] = pfs->t1; /* interrupts while an idle priocessing in gxshade.6.c . */ curve[2].vertex.cc[0] = pfs->t1; @@ -216,7 +212,7 @@ static inline int gs_shading_A_fill_rectangle_aux(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect *clip_rect, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_shading_A_t *const psh = (const gs_shading_A_t *)psh0; gs_function_t * const pfn = psh->params.Function; @@ -231,7 +227,7 @@ int code; state.psh = psh; - code = shade_init_fill_state((shading_fill_state_t *)&pfs1, psh0, dev, pis); + code = shade_init_fill_state((shading_fill_state_t *)&pfs1, psh0, dev, pgs); if (code < 0) return code; pfs1.Function = pfn; @@ -265,7 +261,7 @@ state.u1 = t_rect.q.x; state.t0 = t0 * dd + d0; state.t1 = t1 * dd + d0; - gs_distance_transform(state.delta.x, state.delta.y, &ctm_only(pis), + gs_distance_transform(state.delta.x, state.delta.y, &ctm_only(pgs), &dist); state.length = hypot(dist.x, dist.y); /* device space line length */ code = A_fill_region(&state, &pfs1); @@ -300,20 +296,9 @@ int gs_shading_A_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { - int code; - - if (VD_TRACE_AXIAL_PATCH && vd_allowed('s')) { - vd_get_dc('s'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - } - code = gs_shading_A_fill_rectangle_aux(psh0, rect, rect_clip, dev, pis); - if (VD_TRACE_AXIAL_PATCH && vd_allowed('s')) - vd_release_dc; - return code; + return gs_shading_A_fill_rectangle_aux(psh0, rect, rect_clip, dev, pgs); } /* ---------------- Radial shading ---------------- */ @@ -352,7 +337,7 @@ * quadrant and moving anticlockwise, we now draw the 'undermost' quadrant, * then the two adjacent quadrants, then the topmost quadrant. * - * For the purposes of explaination, we shall label the octants as below: + * For the purposes of explanation, we shall label the octants as below: * * \2|1/ and Quadrants as: | * 3\|/0 Q1 | Q0 @@ -391,6 +376,7 @@ p0.x = 0, p0.y = -1, dirn = 0; /* Align stripes along radii for faster triangulation : */ inside = 1; + pfs->function_arg_shift = 1; } else { /* Must generate canonic quadrangle arcs, because we approximate them with curves. */ @@ -405,6 +391,7 @@ else p0.x = -1, p0.y = 0, dirn = (-dx >= -dy ? 0 : 1); } + pfs->function_arg_shift = 0; } /* fixme: wish: cut invisible parts off. Note : when r0 != r1 the invisible part is not a half circle. */ @@ -432,14 +419,14 @@ for (j = 0; j < 4; j++) { int jj = (j + inside) % 4; - if (gs_point_transform2fixed(&pfs->pis->ctm, p[j*3 + 0].x, p[j*3 + 0].y, &curve[jj].vertex.p) < 0) - gs_point_transform2fixed_clamped(&pfs->pis->ctm, p[j*3 + 0].x, p[j*3 + 0].y, &curve[jj].vertex.p); + if (gs_point_transform2fixed(&pfs->pgs->ctm, p[j*3 + 0].x, p[j*3 + 0].y, &curve[jj].vertex.p) < 0) + gs_point_transform2fixed_clamped(&pfs->pgs->ctm, p[j*3 + 0].x, p[j*3 + 0].y, &curve[jj].vertex.p); - if (gs_point_transform2fixed(&pfs->pis->ctm, p[j*3 + 1].x, p[j*3 + 1].y, &curve[jj].control[0]) < 0) - gs_point_transform2fixed_clamped(&pfs->pis->ctm, p[j*3 + 1].x, p[j*3 + 1].y, &curve[jj].control[0]); + if (gs_point_transform2fixed(&pfs->pgs->ctm, p[j*3 + 1].x, p[j*3 + 1].y, &curve[jj].control[0]) < 0) + gs_point_transform2fixed_clamped(&pfs->pgs->ctm, p[j*3 + 1].x, p[j*3 + 1].y, &curve[jj].control[0]); - if (gs_point_transform2fixed(&pfs->pis->ctm, p[j*3 + 2].x, p[j*3 + 2].y, &curve[jj].control[1]) < 0) - gs_point_transform2fixed_clamped(&pfs->pis->ctm, p[j*3 + 2].x, p[j*3 + 2].y, &curve[jj].control[1]); + if (gs_point_transform2fixed(&pfs->pgs->ctm, p[j*3 + 2].x, p[j*3 + 2].y, &curve[jj].control[1]) < 0) + gs_point_transform2fixed_clamped(&pfs->pgs->ctm, p[j*3 + 2].x, p[j*3 + 2].y, &curve[jj].control[1]); curve[j].straight = (((j + inside) & 1) != 0); } curve[(0 + inside) % 4].vertex.cc[0] = t0; @@ -471,6 +458,915 @@ return 0; } +/* Find the control points for two points on the arc of a circle + * the points must be within the same quadrant. + */ +static int find_arc_control_points(gs_point *from, gs_point *to, gs_point *from_control, gs_point *to_control, gs_point *centre) +{ + double from_tan_alpha, to_tan_alpha, from_alpha, to_alpha; + double half_inscribed_angle, intersect_x, intersect_y, intersect_dist; + double radius = sqrt(((from->x - centre->x) * (from->x - centre->x)) + ((from->y - centre->y) * (from->y - centre->y))); + double tangent_intersect_dist; + double F; + int quadrant; + + /* Quadrant 0 is upper right, numbered anti-clockwise. + * If the direction of the from->to is atni-clockwise, add 4 + */ + if (from->x > to->x) { + if (from->y > to->y) { + if (to->y >= centre->y) + quadrant = 1 + 4; + else + quadrant = 3; + } else { + if (to->x >= centre->x) + quadrant = 0 + 4; + else + quadrant = 2; + } + } else { + if (from->y > to->y) { + if (from->x >= centre->x) + quadrant = 0; + else + quadrant = 2 + 4; + } else { + if (from->x >= centre->x) + quadrant = 3 + 4; + else + quadrant = 1; + } + } + + switch(quadrant) { + /* quadrant 0, arc goes clockwise */ + case 0: + if (from->x == centre->x) { + from_alpha = M_PI / 2; + } else { + from_tan_alpha = (from->y - centre->y) / (from->x - centre->x); + from_alpha = atan(from_tan_alpha); + } + to_tan_alpha = (to->y - centre->y) / (to->x - centre->x); + to_alpha = atan(to_tan_alpha); + + half_inscribed_angle = (from_alpha - to_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x + cos(to_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y + sin(to_alpha + half_inscribed_angle) * intersect_dist; + break; + /* quadrant 1, arc goes clockwise */ + case 1: + from_tan_alpha = (from->y - centre->y) / (centre->x - from->x); + from_alpha = atan(from_tan_alpha); + + if (to->x == centre->x) { + to_alpha = M_PI / 2; + } else { + to_tan_alpha = (to->y - centre->y) / (centre->x - to->x); + to_alpha = atan(to_tan_alpha); + } + + half_inscribed_angle = (to_alpha - from_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x - cos(from_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y + sin(from_alpha + half_inscribed_angle) * intersect_dist; + break; + /* quadrant 2, arc goes clockwise */ + case 2: + if (from->x == centre->x) { + from_alpha = M_PI / 2; + } else { + from_tan_alpha = (centre->y - from->y) / (centre->x - from->x); + from_alpha = atan(from_tan_alpha); + } + + to_tan_alpha = (centre->y - to->y) / (centre->x - to->x); + to_alpha = atan(to_tan_alpha); + + half_inscribed_angle = (to_alpha - from_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x - cos(from_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y - sin(from_alpha + half_inscribed_angle) * intersect_dist; + break; + /* quadrant 3, arc goes clockwise */ + case 3: + from_tan_alpha = (centre->y - from->y) / (from->x - centre->x); + from_alpha = atan(from_tan_alpha); + + if (to->x == centre->x) { + to_alpha = M_PI / 2; + } else { + to_tan_alpha = (centre->y - to->y) / (to->x - centre->x); + to_alpha = atan(to_tan_alpha); + } + + half_inscribed_angle = (to_alpha - from_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x + cos(from_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y - sin(from_alpha + half_inscribed_angle) * intersect_dist; + break; + /* quadrant 0, arc goes anti-clockwise */ + case 4: + from_tan_alpha = (from->y - centre->y) / (from->x - centre->x); + from_alpha = atan(from_tan_alpha); + + if (to->y == centre->y) + to_alpha = M_PI / 2; + else { + to_tan_alpha = (to->y - centre->y) / (to->x - centre->x); + to_alpha = atan(to_tan_alpha); + } + + half_inscribed_angle = (to_alpha - from_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x + cos(from_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y + sin(from_alpha + half_inscribed_angle) * intersect_dist; + break; + /* quadrant 1, arc goes anti-clockwise */ + case 5: + from_tan_alpha = (centre->x - from->x) / (from->y - centre->y); + from_alpha = atan(from_tan_alpha); + + if (to->y == centre->y) { + to_alpha = M_PI / 2; + } + else { + to_tan_alpha = (centre->x - to->x) / (to->y - centre->y); + to_alpha = atan(to_tan_alpha); + } + + half_inscribed_angle = (to_alpha - from_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x - sin(from_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y + cos(from_alpha + half_inscribed_angle) * intersect_dist; + break; + /* quadrant 2, arc goes anti-clockwise */ + case 6: + from_tan_alpha = (from->y - centre->y) / (centre->x - from->x); + from_alpha = atan(from_tan_alpha); + + if (to->x == centre->x) { + to_alpha = M_PI / 2; + } else { + to_tan_alpha = (centre->y - to->y) / (centre->x - to->x); + to_alpha = atan(to_tan_alpha); + } + + half_inscribed_angle = (to_alpha - from_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x - cos(from_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y - sin(from_alpha + half_inscribed_angle) * intersect_dist; + break; + /* quadrant 3, arc goes anti-clockwise */ + case 7: + if (from->x == centre->x) { + from_alpha = M_PI / 2; + } else { + from_tan_alpha = (centre->y - from->y) / (from->x - centre->x); + from_alpha = atan(from_tan_alpha); + } + to_tan_alpha = (centre->y - to->y) / (to->x - centre->x); + to_alpha = atan(to_tan_alpha); + + half_inscribed_angle = (from_alpha - to_alpha) / 2; + intersect_dist = radius / cos(half_inscribed_angle); + tangent_intersect_dist = tan(half_inscribed_angle) * radius; + + intersect_x = centre->x + cos(to_alpha + half_inscribed_angle) * intersect_dist; + intersect_y = centre->y - sin(to_alpha + half_inscribed_angle) * intersect_dist; + break; + } + + F = (4.0 / 3.0) / (1 + sqrt(1 + ((tangent_intersect_dist / radius) * (tangent_intersect_dist / radius)))); + + from_control->x = from->x - ((from->x - intersect_x) * F); + from_control->y = from->y - ((from->y - intersect_y) * F); + to_control->x = to->x - ((to->x - intersect_x) * F); + to_control->y = to->y - ((to->y - intersect_y) * F); + + return 0; +} + +/* Create a 'patch_curve' element whch is a straight line between two points */ +static int patch_lineto(gs_matrix_fixed *ctm, gs_point *from, gs_point *to, patch_curve_t *p, float t) +{ + double x_1third, x_2third, y_1third, y_2third; + + x_1third = (to->x - from->x) / 3; + x_2third = x_1third * 2; + y_1third = (to->y - from->y) / 3; + y_2third = y_1third * 2; + + gs_point_transform2fixed(ctm, from->x, from->y, &p->vertex.p); + gs_point_transform2fixed(ctm, from->x + x_1third, from->y + y_1third, &p->control[0]); + gs_point_transform2fixed(ctm, from->x + x_2third, from->y + y_2third, &p->control[1]); + + p->vertex.cc[0] = t; + p->vertex.cc[1] = t; + p->straight = 1; + + return 0; +} + +static int patch_curveto(gs_matrix_fixed *ctm, gs_point *centre, gs_point *from, gs_point *to, patch_curve_t *p, float t) +{ + gs_point from_control, to_control; + + find_arc_control_points(from, to, &from_control, &to_control, centre); + + gs_point_transform2fixed(ctm, from->x, from->y, &p->vertex.p); + gs_point_transform2fixed(ctm, from_control.x, from_control.y, &p->control[0]); + gs_point_transform2fixed(ctm, to_control.x, to_control.y, &p->control[1]); + p->vertex.cc[0] = t; + p->vertex.cc[1] = t; + p->straight = 0; + + return 0; +} + +static int draw_quarter_annulus(patch_fill_state_t *pfs, gs_point *centre, double radius, gs_point *corner, float t) +{ + gs_point p0, p1, initial; + patch_curve_t p[4]; + int code; + + if (corner->x > centre->x) { + initial.x = centre->x + radius; + } + else { + initial.x = centre->x - radius; + } + initial.y = centre->y; + + p1.x = initial.x; + p1.y = corner->y; + patch_lineto(&pfs->pgs->ctm, &initial, &p1, &p[0], t); + p0.x = centre->x; + p0.y = p1.y; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &p[1], t); + p1.x = centre->x; + if (centre->y > corner->y) { + p1.y = centre->y - radius; + } else { + p1.y = centre->y + radius; + } + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &p[2], t); + patch_curveto(&pfs->pgs->ctm, centre, &p1, &initial, &p[3], t); + code = patch_fill(pfs, (const patch_curve_t *)&p, NULL, NULL); + if (code < 0) + return code; + + if (corner->x > centre->x) + initial.x = corner->x - (corner->x - (centre->x + radius)); + else + initial.x = centre->x - radius; + initial.y = corner->y; + patch_lineto(&pfs->pgs->ctm, corner, &initial, &p[0], t); + + p0.x = initial.x; + p0.y = centre->y; + patch_lineto(&pfs->pgs->ctm, &initial, &p0, &p[1], t); + + p1.y = p0.y; + p1.x = corner->x; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &p[2], t); + patch_lineto(&pfs->pgs->ctm, &p1, corner, &p[3], t); + + return (patch_fill(pfs, (const patch_curve_t *)&p, NULL, NULL)); +} + +static int R_tensor_annulus_extend_tangent(patch_fill_state_t *pfs, + double x0, double y0, double r0, double t0, + double x1, double y1, double r1, double t1, double r2) +{ + patch_curve_t curve[4]; + gs_point p0, p1; + int code = 0, q = 0; + + /* special case axis aligned circles. Its quicker to handle these specially as it + * avoid lots of trigonometry in the general case code, and avoids us + * having to watch out for infinity as the result of tan() operations. + */ + if (x0 == x1 || y0 == y1) { + if (x0 == x1 && y0 > y1) { + /* tangent at top of circles */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 - r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 + r2, p1.y = y1 + r1; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 - r2, p1.y = y1 + r1; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + if (x0 == x1 && y0 < y1) { + /* tangent at bottom of circles */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 - r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 + r2, p1.y = y1 - r1; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 - r2, p1.y = y1 - r1; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + if (y0 == y1 && x0 > x1) { + /* tangent at right of circles */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 - r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 + r1, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 + r1, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + if (y0 == y1 && x0 < x1) { + /* tangent at left of circles */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 + r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 - r1, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p1.x = x1 - r1, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + } + else { + double tx, ty, endx, endy, intersectx, intersecty, alpha, sinalpha, cosalpha, tanalpha; + gs_point centre; + + /* First lets figure out which quadrant the smaller circle is in (we always + * get called to fill from the larger circle), x0, y0, r0 is the smaller circle. + */ + if (x0 < x1) { + if (y0 < y1) + q = 2; + else + q = 1; + } else { + if (y0 < y1) + q = 3; + else + q = 0; + } + switch(q) { + case 0: + /* We have two four-sided elements, from the tangent point + * each side, to the point where the tangent crosses an + * axis of the larger circle. A line back to the edge + * of the larger circle, a line to the point where an axis + * crosses the smaller circle, then an arc back to the starting point. + */ + /* Figure out the tangent point */ + /* sin (angle) = y1 - y0 / r1 - r0 + * ty = ((y1 - y0) / (r1 - r0)) * r1 + */ + ty = y1 + ((y0 - y1) / (r1 - r0)) * r1; + tx = x1 + ((x0 - x1) / (r1 - r0)) * r1; + /* Now actually calculating the point where the tangent crosses the axis of the larger circle + * So we need to know the angle the tangent makes with the axis of the smaller circle + * as its the same angle where it crosses the axis of the larger circle. + * We know the centres and the tangent are co-linear, so sin(a) = y0 - y1 / r1 - r0 + * We know the tangent is r1 from the centre of the larger circle, so the hypotenuse + * is r0 / cos(a). That gives us 'x' and we already know y as its the centre of the larger + * circle + */ + sinalpha = (y0 - y1) / (r1 - r0); + alpha = asin(sinalpha); + cosalpha = cos(alpha); + intersectx = x1 + (r1 / cosalpha); + intersecty = y1; + + p0.x = tx, p0.y = ty; + p1.x = tx + (intersectx - tx) / 2, p1.y = ty - (ty - intersecty) / 2; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = intersectx, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1 + r1, p1.y = y1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + if (intersectx < x1 + r2) { + /* didn't get all the way to the edge, quadrant 3 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = intersectx, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + endx = x1 + r2; + endy = y1 - (tan ((M_PI / 2) - alpha)) * (endx - intersectx); + p0.x = intersectx, p0.y = y1; + p1.x = x1 + r2, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 + r2, p0.y = y0 - r2; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = intersectx, p1.y = p0.y; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = intersectx, p0.y = y1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + } else { + /* Quadrant 3 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + + /* Q2 is always a full annulus... */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + + /* alpha is now the angle between the x axis and the tangent to the + * circles. + */ + alpha = (M_PI / 2) - alpha; + cosalpha = cos(alpha); + endy = y1 + (r1 / cosalpha); + endx = x1; + + p0.x = tx, p0.y = ty; + p1.x = endx - ((endx - tx) / 2), p1.y = endy - ((endy - ty) / 2); + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = endx, p0.y = endy; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1, p1.y = y1 + r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + /* Q1 is simimlar to Q3, either a full quarter annulus + * or a partial one, depending on where the tangent crosses + * the y axis + */ + tanalpha = tan(alpha); + intersecty = y1 + tanalpha * (r2 + (intersectx - x1)); + intersectx = x1 - r2; + + if (endy < y1 + r2) { + /* didn't get all the way to the edge, quadrant 1 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = endy; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p0.x = x1, p0.y = y1 + r1; + p1.x = x1, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 - r2, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = p0.x, p1.y = y1 + r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = x1, p0.y = y1 + r1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + } else { + /* Quadrant 1 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + break; + case 1: + /* We have two four-sided elements, from the tangent point + * each side, to the point where the tangent crosses an + * axis of the larger circle. A line back to the edge + * of the larger circle, a line to the point where an axis + * crosses the smaller circle, then an arc back to the starting point. + */ + /* Figure out the tangent point */ + /* sin (angle) = y1 - y0 / r1 - r0 + * ty = ((y1 - y0) / (r1 - r0)) * r1 + */ + ty = y1 + ((y0 - y1) / (r1 - r0)) * r1; + tx = x1 - ((x1 - x0) / (r1 - r0)) * r1; + /* Now actually calculating the point where the tangent crosses the axis of the larger circle + * So we need to know the angle the tangent makes with the axis of the smaller circle + * as its the same angle where it crosses the axis of the larger circle. + * We know the centres and the tangent are co-linear, so sin(a) = y0 - y1 / r1 - r0 + * We know the tangent is r1 from the centre of the larger circle, so the hypotenuse + * is r0 / cos(a). That gives us 'x' and we already know y as its the centre of the larger + * circle + */ + sinalpha = (y0 - y1) / (r1 - r0); + alpha = asin(sinalpha); + cosalpha = cos(alpha); + intersectx = x1 - (r1 / cosalpha); + intersecty = y1; + + p0.x = tx, p0.y = ty; + p1.x = tx - (tx - intersectx) / 2, p1.y = ty - (ty - intersecty) / 2; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = intersectx, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1 - r1, p1.y = y1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + if (intersectx > x1 - r2) { + /* didn't get all the way to the edge, quadrant 2 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = intersectx, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + endx = x1 - r2; + endy = y1 - (tan ((M_PI / 2) - alpha)) * (intersectx - endx); + p0.x = intersectx, p0.y = y1; + p1.x = x1 - r2, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 - r2, p0.y = y0 - r2; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = intersectx, p1.y = p0.y; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = intersectx, p0.y = y1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + } else { + /* Quadrant 2 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + + /* Q3 is always a full annulus... */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + + /* alpha is now the angle between the x axis and the tangent to the + * circles. + */ + alpha = (M_PI / 2) - alpha; + cosalpha = cos(alpha); + endy = y1 + (r1 / cosalpha); + endx = x1; + + p0.x = tx, p0.y = ty; + p1.x = endx + ((tx - endx) / 2), p1.y = endy - ((endy - ty) / 2); + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = endx, p0.y = endy; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1, p1.y = y1 + r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + /* Q0 is simimlar to Q2, either a full quarter annulus + * or a partial one, depending on where the tangent crosses + * the y axis + */ + tanalpha = tan(alpha); + intersecty = y1 + tanalpha * (r2 + (x1 - intersectx)); + intersectx = x1 + r2; + + if (endy < y1 + r2) { + /* didn't get all the way to the edge, quadrant 0 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = endy; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p0.x = x1, p0.y = y1 + r1; + p1.x = x1, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 + r2, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = p0.x, p1.y = y1 + r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = x1, p0.y = y1 + r1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + } else { + /* Quadrant 0 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + break; + case 2: + /* We have two four-sided elements, from the tangent point + * each side, to the point where the tangent crosses an + * axis of the larger circle. A line back to the edge + * of the larger circle, a line to the point where an axis + * crosses the smaller circle, then an arc back to the starting point. + */ + /* Figure out the tangent point */ + /* sin (angle) = y1 - y0 / r1 - r0 + * ty = ((y1 - y0) / (r1 - r0)) * r1 + */ + ty = y1 - ((y1 - y0) / (r1 - r0)) * r1; + tx = x1 - ((x1 - x0) / (r1 - r0)) * r1; + /* Now actually calculating the point where the tangent crosses the axis of the larger circle + * So we need to know the angle the tangent makes with the axis of the smaller circle + * as its the same angle where it crosses the axis of the larger circle. + * We know the centres and the tangent are co-linear, so sin(a) = y0 - y1 / r1 - r0 + * We know the tangent is r1 from the centre of the larger circle, so the hypotenuse + * is r0 / cos(a). That gives us 'x' and we already know y as its the centre of the larger + * circle + */ + sinalpha = (y1 - y0) / (r1 - r0); + alpha = asin(sinalpha); + cosalpha = cos(alpha); + intersectx = x1 - (r1 / cosalpha); + intersecty = y1; + + p0.x = tx, p0.y = ty; + p1.x = tx + (intersectx - tx) / 2, p1.y = ty - (ty - intersecty) / 2; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = intersectx, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1 - r1, p1.y = y1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + if (intersectx > x1 - r2) { + /* didn't get all the way to the edge, quadrant 1 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = intersectx, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + endy = y1+r2; + endx = intersectx - ((endy - intersecty) / (tan ((M_PI / 2) - alpha))); + p0.x = intersectx, p0.y = y1; + p1.x = endx, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 - r1, p0.y = endy; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1 - r1, p1.y = y1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = intersectx, p0.y = y1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + } else { + /* Quadrant 1 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + + /* Q0 is always a full annulus... */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 + r2; + if (p1.y < 0) + p1.y = 0; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + + /* alpha is now the angle between the x axis and the tangent to the + * circles. + */ + alpha = (M_PI / 2) - alpha; + cosalpha = cos(alpha); + endy = y1 - (r1 / cosalpha); + endx = x1; + + p0.x = tx, p0.y = ty; + p1.x = endx + ((endx - tx) / 2), p1.y = endy - ((ty - endy) / 2); + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = endx, p0.y = endy; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1, p1.y = y1 - r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + /* Q3 is simimlar to Q1, either a full quarter annulus + * or a partial one, depending on where the tangent crosses + * the y axis + */ + tanalpha = tan(alpha); + intersecty = y1 - tanalpha * (r2 + (x1 - intersectx)); + intersectx = x1 + r2; + + if (endy > y1 - r2) { + /* didn't get all the way to the edge, quadrant 3 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = endy; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p0.x = x1, p0.y = y1 - r1; + p1.x = x1, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 + r2, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = p0.x, p1.y = y1 - r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = x1, p0.y = y1 - r1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + } else { + /* Quadrant 1 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + break; + case 3: + /* We have two four-sided elements, from the tangent point + * each side, to the point where the tangent crosses an + * axis of the larger circle. A line back to the edge + * of the larger circle, a line to the point where an axis + * crosses the smaller circle, then an arc back to the starting point. + */ + /* Figure out the tangent point */ + /* sin (angle) = y1 - y0 / r1 - r0 + * ty = ((y1 - y0) / (r1 - r0)) * r1 + */ + ty = y1 - ((y1 - y0) / (r1 - r0)) * r1; + tx = x1 + ((x0 - x1) / (r1 - r0)) * r1; + /* Now actually calculating the point where the tangent crosses the axis of the larger circle + * So we need to know the angle the tangent makes with the axis of the smaller circle + * as its the same angle where it crosses the axis of the larger circle. + * We know the centres and the tangent are co-linear, so sin(a) = y0 - y1 / r1 - r0 + * We know the tangent is r1 from the centre of the larger circle, so the hypotenuse + * is r0 / cos(a). That gives us 'x' and we already know y as its the centre of the larger + * circle + */ + sinalpha = (y1 - y0) / (r1 - r0); + alpha = asin(sinalpha); + cosalpha = cos(alpha); + intersectx = x1 + (r1 / cosalpha); + intersecty = y1; + + p0.x = tx, p0.y = ty; + p1.x = tx + (intersectx - tx) / 2, p1.y = ty + (intersecty - ty) / 2; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = intersectx, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1 + r1, p1.y = y1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + if (intersectx < x1 + r2) { + /* didn't get all the way to the edge, quadrant 0 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = intersectx, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + endy = y1 + r2; + endx = intersectx + ((endy - intersecty) / (tan ((M_PI / 2) - alpha))); + p0.x = intersectx, p0.y = y1; + p1.x = endx, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 + r1, p0.y = endy; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1 + r1, p1.y = y1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = intersectx, p0.y = y1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + } else { + /* Quadrant 0 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 + r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + /* Q1 is always a full annulus... */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = y1 + r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + + /* alpha is now the angle between the x axis and the tangent to the + * circles. + */ + alpha = (M_PI / 2) - alpha; + cosalpha = cos(alpha); + endy = y1 - (r1 / cosalpha); + endx = x1; + + p0.x = tx, p0.y = ty; + p1.x = endx + ((tx - endx) / 2), p1.y = endy + ((ty - endy) / 2); + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = endx, p0.y = endy; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = x1, p1.y = y1 - r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = tx, p0.y = ty; + centre.x = x1, centre.y = y1; + patch_curveto(&pfs->pgs->ctm, ¢re, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + + /* Q3 is simimlar to Q1, either a full quarter annulus + * or a partial one, depending on where the tangent crosses + * the y axis + */ + tanalpha = tan(alpha); + intersecty = y1 - tanalpha * (r2 + (intersectx - x1)); + intersectx = x1 - r2; + + if (endy > y1 - r2) { + /* didn't get all the way to the edge, quadrant 3 is composed of 2 quads :-( + * An 'annulus' where the right edge is less than the normal extent and a + * quad which is a rectangle with one corner chopped of at an angle. + */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = endy; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + p0.x = x1, p0.y = y1 - r1; + p1.x = x1, p1.y = endy; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[0], t0); + p0.x = x1 - r2, p0.y = intersecty; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[1], t0); + p1.x = p0.x, p1.y = y1 - r1; + patch_lineto(&pfs->pgs->ctm, &p0, &p1, &curve[2], t0); + p0.x = x1, p0.y = y1 - r1; + patch_lineto(&pfs->pgs->ctm, &p1, &p0, &curve[3], t0); + code = patch_fill(pfs, curve, NULL, NULL); + if (code < 0) + return code; + } else { + /* Quadrant 1 is a normal quarter annulua */ + p0.x = x1, p0.y = y1; + p1.x = x1 - r2, p1.y = y1 - r2; + draw_quarter_annulus(pfs, &p0, r1, &p1, t0); + } + break; + } + } + return 0; +} + static int R_outer_circle(patch_fill_state_t *pfs, const gs_rect *rect, double x0, double y0, double r0, @@ -557,11 +1453,11 @@ p0.c = c; p1.c = c; p2.c = c; - code = gs_point_transform2fixed(&pfs->pis->ctm, x0, y0, &p0.p); + code = gs_point_transform2fixed(&pfs->pgs->ctm, x0, y0, &p0.p); if (code >= 0) - code = gs_point_transform2fixed(&pfs->pis->ctm, x1, y1, &p1.p); + code = gs_point_transform2fixed(&pfs->pgs->ctm, x1, y1, &p1.p); if (code >= 0) - code = gs_point_transform2fixed(&pfs->pis->ctm, x2, y2, &p2.p); + code = gs_point_transform2fixed(&pfs->pgs->ctm, x2, y2, &p2.p); if (code >= 0) { c->t[0] = c->t[1] = t; patch_resolve_color(c, pfs); @@ -574,8 +1470,7 @@ static int R_obtuse_cone(patch_fill_state_t *pfs, const gs_rect *rect, double x0, double y0, double r0, - double x1, double y1, double r1, double t0, double r_rect, - bool inwards) + double x1, double y1, double r1, double t0, double r_rect) { double dx = x1 - x0, dy = y1 - y0, dr = any_abs(r1 - r0); double d = hypot(dx, dy); @@ -628,12 +1523,8 @@ code = R_tensor_annulus(pfs, x0, y0, r0, t0, ex, ey, er, t0); if (code < 0) return code; - /* Fill entire ending circle to ensure entire rect is covered, but - * only if we are filling "inwards" (as otherwise we will overwrite - * all the hard work we have done to this point) */ - if (inwards) - code = R_tensor_annulus(pfs, ex, ey, er, t0, ex, ey, 0, t0); - return code; + /* Fill entire ending circle to ensure entire rect is covered. */ + return R_tensor_annulus(pfs, ex, ey, er, t0, ex, ey, 0, t0); } } @@ -700,14 +1591,70 @@ double t0, double t1, bool Extend0, bool Extend1) { float x0 = psh->params.Coords[0], y0 = psh->params.Coords[1]; - floatp r0 = psh->params.Coords[2]; + double r0 = psh->params.Coords[2]; float x1 = psh->params.Coords[3], y1 = psh->params.Coords[4]; - floatp r1 = psh->params.Coords[5]; + double r1 = psh->params.Coords[5]; double dx = x1 - x0, dy = y1 - y0, dr = any_abs(r1 - r0); double d = hypot(dx, dy), r; int code; - if (dr >= d - 1e-7 * (d + dr)) { + /* In order for the circles to be nested, one end circle + * needs to be sufficiently large to cover the entirety + * of the other end circle. i.e. + * + * max(r0,r1) >= d + min(r0,r1) + * === min(r0,r1) + dr >= d + min(r0,r1) + * === dr >= d + * + * This, plus a fudge factor for FP operation is what we use below. + * + * An "Obtuse Cone" is defined to be one for which the "opening + * angle" is obtuse. + * + * Consider two circles; one at (r0,r0) of radius r0, and one at + * (r1,r1) of radius r1. These clearly lie on the acute/obtuse + * boundary. The distance between the centres of these two circles + * is d = sqr(2.(r0-r1)^2) by pythagoras. Thus d = sqr(2).dr. + * By observation if d gets longer, we become acute, shorter, obtuse. + * i.e. if sqr(2).dr > d we are obtuse, if d > sqr(2).dr we are acute. + * (Thanks to Paul Gardiner for this reasoning). + * + * The code below tests (dr > d/3) (i.e. 3.dr > d). This + * appears to be a factor of 2 and a bit out, so I am confused + * by it. + * + * Either Igor meant something different to the standard meaning + * of "Obtuse Cone", or he got his maths wrong. Or he was more + * cunning than I can understand. Leave it as it until we find + * an actual example that goes wrong. + */ + + /* Tests with Acrobat seem to indicate that it uses a fudge factor + * of around .0001. (i.e. [1.0001 0 0 0 0 1] is accepted as a + * non nested circle, but [1.00009 0 0 0 0 1] is a nested one. + * Approximate the same sort of value here to appease bug 690831. + */ + if (any_abs (dr - d) < 0.001) { + if ((r0 > r1 && Extend0) || (r1 > r0 && Extend1)) { + r = R_rect_radius(rect, x0, y0); + if (r0 < r1) + code = R_tensor_annulus_extend_tangent(pfs, x0, y0, r0, t1, x1, y1, r1, t1, r); + else + code = R_tensor_annulus_extend_tangent(pfs, x1, y1, r1, t0, x0, y0, r0, t0, r); + if (code < 0) + return code; + } else { + if (r0 > r1) { + if (Extend1 && r1 > 0) + return R_tensor_annulus(pfs, x1, y1, r1, t1, x1, y1, 0, t1); + } + else { + if (Extend0 && r0 > 0) + return R_tensor_annulus(pfs, x0, y0, r0, t0, x0, y0, 0, t0); + } + } + } else + if (dr > d - 1e-4 * (d + dr)) { /* Nested circles, or degenerate. */ if (r0 > r1) { if (Extend0) { @@ -737,7 +1684,7 @@ if (r0 > r1) { if (Extend0) { r = R_rect_radius(rect, x0, y0); - code = R_obtuse_cone(pfs, rect, x0, y0, r0, x1, y1, r1, t0, r, true); + code = R_obtuse_cone(pfs, rect, x0, y0, r0, x1, y1, r1, t0, r); if (code < 0) return code; } @@ -747,7 +1694,7 @@ } else { if (Extend1) { r = R_rect_radius(rect, x1, y1); - code = R_obtuse_cone(pfs, rect, x1, y1, r1, x0, y0, r0, t1, r, false); + code = R_obtuse_cone(pfs, rect, x1, y1, r1, x0, y0, r0, t1, r); if (code < 0) return code; } @@ -802,7 +1749,7 @@ return gx_fill_rectangle_device_rop(fixed2int_pixround(clip_rect->p.x), fixed2int_pixround(clip_rect->p.y), fixed2int_pixround(clip_rect->q.x) - fixed2int_pixround(clip_rect->p.x), fixed2int_pixround(clip_rect->q.y) - fixed2int_pixround(clip_rect->p.y), - &dc, pfs->dev, pfs->pis->log_op); + &dc, pfs->dev, pfs->pgs->log_op); #else /* Can't apply fill_rectangle, because the clist writer device doesn't pass the clipping path with fill_recatangle. Convert into trapezoids instead. @@ -1049,7 +1996,7 @@ } static int -compute_radial_shading_span(radial_shading_attrs_t *rsa, float x0, float y0, floatp r0, float x1, float y1, floatp r1, const gs_rect * rect) +compute_radial_shading_span(radial_shading_attrs_t *rsa, float x0, float y0, double r0, float x1, float y1, double r1, const gs_rect * rect) { /* If the shading area is much larger than the path bbox, we want to shorten the shading for a faster rendering. @@ -1164,7 +2111,7 @@ } static bool -shorten_radial_shading(float *x0, float *y0, floatp *r0, float *d0, float *x1, float *y1, floatp *r1, float *d1, double span_[2]) +shorten_radial_shading(float *x0, float *y0, double *r0, float *d0, float *x1, float *y1, double *r1, float *d1, double span_[2]) { double s0 = span_[0], s1 = span_[1], w; @@ -1224,14 +2171,14 @@ static int gs_shading_R_fill_rectangle_aux(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect *clip_rect, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_shading_R_t *const psh = (const gs_shading_R_t *)psh0; float d0 = psh->params.Domain[0], d1 = psh->params.Domain[1]; float x0 = psh->params.Coords[0], y0 = psh->params.Coords[1]; - floatp r0 = psh->params.Coords[2]; + double r0 = psh->params.Coords[2]; float x1 = psh->params.Coords[3], y1 = psh->params.Coords[4]; - floatp r1 = psh->params.Coords[5]; + double r1 = psh->params.Coords[5]; radial_shading_attrs_t rsa; int span_type; /* <0 - don't shorten, 1 - extent0, 2 - first contact, 4 - last contact, 8 - extent1. */ int code; @@ -1239,7 +2186,7 @@ if (r0 == 0 && r1 == 0) return 0; /* PLRM requires to paint nothing. */ - code = shade_init_fill_state((shading_fill_state_t *)&pfs1, psh0, dev, pis); + code = shade_init_fill_state((shading_fill_state_t *)&pfs1, psh0, dev, pgs); if (code < 0) return code; pfs1.Function = psh->params.Function; @@ -1248,7 +2195,7 @@ if (pfs1.icclink != NULL) gsicc_release_link(pfs1.icclink); return code; } - pfs1.function_arg_shift = 1; + pfs1.function_arg_shift = 0; pfs1.rect = *clip_rect; pfs1.maybe_self_intersecting = false; if (is_radial_shading_large(x0, y0, r0, x1, y1, r1, rect)) @@ -1273,7 +2220,7 @@ code = R_extensions(&pfs1, psh, rect, d0, d1, psh->params.Extend[0], false); if ((code >= 0) && (span_type & 2)) { float X0 = x0, Y0 = y0, D0 = d0, X1 = x1, Y1 = y1, D1 = d1; - floatp R0 = r0, R1 = r1; + double R0 = r0, R1 = r1; if ((span_type & 4) && rsa.span[0][1] >= rsa.span[1][0]) { double united[2]; @@ -1290,7 +2237,7 @@ if (code >= 0 && second_interval) { if (span_type & 4) { float X0 = x0, Y0 = y0, D0 = d0, X1 = x1, Y1 = y1, D1 = d1; - floatp R0 = r0, R1 = r1; + double R0 = r0, R1 = r1; shorten_radial_shading(&X0, &Y0, &R0, &D0, &X1, &Y1, &R1, &D1, rsa.span[1]); code = R_tensor_annulus(&pfs1, X0, Y0, R0, D0, X1, Y1, R1, D1); @@ -1308,18 +2255,7 @@ int gs_shading_R_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { - int code; - - if (VD_TRACE_RADIAL_PATCH && vd_allowed('s')) { - vd_get_dc('s'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - } - code = gs_shading_R_fill_rectangle_aux(psh0, rect, rect_clip, dev, pis); - if (VD_TRACE_FUNCTIONAL_PATCH && vd_allowed('s')) - vd_release_dc; - return code; + return gs_shading_R_fill_rectangle_aux(psh0, rect, rect_clip, dev, pgs); } diff -Nru ghostscript-9.10~dfsg/base/gxshade4.c ghostscript-9.25~dfsg+1/base/gxshade4.c --- ghostscript-9.10~dfsg/base/gxshade4.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxshade4.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,24 +25,21 @@ #include "gxcspace.h" #include "gxdcolor.h" #include "gxdevcli.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxpath.h" #include "gxshade.h" #include "gxshade4.h" -#include "vdtrace.h" #include "gsicc_cache.h" -#define VD_TRACE_TRIANGLE_PATCH 1 - /* Initialize the fill state for triangle shading. */ int mesh_init_fill_state(mesh_fill_state_t * pfs, const gs_shading_mesh_t * psh, const gs_fixed_rect * rect_clip, gx_device * dev, - gs_imager_state * pis) + gs_gstate * pgs) { int code; code = shade_init_fill_state((shading_fill_state_t *) pfs, - (const gs_shading_t *)psh, dev, pis); + (const gs_shading_t *)psh, dev, pgs); if (code < 0) return code; pfs->pshm = psh; @@ -90,7 +87,7 @@ int gs_shading_FfGt_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_shading_FfGt_t * const psh = (const gs_shading_FfGt_t *)psh0; patch_fill_state_t pfs; @@ -103,14 +100,8 @@ provides a non-const access. */ int code; - if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) { - vd_get_dc('s'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - } code = shade_init_fill_state((shading_fill_state_t *)&pfs, - (const gs_shading_t *)psh, dev, pis); + (const gs_shading_t *)psh, dev, pgs); if (code < 0) return code; pfs.Function = pshm->params.Function; @@ -125,7 +116,7 @@ vb.c = cb = C[1]; vc.c = cc = C[2]; shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params, - pis); + pgs); /* CET 09-47J.PS SpecialTestI04Test01 does not need the color data alignment. */ while ((flag = shade_next_flag(&cs, num_bits)) >= 0) { switch (flag) { @@ -144,6 +135,7 @@ va = vb; ca = cb; vb.c = cb = c; + /* fall through */ case 2: c = cb; vb = vc; @@ -156,8 +148,6 @@ } cs.align(&cs, 8); /* Debugged with 12-14O.PS page 2. */ } - if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) - vd_release_dc; release_colors(&pfs, pfs.color_stack, 3); if (pfs.icclink != NULL) gsicc_release_link(pfs.icclink); if (term_patch_fill_state(&pfs)) @@ -170,7 +160,7 @@ int gs_shading_LfGt_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_shading_LfGt_t * const psh = (const gs_shading_LfGt_t *)psh0; patch_fill_state_t pfs; @@ -184,14 +174,8 @@ patch_color_t *c, *cn; /* cn == next.c always, provides a non-contst access. */ int i, code; - if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) { - vd_get_dc('s'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - } code = shade_init_fill_state((shading_fill_state_t *)&pfs, - (const gs_shading_t *)psh, dev, pis); + (const gs_shading_t *)psh, dev, pgs); if (code < 0) return code; pfs.Function = pshm->params.Function; @@ -202,20 +186,20 @@ reserve_colors(&pfs, &cn, 1); /* Can't fail. */ next.c = cn; shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params, - pis); + pgs); vertex = (shading_vertex_t *) - gs_alloc_byte_array(pis->memory, per_row, sizeof(*vertex), + gs_alloc_byte_array(pgs->memory, per_row, sizeof(*vertex), "gs_shading_LfGt_render"); if (vertex == NULL) { code = gs_note_error(gs_error_VMerror); goto out; } - color_buffer = gs_alloc_bytes(pis->memory, pfs.color_stack_step * per_row, "gs_shading_LfGt_fill_rectangle"); + color_buffer = gs_alloc_bytes(pgs->memory, pfs.color_stack_step * per_row, "gs_shading_LfGt_fill_rectangle"); if (color_buffer == NULL) { code = gs_note_error(gs_error_VMerror); goto out; } - color_buffer_ptrs = (patch_color_t **)gs_alloc_bytes(pis->memory, + color_buffer_ptrs = (patch_color_t **)gs_alloc_bytes(pgs->memory, sizeof(patch_color_t *) * per_row, "gs_shading_LfGt_fill_rectangle"); if (color_buffer_ptrs == NULL) { code = gs_note_error(gs_error_VMerror); @@ -253,11 +237,9 @@ next.c = cn = c; } out: - if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) - vd_release_dc; - gs_free_object(pis->memory, vertex, "gs_shading_LfGt_render"); - gs_free_object(pis->memory, color_buffer, "gs_shading_LfGt_render"); - gs_free_object(pis->memory, color_buffer_ptrs, "gs_shading_LfGt_render"); + gs_free_object(pgs->memory, vertex, "gs_shading_LfGt_render"); + gs_free_object(pgs->memory, color_buffer, "gs_shading_LfGt_render"); + gs_free_object(pgs->memory, color_buffer_ptrs, "gs_shading_LfGt_render"); release_colors(&pfs, pfs.color_stack, 1); if (pfs.icclink != NULL) gsicc_release_link(pfs.icclink); if (term_patch_fill_state(&pfs)) diff -Nru ghostscript-9.10~dfsg/base/gxshade4.h ghostscript-9.25~dfsg+1/base/gxshade4.h --- ghostscript-9.10~dfsg/base/gxshade4.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxshade4.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -176,7 +176,7 @@ int mesh_init_fill_state(mesh_fill_state_t * pfs, const gs_shading_mesh_t * psh, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis); + gx_device * dev, gs_gstate * pgs); int init_patch_fill_state(patch_fill_state_t *pfs); bool term_patch_fill_state(patch_fill_state_t *pfs); @@ -191,7 +191,7 @@ int patch_fill(patch_fill_state_t * pfs, const patch_curve_t curve[4], const gs_fixed_point interior[4], void (*transform) (gs_fixed_point *, const patch_curve_t[4], - const gs_fixed_point[4], floatp, floatp)); + const gs_fixed_point[4], double, double)); int constant_color_quadrangle(patch_fill_state_t *pfs, const quadrangle_patch *p, bool self_intersecting); diff -Nru ghostscript-9.10~dfsg/base/gxshade6.c ghostscript-9.25~dfsg+1/base/gxshade6.c --- ghostscript-9.10~dfsg/base/gxshade6.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxshade6.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -27,7 +27,7 @@ #include "gscicach.h" #include "gxcspace.h" #include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxshade.h" #include "gxdevcli.h" #include "gxshade4.h" @@ -35,12 +35,9 @@ #include "gzpath.h" #include "stdint_.h" #include "math_.h" -#include "vdtrace.h" #include "gsicc_cache.h" #include "gxdevsop.h" -#define VD_TRACE_TENSOR_PATCH 1 - /* The original version of the shading code 'decompose's shadings into * smaller and smaller regions until they are smaller than 1 pixel, and then * fills them. (Either with a constant colour, or with a linear filled trap). @@ -220,9 +217,9 @@ { if (!USE_LINEAR_COLOR_PROCS) return false; - if (pfs->dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN) + if (!colors_are_separable_and_linear(&pfs->dev->color_info)) return false; - if (gx_get_cmap_procs(pfs->pis, pfs->dev)->is_halftoned(pfs->pis, pfs->dev)) + if (gx_get_cmap_procs(pfs->pgs, pfs->dev)->is_halftoned(pfs->pgs, pfs->dev)) return false; return true; } @@ -245,7 +242,7 @@ if (pfs->unlinear || pcs == NULL) pfs->pcic = NULL; else { - pfs->pcic = gs_color_index_cache_create(memory, pcs, pfs->dev, pfs->pis, true, pfs->trans_device); + pfs->pcic = gs_color_index_cache_create(memory, pcs, pfs->dev, pfs->pgs, true, pfs->trans_device); if (pfs->pcic == NULL) return_error(gs_error_VMerror); } @@ -282,19 +279,19 @@ #else pfs->decomposition_limit = fixed_1; #endif - pfs->fixed_flat = float2fixed(pfs->pis->flatness); + pfs->fixed_flat = float2fixed(pfs->pgs->flatness); /* Restrict the pfs->smoothness with 1/min_linear_grades, because cs_is_linear can't provide a better precision due to the color representation with integers. */ - pfs->smoothness = max(pfs->pis->smoothness, 1.0 / min_linear_grades); + pfs->smoothness = max(pfs->pgs->smoothness, 1.0 / min_linear_grades); pfs->color_stack_size = 0; pfs->color_stack_step = 0; pfs->color_stack_ptr = NULL; pfs->color_stack = NULL; pfs->color_stack_limit = NULL; pfs->unlinear = !is_linear_color_applicable(pfs); - return alloc_patch_fill_memory(pfs, pfs->pis->memory, pcs); + return alloc_patch_fill_memory(pfs, pfs->pgs->memory, pcs); } bool @@ -337,7 +334,7 @@ */ static void patch_interpolate_color(patch_color_t * ppcr, const patch_color_t * ppc0, - const patch_color_t * ppc1, const patch_fill_state_t *pfs, floatp t) + const patch_color_t * ppc1, const patch_fill_state_t *pfs, double t) { /* The old code gives -IND on Intel. */ if (pfs->Function) { @@ -383,7 +380,7 @@ static void curve_eval(gs_fixed_point * pt, const gs_fixed_point * p0, const gs_fixed_point * p1, const gs_fixed_point * p2, - const gs_fixed_point * p3, floatp t) + const gs_fixed_point * p3, double t) { fixed a, b, c, d; fixed t01, t12; @@ -405,7 +402,7 @@ /* Calculate the device-space coordinate corresponding to (u,v). */ static void Cp_transform(gs_fixed_point * pt, const patch_curve_t curve[4], - const gs_fixed_point ignore_interior[4], floatp u, floatp v) + const gs_fixed_point ignore_interior[4], double u, double v) { double co_u = 1.0 - u, co_v = 1.0 - v; gs_fixed_point c1u, d1v, c2u, d2v; @@ -439,7 +436,7 @@ int gs_shading_Cp_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_shading_Cp_t * const psh = (const gs_shading_Cp_t *)psh0; patch_fill_state_t state; @@ -448,7 +445,7 @@ int code; code = mesh_init_fill_state((mesh_fill_state_t *) &state, - (const gs_shading_mesh_t *)psh0, rect_clip, dev, pis); + (const gs_shading_mesh_t *)psh0, rect_clip, dev, pgs); if (code < 0) { if (state.icclink != NULL) gsicc_release_link(state.icclink); return code; @@ -459,24 +456,15 @@ if (state.icclink != NULL) gsicc_release_link(state.icclink); return code; } - if (VD_TRACE_TENSOR_PATCH && vd_allowed('s')) { - vd_get_dc('s'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - /* vd_erase(RGB(192, 192, 192)); */ - } curve[0].straight = curve[1].straight = curve[2].straight = curve[3].straight = false; - shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params, pis); + shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params, pgs); while ((code = shade_next_patch(&cs, psh->params.BitsPerFlag, curve, NULL)) == 0 && (code = patch_fill(&state, curve, NULL, Cp_transform)) >= 0 ) { DO_NOTHING; } - if (VD_TRACE_TENSOR_PATCH && vd_allowed('s')) - vd_release_dc; if (term_patch_fill_state(&state)) return_error(gs_error_unregistered); /* Must not happen. */ if (state.icclink != NULL) gsicc_release_link(state.icclink); @@ -488,7 +476,7 @@ /* Calculate the device-space coordinate corresponding to (u,v). */ static void Tpp_transform(gs_fixed_point * pt, const patch_curve_t curve[4], - const gs_fixed_point interior[4], floatp u, floatp v) + const gs_fixed_point interior[4], double u, double v) { double Bu[4], Bv[4]; gs_fixed_point pts[4][4]; @@ -537,7 +525,7 @@ int gs_shading_Tpp_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_shading_Tpp_t * const psh = (const gs_shading_Tpp_t *)psh0; patch_fill_state_t state; @@ -547,7 +535,7 @@ int code; code = mesh_init_fill_state((mesh_fill_state_t *) & state, - (const gs_shading_mesh_t *)psh0, rect_clip, dev, pis); + (const gs_shading_mesh_t *)psh0, rect_clip, dev, pgs); if (code < 0) { if (state.icclink != NULL) gsicc_release_link(state.icclink); return code; @@ -556,15 +544,8 @@ code = init_patch_fill_state(&state); if(code < 0) return code; - if (VD_TRACE_TENSOR_PATCH && vd_allowed('s')) { - vd_get_dc('s'); - vd_set_shift(0, 0); - vd_set_scale(0.01); - vd_set_origin(0, 0); - /* vd_erase(RGB(192, 192, 192)); */ - } curve[0].straight = curve[1].straight = curve[2].straight = curve[3].straight = false; - shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params, pis); + shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params, pgs); while ((code = shade_next_patch(&cs, psh->params.BitsPerFlag, curve, interior)) == 0) { /* @@ -583,8 +564,6 @@ } if (term_patch_fill_state(&state)) return_error(gs_error_unregistered); /* Must not happen. */ - if (VD_TRACE_TENSOR_PATCH && vd_allowed('s')) - vd_release_dc; if (state.icclink != NULL) gsicc_release_link(state.icclink); return min(code, 0); } @@ -789,53 +768,6 @@ memset(l, 0, sizeof(*l) * n); } -static void -draw_patch(const tensor_patch *p, bool interior, ulong rgbcolor) -{ -#ifdef DEBUG -#if 0 /* Disabled for a better view with a specific purpose. - Feel free to enable if needed. */ - int i, step = (interior ? 1 : 3); - - for (i = 0; i < 4; i += step) { - vd_curve(p->pole[i][0].x, p->pole[i][0].y, - p->pole[i][1].x, p->pole[i][1].y, - p->pole[i][2].x, p->pole[i][2].y, - p->pole[i][3].x, p->pole[i][3].y, - 0, rgbcolor); - vd_curve(p->pole[0][i].x, p->pole[0][i].y, - p->pole[1][i].x, p->pole[1][i].y, - p->pole[2][i].x, p->pole[2][i].y, - p->pole[3][i].x, p->pole[3][i].y, - 0, rgbcolor); - } -#endif -#endif -} - -static inline void -draw_triangle(const gs_fixed_point *p0, const gs_fixed_point *p1, - const gs_fixed_point *p2, ulong rgbcolor) -{ -#ifdef DEBUG - if (!vd_enabled) - return; - vd_quad(p0->x, p0->y, p0->x, p0->y, p1->x, p1->y, p2->x, p2->y, 0, rgbcolor); -#endif -} - -static inline void -draw_quadrangle(const quadrangle_patch *p, ulong rgbcolor) -{ -#ifdef DEBUG - vd_quad(p->p[0][0]->p.x, p->p[0][0]->p.y, - p->p[0][1]->p.x, p->p[0][1]->p.y, - p->p[1][1]->p.x, p->p[1][1]->p.y, - p->p[1][0]->p.x, p->p[1][0]->p.y, - 0, rgbcolor); -#endif -} - /* For a given set of poles in the tensor patch (for instance * [0][0], [0][1], [0][2], [0][3] or [0][2], [1][2], [2][2], [3][2]) * return the number of subdivisions required to flatten the bezier @@ -930,7 +862,6 @@ fixed ytop = min(ytop0, swap_axes ? pfs->rect.q.x : pfs->rect.q.y); fixed xleft = (swap_axes ? pfs->rect.p.y : pfs->rect.p.x); fixed xright = (swap_axes ? pfs->rect.q.y : pfs->rect.q.x); - vd_save; if (ybot >= ytop) return 0; @@ -1196,18 +1127,18 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &lenew, &re, ybot, ytl, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &re, ytl, ybr, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; ybot = ybr; return dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &renew, ybr, ytop, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); } else if (ytr < ybl) { /* | | * ---+-----+---- @@ -1219,17 +1150,17 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &renew, ybot, ytr, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &re, ytr, ybl, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; return dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &re, ybl, ytop, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); } /* Fill in any section where both left and right edges are * diagonal at the bottom */ @@ -1244,7 +1175,7 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &re, ybot, ymid, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; ybot = ymid; @@ -1262,7 +1193,7 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &re, ymid, ytop, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; ytop = ymid; @@ -1276,7 +1207,7 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &renew, ybot, ybl, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; ybot = ybl; @@ -1288,7 +1219,7 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &lenew, &re, ybot, ybr, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; ybot = ybr; @@ -1302,7 +1233,7 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &le, &renew, ytl, ytop, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; ytop = ytl; @@ -1314,7 +1245,7 @@ */ code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &lenew, &re, ytr, ytop, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); if (code < 0) return code; ytop = ytr; @@ -1325,19 +1256,15 @@ return 0; return dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, &lenew, &renew, ybot, ytop, - swap_axes, pdevc, pfs->pis->log_op); + swap_axes, pdevc, pfs->pgs->log_op); } } - if (!VD_TRACE_DOWN) - vd_disable; - code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, - &le, &re, ybot, ytop, swap_axes, pdevc, pfs->pis->log_op); - vd_restore; - return code; + return dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, + &le, &re, ybot, ytop, swap_axes, pdevc, pfs->pgs->log_op); } static inline void -dc2fc(const patch_fill_state_t *pfs, gx_device_color *pdevc, +dc2fc31(const patch_fill_state_t *pfs, gx_device_color *pdevc, frac31 fc[GX_DEVICE_COLOR_MAX_COMPONENTS]) { int j; @@ -1352,12 +1279,12 @@ int shift = cinfo->comp_shift[j]; int bits = cinfo->comp_bits[j]; - fc[j] = ((pdevc->colors.pure >> shift) & ((1 << bits) - 1)) << + fc[j] = ((pdevc->colors.pure >> shift) & ((1 << bits) - 1)) << (sizeof(frac31) * 8 - 1 - bits); } } else { for (j = 0; j < cinfo->num_components; j++) { - fc[j] = cv2frac(pdevc->colors.devn.values[j]); + fc[j] = cv2frac31(pdevc->colors.devn.values[j]); } } } @@ -1365,8 +1292,8 @@ #define DEBUG_COLOR_INDEX_CACHE 0 static inline int -patch_color_to_device_color_inline(const patch_fill_state_t *pfs, - const patch_color_t *c, gx_device_color *pdevc, +patch_color_to_device_color_inline(const patch_fill_state_t *pfs, + const patch_color_t *c, gx_device_color *pdevc, frac31 *frac_values) { /* Must return 2 if the color is not pure. @@ -1374,10 +1301,6 @@ */ int code; gx_device_color devc; - gx_device *dev = pfs->dev; - - if (pfs->trans_device != NULL) - dev = pfs->trans_device; if (DEBUG_COLOR_INDEX_CACHE && pdevc == NULL) pdevc = &devc; @@ -1399,15 +1322,15 @@ pdevc = &devc; memcpy(fcc.paint.values, c->cc.paint.values, sizeof(fcc.paint.values[0]) * pfs->num_components); - code = pcs->type->remap_color(&fcc, pcs, pdevc, pfs->pis, - pfs->dev, gs_color_select_texture); + code = pcs->type->remap_color(&fcc, pcs, pdevc, pfs->pgs, + pfs->trans_device, gs_color_select_texture); if (code < 0) return code; if (frac_values != NULL) { if (!(pdevc->type == &gx_dc_type_data_devn || - pdevc->type == &gx_dc_type_data_pure)) + pdevc->type == &gx_dc_type_data_pure)) return 2; - dc2fc(pfs, pdevc, frac_values); + dc2fc31(pfs, pdevc, frac_values); } # if DEBUG_COLOR_INDEX_CACHE if (cindex != pdevc->colors.pure) @@ -1508,7 +1431,6 @@ patch_color_t c1 = *c; gx_device_color dc; int code; - vd_save; # if NOFILL_TEST /* if (dbg_nofill) @@ -1517,12 +1439,8 @@ code = patch_color_to_device_color_inline(pfs, &c1, &dc, NULL); if (code < 0) return code; - if (!VD_TRACE_DOWN) - vd_disable; - code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, - le, re, ybot, ytop, swap_axes, &dc, pfs->pis->log_op); - vd_restore; - return code; + return dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, + le, re, ybot, ytop, swap_axes, &dc, pfs->pgs->log_op); } static inline float @@ -1568,7 +1486,9 @@ if (s > pfs->smoothness) return 0; - code = cs_is_linear(cs, pfs->pis, pfs->trans_device, + if (pfs->cs_always_linear) + return 1; + code = cs_is_linear(cs, pfs->pgs, pfs->trans_device, &c0->cc, &c1->cc, NULL, NULL, pfs->smoothness - s, pfs->icclink); if (code <= 0) return code; @@ -1671,11 +1591,6 @@ code = patch_color_to_device_color_inline(pfs, c1, NULL, fc[1]); if (code < 0) goto out; - if (fa.swap_axes) { - vd_quad(le->start.y, le->start.x, le->end.y, le->end.x, re->end.y, re->end.x, re->start.y, re->start.x, 0, RGB(0,255,0)); - } else { - vd_quad(le->start.x, le->start.y, le->end.x, le->end.y, re->end.x, re->end.y, re->start.x, re->start.y, 0, RGB(0,255,0)); - } code = dev_proc(pdev, fill_linear_color_trapezoid)(pdev, &fa, &le->start, &le->end, &re->start, &re->end, fc[0], fc[1], NULL, NULL); @@ -1687,9 +1602,10 @@ } if (code < 0) goto out; - else /* code == 0, the device requested to decompose the area. */ + else { /* code == 0, the device requested to decompose the area. */ code = gs_note_error(gs_error_unregistered); /* Must not happen. */ goto out; + } } if (!pfs->unlinear || !pfs->linear_color || color_span(pfs, c0, c1) > pfs->smoothness) { @@ -1736,12 +1652,6 @@ return 0; dx1 = q[1].x - q[0].x, dy1 = q[1].y - q[0].y; dx2 = q[2].x - q[0].x, dy2 = q[2].y - q[0].y; -#if 1 - if (!swap_axes) - vd_quad(q[0].x, q[0].y, q[1].x, q[1].y, q[3].x, q[3].y, q[2].x, q[2].y, 0, RGB(255, 0, 0)); - else - vd_quad(q[0].y, q[0].x, q[1].y, q[1].x, q[3].y, q[3].x, q[2].y, q[2].x, 0, RGB(255, 0, 0)); -#endif if ((int64_t)dx1 * dy2 != (int64_t)dy1 * dx2) { orient = ((int64_t)dx1 * dy2 > (int64_t)dy1 * dx2); return linear_color_trapezoid(pfs, q, 0, 1, 2, 3, ybot, ytop, swap_axes, c0, c1, orient); @@ -1819,6 +1729,7 @@ split_curve_s(pole, q0, q1, 1); } +#ifdef SHADING_SWAP_AXES_FOR_PRECISION static inline void do_swap_axes(gs_fixed_point *p, int k) { @@ -1829,18 +1740,6 @@ } } -static inline void -y_extreme_vertice(gs_fixed_point *q, const gs_fixed_point *p, int k, int minmax) -{ - int i; - gs_fixed_point r = *p; - - for (i = 1; i < k; i++) - if ((p[i].y - r.y) * minmax > 0) - r = p[i]; - *q = r; -} - static inline fixed span_x(const gs_fixed_point *p, int k) { @@ -1866,27 +1765,7 @@ } return ymax - ymin; } - -static inline void -draw_wedge(const gs_fixed_point *p, int n) -{ -#ifdef DEBUG - int i; - - if (!vd_enabled) - return; - vd_setlinewidth(4); - vd_setcolor(RGB(255, 0, 0)); - vd_beg_path; - vd_moveto(p[0].x, p[0].y); - for (i = 1; i < n; i++) - vd_lineto(p[i].x, p[i].y); - vd_closepath; - vd_end_path; - vd_fill; - /*vd_stroke;*/ #endif -} static inline fixed manhattan_dist(const gs_fixed_point *p0, const gs_fixed_point *p1) @@ -2142,9 +2021,12 @@ /* fixme: check an inner color ? */ s01 = max(s0, s1); s012 = max(s01, s2); - code = cs_is_linear(cs, pfs->pis, pfs->trans_device, - &p0->c->cc, &p1->c->cc, &p2->c->cc, NULL, - pfs->smoothness - s012, pfs->icclink); + if (pfs->cs_always_linear) + code = 1; + else + code = cs_is_linear(cs, pfs->pgs, pfs->trans_device, + &p0->c->cc, &p1->c->cc, &p2->c->cc, NULL, + pfs->smoothness - s012, pfs->icclink); if (code < 0) return code; if (code == 0) @@ -2155,7 +2037,6 @@ frac31 fc[3][GX_DEVICE_COLOR_MAX_COMPONENTS]; gs_fill_attributes fa; gx_device_color dc[3]; - vd_save; fa.clip = &pfs->rect; fa.ht = NULL; @@ -2164,7 +2045,7 @@ code = patch_color_to_device_color_inline(pfs, p0->c, &dc[0], fc[0]); if (code != 0) return code; - if (!(dc[0].type == &gx_dc_type_data_pure || + if (!(dc[0].type == &gx_dc_type_data_pure || dc[0].type == &gx_dc_type_data_devn)) return 2; if (!wedge) { @@ -2175,13 +2056,9 @@ code = patch_color_to_device_color_inline(pfs, p2->c, &dc[2], fc[2]); if (code != 0) return code; - draw_triangle(&p0->p, &p1->p, &p2->p, RGB(255, 0, 0)); - if (!VD_TRACE_DOWN) - vd_disable; code = dev_proc(pdev, fill_linear_color_triangle)(pdev, &fa, &p0->p, &p1->p, &p2->p, fc[0], (wedge ? NULL : fc[1]), fc[2]); - vd_restore; if (code == 1) return 0; /* The area is filled. */ if (code < 0) @@ -2198,7 +2075,6 @@ if ((int64_t)(q1->p.x - q0->p.x) * (q2->p.y - q0->p.y) == (int64_t)(q1->p.y - q0->p.y) * (q2->p.x - q0->p.x)) return 0; /* Zero area. */ - draw_triangle(&q0->p, &q1->p, &q2->p, RGB(255, 255, 0)); /* Can't apply try_device_linear_color here because didn't check is_color_linear. @@ -2469,7 +2345,6 @@ return code; } else { if (INTERPATCH_PADDING && (wedge_type & interpatch_padding)) { - vd_bar(pole[0].x, pole[0].y, pole[3].x, pole[3].y, 0, RGB(255, 0, 0)); code = mesh_padding(pfs, &pole[0], &pole[3], c0, c1); if (code < 0) return code; @@ -2535,39 +2410,35 @@ gs_fixed_edge ue; int code; gx_device_color dc; - vd_save; # if NOFILL_TEST if (dbg_nofill) return 0; # endif - if (!VD_TRACE_DOWN) - vd_disable; code = patch_color_to_device_color_inline(pfs, c, &dc, NULL); if (code < 0) return code; if (le->end.y < re->end.y) { code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, - le, re, le->start.y, le->end.y, false, &dc, pfs->pis->log_op); + le, re, le->start.y, le->end.y, false, &dc, pfs->pgs->log_op); if (code >= 0) { ue.start = le->end; ue.end = re->end; code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, - &ue, re, le->end.y, re->end.y, false, &dc, pfs->pis->log_op); + &ue, re, le->end.y, re->end.y, false, &dc, pfs->pgs->log_op); } } else if (le->end.y > re->end.y) { code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, - le, re, le->start.y, re->end.y, false, &dc, pfs->pis->log_op); + le, re, le->start.y, re->end.y, false, &dc, pfs->pgs->log_op); if (code >= 0) { ue.start = re->end; ue.end = le->end; code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, - le, &ue, re->end.y, le->end.y, false, &dc, pfs->pis->log_op); + le, &ue, re->end.y, le->end.y, false, &dc, pfs->pgs->log_op); } } else code = dev_proc(pfs->dev, fill_trapezoid)(pfs->dev, - le, re, le->start.y, le->end.y, false, &dc, pfs->pis->log_op); - vd_restore; + le, re, le->start.y, le->end.y, false, &dc, pfs->pgs->log_op); return code; } @@ -2584,7 +2455,6 @@ if (color_stack_ptr == NULL) return_error(gs_error_unregistered); /* Must not happen. */ - draw_triangle(&p0->p, &p1->p, &p2->p, RGB(255, 0, 0)); patch_interpolate_color(c[0], p0->c, p1->c, pfs, 0.5); patch_interpolate_color(c[1], p2->c, c[0], pfs, 0.5); for (i = 0; i < 3; i++) { @@ -2624,7 +2494,6 @@ gx_device_color dc; bool orient; - draw_quadrangle(p, RGB(0, 255, 0)); patch_interpolate_color(c[1], p->p[0][0]->c, p->p[0][1]->c, pfs, 0.5); patch_interpolate_color(c[2], p->p[1][0]->c, p->p[1][1]->c, pfs, 0.5); patch_interpolate_color(c[0], c[1], c[2], pfs, 0.5); @@ -2634,8 +2503,9 @@ { gs_fixed_point qq[4]; make_vertices(qq, p); -# if 0 /* Swapping axes may improve the precision, - but slows down due to the area expantion needed +#ifdef SHADING_SWAP_AXES_FOR_PRECISION + /* Swapping axes may improve the precision, + but slows down due to the area expansion needed in gx_shade_trapezoid. */ dx = span_x(qq, 4); dy = span_y(qq, 4); @@ -2643,7 +2513,7 @@ do_swap_axes(qq, 4); swap_axes = true; } -# endif +#endif wrap_vertices_by_y(q, qq); } { fixed dx1 = q[1].x - q[0].x, dy1 = q[1].y - q[0].y; @@ -2877,26 +2747,6 @@ return !code; } -static inline bool -quadrangle_bbox_covers_pixel_centers(const quadrangle_patch *p) -{ - fixed xbot, xtop, ybot, ytop; - - xbot = min(min(p->p[0][0]->p.x, p->p[0][1]->p.x), - min(p->p[1][0]->p.x, p->p[1][1]->p.x)); - xtop = max(max(p->p[0][0]->p.x, p->p[0][1]->p.x), - max(p->p[1][0]->p.x, p->p[1][1]->p.x)); - if (covers_pixel_centers(xbot, xtop)) - return true; - ybot = min(min(p->p[0][0]->p.y, p->p[0][1]->p.y), - min(p->p[1][0]->p.y, p->p[1][1]->p.y)); - ytop = max(max(p->p[0][0]->p.y, p->p[0][1]->p.y), - max(p->p[1][0]->p.y, p->p[1][1]->p.y)); - if (covers_pixel_centers(ybot, ytop)) - return true; - return false; -} - static inline void divide_bar(patch_fill_state_t *pfs, const shading_vertex_t *p0, const shading_vertex_t *p1, int radix, shading_vertex_t *p, @@ -2918,7 +2768,7 @@ patch_color_t *c[3]; wedge_vertex_list_t L01, L12, L20, L[3]; bool inside_save = pfs->inside; - gs_fixed_rect r, r1; + gs_fixed_rect r = {{0,0},{0,0}}, r1 = {{0,0},{0,0}}; int code = 0; byte *color_stack_ptr; const bool inside = pfs->inside; /* 'const' should help compiler to analyze initializations. */ @@ -3085,7 +2935,7 @@ int i; pfs->dev = dev; - pfs->pis = NULL; + pfs->pgs = NULL; pfs->direct_space = NULL; pfs->num_components = dev->color_info.num_components; /* pfs->cc_max_error[GS_CLIENT_COLOR_MAX_COMPONENTS] unused */ @@ -3138,7 +2988,7 @@ patch_fill_state_t *pfs = fa->pfs; patch_color_t c[3]; shading_vertex_t p[3]; - int i; + uchar i; /* pfs->rect = *fa->clip; unused ? */ p[0].p = *p0; @@ -3477,7 +3327,7 @@ bool linear_color_save = pfs->linear_color; bool inside_save = pfs->inside; const bool inside = pfs->inside; /* 'const' should help compiler to analyze initializations. */ - gs_fixed_rect r, r1; + gs_fixed_rect r = {{0,0},{0,0}}, r1 = {{0,0},{0,0}}; /* Warning : pfs->monotonic_color is not restored on error. */ if (!inside) { @@ -3648,7 +3498,7 @@ code = fill_triangle_wedge(pfs, s0.p[0][1], s1.p[1][1], s0.p[1][1]); } if (code >= 0) - code = fill_quadrangle(pfs, &s0, big); + code = fill_quadrangle(pfs, &s0, big1); if (code >= 0) { if (LAZY_WEDGES) { l0.last_side = true; @@ -3720,6 +3570,7 @@ return code; } +/* This splits tensor patch p->pole[v][u] on u to give s0->pole[v][u] and s1->pole[v][u] */ static inline void split_stripe(patch_fill_state_t *pfs, tensor_patch *s0, tensor_patch *s1, const tensor_patch *p, patch_color_t *c[2]) { @@ -3739,6 +3590,7 @@ s1->c[1][1] = p->c[1][1]; } +/* This splits tensor patch p->pole[v][u] on v to give s0->pole[v][u] and s1->pole[v][u] */ static inline void split_patch(patch_fill_state_t *pfs, tensor_patch *s0, tensor_patch *s1, const tensor_patch *p, patch_color_t *c[2]) { @@ -3807,10 +3659,6 @@ if(color_stack_ptr == NULL) return_error(gs_error_unregistered); /* Must not happen. */ split_stripe(pfs, &s0, &s1, p, c); - if (0) { /* Debug purpose only. */ - draw_patch(&s0, true, RGB(0, 128, 128)); - draw_patch(&s1, true, RGB(0, 128, 128)); - } code = decompose_stripe(pfs, &s0, ku / 2); if (code >= 0) code = decompose_stripe(pfs, &s1, ku / 2); @@ -3855,8 +3703,6 @@ /* The stripe is flattened enough by V, so ignore inner poles. */ int ku[4], kum, code; - if (0) - draw_patch(p, true, RGB(0, 255, 255)); /* Debug purpose only. */ /* We would like to apply iterations for enumerating the kum curve parts, but the roundinmg errors would be too complicated due to the dependence on the direction. Note that neigbour @@ -3870,11 +3716,9 @@ if (code < 0) return code; if (INTERPATCH_PADDING) { - vd_bar(p->pole[0][0].x, p->pole[0][0].y, p->pole[3][0].x, p->pole[3][0].y, 0, RGB(255, 0, 0)); code = mesh_padding(pfs, &p->pole[0][0], &p->pole[3][0], p->c[0][0], p->c[1][0]); if (code < 0) return code; - vd_bar(p->pole[0][3].x, p->pole[0][3].y, p->pole[3][3].x, p->pole[3][3].y, 0, RGB(255, 0, 0)); code = mesh_padding(pfs, &p->pole[0][3], &p->pole[3][3], p->c[0][1], p->c[1][1]); if (code < 0) return code; @@ -3885,28 +3729,6 @@ return fill_wedges(pfs, ku[3], kum, p->pole[3], 1, p->c[1][0], p->c[1][1], inpatch_wedge); } -static inline bool -is_curve_x_monotonic(const gs_fixed_point *pole, int pole_step) -{ /* true = monotonic, false = don't know. */ - return (pole[0 * pole_step].x <= pole[1 * pole_step].x && - pole[1 * pole_step].x <= pole[2 * pole_step].x && - pole[2 * pole_step].x <= pole[3 * pole_step].x) || - (pole[0 * pole_step].x >= pole[1 * pole_step].x && - pole[1 * pole_step].x >= pole[2 * pole_step].x && - pole[2 * pole_step].x >= pole[3 * pole_step].x); -} - -static inline bool -is_curve_y_monotonic(const gs_fixed_point *pole, int pole_step) -{ /* true = monotonic, false = don't know. */ - return (pole[0 * pole_step].y <= pole[1 * pole_step].y && - pole[1 * pole_step].y <= pole[2 * pole_step].y && - pole[2 * pole_step].y <= pole[3 * pole_step].y) || - (pole[0 * pole_step].y >= pole[1 * pole_step].y && - pole[1 * pole_step].y >= pole[2 * pole_step].y && - pole[2 * pole_step].y >= pole[3 * pole_step].y); -} - static inline bool neqs(int *a, int b) { /* Unequal signs. Assuming -1, 0, 1 only. */ if (*a * b < 0) @@ -4077,7 +3899,7 @@ if (!pfs->inside) { gs_fixed_rect r, r1; - + tensor_patch_bbox(&r, p); r.p.x -= INTERPATCH_PADDING; r.p.y -= INTERPATCH_PADDING; @@ -4094,8 +3916,6 @@ color_stack_ptr = reserve_colors_inline(pfs, c, 2); if(color_stack_ptr == NULL) return_error(gs_error_unregistered); /* Must not happen. */ - if (0) - draw_patch(p, true, RGB(255, 255, 0)); /* Debug purpose only. */ split_patch(pfs, &s0, &s1, p, c); if (kv0 <= 1) { q0.p = s0.pole[0][0]; @@ -4119,7 +3939,7 @@ code = fill_patch(pfs, &s0, kv / 2, kv0 / 2, kv1 / 2); if (code >= 0) code = fill_patch(pfs, &s1, kv / 2, kv0 / 2, kv1 / 2); - /* fixme : To privide the precise filling order, we must + /* fixme : To provide the precise filling order, we must decompose left and right wedges into pieces by intersections with stripes, and fill each piece with its stripe. A lazy wedge list would be fine for storing @@ -4129,14 +3949,14 @@ the wedge color appears a constant, so the filling order isn't important. The order is important for other self-overlapping patches, but the visible effect is - just a slight norrowing the patch (as its lower layer appears + just a slight narrowing of the patch (as its lower layer appears visible through the upper layer near the side). This kind of dropout isn't harmful, because - contacring self-overlapping patches are painted + contacting self-overlapping patches are painted one after one by definition, so that a side coverage break appears unavoidable by definition. - Delaying this improvement because it is low important. + Delaying this improvement because it is low importance. */ release_colors_inline(pfs, color_stack_ptr, 2); pfs->inside = save_inside; @@ -4144,15 +3964,15 @@ } } -static inline fixed -lcp1(fixed p0, fixed p3) -{ /* Computing the 1st pole of a 3d order besier, which applears a line. */ - return (p0 + p0 + p3) / 3; -} -static inline fixed -lcp2(fixed p0, fixed p3) -{ /* Computing the 2nd pole of a 3d order besier, which applears a line. */ - return (p0 + p3 + p3) / 3; +static inline int64_t +lcp1(int64_t p0, int64_t p3) +{ /* Computing the 1st pole of a 3d order besier, which appears a line. */ + return (p0 + p0 + p3); +} +static inline int64_t +lcp2(int64_t p0, int64_t p3) +{ /* Computing the 2nd pole of a 3d order besier, which appears a line. */ + return (p0 + p3 + p3); } static void @@ -4189,39 +4009,39 @@ p->pole[2][2] = interior[2]; p->pole[2][1] = interior[3]; } else { - p->pole[1][1].x = lcp1(p->pole[0][1].x, p->pole[3][1].x) + - lcp1(p->pole[1][0].x, p->pole[1][3].x) - - lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x), - lcp1(p->pole[3][0].x, p->pole[3][3].x)); - p->pole[1][2].x = lcp1(p->pole[0][2].x, p->pole[3][2].x) + - lcp2(p->pole[1][0].x, p->pole[1][3].x) - - lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x), - lcp2(p->pole[3][0].x, p->pole[3][3].x)); - p->pole[2][1].x = lcp2(p->pole[0][1].x, p->pole[3][1].x) + - lcp1(p->pole[2][0].x, p->pole[2][3].x) - - lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x), - lcp1(p->pole[3][0].x, p->pole[3][3].x)); - p->pole[2][2].x = lcp2(p->pole[0][2].x, p->pole[3][2].x) + - lcp2(p->pole[2][0].x, p->pole[2][3].x) - - lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x), - lcp2(p->pole[3][0].x, p->pole[3][3].x)); - - p->pole[1][1].y = lcp1(p->pole[0][1].y, p->pole[3][1].y) + - lcp1(p->pole[1][0].y, p->pole[1][3].y) - - lcp1(lcp1(p->pole[0][0].y, p->pole[0][3].y), - lcp1(p->pole[3][0].y, p->pole[3][3].y)); - p->pole[1][2].y = lcp1(p->pole[0][2].y, p->pole[3][2].y) + - lcp2(p->pole[1][0].y, p->pole[1][3].y) - - lcp1(lcp2(p->pole[0][0].y, p->pole[0][3].y), - lcp2(p->pole[3][0].y, p->pole[3][3].y)); - p->pole[2][1].y = lcp2(p->pole[0][1].y, p->pole[3][1].y) + - lcp1(p->pole[2][0].y, p->pole[2][3].y) - - lcp2(lcp1(p->pole[0][0].y, p->pole[0][3].y), - lcp1(p->pole[3][0].y, p->pole[3][3].y)); - p->pole[2][2].y = lcp2(p->pole[0][2].y, p->pole[3][2].y) + - lcp2(p->pole[2][0].y, p->pole[2][3].y) - - lcp2(lcp2(p->pole[0][0].y, p->pole[0][3].y), - lcp2(p->pole[3][0].y, p->pole[3][3].y)); + p->pole[1][1].x = (fixed)((3*(lcp1(p->pole[0][1].x, p->pole[3][1].x) + + lcp1(p->pole[1][0].x, p->pole[1][3].x)) - + lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x), + lcp1(p->pole[3][0].x, p->pole[3][3].x)))/9); + p->pole[1][2].x = (fixed)((3*(lcp1(p->pole[0][2].x, p->pole[3][2].x) + + lcp2(p->pole[1][0].x, p->pole[1][3].x)) - + lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x), + lcp2(p->pole[3][0].x, p->pole[3][3].x)))/9); + p->pole[2][1].x = (fixed)((3*(lcp2(p->pole[0][1].x, p->pole[3][1].x) + + lcp1(p->pole[2][0].x, p->pole[2][3].x)) - + lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x), + lcp1(p->pole[3][0].x, p->pole[3][3].x)))/9); + p->pole[2][2].x = (fixed)((3*(lcp2(p->pole[0][2].x, p->pole[3][2].x) + + lcp2(p->pole[2][0].x, p->pole[2][3].x)) - + lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x), + lcp2(p->pole[3][0].x, p->pole[3][3].x)))/9); + + p->pole[1][1].y = (fixed)((3*(lcp1(p->pole[0][1].y, p->pole[3][1].y) + + lcp1(p->pole[1][0].y, p->pole[1][3].y)) - + lcp1(lcp1(p->pole[0][0].y, p->pole[0][3].y), + lcp1(p->pole[3][0].y, p->pole[3][3].y)))/9); + p->pole[1][2].y = (fixed)((3*(lcp1(p->pole[0][2].y, p->pole[3][2].y) + + lcp2(p->pole[1][0].y, p->pole[1][3].y)) - + lcp1(lcp2(p->pole[0][0].y, p->pole[0][3].y), + lcp2(p->pole[3][0].y, p->pole[3][3].y)))/9); + p->pole[2][1].y = (fixed)((3*(lcp2(p->pole[0][1].y, p->pole[3][1].y) + + lcp1(p->pole[2][0].y, p->pole[2][3].y)) - + lcp2(lcp1(p->pole[0][0].y, p->pole[0][3].y), + lcp1(p->pole[3][0].y, p->pole[3][3].y)))/9); + p->pole[2][2].y = (fixed)((3*(lcp2(p->pole[0][2].y, p->pole[3][2].y) + + lcp2(p->pole[2][0].y, p->pole[2][3].y)) - + lcp2(lcp2(p->pole[0][0].y, p->pole[0][3].y), + lcp2(p->pole[3][0].y, p->pole[3][3].y)))/9); } patch_set_color(pfs, p->c[0][0], curve[0].vertex.cc); patch_set_color(pfs, p->c[1][0], curve[1].vertex.cc); @@ -4261,7 +4081,7 @@ patch_fill(patch_fill_state_t *pfs, const patch_curve_t curve[4], const gs_fixed_point interior[4], void (*transform) (gs_fixed_point *, const patch_curve_t[4], - const gs_fixed_point[4], floatp, floatp)) + const gs_fixed_point[4], double, double)) { tensor_patch p; patch_color_t *c[4]; @@ -4330,7 +4150,6 @@ if (code < 0) goto out; } - /* draw_patch(&p, true, RGB(0, 0, 0)); */ /* How many subdividions of the patch in the u and v direction? */ kv[0] = curve_samples(pfs, &p.pole[0][0], 4, pfs->fixed_flat); kv[1] = curve_samples(pfs, &p.pole[0][1], 4, pfs->fixed_flat); @@ -4343,9 +4162,9 @@ ku[3] = curve_samples(pfs, p.pole[3], 1, pfs->fixed_flat); kum = max(max(ku[0], ku[1]), max(ku[2], ku[3])); # if NOFILL_TEST - dbg_nofill = false; + dbg_nofill = false; # endif - code = fill_wedges(pfs, ku[0], kum, p.pole[0], 1, p.c[0][0], p.c[0][1], + code = fill_wedges(pfs, ku[0], kum, p.pole[0], 1, p.c[0][0], p.c[0][1], interpatch_padding | inpatch_wedge); if (code >= 0) { /* We would like to apply iterations for enumerating the kvm curve parts, diff -Nru ghostscript-9.10~dfsg/base/gxshade.c ghostscript-9.25~dfsg+1/base/gxshade.c --- ghostscript-9.10~dfsg/base/gxshade.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxshade.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,13 +23,15 @@ #include "gscindex.h" #include "gscie.h" /* requires gscspace.h */ #include "gxdevcli.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxdht.h" /* for computing # of different colors */ #include "gxpaint.h" #include "gxshade.h" #include "gxshade4.h" #include "gsicc.h" #include "gsicc_cache.h" +#include "gxcdevn.h" +#include "gximage.h" /* Define a maximum smoothness value. */ /* smoothness > 0.2 produces severely blocky output. */ @@ -52,10 +54,10 @@ void shade_next_init(shade_coord_stream_t * cs, const gs_shading_mesh_params_t * params, - const gs_imager_state * pis) + const gs_gstate * pgs) { cs->params = params; - cs->pctm = &pis->ctm; + cs->pctm = &pgs->ctm; if (data_source_is_stream(params->DataSource)) { /* * Rewind the data stream iff it is reusable -- either a reusable @@ -312,11 +314,13 @@ /* Initialize the common parts of the recursion state. */ int shade_init_fill_state(shading_fill_state_t * pfs, const gs_shading_t * psh, - gx_device * dev, gs_imager_state * pis) + gx_device * dev, gs_gstate * pgs) { const gs_color_space *pcs = psh->params.ColorSpace; - float max_error = min(pis->smoothness, MAX_SMOOTHNESS); + float max_error = min(pgs->smoothness, MAX_SMOOTHNESS); bool is_lab; + bool cs_lin_test; + int code; /* * There's no point in trying to achieve smoothness beyond what @@ -329,8 +333,9 @@ int ci; gsicc_rendering_param_t rendering_params; + pfs->cs_always_linear = false; pfs->dev = dev; - pfs->pis = pis; + pfs->pgs = pgs; top: pfs->direct_space = pcs; pfs->num_components = gs_color_space_num_components(pcs); @@ -358,9 +363,8 @@ break; } if (num_colors <= 32) { - gx_ht_order_component *components = pis->dev_ht->components; /****** WRONG FOR MULTI-PLANE HALFTONES ******/ - num_colors *= pis->dev_ht->components[0].corder.num_levels; + num_colors *= pgs->dev_ht->components[0].corder.num_levels; } if (psh->head.type == 2 || psh->head.type == 3) { max_error *= 0.25; @@ -372,41 +376,63 @@ pfs->cc_max_error[ci] = (ranges == 0 ? max_error : max_error * (ranges[ci].rmax - ranges[ci].rmin)); - if (pis->has_transparency && pis->trans_device != NULL) { - pfs->trans_device = pis->trans_device; + if (pgs->has_transparency && pgs->trans_device != NULL) { + pfs->trans_device = pgs->trans_device; } else { pfs->trans_device = dev; } /* If the CS is PS based and we have not yet converted to the ICC form then go ahead and do that now */ if (gs_color_space_is_PSCIE(pcs) && pcs->icc_equivalent == NULL) { - gs_colorspace_set_icc_equivalent((gs_color_space *)pcs, &(is_lab), pis->memory); + code = gs_colorspace_set_icc_equivalent((gs_color_space *)pcs, &(is_lab), pgs->memory); + if (code < 0) + return code; } - rendering_params.black_point_comp = pis->blackptcomp; + rendering_params.black_point_comp = pgs->blackptcomp; rendering_params.graphics_type_tag = GS_PATH_TAG; rendering_params.override_icc = false; rendering_params.preserve_black = gsBKPRESNOTSPECIFIED; - rendering_params.rendering_intent = pis->renderingintent; + rendering_params.rendering_intent = pgs->renderingintent; rendering_params.cmm = gsCMM_DEFAULT; /* Grab the icc link transform that we need now */ if (pcs->cmm_icc_profile_data != NULL) { - pfs->icclink = gsicc_get_link(pis, pis->trans_device, pcs, NULL, - &rendering_params, pis->memory); + pfs->icclink = gsicc_get_link(pgs, pgs->trans_device, pcs, NULL, + &rendering_params, pgs->memory); if (pfs->icclink == NULL) - return gs_error_VMerror; + return_error(gs_error_VMerror); } else { if (pcs->icc_equivalent != NULL ) { /* We have a PS equivalent ICC profile. We may need to go through special range adjustments in this case */ - pfs->icclink = gsicc_get_link(pis, pis->trans_device, + pfs->icclink = gsicc_get_link(pgs, pgs->trans_device, pcs->icc_equivalent, NULL, - &rendering_params, pis->memory); + &rendering_params, pgs->memory); if (pfs->icclink == NULL) - return gs_error_VMerror; + return_error(gs_error_VMerror); } else { pfs->icclink = NULL; } } + /* Two possible cases of interest here for performance. One is that the + * icclink is NULL, which could occur if the source space were DeviceN or + * a separation color space, while at the same time, the output device + * supports these colorants (e.g. a separation device). The other case is + * that the icclink is the identity. This could happen for example if the + * source space were CMYK and we are going out to a CMYK device. For both + * of these cases we can avoid going through the standard + * color mappings to determine linearity. This is true, provided that the + * transfer function is linear. It is likely that we can improve + * things even in cases where the transfer function is nonlinear, but for + * now, we will punt on those and let them go through the longer processing + * steps */ + if (pfs->icclink == NULL) + cs_lin_test = !(using_alt_color_space((gs_gstate*)pgs)); + else + cs_lin_test = pfs->icclink->is_identity; + + if (cs_lin_test && !gx_has_transfer(pgs, dev->color_info.num_components)) { + pfs->cs_always_linear = true; + } return 0; } @@ -420,6 +446,6 @@ params.rule = -1; /* irrelevant */ params.adjust = *fill_adjust; params.flatness = 0; /* irrelevant */ - return (*dev_proc(pfs->dev, fill_path)) (pfs->dev, pfs->pis, ppath, + return (*dev_proc(pfs->dev, fill_path)) (pfs->dev, pfs->pgs, ppath, ¶ms, pdevc, NULL); } diff -Nru ghostscript-9.10~dfsg/base/gxshade.h ghostscript-9.25~dfsg+1/base/gxshade.h --- ghostscript-9.10~dfsg/base/gxshade.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxshade.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -140,7 +140,7 @@ /* Initialize a packed value stream. */ void shade_next_init(shade_coord_stream_t * cs, const gs_shading_mesh_params_t * params, - const gs_imager_state * pis); + const gs_gstate * pgs); /* Get the next flag value. */ int shade_next_flag(shade_coord_stream_t * cs, int BitsPerFlag); @@ -194,12 +194,13 @@ */ #define shading_fill_state_common\ gx_device *dev;\ - gs_imager_state *pis;\ + gs_gstate *pgs;\ const gs_color_space *direct_space;\ int num_components; /* # of color components in direct_space */\ float cc_max_error[GS_CLIENT_COLOR_MAX_COMPONENTS];\ gx_device *trans_device;\ - gsicc_link_t *icclink + gsicc_link_t *icclink;\ + bool cs_always_linear typedef struct shading_fill_state_s { shading_fill_state_common; @@ -208,7 +209,7 @@ /* Initialize the common parts of the recursion state. */ int shade_init_fill_state(shading_fill_state_t * pfs, const gs_shading_t * psh, gx_device * dev, - gs_imager_state * pis); + gs_gstate * pgs); /* Fill one piece of a shading. */ #ifndef gx_device_color_DEFINED diff -Nru ghostscript-9.10~dfsg/base/gxstate.h ghostscript-9.25~dfsg+1/base/gxstate.h --- ghostscript-9.10~dfsg/base/gxstate.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxstate.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,9 +20,9 @@ # define gxstate_INCLUDED /* Opaque type for a graphics state */ -#ifndef gs_state_DEFINED -# define gs_state_DEFINED -typedef struct gs_state_s gs_state; +#ifndef gs_gstate_DEFINED +# define gs_gstate_DEFINED +typedef struct gs_gstate_s gs_gstate; #endif #include "gscspace.h" @@ -34,10 +34,10 @@ */ /* Memory and save/restore management */ -gs_memory_t *gs_state_memory(const gs_state *); -gs_state *gs_state_saved(const gs_state *); -gs_state *gs_state_swap_saved(gs_state *, gs_state *); -gs_memory_t *gs_state_swap_memory(gs_state *, gs_memory_t *); +gs_memory_t *gs_gstate_memory(const gs_gstate *); +gs_gstate *gs_gstate_saved(const gs_gstate *); +gs_gstate *gs_gstate_swap_saved(gs_gstate *, gs_gstate *); +gs_memory_t *gs_gstate_swap_memory(gs_gstate *, gs_memory_t *); /* * "Client data" interface for graphics states. @@ -45,9 +45,9 @@ * As of release 4.36, the copy procedure is superseded by copy_for * (although it will still be called if there is no copy_for procedure). */ -typedef void *(*gs_state_alloc_proc_t) (gs_memory_t * mem); -typedef int (*gs_state_copy_proc_t) (void *to, const void *from); -typedef void (*gs_state_free_proc_t) (void *old, gs_memory_t * mem); +typedef void *(*gs_gstate_alloc_proc_t) (gs_memory_t * mem); +typedef int (*gs_gstate_copy_proc_t) (void *to, const void *from); +typedef void (*gs_gstate_free_proc_t) (void *old, gs_memory_t * mem); typedef enum { copy_for_gsave, /* from = current, to = new(saved) */ @@ -56,27 +56,27 @@ copy_for_setgstate, /* from = stored, to = current */ copy_for_copygstate, /* from & to are specified explicitly */ copy_for_currentgstate /* from = current, to = stored */ -} gs_state_copy_reason_t; +} gs_gstate_copy_reason_t; /* Note that the 'from' argument of copy_for is not const. */ /* This is deliberate -- some clients need this. */ -typedef int (*gs_state_copy_for_proc_t) (void *to, void *from, - gs_state_copy_reason_t reason); -typedef struct gs_state_client_procs_s { - gs_state_alloc_proc_t alloc; - gs_state_copy_proc_t copy; - gs_state_free_proc_t free; - gs_state_copy_for_proc_t copy_for; -} gs_state_client_procs; -void gs_state_set_client(gs_state *, void *, const gs_state_client_procs *, +typedef int (*gs_gstate_copy_for_proc_t) (void *to, void *from, + gs_gstate_copy_reason_t reason); +typedef struct gs_gstate_client_procs_s { + gs_gstate_alloc_proc_t alloc; + gs_gstate_copy_proc_t copy; + gs_gstate_free_proc_t free; + gs_gstate_copy_for_proc_t copy_for; +} gs_gstate_client_procs; +void gs_gstate_set_client(gs_gstate *, void *, const gs_gstate_client_procs *, bool client_has_pattern_streams); /* gzstate.h redefines the following: */ -#ifndef gs_state_client_data -void *gs_state_client_data(const gs_state *); +#ifndef gs_gstate_client_data +void *gs_gstate_client_data(const gs_gstate *); #endif /* Accessories. */ -gs_id gx_get_clip_path_id(gs_state *); +gs_id gx_get_clip_path_id(gs_gstate *); #endif /* gxstate_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gxstdio.h ghostscript-9.25~dfsg+1/base/gxstdio.h --- ghostscript-9.10~dfsg/base/gxstdio.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxstdio.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gxstroke.c ghostscript-9.25~dfsg+1/base/gxstroke.c --- ghostscript-9.10~dfsg/base/gxstroke.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxstroke.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -29,12 +29,11 @@ #include "gsdevice.h" #include "gxdevice.h" #include "gxhttile.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gzline.h" #include "gzpath.h" #include "gzcpath.h" #include "gxpaint.h" -#include "vdtrace.h" #include "gsstate.h" /* for gs_currentcpsimode */ /* RJW: There appears to be a difference in the xps and postscript models @@ -59,10 +58,10 @@ #define USE_FILL_ADJUSTMENT #ifdef USE_FILL_ADJUSTMENT -# define STROKE_ADJUSTMENT(thin, pis, xy)\ - (thin ? fixed_0 : (pis)->fill_adjust.xy) +# define STROKE_ADJUSTMENT(thin, pgs, xy)\ + (thin ? fixed_0 : (pgs)->fill_adjust.xy) #else -# define STROKE_ADJUSTMENT(thin, pis, xy) fixed_0 +# define STROKE_ADJUSTMENT(thin, pgs, xy) fixed_0 #endif /* @@ -101,34 +100,34 @@ * check and covers many common cases. Clients that care always have the * option of using strokepath to get an exact result. */ -static float join_expansion_factor(const gs_imager_state *, gs_line_join); +static float join_expansion_factor(const gs_gstate *, gs_line_join); int -gx_stroke_path_expansion(const gs_imager_state * pis, const gx_path * ppath, +gx_stroke_path_expansion(const gs_gstate * pgs, const gx_path * ppath, gs_fixed_point * ppt) { const subpath *psub = ppath->first_subpath; const segment *pseg; - double cx = fabs(pis->ctm.xx) + fabs(pis->ctm.yx); - double cy = fabs(pis->ctm.xy) + fabs(pis->ctm.yy); - double expand = pis->line_params.half_width; + double cx = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yx); + double cy = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yy); + double expand = pgs->line_params.half_width; int result = 1; /* Adjust the expansion (E) for square caps, if needed */ - if (pis->line_params.start_cap == gs_cap_square || - pis->line_params.end_cap == gs_cap_square) + if (pgs->line_params.start_cap == gs_cap_square || + pgs->line_params.end_cap == gs_cap_square) expand *= 1.414213562; /* Check for whether an exact result can be computed easily. */ - if (is_fzero2(pis->ctm.xy, pis->ctm.yx) || - is_fzero2(pis->ctm.xx, pis->ctm.yy) + if (is_fzero2(pgs->ctm.xy, pgs->ctm.yx) || + is_fzero2(pgs->ctm.xx, pgs->ctm.yy) ) { bool must_be_closed = - !(pis->line_params.start_cap == gs_cap_square || - pis->line_params.start_cap == gs_cap_round || - pis->line_params.end_cap == gs_cap_square || - pis->line_params.end_cap == gs_cap_round || - pis->line_params.dash_cap == gs_cap_square || - pis->line_params.dash_cap == gs_cap_round); + !(pgs->line_params.start_cap == gs_cap_square || + pgs->line_params.start_cap == gs_cap_round || + pgs->line_params.end_cap == gs_cap_square || + pgs->line_params.end_cap == gs_cap_round || + pgs->line_params.dash_cap == gs_cap_square || + pgs->line_params.dash_cap == gs_cap_round); gs_fixed_point prev; prev.x = prev.y = 0; /* Quiet gcc warning. */ @@ -161,11 +160,11 @@ (pseg = pseg->next) == 0 || pseg->type == s_line_close)) DO_NOTHING; else { - float factor = join_expansion_factor(pis, pis->line_params.join); + float factor = join_expansion_factor(pgs, pgs->line_params.join); - if (pis->line_params.curve_join >= 0) - factor = max(factor, join_expansion_factor(pis, - (gs_line_join)pis->line_params.curve_join)); + if (pgs->line_params.curve_join >= 0) + factor = max(factor, join_expansion_factor(pgs, + (gs_line_join)pgs->line_params.curve_join)); expand *= factor; } } @@ -186,10 +185,10 @@ return result; } static float -join_expansion_factor(const gs_imager_state *pis, gs_line_join join) +join_expansion_factor(const gs_gstate *pgs, gs_line_join join) { switch (join) { - case gs_join_miter: return pis->line_params.miter_limit; + case gs_join_miter: return pgs->line_params.miter_limit; case gs_join_triangle: return 2.0; default: return 1.0; } @@ -297,7 +296,7 @@ /* Other forward declarations */ static bool width_is_thin(pl_ptr); -static void adjust_stroke(gx_device *, pl_ptr, const gs_imager_state *, bool, bool, note_flags); +static void adjust_stroke(gx_device *, pl_ptr, const gs_gstate *, bool, bool, note_flags); static int line_join_points(const gx_line_params * pgs_lp, pl_ptr plp, pl_ptr nplp, gs_fixed_point * join_points, @@ -327,28 +326,28 @@ /* Define the default implementation of the device stroke_path procedure. */ int -gx_default_stroke_path(gx_device * dev, const gs_imager_state * pis, +gx_default_stroke_path(gx_device * dev, const gs_gstate * pgs, gx_path * ppath, const gx_stroke_params * params, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) { - return gx_stroke_path_only(ppath, (gx_path *) 0, dev, pis, params, + return gx_stroke_path_only(ppath, (gx_path *) 0, dev, pgs, params, pdcolor, pcpath); } /* Fill a partial stroked path. Free variables: */ -/* to_path, stroke_path_body, fill_params, always_thin, pis, dev, pdevc, */ +/* to_path, stroke_path_body, fill_params, always_thin, pgs, dev, pdevc, */ /* code, ppath, exit(label). */ #define FILL_STROKE_PATH(dev, thin, pcpath, final)\ if(to_path==&stroke_path_body && !gx_path_is_void(&stroke_path_body) &&\ - (final || lop_is_idempotent(pis->log_op))) {\ - fill_params.adjust.x = STROKE_ADJUSTMENT(thin, pis, x);\ - fill_params.adjust.y = STROKE_ADJUSTMENT(thin, pis, y);\ + (final || lop_is_idempotent(pgs->log_op))) {\ + fill_params.adjust.x = STROKE_ADJUSTMENT(thin, pgs, x);\ + fill_params.adjust.y = STROKE_ADJUSTMENT(thin, pgs, y);\ if (to_path_reverse != NULL) {\ code = gx_join_path_and_reverse(to_path, to_path_reverse);\ if(code < 0) goto exit;\ }\ - code = gx_fill_path_only(to_path, dev, pis, &fill_params, pdevc, pcpath);\ + code = gx_fill_path_only(to_path, dev, pgs, &fill_params, pdevc, pcpath);\ gx_path_free(&stroke_path_body, "fill_stroke_path");\ if ( code < 0 ) goto exit;\ gx_path_init_local(&stroke_path_body, ppath->memory);\ @@ -363,7 +362,7 @@ */ #define stroke_line_proc(proc)\ int proc(gx_path *, gx_path *, bool ensure_closed, int, pl_ptr, pl_ptr,\ - const gx_device_color *, gx_device *, const gs_imager_state *,\ + const gx_device_color *, gx_device *, const gs_gstate *,\ const gx_stroke_params *, const gs_fixed_rect *, int,\ gs_line_join, bool, note_flags) typedef stroke_line_proc((*stroke_line_proc_t)); @@ -374,7 +373,7 @@ static stroke_line_proc(stroke_fill); static int stroke_add_initial_cap_compat(gx_path * ppath, pl_ptr plp, bool adlust_longitude, const gx_device_color * pdevc, gx_device * dev, - const gs_imager_state * pis); + const gs_gstate * pgs); /* Define the orientations we handle specially. */ typedef enum { @@ -419,29 +418,29 @@ */ static int gx_stroke_path_only_aux(gx_path * ppath, gx_path * to_path, gx_device * pdev, - const gs_imager_state * pis, const gx_stroke_params * params, + const gs_gstate * pgs, const gx_stroke_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { - bool CPSI_mode = gs_currentcpsimode(pis->memory); + bool CPSI_mode = gs_currentcpsimode(pgs->memory); bool traditional = CPSI_mode | params->traditional; stroke_line_proc_t line_proc = ((to_path == 0 && !gx_dc_is_pattern1_color_clist_based(pdevc)) - ? stroke_fill : + ? (lop_is_idempotent(pgs->log_op) ? stroke_fill : stroke_add) : (traditional ? stroke_add_compat : stroke_add_fast)); gs_fixed_rect ibox, cbox; gx_device_clip cdev; gx_device *dev = pdev; int code = 0; gx_fill_params fill_params; - const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis); + const gx_line_params *pgs_lp = gs_currentlineparams_inline(pgs); int dash_count = pgs_lp->dash.pattern_size; gx_path fpath, dpath; gx_path stroke_path_body; gx_path stroke_path_reverse; gx_path *to_path_reverse = NULL; const gx_path *spath; - float xx = pis->ctm.xx, xy = pis->ctm.xy; - float yx = pis->ctm.yx, yy = pis->ctm.yy; + float xx = pgs->ctm.xx, xy = pgs->ctm.xy; + float yx = pgs->ctm.yx, yy = pgs->ctm.yy; /* * We are dealing with a reflected coordinate system * if transform(1,0) is counter-clockwise from transform(0,1). @@ -466,19 +465,7 @@ (uniform = 0, reflected = xy * yx > xx * yy, orient_other)); - /* - * Formerly, there was a hack here that only treated the joins of - * flattened curves specially if the dot length was non-zero. - * This was a surrogate to detect use of the library by PCL - * interpreters. We have replaced this hack with an explicit - * curve join parameter in the graphics state. - */ -#if 0 - segment_notes not_first = - (!is_fzero(pis->line_params.dot_length) ? sn_not_first : sn_none); -#else const segment_notes not_first = sn_not_first; -#endif gs_line_join curve_join = (pgs_lp->curve_join >= 0 ? (gs_line_join)pgs_lp->curve_join : pgs_lp->join == gs_join_none || pgs_lp->join == gs_join_round ? @@ -499,7 +486,6 @@ #ifdef DEBUG if (gs_debug_c('o')) { - int count = pgs_lp->dash.pattern_size; int i; dmlprintf4(ppath->memory, "[o]half_width=%f, start_cap=%d, end_cap=%d, dash_cap=%d,\n", @@ -508,8 +494,8 @@ dmlprintf3(ppath->memory, " join=%d, miter_limit=%f, miter_check=%f,\n", (int)pgs_lp->join, pgs_lp->miter_limit, pgs_lp->miter_check); - dmlprintf1(ppath->memory, " dash pattern=%d", count); - for (i = 0; i < count; i++) + dmlprintf1(ppath->memory, " dash pattern=%d", dash_count); + for (i = 0; i < dash_count; i++) dmprintf1(ppath->memory, ",%f", pgs_lp->dash.pattern[i]); dmputs(ppath->memory, ",\n"); dmlprintf4(ppath->memory, "\toffset=%f, init(ink_on=%d, index=%d, dist_left=%f)\n", @@ -523,13 +509,13 @@ { gs_fixed_point expansion; - if (gx_stroke_path_expansion(pis, ppath, &expansion) < 0) { + if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) { /* The expansion is so large it caused a limitcheck. */ ibox.p.x = ibox.p.y = min_fixed; ibox.q.x = ibox.q.y = max_fixed; } else { - expansion.x += pis->fill_adjust.x; - expansion.y += pis->fill_adjust.y; + expansion.x += pgs->fill_adjust.x; + expansion.y += pgs->fill_adjust.y; /* * It's theoretically possible for the following computations to * overflow, so we need to check for this. @@ -596,7 +582,7 @@ } } fill_params.rule = gx_rule_winding_number; - fill_params.flatness = pis->flatness; + fill_params.flatness = pgs->flatness; if (line_width < 0) line_width = -line_width; line_width_and_scale = line_width * (double)int2fixed(1); @@ -645,7 +631,7 @@ } } if_debug7m('o', ppath->memory, "[o]ctm=(%g,%g,%g,%g,%g,%g) thin=%d\n", - xx, xy, yx, yy, pis->ctm.tx, pis->ctm.ty, always_thin); + xx, xy, yx, yy, pgs->ctm.tx, pgs->ctm.ty, always_thin); if (device_dot_length != 0) { /* * Compute the dot length in device space. We can't do this @@ -658,7 +644,7 @@ gs_deviceinitialmatrix(pdev, &mat); pmat = &mat; } else - pmat = (const gs_matrix *)&pis->ctm; + pmat = (const gs_matrix *)&pgs->ctm; device_dot_length *= fabs(pmat->xy) + fabs(pmat->yy); } /* Start by flattening the path. We should do this on-the-fly.... */ @@ -670,17 +656,39 @@ } else { gx_path_init_local(&fpath, ppath->memory); if ((code = gx_path_add_flattened_for_stroke(ppath, &fpath, - params->flatness, pis)) < 0 + params->flatness, pgs)) < 0 ) return code; spath = &fpath; } if (dash_count) { - gx_path_init_local(&dpath, ppath->memory); - code = gx_path_add_dash_expansion(spath, &dpath, pis); - if (code < 0) - goto exf; - spath = &dpath; + float max_dash_len = 0; + float expand_squared; + int i; + float adjust = (float)pgs->fill_adjust.x; + if (adjust > (float)pgs->fill_adjust.y) + adjust = (float)pgs->fill_adjust.y; + for (i = 0; i < dash_count; i++) { + if (max_dash_len < pgs_lp->dash.pattern[i]) + max_dash_len = pgs_lp->dash.pattern[i]; + } + expand_squared = pgs->ctm.xx * pgs->ctm.yy - pgs->ctm.xy * pgs->ctm.yx; + if (expand_squared < 0) + expand_squared = -expand_squared; + expand_squared *= max_dash_len * max_dash_len; + /* Wide lines in curves can show dashes up, so fudge to allow for + * this. */ + if (pgs->line_params.half_width > 1) + adjust /= pgs->line_params.half_width; + if (expand_squared*65536.0f >= (float)(adjust*adjust)) { + gx_path_init_local(&dpath, ppath->memory); + code = gx_path_add_dash_expansion(spath, &dpath, pgs); + if (code < 0) + goto exf; + spath = &dpath; + } else { + dash_count = 0; + } } if (to_path == 0) { /* We might try to defer this if it's expensive.... */ @@ -699,6 +707,7 @@ bool is_closed = ((const subpath *)pseg)->is_closed; partial_line pl, pl_prev, pl_first; bool zero_length = true; + int pseg_notes = pseg->notes; flags = nf_all_from_arc; @@ -712,9 +721,12 @@ /* Compute the width parameters in device space. */ /* We work with unscaled values, for speed. */ fixed sx, udx, sy, udy; - bool is_dash_segment = false; + bool is_dash_segment; + + pseg_notes = pseg->notes; - d1:if (pseg->type == s_dash) { + d2:is_dash_segment = false; + d1:if (pseg->type == s_dash) { dash_segment *pd = (dash_segment *)pseg; sx = pd->pt.x; @@ -736,10 +748,10 @@ } zero_length &= ((udx | udy) == 0); pl.o.p.x = x, pl.o.p.y = y; - d:flags = (((pseg->notes & sn_not_first) ? + d:flags = (((pseg_notes & sn_not_first) ? ((flags & nf_all_from_arc) | nf_some_from_arc) : 0) | - ((pseg->notes & sn_dash_head) ? nf_dash_head : 0) | - ((pseg->notes & sn_dash_tail) ? nf_dash_tail : 0) | + ((pseg_notes & sn_dash_head) ? nf_dash_head : 0) | + ((pseg_notes & sn_dash_tail) ? nf_dash_tail : 0) | (flags & ~nf_all_from_arc)); pl.e.p.x = sx, pl.e.p.y = sy; if (!(udx | udy) || pseg->type == s_dash || pseg->type == s_gap) { /* degenerate or short */ @@ -749,7 +761,20 @@ * Otherwise, ignore the degenerate segment. */ if (index != 0 && pseg->type != s_dash && pseg->type != s_gap) - continue; + { + if (pseg->next == NULL || pseg->next->type == s_start) + continue; + pseg = pseg->next; + /* We're skipping a degenerate path segment; if it was + * labelled as being the first from a curve, then make + * sure the one we're skipping to is also labelled as + * being the first from a curve, otherwise we can get + * improper joins being used. See Bug 696466. */ + pseg_notes = (((pseg_notes & sn_not_first) == 0) ? + (pseg->notes & ~sn_not_first) : + pseg->notes); + goto d2; + } /* Check for a degenerate subpath. */ while ((pseg = pseg->next) != 0 && pseg->type != s_start @@ -867,14 +892,21 @@ gs_point dpt; /* unscaled */ float wl; - gs_imager_idtransform(pis, - (float)udx, (float)udy, &dpt); - wl = line_width_and_scale / - hypot(dpt.x, dpt.y); - /* Construct the width vector in */ - /* user space, still unscaled. */ - dpt.x *= wl; - dpt.y *= wl; + code = gs_gstate_idtransform(pgs, + (float)udx, (float)udy, + &dpt); + if (code < 0) { + dpt.x = 0; dpt.y = 0; + /* Swallow the error */ + code = 0; + } else { + wl = line_width_and_scale / + hypot(dpt.x, dpt.y); + /* Construct the width vector in */ + /* user space, still unscaled. */ + dpt.x *= wl; + dpt.y *= wl; + } /* * We now compute both perpendicular @@ -904,7 +936,7 @@ if (!pl.thin) { if (index) dev->sgr.stroke_stored = false; - adjust_stroke(dev, &pl, pis, false, + adjust_stroke(dev, &pl, pgs, false, (pseg->prev == 0 || pseg->prev->type == s_start) && (pseg->next == 0 || pseg->next->type == s_start) && (zero_length || !is_closed), @@ -914,7 +946,7 @@ } if (index++) { gs_line_join join = - (pseg->notes & not_first ? curve_join : pgs_lp->join); + (pseg_notes & not_first ? curve_join : pgs_lp->join); int first; pl_ptr lptr; bool ensure_closed; @@ -942,13 +974,13 @@ } ensure_closed = ((to_path == &stroke_path_body && - lop_is_idempotent(pis->log_op)) || + lop_is_idempotent(pgs->log_op)) || (lptr == NULL ? true : lptr->thin)); /* Draw the PREVIOUS line segment, joining it to lptr (or * capping if lptr == NULL. */ code = (*line_proc) (to_path, to_path_reverse, ensure_closed, first, &pl_prev, lptr, - pdevc, dev, pis, params, &cbox, + pdevc, dev, pgs, params, &cbox, uniform, join, initial_matrix_reflected, COMBINE_FLAGS(flags)); if (code < 0) @@ -993,7 +1025,7 @@ (flags & ~nf_all_from_arc)); code = (*line_proc) (to_path, to_path_reverse, true, index - 1, &pl_prev, lptr, pdevc, - dev, pis, params, &cbox, uniform, join, + dev, pgs, params, &cbox, uniform, join, initial_matrix_reflected, COMBINE_FLAGS(flags)); if (code < 0) @@ -1003,7 +1035,7 @@ pgs_lp->start_cap : pgs_lp->dash_cap); if (traditional && lptr == 0 && cap != gs_cap_butt) { /* Create the initial cap at last. */ - code = stroke_add_initial_cap_compat(to_path, &pl_first, index == 1, pdevc, dev, pis); + code = stroke_add_initial_cap_compat(to_path, &pl_first, index == 1, pdevc, dev, pgs); if (code < 0) goto exit; FILL_STROKE_PATH(pdev, always_thin, pcpath, false); @@ -1031,26 +1063,10 @@ int gx_stroke_path_only(gx_path * ppath, gx_path * to_path, gx_device * pdev, - const gs_imager_state * pis, const gx_stroke_params * params, + const gs_gstate * pgs, const gx_stroke_params * params, const gx_device_color * pdevc, const gx_clip_path * pcpath) { - int code; - - if (vd_allowed('S')) { - vd_get_dc('S'); - if (vd_enabled) { - vd_set_shift(0, 100); - vd_set_scale(0.03); - vd_set_origin(0, 0); - vd_erase(RGB(192, 192, 192)); - } - } - if (vd_enabled) - vd_setcolor(pdevc->colors.pure); - code = gx_stroke_path_only_aux(ppath, to_path, pdev, pis, params, pdevc, pcpath); - if (vd_allowed('S')) - vd_release_dc; - return code; + return gx_stroke_path_only_aux(ppath, to_path, pdev, pgs, params, pdevc, pcpath); } /* ------ Internal routines ------ */ @@ -1099,7 +1115,7 @@ /* Adjust the endpoints and width of a stroke segment along a specified axis */ static void -adjust_stroke_transversal(pl_ptr plp, const gs_imager_state * pis, bool thin, bool horiz) +adjust_stroke_transversal(pl_ptr plp, const gs_gstate * pgs, bool thin, bool horiz) { fixed *pw; fixed *pov; @@ -1110,11 +1126,11 @@ if (horiz) { /* More horizontal stroke */ pw = &plp->width.y, pov = &plp->o.p.y, pev = &plp->e.p.y; - adj2 = STROKE_ADJUSTMENT(thin, pis, y) << 1; + adj2 = STROKE_ADJUSTMENT(thin, pgs, y) << 1; } else { /* More vertical stroke */ pw = &plp->width.x, pov = &plp->o.p.x, pev = &plp->e.p.x; - adj2 = STROKE_ADJUSTMENT(thin, pis, x) << 1; + adj2 = STROKE_ADJUSTMENT(thin, pgs, x) << 1; } /* Round the larger component of the width up or down, */ /* whichever way produces a result closer to the correct width. */ @@ -1147,7 +1163,7 @@ } static void -adjust_stroke_longitude(pl_ptr plp, const gs_imager_state * pis, +adjust_stroke_longitude(pl_ptr plp, const gs_gstate * pgs, bool thin, bool horiz, gs_line_cap start_cap, gs_line_cap end_cap) { @@ -1163,8 +1179,8 @@ fixed length = any_abs(*pov - *pev); fixed length_r, length_r_2; fixed mv = (*pov + *pev) / 2, mv_r; - fixed adj2 = (horiz ? STROKE_ADJUSTMENT(thin, pis, x) - : STROKE_ADJUSTMENT(thin, pis, y)) << 1; + fixed adj2 = (horiz ? STROKE_ADJUSTMENT(thin, pgs, x) + : STROKE_ADJUSTMENT(thin, pgs, y)) << 1; /* fixme : The best value for adjust_longitude is whether @@ -1204,20 +1220,20 @@ /* to achieve more uniform rendering. */ /* Only o.p, e.p, e.cdelta, and width have been set. */ static void -adjust_stroke(gx_device *dev, pl_ptr plp, const gs_imager_state * pis, +adjust_stroke(gx_device *dev, pl_ptr plp, const gs_gstate * pgs, bool thin, bool adjust_longitude, note_flags flags) { bool horiz, adjust = true; gs_line_cap start_cap = (flags & nf_dash_head ? - pis->line_params.dash_cap : - pis->line_params.start_cap); + pgs->line_params.dash_cap : + pgs->line_params.start_cap); gs_line_cap end_cap = (flags & nf_dash_tail ? - pis->line_params.dash_cap : - pis->line_params.end_cap); + pgs->line_params.dash_cap : + pgs->line_params.end_cap); /* If stroke_adjustment is disabled, or this isn't a horizontal or * vertical line, then bale. */ - if (!pis->stroke_adjust || (plp->width.x != 0 && plp->width.y != 0)) { + if (!pgs->stroke_adjust || (plp->width.x != 0 && plp->width.y != 0)) { dev->sgr.stroke_stored = false; return; /* don't adjust */ } @@ -1300,9 +1316,9 @@ dev->sgr.stroke_stored = false; if (adjust) { horiz = (any_abs(plp->width.x) <= any_abs(plp->width.y)); - adjust_stroke_transversal(plp, pis, thin, horiz); + adjust_stroke_transversal(plp, pgs, thin, horiz); if (adjust_longitude) - adjust_stroke_longitude(plp, pis, thin, horiz, start_cap, end_cap); + adjust_stroke_longitude(plp, pgs, thin, horiz, start_cap, end_cap); } if ((start_cap == gs_cap_butt) || (end_cap == gs_cap_butt)) { dev->sgr.adjusted[0] = plp->o.p; @@ -1385,7 +1401,7 @@ static int stroke_fill(gx_path * ppath, gx_path * rpath, bool ensure_closed, int first, register pl_ptr plp, pl_ptr nplp, const gx_device_color * pdevc, - gx_device * dev, const gs_imager_state * pis, + gx_device * dev, const gs_gstate * pgs, const gx_stroke_params * params, const gs_fixed_rect * pbbox, int uniform, gs_line_join join, bool reflected, note_flags flags) @@ -1395,16 +1411,17 @@ const fixed litox = plp->e.p.x; const fixed litoy = plp->e.p.y; + /* assert(lop_is_idempotent(pgs->log_op)); */ if (plp->thin) { /* Minimum-width line, don't have to be careful with caps/joins. */ return (*dev_proc(dev, draw_thin_line))(dev, lix, liy, litox, litoy, - pdevc, pis->log_op, - pis->fill_adjust.x, - pis->fill_adjust.y); + pdevc, pgs->log_op, + pgs->fill_adjust.x, + pgs->fill_adjust.y); } /* Check for being able to fill directly. */ { - const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis); + const gx_line_params *pgs_lp = gs_currentlineparams_inline(pgs); gs_line_cap start_cap = (flags & nf_dash_head ? pgs_lp->dash_cap : pgs_lp->start_cap); gs_line_cap end_cap = (flags & nf_dash_tail ? @@ -1419,8 +1436,7 @@ && (end_cap == gs_cap_butt || end_cap == gs_cap_square) && (join == gs_join_bevel || join == gs_join_miter || join == gs_join_none) - && (pis->fill_adjust.x | pis->fill_adjust.y) == 0 - && lop_is_idempotent(pis->log_op) + && (pgs->fill_adjust.x | pgs->fill_adjust.y) == 0 ) { gs_fixed_point points[6]; int npoints, code; @@ -1432,7 +1448,7 @@ else code = line_join_points(pgs_lp, plp, nplp, points + npoints, (uniform ? (gs_matrix *) 0 : - &ctm_only(pis)), join, reflected); + &ctm_only(pgs)), join, reflected); if (code < 0) goto general; /* Make sure the parallelogram fill won't overflow. */ @@ -1467,7 +1483,7 @@ bevel->x, bevel->y, bevel[1].x - bevel->x, bevel[1].y - bevel->y, bevel[2].x - bevel->x, bevel[2].y - bevel->y, - pdevc, pis->log_op); + pdevc, pgs->log_op); if (code < 0) return code; } @@ -1476,7 +1492,7 @@ return (*dev_proc(dev, fill_parallelogram)) (dev, points[1].x, points[1].y, ax, ay, bx, by, - pdevc, pis->log_op); + pdevc, pgs->log_op); fill: code = add_points(ppath, points, npoints + code, true); if (code < 0) @@ -1487,7 +1503,7 @@ /* General case: construct a path for the fill algorithm. */ general: return stroke_add(ppath, rpath, ensure_closed, first, plp, nplp, pdevc, - dev, pis, params, pbbox, uniform, join, reflected, + dev, pgs, params, pbbox, uniform, join, reflected, flags); } @@ -1495,12 +1511,12 @@ static int stroke_add(gx_path * ppath, gx_path * rpath, bool ensure_closed, int first, pl_ptr plp, pl_ptr nplp, const gx_device_color * pdevc, - gx_device * dev, const gs_imager_state * pis, + gx_device * dev, const gs_gstate * pgs, const gx_stroke_params * params, const gs_fixed_rect * ignore_pbbox, int uniform, gs_line_join join, bool reflected, note_flags flags) { - const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis); + const gx_line_params *pgs_lp = gs_currentlineparams_inline(pgs); gs_fixed_point points[8]; int npoints; int code; @@ -1514,12 +1530,11 @@ /* We didn't set up the endpoint parameters before, */ /* because the line was thin. Do it now. */ set_thin_widths(plp); - adjust_stroke(dev, plp, pis, true, first == 0 && nplp == 0, flags); + adjust_stroke(dev, plp, pgs, true, first == 0 && nplp == 0, flags); compute_caps(plp); } /* Create an initial cap if desired. */ if (first == 0 && start_cap == gs_cap_round) { - vd_moveto(plp->o.co.x, plp->o.co.y); if ((code = gx_path_add_point(ppath, plp->o.co.x, plp->o.co.y)) < 0 || (code = add_pie_cap(ppath, &plp->o)) < 0) return code; @@ -1534,7 +1549,6 @@ /* Add a final cap. */ if (end_cap == gs_cap_round) { ASSIGN_POINT(&points[npoints], plp->e.co); - vd_lineto(points[npoints].x, points[npoints].y); ++npoints; if ((code = add_points(ppath, points, npoints, moveto_first)) < 0) return code; @@ -1546,7 +1560,6 @@ code = cap_points(gs_cap_butt, &plp->e, points + npoints); else if (join == gs_join_round) { ASSIGN_POINT(&points[npoints], plp->e.co); - vd_lineto(points[npoints].x, points[npoints].y); ++npoints; if ((code = add_points(ppath, points, npoints, moveto_first)) < 0) return code; @@ -1557,7 +1570,6 @@ * then the join should actually be a round one, because it would * have been round if we had flattened it enough. */ ASSIGN_POINT(&points[npoints], plp->e.co); - vd_lineto(points[npoints].x, points[npoints].y); ++npoints; if ((code = add_points(ppath, points, npoints, moveto_first)) < 0) return code; @@ -1565,7 +1577,7 @@ goto done; } else /* non-round join */ code = line_join_points(pgs_lp, plp, nplp, points + npoints, - (uniform ? (gs_matrix *) 0 : &ctm_only(pis)), + (uniform ? (gs_matrix *) 0 : &ctm_only(pgs)), join, reflected); if (code < 0) return code; @@ -1573,25 +1585,68 @@ done: if (code < 0) return code; - vd_closepath; if ((flags & nf_some_from_arc) && (!plp->thin) && (nplp != NULL) && (!nplp->thin)) code = join_under_pie(ppath, plp, nplp, reflected); return gx_path_close_subpath(ppath); } +/* When painting the 'underjoin' (the 'inside' of a join), we + * need to take special care if the curve is particularly wide as + * the leading edge of the underside of the first stroked segment + * may be beyond the leading edge of the underside of the second + * stroked segment. Similarly, the trailing edge of the second + * stroked segment may be behing the trailing edge of the first + * stroked segment. We detect those cases here. + * + * We detect the first case by projecting plp.width onto nplp.vector. + * If the projected vector is longer then nplp.vector, we have a + * problem. + * + * len_vector_squared = nplp.vector.x * nplp.vector.x + nplp.vector.y * nplp.nvector.y + * len_vector = sqr(len_vector_squared) + * len_projection_unnormalised = plp.width.x * nplp.vector.x + plp.width.y * nplp.vector.y + * len_projection = len_projection_unnormalised / len_vector + * + * len_projection > len_vector === len_projection_unnormalised > len_vector * len_vector + * === len_projection_unnormalised > len_vector_squared + */ + +#ifdef SLOWER_BUT_MORE_ACCURATE_STROKING +static bool +wide_underjoin(pl_ptr plp, pl_ptr nplp) +{ + double h_squared = (double)nplp->vector.x * nplp->vector.x + (double)nplp->vector.y * nplp->vector.y; + double dot = (double)plp->width.x * nplp->vector.x + (double)plp->width.y * nplp->vector.y; + + if (dot < 0) + dot = -dot; + if (dot > h_squared) + return 1; + + h_squared = (double)plp->vector.x * plp->vector.x + (double)plp->vector.y * plp->vector.y; + dot = (double)nplp->width.x * plp->vector.x + (double)nplp->width.y * plp->vector.y; + if (dot < 0) + dot = -dot; + if (dot > h_squared) + return 1; + + return 0; +} +#endif + /* Add a segment to the path. * This works by crafting 2 paths, one for each edge, that will later be * merged together. */ static int stroke_add_fast(gx_path * ppath, gx_path * rpath, bool ensure_closed, int first, pl_ptr plp, pl_ptr nplp, const gx_device_color * pdevc, - gx_device * dev, const gs_imager_state * pis, + gx_device * dev, const gs_gstate * pgs, const gx_stroke_params * params, const gs_fixed_rect * ignore_pbbox, int uniform, gs_line_join join, bool reflected, note_flags flags) { - const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis); + const gx_line_params *pgs_lp = gs_currentlineparams_inline(pgs); gs_fixed_point points[8]; gs_fixed_point rpoints[8]; int npoints = 0; @@ -1605,7 +1660,7 @@ /* We didn't set up the endpoint parameters before, */ /* because the line was thin. Do it now. */ set_thin_widths(plp); - adjust_stroke(dev, plp, pis, true, first == 0 && nplp == 0, flags); + adjust_stroke(dev, plp, pgs, true, first == 0 && nplp == 0, flags); compute_caps(plp); } start_cap = (flags & nf_dash_head ? @@ -1624,7 +1679,6 @@ if (first == 0) { /* Create an initial cap. */ if (start_cap == gs_cap_round) { - vd_moveto(plp->o.co.x, plp->o.co.y); if ((code = gx_path_add_point(ppath, plp->o.co.x, plp->o.co.y)) < 0 || (code = add_pie_cap(ppath, &plp->o)) < 0) return code; @@ -1687,21 +1741,21 @@ * line segments generated from arcs to be round. This would * solve some flatness issues, but makes some pathological * cases incredibly slow. */ - if ((join == gs_join_round) - /* || (flags & nf_all_from_arc) */) { + if (join == gs_join_round /* || (flags & nf_all_from_arc) */) { code = add_pie_join_fast_ccw(ppath, plp, nplp, reflected); } else { /* non-round join */ code = line_join_points_fast_ccw(pgs_lp, plp, nplp, points, (uniform ? (gs_matrix *) 0 : - &ctm_only(pis)), + &ctm_only(pgs)), join); npoints = code; } if (code < 0) return code; /* The underjoin */ - if (!(flags & nf_some_from_arc)) { +#ifndef SLOWER_BUT_MORE_ACCURATE_STROKING + if ((flags & (nf_some_from_arc | nf_prev_some_from_arc)) == 0) { /* RJW: This is an approximation. We ought to draw a line * back to nplp->o.p, and then independently fill any exposed * region under the curve with a round join. Sadly, that's @@ -1714,10 +1768,31 @@ * most cases it's close, and results in faster to fill * paths. */ + /* RJW: This goes wrong for some paths, as the 'underjoin' wind + * will be the wrong way. See bug 694971 */ code = gx_path_add_line(rpath, nplp->o.p.x, nplp->o.p.y); if (code < 0) return code; } +#else + if (wide_underjoin(plp, nplp)) + { + code = gx_path_add_line(rpath, nplp->o.p.x, nplp->o.p.y); + if (code < 0) + return code; + if ((flags & (nf_some_from_arc | nf_prev_some_from_arc)) != 0) { + code = gx_path_add_line(rpath, nplp->o.co.x, nplp->o.co.y); + if (code < 0) + return code; + code = gx_path_add_line(rpath, plp->e.ce.x, plp->e.ce.y); + if (code < 0) + return code; + code = gx_path_add_line(rpath, nplp->o.p.x, nplp->o.p.y); + if (code < 0) + return code; + } + } +#endif code = gx_path_add_line(rpath, nplp->o.co.x, nplp->o.co.y); } else { /* CW rotation. Join in the reverse path. "Underjoin" in the @@ -1727,21 +1802,21 @@ * line segments generated from arcs to be round. This would * solve some flatness issues, but makes some pathological * cases incredibly slow. */ - if ((join == gs_join_round) - /* || (flags & nf_all_from_arc) */) { + if (join == gs_join_round /* || (flags & nf_all_from_arc) */) { code = add_pie_join_fast_cw(rpath, plp, nplp, reflected); } else { /* non-round join */ code = line_join_points_fast_cw(pgs_lp, plp, nplp, rpoints, (uniform ? (gs_matrix *) 0 : - &ctm_only(pis)), + &ctm_only(pgs)), join); nrpoints = code; } if (code < 0) return code; /* The underjoin */ - if (!(flags & nf_some_from_arc)) { +#ifndef SLOWER_BUT_MORE_ACCURATE_STROKING + if ((flags & (nf_some_from_arc | nf_prev_some_from_arc)) == 0) { /* RJW: This is an approximation. We ought to draw a line * back to nplp->o.p, and then independently fill any exposed * region under the curve with a round join. Sadly, that's @@ -1754,10 +1829,31 @@ * most cases it's close, and results in faster to fill * paths. */ + /* RJW: This goes wrong for some paths, as the 'underjoin' wind + * will be the wrong way. See bug 694971 */ code = gx_path_add_line(ppath, nplp->o.p.x, nplp->o.p.y); if (code < 0) return code; } +#else + if (wide_underjoin(plp, nplp)) + { + code = gx_path_add_line(ppath, nplp->o.p.x, nplp->o.p.y); + if (code < 0) + return code; + if ((flags & (nf_some_from_arc | nf_prev_some_from_arc)) != 0) { + code = gx_path_add_line(ppath, nplp->o.ce.x, nplp->o.ce.y); + if (code < 0) + return code; + code = gx_path_add_line(ppath, plp->e.co.x, plp->e.co.y); + if (code < 0) + return code; + code = gx_path_add_line(ppath, nplp->o.p.x, nplp->o.p.y); + if (code < 0) + return code; + } + } +#endif code = gx_path_add_line(ppath, nplp->o.ce.x, nplp->o.ce.y); } } @@ -1773,7 +1869,6 @@ if (code < 0) return code; } - vd_closepath; if (ensure_closed) return gx_join_path_and_reverse(ppath, rpath); return 0; @@ -1789,7 +1884,7 @@ stroke_add_compat(gx_path * ppath, gx_path *rpath, bool ensure_closed, int first, pl_ptr plp, pl_ptr nplp, const gx_device_color * pdevc, gx_device * dev, - const gs_imager_state * pis, + const gs_gstate * pgs, const gx_stroke_params * params, const gs_fixed_rect * ignore_pbbox, int uniform, gs_line_join join, bool reflected, note_flags flags) @@ -1797,7 +1892,7 @@ /* Actually it adds 2 contours : one for the segment itself, and another one for line join or for the ending cap. Note CPSI creates negative contours. */ - const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis); + const gx_line_params *pgs_lp = gs_currentlineparams_inline(pgs); gs_fixed_point points[5]; int npoints; bool const moveto_first = true; /* Keeping this code closer to "stroke_add". */ @@ -1807,7 +1902,7 @@ /* We didn't set up the endpoint parameters before, */ /* because the line was thin. Do it now. */ set_thin_widths(plp); - adjust_stroke(dev, plp, pis, true, first == 0 && nplp == 0, flags); + adjust_stroke(dev, plp, pgs, true, first == 0 && nplp == 0, flags); compute_caps(plp); } /* The segment itself : */ @@ -1821,7 +1916,6 @@ code = gx_path_close_subpath(ppath); if (code < 0) return code; - vd_closepath; npoints = 0; if (nplp == 0) { /* Add a final cap. */ @@ -1829,7 +1923,6 @@ return 0; if (pgs_lp->start_cap == gs_cap_round) { ASSIGN_POINT(&points[npoints], plp->e.co); - vd_lineto(points[npoints].x, points[npoints].y); ++npoints; if ((code = add_points(ppath, points, npoints, moveto_first)) < 0) return code; @@ -1845,7 +1938,6 @@ npoints += code; } else if (join == gs_join_round) { ASSIGN_POINT(&points[npoints], plp->e.co); - vd_lineto(points[npoints].x, points[npoints].y); ++npoints; if ((code = add_points(ppath, points, npoints, moveto_first)) < 0) return code; @@ -1859,10 +1951,9 @@ if (ccw ^ reflected) { ASSIGN_POINT(&points[0], plp->e.co); - vd_lineto(points[0].x, points[0].y); ++npoints; code = line_join_points(pgs_lp, plp, nplp, points + npoints, - (uniform ? (gs_matrix *) 0 : &ctm_only(pis)), + (uniform ? (gs_matrix *) 0 : &ctm_only(pgs)), join, reflected); if (code < 0) return code; @@ -1870,7 +1961,7 @@ npoints += code; } else { code = line_join_points(pgs_lp, plp, nplp, points, - (uniform ? (gs_matrix *) 0 : &ctm_only(pis)), + (uniform ? (gs_matrix *) 0 : &ctm_only(pgs)), join, reflected); if (code < 0) return code; @@ -1882,7 +1973,6 @@ if (code < 0) return code; code = gx_path_close_subpath(ppath); - vd_closepath; return code; } @@ -1895,10 +1985,10 @@ static int stroke_add_initial_cap_compat(gx_path * ppath, pl_ptr plp, bool adlust_longitude, const gx_device_color * pdevc, gx_device * dev, - const gs_imager_state * pis) + const gs_gstate * pgs) { - const gx_line_params *pgs_lp = gs_currentlineparams_inline(pis); - gs_fixed_point points[4]; + const gx_line_params *pgs_lp = gs_currentlineparams_inline(pgs); + gs_fixed_point points[5]; int npoints = 0; int code; @@ -1908,12 +1998,11 @@ /* We didn't set up the endpoint parameters before, */ /* because the line was thin. Do it now. */ set_thin_widths(plp); - adjust_stroke(dev, plp, pis, true, adlust_longitude, 0); + adjust_stroke(dev, plp, pgs, true, adlust_longitude, 0); compute_caps(plp); } /* Create an initial cap if desired. */ if (pgs_lp->start_cap == gs_cap_round) { - vd_moveto(plp->o.co.x, plp->o.co.y); if ((code = gx_path_add_point(ppath, plp->o.co.x, plp->o.co.y)) < 0 || (code = add_round_cap(ppath, &plp->o)) < 0 ) @@ -1941,17 +2030,12 @@ { int code; - /* vd_setcolor(0); */ - vd_setlinewidth(0); if (moveto_first) { code = gx_path_add_point(ppath, points[0].x, points[0].y); - vd_moveto(points[0].x, points[0].y); if (code < 0) return code; - vd_lineto_multi(points + 1, npoints - 1); return gx_path_add_lines(ppath, points + 1, npoints - 1); } else { - vd_lineto_multi(points, npoints); return gx_path_add_lines(ppath, points, npoints); } } @@ -2367,7 +2451,6 @@ (code = gx_path_add_line(ppath, xe, ye)) < 0 ) return code; - vd_lineto(xe, ye); return 0; } @@ -2385,7 +2468,6 @@ quarter_arc_fraction)) < 0 || (code = gx_path_add_line(ppath, xe, ye)) < 0) return code; - vd_lineto(xe, ye); return 0; } @@ -2506,7 +2588,6 @@ (code = gx_path_add_line(ppath, plp->e.ce.x, plp->e.ce.y)) < 0)) return code; - vd_lineto(plp->e.ce.x, plp->e.ce.y); return 0; } diff -Nru ghostscript-9.10~dfsg/base/gxsync.c ghostscript-9.25~dfsg+1/base/gxsync.c --- ghostscript-9.10~dfsg/base/gxsync.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxsync.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -76,6 +76,14 @@ } } +gx_semaphore_t *(gx_semaphore_label)(gx_semaphore_t *sema, const char *name) +{ + (void)name; + if (sema) + gp_semaphore_label(&sema->native, name); + return sema; +} + /* Macros defined in gxsync.h, but redefined here so compiler chex consistency */ #define gx_semaphore_wait(sema) gp_semaphore_wait(&(sema)->native) #define gx_semaphore_signal(sema) gp_semaphore_signal(&(sema)->native) @@ -129,6 +137,15 @@ } } +gx_monitor_t * +(gx_monitor_label)(gx_monitor_t *mon, const char *name) +{ + (void)name; + if (mon) + gp_monitor_label(&mon->native, name); + return mon; +} + /* Macros defined in gxsync.h, but redefined here so compiler chex consistency */ #define gx_monitor_enter(sema) gp_monitor_enter(&(sema)->native) #define gx_monitor_leave(sema) gp_monitor_leave(&(sema)->native) diff -Nru ghostscript-9.10~dfsg/base/gxsync.h ghostscript-9.25~dfsg+1/base/gxsync.h --- ghostscript-9.10~dfsg/base/gxsync.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxsync.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -45,6 +45,11 @@ gx_semaphore_t * sema /* semaphore to delete */ ); +gx_semaphore_t *gx_semaphore_label(gx_semaphore_t *mon, const char *name); +#ifndef BOBBIN +#define gx_semaphore_label(A,B) (A) +#endif + #define gx_semaphore_wait(sema) gp_semaphore_wait(&(sema)->native) #define gx_semaphore_signal(sema) gp_semaphore_signal(&(sema)->native) @@ -65,6 +70,11 @@ gx_monitor_t * mon /* monitor to delete */ ); +gx_monitor_t *gx_monitor_label(gx_monitor_t *mon, const char *name); +#ifndef BOBBIN +#define gx_monitor_label(A,B) (A) +#endif + #define gx_monitor_enter(sema) gp_monitor_enter(&(sema)->native) #define gx_monitor_leave(sema) gp_monitor_leave(&(sema)->native) diff -Nru ghostscript-9.10~dfsg/base/gxtext.h ghostscript-9.25~dfsg+1/base/gxtext.h --- ghostscript-9.10~dfsg/base/gxtext.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxtext.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -21,6 +21,7 @@ #include "gstext.h" #include "gsrefct.h" +#include "gxfixed.h" /* Define the abstract type for the object procedures. */ typedef struct gs_text_enum_procs_s gs_text_enum_procs_t; @@ -65,6 +66,54 @@ gx_font_stack_item_t items[1 + MAX_FONT_STACK]; } gx_font_stack_t; +/* An enumeration object for string display. */ +typedef enum { + sws_none, + sws_cache, /* setcachedevice[2] */ + sws_no_cache, /* setcharwidth */ + sws_cache_width_only, /* setcharwidth for xfont char */ + sws_retry /* retry setcachedevice[2] */ +} show_width_status; + +/* The type of cached characters is opaque. */ +#ifndef cached_char_DEFINED +# define cached_char_DEFINED +typedef struct cached_char_s cached_char; +#endif + +/* The type of cached font/matrix pairs is opaque. */ +#ifndef cached_fm_pair_DEFINED +# define cached_fm_pair_DEFINED +typedef struct cached_fm_pair_s cached_fm_pair; +#endif + +/* The type of font objects is opaque. */ +#ifndef gs_font_DEFINED +# define gs_font_DEFINED +typedef struct gs_font_s gs_font; +#endif + +/* The type of text enum objects is opaque. */ +#ifndef gs_text_enum_DEFINED +# define gs_text_enum_DEFINED +typedef struct gs_text_enum_s gs_text_enum_t; +#endif + +#ifndef gs_show_enum_DEFINED +# define gs_show_enum_DEFINED +typedef struct gs_show_enum_s gs_show_enum; +#endif + +/* The types of memory and null devices may be opaque. */ +#ifndef gx_device_memory_DEFINED +# define gx_device_memory_DEFINED +typedef struct gx_device_memory_s gx_device_memory; +#endif +#ifndef gx_device_null_DEFINED +# define gx_device_null_DEFINED +typedef struct gx_device_null_s gx_device_null; +#endif + /* * Define the common part of the structure that tracks the state of text * processing. All implementations of text_begin must allocate one of these @@ -85,7 +134,7 @@ gs_text_params_t text; /* must be first for subclassing */\ gx_device *dev;\ gx_device *imaging_dev; /* see note below */\ - gs_imager_state *pis;\ + gs_gstate *pgs;\ gs_font *orig_font;\ gx_path *path; /* unless DO_NONE & !RETURN_WIDTH */\ const gx_device_color *pdcolor; /* if DO_DRAW */\ @@ -111,6 +160,9 @@ /* byte code of 32, not for a multi-byte code of 32. So, for example */ \ /* not for character code <0020>. */ \ bool single_byte_space; \ + /* We also need to know how many bytes of the string we used in order to */ \ + /* decode this character. So that we can tell if a space is <0020> or <20> */ \ + int bytes_decoded; \ gs_point FontBBox_as_Metrics2; /* used with FontType 9,11 && WMode 1 */\ ulong text_enum_id; /* debug purpose only - not used by algorythm. */\ /* The following is controlled by a device. */\ @@ -119,7 +171,43 @@ gs_log2_scale_point fapi_log2_scale; /* scaling factors for oversampling with FAPI, -1 = not valid */\ gs_point fapi_glyph_shift; /* glyph shift for FAPI-handled font */\ /* The following are used to return information to the client. */\ - gs_text_returned_t returned + gs_text_returned_t returned; \ + /* Following are set at creation time */ \ + bool auto_release; /* true if old API, false if new */ \ + gs_gstate *pgs2; \ + int level; /* save the level of pgs */ \ + gs_char_path_mode charpath_flag; \ + gs_gstate *show_gstate; /* for setting pgs->show_gstate */ \ + /* at returns/callouts */ \ + int can_cache; /* -1 if can't use cache at all, */ \ + /* 0 if can read but not load, */ \ + /* 1 if can read and load */ \ + gs_int_rect ibox; /* int version of quick-check */ \ + /* (inner) clipping box */ \ + gs_int_rect obox; /* int version of (outer) clip box */ \ + int ftx, fty; /* transformed font translation */ \ + /* Following are updated dynamically */ \ + gs_glyph (*encode_char)(gs_font *, gs_char, gs_glyph_space_t); /* copied from font */ \ + gx_device_memory *dev_cache; /* cache device */ \ + gx_device_memory *dev_cache2; /* underlying alpha memory device, */ \ + /* if dev_cache is an alpha buffer */ \ + gx_device_null *dev_null; /* null device for stringwidth */ \ + /*uint index; */ /* index within string */ \ + /*uint xy_index;*/ /* index within X/Y widths */ \ + /*gs_char returned.current_char;*/ /* current char for render or move */ \ + /*gs_glyph returned.current_glyph;*/ /* current glyph ditto */ \ + gs_fixed_point wxy; /* width of current char in device coords */ \ + gs_point wxy_float; /* same for huge characters */ \ + bool use_wxy_float; \ + gs_fixed_point origin; /* unrounded origin of current char */ \ + /* in device coords, needed for */ \ + /* charpath and WMode=1 */ \ + cached_char *cc; /* being accumulated */ \ + /*gs_point returned.total_width;*/ /* total width of string, set at end */ \ + show_width_status width_status; \ + /*gs_log2_scale_point log2_scale;*/ \ + int (*continue_proc) (gs_show_enum *) /* continuation procedure */ + /* The typedef is in gstext.h. */ struct gs_text_enum_s { gs_text_enum_common; @@ -175,13 +263,20 @@ */ int gs_text_enum_init(gs_text_enum_t *pte, const gs_text_enum_procs_t *procs, - gx_device *dev, gs_imager_state *pis, + gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, gs_font *font, gx_path *path, const gx_device_color *pdcolor, const gx_clip_path *pcpath, gs_memory_t *mem); +/* Allocate a text enumerator. + * This is primarily intended for code avoiding the device API, such + * as that purely for retrieving metrics + */ +gs_text_enum_t * +gs_text_enum_alloc(gs_memory_t * mem, gs_gstate * pgs, client_name_t cname); + /* * Copy the dynamically changing elements from one enumerator to another. * This is useful primarily for enumerators that sometimes pass the diff -Nru ghostscript-9.10~dfsg/base/gxtmap.h ghostscript-9.25~dfsg+1/base/gxtmap.h --- ghostscript-9.10~dfsg/base/gxtmap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxtmap.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,13 +32,13 @@ * Define the type of a mapping procedure. There are two forms of this. * The original form passed only the transfer map itself as an argument: */ -typedef float (*gs_mapping_proc) (floatp, const gx_transfer_map *); +typedef float (*gs_mapping_proc) (double, const gx_transfer_map *); /* * Later, we recognized that this procedure should really be a general * closure: */ -typedef float (*gs_mapping_closure_proc_t) (floatp value, +typedef float (*gs_mapping_closure_proc_t) (double value, const gx_transfer_map * pmap, const void *proc_data); typedef struct gs_mapping_closure_s { diff -Nru ghostscript-9.10~dfsg/base/gxttfb.c ghostscript-9.25~dfsg+1/base/gxttfb.c --- ghostscript-9.10~dfsg/base/gxttfb.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxttfb.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -33,7 +33,7 @@ #include "gdebug.h" #include "memory_.h" #include "math_.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxpaint.h" #include "gzspotan.h" #include @@ -76,15 +76,17 @@ gx_ttfReader *r = (gx_ttfReader *)self; const byte *q; - if (!r->error) { + if (r->error >= 0) { if (r->extra_glyph_index != -1) { q = r->glyph_data.bits.data + r->pos; - r->error = (r->glyph_data.bits.size - r->pos < n ? + r->error = ((r->pos >= r->glyph_data.bits.size || + r->glyph_data.bits.size - r->pos < n) ? gs_note_error(gs_error_invalidfont) : 0); if (r->error == 0) memcpy(p, q, n); } else { unsigned int cnt; + r->error = 0; for (cnt = 0; cnt < (uint)n; cnt += r->error) { r->error = r->pfont->data.string_proc(r->pfont, (ulong)r->pos + cnt, (ulong)n - cnt, &q); @@ -99,7 +101,7 @@ } } } - if (r->error) { + if (r->error < 0) { memset(p, 0, n); return; } @@ -170,7 +172,7 @@ self->extra_glyph_index = -1; gs_glyph_data_free(&self->glyph_data, "gx_ttfReader__Reset"); } - self->error = false; + self->error = 0; self->pos = 0; } @@ -187,7 +189,7 @@ r->super.LoadGlyph = gx_ttfReader__LoadGlyph; r->super.ReleaseGlyph = gx_ttfReader__ReleaseGlyph; r->pos = 0; - r->error = false; + r->error = 0; r->extra_glyph_index = -1; memset(&r->glyph_data, 0, sizeof(r->glyph_data)); r->pfont = NULL; @@ -212,8 +214,6 @@ int code; int factor = self->pfont->data.unitsPerEm; - if (bVertical) - factor = factor; /* See simple_glyph_metrics */ code = self->pfont->data.get_metrics(self->pfont, glyph_index, bVertical, sbw); if (code < 0) return code; @@ -239,6 +239,7 @@ { } +#ifdef DEBUG static int DebugPrint(ttfFont *ttf, const char *fmt, ...) { char buf[500]; @@ -255,6 +256,7 @@ } return 0; } +#endif static void WarnBadInstruction(gs_font_type42 *pfont, int glyph_index) { @@ -482,7 +484,7 @@ { gx_ttfExport *e = (gx_ttfExport *)self; - if (!e->error) + if (e->error >= 0) e->error = gx_path_add_point(e->path, float2fixed(p->x), float2fixed(p->y)); } @@ -490,7 +492,7 @@ { gx_ttfExport *e = (gx_ttfExport *)self; - if (!e->error) + if (e->error >= 0) e->error = gx_path_add_line_notes(e->path, float2fixed(p->x), float2fixed(p->y), sn_none); } @@ -498,7 +500,7 @@ { gx_ttfExport *e = (gx_ttfExport *)self; - if (!e->error) { + if (e->error >= 0) { if (e->monotonize) { curve_segment s; @@ -518,7 +520,7 @@ { gx_ttfExport *e = (gx_ttfExport *)self; - if (!e->error) + if (e->error >= 0) e->error = gx_path_close_subpath_notes(e->path, sn_none); } @@ -646,7 +648,7 @@ gs_font_type42 *pfont, const gs_log2_scale_point *pscale, gx_ttfExport *e, ttfOutliner *o) { /* Not completed yet. */ - gs_imager_state is_stub; + gs_gstate gs_stub; gx_fill_params params; gx_device_color devc_stub; int code; @@ -686,7 +688,7 @@ o->post_transform.b = o->post_transform.c = 0; o->post_transform.tx = o->post_transform.ty = 0; ttfOutliner__DrawGlyphOutline(o); - if (e->error) + if (e->error < 0) return e->error; code = t1_hinter__set_font42_data(&h.super, FontType, &pfont->data, false); if (code < 0) @@ -697,8 +699,8 @@ code = gx_path_bbox(path, &bbox); if (code < 0) return code; - memset(&is_stub, 0, sizeof(is_stub)); - is_stub.memory = padev->memory; + memset(&gs_stub, 0, sizeof(gs_stub)); + gs_stub.memory = padev->memory; set_nonclient_dev_color(&devc_stub, 1); params.rule = gx_rule_winding_number; params.adjust.x = params.adjust.y = 0; @@ -710,7 +712,7 @@ transpose_path(path); gx_san_begin(padev); code = dev_proc(padev, fill_path)((gx_device *)padev, - &is_stub, path, ¶ms, &devc_stub, NULL); + &gs_stub, path, ¶ms, &devc_stub, NULL); gx_san_end(padev); if (code >= 0) code = gx_san_generate_stems(padev, OVERALL_HINT && h.transpose, @@ -733,7 +735,7 @@ code = t1_hinter__endglyph(&h.super); } else { ttfOutliner__DrawGlyphOutline(o); - if (e->error) + if (e->error < 0) return e->error; } return code; diff -Nru ghostscript-9.10~dfsg/base/gxttfb.h ghostscript-9.25~dfsg+1/base/gxttfb.h --- ghostscript-9.10~dfsg/base/gxttfb.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxttfb.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -34,7 +34,7 @@ struct gx_ttfReader_s { ttfReader super; int pos; - bool error; + int error; int extra_glyph_index; gs_font_type42 *pfont; gs_memory_t *memory; diff -Nru ghostscript-9.10~dfsg/base/gxttf.h ghostscript-9.25~dfsg+1/base/gxttf.h --- ghostscript-9.10~dfsg/base/gxttf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxttf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -142,7 +142,10 @@ sCapHeight[2], usDefaultChar[2], usBreakChar[2], - usMaxContext[2]; + usMaxContext[2], + /* version 5 */ + usLowerOpticalPointSize[2], + usUpperOpticalPointSize[2]; } ttf_OS_2_t; /* ------ vhea ------ */ diff -Nru ghostscript-9.10~dfsg/base/gxtype1.c ghostscript-9.25~dfsg+1/base/gxtype1.c --- ghostscript-9.10~dfsg/base/gxtype1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxtype1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,7 +25,7 @@ #include "gxarith.h" #include "gxchrout.h" #include "gxfixed.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gxmatrix.h" #include "gxcoord.h" #include "gxfont.h" @@ -63,7 +63,7 @@ index % ST_GLYPH_DATA_NUM_PTRS); return 0; } -ENUM_PTR3(0, gs_type1_state, pfont, pis, path); +ENUM_PTR3(0, gs_type1_state, pfont, pgs, path); ENUM_PTR(3, gs_type1_state, callback_data); ENUM_PTRS_END static RELOC_PTRS_WITH(gs_type1_state_reloc_ptrs, gs_type1_state *pcis) @@ -71,7 +71,7 @@ int i; RELOC_PTR(gs_type1_state, pfont); - RELOC_PTR(gs_type1_state, pis); + RELOC_PTR(gs_type1_state, pgs); RELOC_PTR(gs_type1_state, path); RELOC_PTR(gs_type1_state, callback_data); for (i = 0; i < pcis->ips_count; i++) { @@ -96,7 +96,7 @@ /* Initialize a Type 1 interpreter. */ /* The caller must supply a string to the first call of gs_type1_interpret. */ int -gs_type1_interp_init(register gs_type1_state * pcis, gs_imager_state * pis, +gs_type1_interp_init(register gs_type1_state * pcis, gs_gstate * pgs, gx_path * ppath, const gs_log2_scale_point * pscale, const gs_log2_scale_point * psubpixels, bool no_grid_fitting, int paint_type, gs_font_type1 * pfont) @@ -107,9 +107,9 @@ const gs_log2_scale_point *plog2_subpixels = (FORCE_HINTS_TO_BIG_PIXELS ? (psubpixels != NULL ? psubpixels : plog2_scale) : &no_scale); - if_debug0m('1', pis->memory, "[1]gs_type1_interp_init\n"); + if_debug0m('1', pgs->memory, "[1]gs_type1_interp_init\n"); pcis->pfont = pfont; - pcis->pis = pis; + pcis->pgs = pgs; pcis->path = ppath; pcis->callback_data = pfont; /* default callback data */ pcis->no_grid_fitting = no_grid_fitting; @@ -163,11 +163,11 @@ void gs_type1_finish_init(gs_type1_state * pcis) { - gs_imager_state *pis = pcis->pis; + gs_gstate *pgs = pcis->pgs; const int max_coeff_bits = 11; /* max coefficient in char space */ /* Set up the fixed version of the transformation. */ - gx_matrix_to_fixed_coeff(&ctm_only(pis), &pcis->fc, max_coeff_bits); + gx_matrix_to_fixed_coeff(&ctm_only(pgs), &pcis->fc, max_coeff_bits); /* Set the current point of the path to the origin, */ pcis->origin.x = pcis->path->position.x; @@ -180,7 +180,7 @@ pcis->vs_offset.x = pcis->vs_offset.y = 0; /* Compute the flatness needed for accurate rendering. */ - pcis->flatness = gs_char_flatness(pis, 0.001); + pcis->flatness = gs_char_flatness(pgs, 0.001); pcis->init_done = 1; } @@ -272,7 +272,7 @@ int gs_type1_endchar(gs_type1_state * pcis) { - gs_imager_state *pis = pcis->pis; + gs_gstate *pgs = pcis->pgs; if (pcis->seac_accent >= 0) { /* We just finished the base character of a seac. */ /* Do the accent. */ @@ -321,10 +321,10 @@ return 1; } if (pcis->pfont->PaintType == 0) - pis->fill_adjust.x = pis->fill_adjust.y = -1; + pgs->fill_adjust.x = pgs->fill_adjust.y = -1; /* Set the flatness for curve rendering. */ if (!pcis->no_grid_fitting) - gs_imager_setflat(pis, pcis->flatness); + gs_setflat(pgs, pcis->flatness); return 0; } @@ -419,7 +419,7 @@ switch ((char_command) c) { default: cnext; - goto out; + break; case c2_shortint: { short sint = *cip++; @@ -455,7 +455,7 @@ c = pdata->gsubrNumberBias; } else { - c = fixed2int_var(*csp) + pdata->subroutineNumberBias; + c = fixed2int_var(*csp) + pdata->gsubrNumberBias; } code = pdata->procs.subr_data (pfont, c, true, &ipsp[1].cs_data); @@ -515,9 +515,14 @@ goto out; /* not seac */ do_seac: /* This is the payoff for all this code! */ - chars[0] = fixed2int(csp[-1]); - chars[1] = fixed2int(csp[0]); - return 1; + if (CS_CHECK_CSTACK_BOUNDS(&csp[-1], cstack)) { + chars[0] = fixed2int(csp[-1]); + chars[1] = fixed2int(csp[0]); + return 1; + } + else { + return_error(gs_error_invalidfont); + } case cx_escape: charstring_next(*cip, state, c, encrypted); ++cip; @@ -631,11 +636,11 @@ /* * Interpret the CharString until we get to the [h]sbw. */ - gs_imager_state gis; + gs_gstate gis; gs_type1_state cis; int value; - /* Initialize just enough of the imager state. */ + /* Initialize just enough of the gs_gstate. */ if (pmat) gs_matrix_fixed_from_matrix(&gis.ctm, pmat); else { @@ -650,6 +655,7 @@ if (code < 0) return code; cis.no_grid_fitting = true; + memset(&path, 0x00, sizeof(path)); gx_path_init_bbox_accumulator(&path); cis.path = &path; code = pdata->interpret(&cis, &gdata, &value); diff -Nru ghostscript-9.10~dfsg/base/gxtype1.h ghostscript-9.25~dfsg+1/base/gxtype1.h --- ghostscript-9.10~dfsg/base/gxtype1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxtype1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -95,7 +95,7 @@ t1_hinter h; /* The following are set at initialization */ gs_font_type1 *pfont; /* font-specific data */ - gs_imager_state *pis; /* imager state */ + gs_gstate *pgs; /* gs_gstate */ gx_path *path; /* path for appending */ bool no_grid_fitting; int paint_type; /* 0/3 for fill, 1/2 for stroke */ @@ -167,6 +167,7 @@ /* Copy the operand stack out of the saved state. */ #define INIT_CSTACK(cstack, csp, pcis)\ BEGIN\ + memset(cstack, 0x00, sizeof(cstack));\ if ( pcis->os_count == 0 )\ CLEAR_CSTACK(cstack, csp);\ else {\ @@ -174,6 +175,13 @@ csp = &cstack[pcis->os_count - 1];\ }\ END +#define CS_CHECK_CSTACK_BOUNDS(csaddr, cs) \ + (csaddr >= &(cs[0]) && \ + csaddr < &(cs[ostack_size])) + +#define CS_CHECK_TRANSIENT_BOUNDS(csaddr, cs) \ + (csaddr >= &(cs[0]) && \ + csaddr < &(cs[32])) /* size defined in gs_type1_state_s above */ #define CS_CHECK_PUSH(csp, cstack)\ BEGIN\ @@ -181,6 +189,25 @@ return_error(gs_error_invalidfont);\ END +#define CS_CHECK_PUSHN(csp, cstack, n)\ + BEGIN\ + if (csp >= &cstack[countof(cstack) - n])\ + return_error(gs_error_invalidfont);\ + END + +#define CS_CHECK_POP(csp, cstack)\ + BEGIN\ + if (csp < &cstack[0])\ + return_error(gs_error_invalidfont);\ + END + +#define CS_CHECK_IPSTACK(ips, ipstack)\ + BEGIN\ + if (ips > &ipstack[ipstack_size + 1] \ + || ips < &ipstack[0])\ + return_error(gs_error_invalidfont);\ + END + /* Decode a 1-byte number. */ #define decode_num1(var, c)\ (var = c_value_num1(c)) @@ -220,7 +247,7 @@ /* Decode a 4-byte number, but don't push it, because Type 1 and Type 2 */ /* charstrings scale it differently. */ -#if arch_sizeof_long > 4 +#if ARCH_SIZEOF_LONG > 4 # define sign_extend_num4(lw)\ lw = (lw ^ 0x80000000L) - 0x80000000L #else diff -Nru ghostscript-9.10~dfsg/base/gxxfont.h ghostscript-9.25~dfsg+1/base/gxxfont.h --- ghostscript-9.10~dfsg/base/gxxfont.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gxxfont.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gzacpath.h ghostscript-9.25~dfsg+1/base/gzacpath.h --- ghostscript-9.10~dfsg/base/gzacpath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzacpath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -34,6 +34,7 @@ gs_int_rect clip_box; gs_int_rect bbox; gx_clip_list list; + bool transpose; } gx_device_cpath_accum; #define public_st_device_cpath_accum()\ @@ -42,7 +43,7 @@ device_cpath_accum_reloc_ptrs, gx_device_finalize) /* Start accumulating a clipping path. */ -void gx_cpath_accum_begin(gx_device_cpath_accum * padev, gs_memory_t * mem); +void gx_cpath_accum_begin(gx_device_cpath_accum * padev, gs_memory_t * mem, bool transpose); /* Set the accumulator's clipping box. */ void gx_cpath_accum_set_cbox(gx_device_cpath_accum * padev, @@ -50,7 +51,8 @@ /* Finish accumulating a clipping path. */ /* Note that this releases the old contents of the clipping path. */ -int gx_cpath_accum_end(const gx_device_cpath_accum * padev, +/* Also, if the list is transposed, the adev->bbox will be set to "normal" untransposed */ +int gx_cpath_accum_end(gx_device_cpath_accum * padev, gx_clip_path * pcpath); /* Discard an accumulator in case of error. */ @@ -58,7 +60,7 @@ /* Intersect two clipping paths using an accumulator. */ int gx_cpath_intersect_path_slow(gx_clip_path *, gx_path *, int, - gs_imager_state *, const gx_fill_params *); + gs_gstate *, const gx_fill_params *); int cpath_accum_fill_rect_with(gx_device_cpath_accum *pcdev, gx_device *tdev, gx_device_color *pdevc); diff -Nru ghostscript-9.10~dfsg/base/gzcpath.h ghostscript-9.25~dfsg+1/base/gzcpath.h --- ghostscript-9.10~dfsg/base/gzcpath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzcpath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -77,6 +77,8 @@ gx_cpath_path_list *path_list; /* The id changes whenever the clipping region changes. */ gs_id id; + /* The last rectangle we accessed while using this clip_path */ + gx_clip_rect *cached; }; extern_st(st_clip_path); @@ -110,9 +112,4 @@ bool any_rectangles; }; -#define private_st_cpath_enum() /* in gxcpath.c */\ - gs_private_st_suffix_add2(st_cpath_enum, gs_cpath_enum, "gs_cpath_enum",\ - cpath_enum_enum_ptrs, cpath_enum_reloc_ptrs, st_path_enum,\ - visit, rp) - #endif /* gzcpath_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gzht.h ghostscript-9.25~dfsg+1/base/gzht.h --- ghostscript-9.10~dfsg/base/gzht.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzht.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -45,8 +45,9 @@ int gx_ht_construct_threshold_order(gx_ht_order *, const byte *); void gx_ht_construct_bit(gx_ht_bit * bit, int width, int bit_num); void gx_ht_construct_bits(gx_ht_order *); +bool gx_transfer_is_monotonic(const gs_gstate *pgs, int plane_index); int gx_ht_construct_threshold(gx_ht_order *d_order, gx_device *dev, - const gs_imager_state * pis, int plane_index); + const gs_gstate * pgs, int plane_index); /* Halftone enumeration structure */ struct gs_screen_enum_s { @@ -56,7 +57,7 @@ gs_matrix mat_inv; /* the inversion of mat */ int x, y; int strip, shift; - gs_state *pgs; + gs_gstate *pgs; }; #define private_st_gs_screen_enum() /* in gshtscr.c */\ @@ -65,13 +66,13 @@ /* order.levels, order.bits, pgs) */ /* Prepare a device halftone for installation, but don't install it. */ -int gs_sethalftone_prepare(gs_state *, gs_halftone *, +int gs_sethalftone_prepare(gs_gstate *, gs_halftone *, gx_device_halftone *); /* Allocate and initialize a spot screen. */ /* This is the first half of gs_screen_init_accurate/memory. */ int gs_screen_order_alloc(gx_ht_order *, gs_memory_t *); -int gs_screen_order_init_memory(gx_ht_order *, const gs_state *, +int gs_screen_order_init_memory(gx_ht_order *, const gs_gstate *, gs_screen_halftone *, bool, gs_memory_t *); #define gs_screen_order_init(porder, pgs, phsp, accurate)\ @@ -80,14 +81,14 @@ /* Prepare to sample a spot screen. */ /* This is the second half of gs_screen_init_accurate/memory. */ int gs_screen_enum_init_memory(gs_screen_enum *, const gx_ht_order *, - gs_state *, const gs_screen_halftone *, + gs_gstate *, const gs_screen_halftone *, gs_memory_t *); #define gs_screen_enum_init(penum, porder, pgs, phsp)\ gs_screen_enum_init_memory(penum, porder, pgs, phsp, pgs->memory) /* Process an entire screen plane. */ -int gx_ht_process_screen_memory(gs_screen_enum * penum, gs_state * pgs, +int gx_ht_process_screen_memory(gs_screen_enum * penum, gs_gstate * pgs, gs_screen_halftone * phsp, bool accurate, gs_memory_t * mem); @@ -135,7 +136,7 @@ #define max_ht_cached_tiles_SMALL 256 #define max_ht_cache_bits_size_SMALL 8192 /* enough for 256 levels 8x8 */ -#if arch_small_memory +#if ARCH_SMALL_MEMORY # define max_ht_cached_tiles max_ht_cached_tiles_SMALL # define max_ht_cache_bits_size max_ht_cache_bits_size_SMALL #else @@ -188,10 +189,10 @@ void gx_ht_order_release(gx_ht_order * porder, gs_memory_t * mem, bool free_cache); /* - * Install a device halftone in an imager state. Note that this does not + * Install a device halftone in an gs_gstate. Note that this does not * read or update the client halftone. */ -int gx_imager_dev_ht_install(gs_imager_state * pis, +int gx_gstate_dev_ht_install(gs_gstate * pgs, gx_device_halftone * pdht, gs_halftone_type type, const gx_device * dev); @@ -201,13 +202,13 @@ * level of the gs_halftone and the gx_device_halftone, and take ownership * of any substructures. */ -int gx_ht_install(gs_state *, const gs_halftone *, gx_device_halftone *); +int gx_ht_install(gs_gstate *, const gs_halftone *, gx_device_halftone *); /* Reestablish the effective transfer functions, taking into account */ /* any overrides from halftone dictionaries. */ /* Some compilers object to names longer than 31 characters.... */ -void gx_imager_set_effective_xfer(gs_imager_state * pis); -void gx_set_effective_transfer(gs_state * pgs); +void gx_gstate_set_effective_xfer(gs_gstate * pgs); +void gx_set_effective_transfer(gs_gstate * pgs); /* * This routine will take a color name (defined by a ptr and size) and @@ -233,6 +234,6 @@ * This version converts a name index value into a string and size and * then call gs_color_name_component_number. */ -int gs_cname_to_colorant_number(gs_state * pgs, byte * pname, uint name_size, +int gs_cname_to_colorant_number(gs_gstate * pgs, byte * pname, uint name_size, int halftonetype); #endif /* gzht_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gzline.h ghostscript-9.25~dfsg+1/base/gzline.h --- ghostscript-9.10~dfsg/base/gzline.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzline.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -31,6 +31,6 @@ #define st_line_params_num_ptrs 1 /* Internal accessor for line parameters in graphics state */ -const gx_line_params *gs_currentlineparams(const gs_imager_state *); +const gx_line_params *gs_currentlineparams(const gs_gstate *); #endif /* gzline_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/gzpath.h ghostscript-9.25~dfsg+1/base/gzpath.h --- ghostscript-9.10~dfsg/base/gzpath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzpath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -326,7 +326,6 @@ byte /*gx_path_state_flags*/ state_flags; /* (see above) */ byte /*bool*/ bbox_set; /* true if setbbox is in effect */ byte /*bool*/ bbox_accurate;/* true if bbox is accurate */ - byte _pad; /* just in case the compiler doesn't do it */ int subpath_count; int curve_count; gs_fixed_point position; /* current position */ diff -Nru ghostscript-9.10~dfsg/base/gzspotan.c ghostscript-9.25~dfsg+1/base/gzspotan.c --- ghostscript-9.10~dfsg/base/gzspotan.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzspotan.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,17 +25,9 @@ #include "gzspotan.h" #include "gxfixed.h" #include "gxdevice.h" -#include "gxfdrop.h" /* Only for VD_* constants. */ #include "gzpath.h" #include "memory_.h" #include "math_.h" -#include "vdtrace.h" - -#define VD_TRAP_N_COLOR RGB(128, 128, 0) -#define VD_TRAP_U_COLOR RGB(0, 0, 255) -#define VD_CONT_COLOR RGB(0, 255, 0) -#define VD_STEM_COLOR RGB(255, 255, 255) -#define VD_HINT_COLOR RGB(255, 0, 0) public_st_device_spot_analyzer(); private_st_san_trap(); @@ -358,8 +350,6 @@ t->xrtop = last->xrtop; t->rightmost &= last->rightmost; t->leftmost &= last->leftmost; - vd_quad(t->xlbot, t->ybot, t->xrbot, t->ybot, - t->xrtop, t->ytop, t->xltop, t->ytop, 1, VD_TRAP_U_COLOR); code = trap_unreserve(padev, last); if (code < 0) return code; @@ -523,8 +513,6 @@ last->fork = 0; last->visited = false; last->leftmost = last->rightmost = true; - vd_quad(last->xlbot, last->ybot, last->xrbot, last->ybot, - last->xrtop, last->ytop, last->xltop, last->ytop, 1, VD_TRAP_N_COLOR); if (padev->top_band != NULL) { padev->top_band->rightmost = false; last->leftmost = false; @@ -536,7 +524,7 @@ while (padev->bot_current != NULL && padev->bot_current->xrtop < xlbot) padev->bot_current = (trap_is_last(padev->bot_band, padev->bot_current) ? NULL : padev->bot_current->next); - if (padev->bot_current != 0) { + if (padev->bot_current != 0 && padev->bot_band != NULL) { gx_san_trap *t = padev->bot_current; gx_san_trap *bot_last = band_list_last(padev->bot_band); @@ -547,9 +535,6 @@ return_error(gs_error_VMerror); cont->lower = t; cont->upper = last; - vd_bar((t->xltop + t->xrtop + t->xlbot + t->xrbot) / 4, (t->ytop + t->ybot) / 2, - (last->xltop + last->xrtop + last->xlbot + last->xrbot) / 4, - (last->ytop + last->ybot) / 2, 0, VD_CONT_COLOR); cont_list_insert_last(&t->upper, cont); last->fork++; if (t == bot_last) @@ -609,7 +594,6 @@ sect.xr = at_top ? best_trap->xrtop : best_trap->xrbot; sect.l = best_trap->l; sect.r = best_trap->r; - vd_bar(sect.xl, sect.yl, sect.xr, sect.yr, 0, VD_HINT_COLOR); code = handler(client_data, §); if (code < 0) return code; @@ -642,14 +626,11 @@ { if (s->type == s_curve) { const curve_segment *c = (const curve_segment *)s; - vd_curve(p->pt.x, p->pt.y, c->p1.x, c->p1.y, c->p2.x, c->p2.y, - s->pt.x, s->pt.y, 0, VD_HINT_COLOR); if (ybot <= p->pt.y && p->pt.y <= ytop) choose_by_vector(c->p1.x, c->p1.y, p->pt.x, p->pt.y, s, slope, len, store_segm, store_x, store_y); if (ybot <= s->pt.y && s->pt.y <= ytop) choose_by_vector(c->p2.x, c->p2.y, s->pt.x, s->pt.y, s, slope, len, store_segm, store_x, store_y); } else { - vd_bar(p->pt.x, p->pt.y, s->pt.x, s->pt.y, 0, VD_HINT_COLOR); choose_by_vector(s->pt.x, s->pt.y, p->pt.x, p->pt.y, s, slope, len, store_segm, store_x, store_y); } } @@ -719,7 +700,6 @@ return 0; sect.xr = padev->xmax + 1000; /* ignore side */ } - vd_bar(sect.xl, sect.yl, sect.xr, sect.yr, 0, VD_HINT_COLOR); code = handler(client_data, §); if (code < 0) return code; @@ -801,8 +781,6 @@ t1->visited = true; } /* We've got a stem suspection from t0 to t1. */ - vd_quad(t0->xlbot, t0->ybot, t0->xrbot, t0->ybot, - t1->xrtop, t1->ytop, t1->xltop, t1->ytop, 1, VD_STEM_COLOR); for (t = t0; ; t = t->upper->upper) { length += trap_axis_length(t); area += trap_area(t); @@ -830,25 +808,5 @@ bool overall_hints, void *client_data, int (*handler)(void *client_data, gx_san_sect *ss)) { - int code; - bool got_dc = false; - vd_save; - - if (vd_allowed('F') || vd_allowed('f')) { - if (!vd_enabled) { - vd_get_dc('f'); - got_dc = vd_enabled; - } - if (vd_enabled) { - vd_set_shift(0, 0); - vd_set_scale(VD_SCALE); - vd_set_origin(0, 0); - } - } else - vd_disable; - code = gx_san_generate_stems_aux(padev, overall_hints, client_data, handler); - if (got_dc) - vd_release_dc; - vd_restore; - return code; + return gx_san_generate_stems_aux(padev, overall_hints, client_data, handler); } diff -Nru ghostscript-9.10~dfsg/base/gzspotan.h ghostscript-9.25~dfsg+1/base/gzspotan.h --- ghostscript-9.10~dfsg/base/gzspotan.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzspotan.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/gzstate.h ghostscript-9.25~dfsg+1/base/gzstate.h --- ghostscript-9.10~dfsg/base/gzstate.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/gzstate.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,155 +19,7 @@ #ifndef gzstate_INCLUDED # define gzstate_INCLUDED -#include "gscpm.h" -#include "gscspace.h" -#include "gsrefct.h" -#include "gxdcolor.h" -#include "gxistate.h" +#include "gxgstate.h" #include "gsstate.h" -#include "gxstate.h" - -/* Opaque types referenced by the graphics state. */ -#ifndef gx_path_DEFINED -# define gx_path_DEFINED -typedef struct gx_path_s gx_path; -#endif -#ifndef gx_clip_path_DEFINED -# define gx_clip_path_DEFINED -typedef struct gx_clip_path_s gx_clip_path; -#endif -#ifndef gx_clip_stack_DEFINED -# define gx_clip_stack_DEFINED -typedef struct gx_clip_stack_s gx_clip_stack_t; -#endif -#ifndef gs_color_space_DEFINED -# define gs_color_space_DEFINED -typedef struct gs_color_space_s gs_color_space; -#endif -#ifndef gs_client_color_DEFINED -# define gs_client_color_DEFINED -typedef struct gs_client_color_s gs_client_color; -#endif -#ifndef gs_font_DEFINED -# define gs_font_DEFINED -typedef struct gs_font_s gs_font; -#endif -#ifndef gs_device_filter_stack_DEFINED -# define gs_device_filter_stack_DEFINED -typedef struct gs_device_filter_stack_s gs_device_filter_stack_t; -#endif - -/* Device filter stack structure is defined here so that gstate - lifecycle operations can access reference count; implementation is - in gsdfilt.c. - */ - -#ifndef gs_device_filter_DEFINED -# define gs_device_filter_DEFINED -typedef struct gs_device_filter_s gs_device_filter_t; -#endif - -/* This is the base structure from which device filters are derived. */ -struct gs_device_filter_stack_s { - gs_device_filter_stack_t *next; - gs_device_filter_t *df; - gx_device *next_device; - rc_header rc; -}; - -/* Graphics state structure. */ - -struct gs_state_s { - gs_imager_state_common; /* imager state, must be first */ - gs_state *saved; /* previous state from gsave */ - - /* Transformation: */ - - gs_matrix ctm_inverse; - bool ctm_inverse_valid; /* true if ctm_inverse = ctm^-1 */ - gs_matrix ctm_default; - bool ctm_default_set; /* if true, use ctm_default; */ - /* if false, ask device */ - /* Paths: */ - - gx_path *path; - gx_clip_path *clip_path; - gx_clip_stack_t *clip_stack; /* (LanguageLevel 3 only) */ - gx_clip_path *view_clip; /* (may be 0, or have rule = 0) */ - - /* Effective clip path cache */ - gs_id effective_clip_id; /* (key) clip path id */ - gs_id effective_view_clip_id; /* (key) view clip path id */ - gx_clip_path *effective_clip_path; /* (value) effective clip path, */ - /* possibly = clip_path or view_clip */ - bool effective_clip_shared; /* true iff e.c.p. = c.p. or v.c. */ - -#define gs_currentdevicecolor_inline(pgs) \ - ((pgs)->color[0].dev_color) -#define gs_currentcolor_inline(pgs) \ - ((pgs)->color[0].ccolor) -#define gs_currentcolorspace_inline(pgs) \ - ((pgs)->color[0].color_space) -#define gs_altdevicecolor_inline(pgs) \ - ((pgs)->color[1].dev_color) - - /* Current colors (non-stroking, and stroking) */ - struct { - gs_color_space *color_space; /* after substitution */ - gs_client_color *ccolor; - gx_device_color *dev_color; - } color[2]; - - /* Font: */ - - gs_font *font; - gs_font *root_font; - gs_matrix_fixed char_tm; /* font matrix * ctm */ -#define char_tm_only(pgs) *(gs_matrix *)&(pgs)->char_tm - bool char_tm_valid; /* true if char_tm is valid */ - gs_in_cache_device_t in_cachedevice; /* (see gscpm.h) */ - gs_char_path_mode in_charpath; /* (see gscpm.h) */ - gs_state *show_gstate; /* gstate when show was invoked */ - /* (so charpath can append to path) */ - - /* Other stuff: */ - - int level; /* incremented by 1 per gsave */ - gx_device *device; -#undef gs_currentdevice_inline -#define gs_currentdevice_inline(pgs) ((pgs)->device) - gs_device_filter_stack_t *dfilter_stack; - - /* Client data: */ - - /*void *client_data;*/ /* in imager state */ -#define gs_state_client_data(pgs) ((pgs)->client_data) - gs_state_client_procs client_procs; -}; - -#define public_st_gs_state() /* in gsstate.c */\ - gs_public_st_composite(st_gs_state, gs_state, "gs_state",\ - gs_state_enum_ptrs, gs_state_reloc_ptrs) - -/* - * Enumerate the pointers in a graphics state, other than the ones in the - * imager state, and device, which must be handled specially. - */ -#define gs_state_do_ptrs(m)\ - m(0,saved) m(1,path) m(2,clip_path) m(3,clip_stack)\ - m(4,view_clip) m(5,effective_clip_path)\ - m(6,color[0].color_space) m(7,color[0].ccolor) m(8,color[0].dev_color)\ - m(9,color[1].color_space) m(10,color[1].ccolor) m(11,color[1].dev_color)\ - m(12,font) m(13,root_font) m(14,show_gstate) -#define gs_state_num_ptrs 15 - -/* The following macro is used for development purpose for designating places - where current point is changed. Clients must not use it. */ -#define gx_setcurrentpoint(pgs, xx, yy)\ - (pgs)->current_point.x = xx;\ - (pgs)->current_point.y = yy; - -int gs_swapcolors(gs_state *); -void gs_swapcolors_quick(gs_state *); #endif /* gzstate_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/icc34.h ghostscript-9.25~dfsg+1/base/icc34.h --- ghostscript-9.10~dfsg/base/icc34.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/icc34.h 2018-09-13 10:02:01.000000000 +0000 @@ -161,14 +161,12 @@ typedef @INT32_T@ icInt32Number; typedef @INT32_T@ icInt64Number[2]; -#else +#elif defined (__digital__) && defined (__unix__) /* *Apr-17-2002: Modified by Marti Maria in order to provide wider portability. */ -#if defined (__digital__) && defined (__unix__) - /* Tru64 */ #include @@ -183,8 +181,7 @@ typedef int32_t icInt32Number; typedef int32_t icInt64Number[2]; -#else -#ifdef __sgi +#elif defined(__sgi) #include "sgidefs.h" @@ -205,14 +202,13 @@ typedef __int32_t icInt64Number[2]; -#else -#if defined(__GNUC__) || defined(__unix__) || defined(__unix) +#elif defined(__GNUC__) || defined(__unix__) || defined(__unix) #include -#if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__) +#if defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__) || defined(HAVE_STDINT_H) -#if defined (__MINGW) || defined(__MINGW32__) +#if defined (__MINGW) || defined(__MINGW32__) || defined(HAVE_STDINT_H) #include #endif @@ -230,7 +226,7 @@ typedef u_int32_t icUInt32Number; typedef u_int32_t icUInt64Number[2]; -#endif +#endif /* defined(__sun) || defined(__hpux) || defined (__MINGW) || defined(__MINGW32__) || defined(HAVE_STDINT_H) */ /* Signed numbers */ @@ -260,9 +256,6 @@ #endif /* default defs */ -#endif -#endif -#endif /* Base types */ diff -Nru ghostscript-9.10~dfsg/base/ijs.mak ghostscript-9.25~dfsg+1/base/ijs.mak --- ghostscript-9.10~dfsg/base/ijs.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ijs.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # makefile for ijs client library code. @@ -40,7 +40,7 @@ IJS_CC=$(CC_) $(IJS_CCFLAGS) # Define the name of this makefile. -IJS_MAK=$(GLSRC)ijs.mak +IJS_MAK=$(GLSRC)ijs.mak $(TOP_MAKEFILES) ijs.clean : ijs.config-clean ijs.clean-not-config-clean @@ -58,14 +58,14 @@ ijslib_=$(IJSOBJ)ijs.$(OBJ) $(IJSOBJ)ijs_server.$(OBJ) \ $(IJSOBJ)ijs_client.$(OBJ) $(IJSOBJ)ijs_exec_$(IJSEXECTYPE).$(OBJ) -$(IJSGEN)ijslib_0.dev : $(TOP_MAKEFILES) $(IJS_MAK) $(ECHOGS_XE) $(ijslib_) +$(IJSGEN)ijslib_0.dev : $(IJS_MAK) $(ECHOGS_XE) $(ijslib_) $(MAKEDIRS) $(SETMOD) $(IJSGEN)ijslib_0 $(ijslib_) -$(IJSGEN)ijslib_1.dev : $(TOP_MAKEFILES) $(IJS_MAK) $(ECHOGS_XE) +$(IJSGEN)ijslib_1.dev : $(IJS_MAK) $(ECHOGS_XE) $(MAKEDIRS) $(SETMOD) $(IJSGEN)ijslib_1 -lib $(IJS_NAME) -$(IJSGEN)ijslib.dev : $(TOP_MAKEFILES) $(IJS_MAK) $(IJSGEN)ijslib_$(SHARE_IJS).dev +$(IJSGEN)ijslib.dev : $(IJS_MAK) $(IJSGEN)ijslib_$(SHARE_IJS).dev $(MAKEDIRS) $(CP_) $(IJSGEN)ijslib_$(SHARE_IJS).dev $(IJSGEN)ijslib.dev @@ -74,25 +74,25 @@ ijs_client_h=$(IJSSRC)$(D)ijs_client.h ijs_server_h=$(IJSSRC)$(D)ijs_server.h -$(IJSOBJ)ijs.$(OBJ) : $(IJSSRC)ijs.c $(IJSDEP) $(ijs_h) $(ECHOGS_XE) +$(IJSOBJ)ijs.$(OBJ) : $(IJSSRC)ijs.c $(IJSDEP) $(ijs_h) $(ECHOGS_XE) $(IJS_MAK) $(IJS_MAK) $(MAKEDIRS) # echo $(IJS_CCFLAGS) $(EXP)$(ECHOGS_XE) $(IJS_CCFLAGS) $(IJS_CC) $(IJSO_)ijs.$(OBJ) $(C_) $(IJSSRC)ijs.c $(IJSOBJ)ijs_client.$(OBJ) : $(IJSSRC)ijs_client.c \ - $(IJSDEP) $(ijs_h) $(ijs_client_h) + $(IJSDEP) $(ijs_h) $(ijs_client_h) $(IJS_MAK) $(MAKEDIRS) $(IJS_CC) $(IJSO_)ijs_client.$(OBJ) $(C_) $(IJSSRC)ijs_client.c $(IJSOBJ)ijs_server.$(OBJ) : $(IJSSRC)ijs_server.c \ - $(IJSDEP) $(ijs_h) $(ijs_server_h) + $(IJSDEP) $(ijs_h) $(ijs_server_h) $(IJS_MAK) $(MAKEDIRS) $(IJS_CC) $(IJSO_)ijs_server.$(OBJ) $(C_) $(IJSSRC)ijs_server.c $(IJSOBJ)ijs_exec_unix.$(OBJ) : $(IJSSRC)ijs_exec_unix.c \ - $(IJSDEP) $(ijs_h) $(ijs_client_h) + $(IJSDEP) $(ijs_h) $(ijs_client_h) $(IJS_MAK) $(MAKEDIRS) $(IJS_CC) $(IJSO_)ijs_exec_unix.$(OBJ) $(C_) $(IJSSRC)ijs_exec_unix.c $(IJSOBJ)ijs_exec_win.$(OBJ) : $(IJSSRC)ijs_exec_win.c \ - $(IJSDEP) $(ijs_h) $(ijs_client_h) + $(IJSDEP) $(ijs_h) $(ijs_client_h) $(IJS_MAK) $(MAKEDIRS) # This can't be compiled with /Za because it needs windows.h. $(CC_WX) $(IJS_CCFLAGS) $(IJSO_)ijs_exec_win.$(OBJ) $(C_) $(IJSSRC)ijs_exec_win.c @@ -108,20 +108,20 @@ ijs_examples_=$(ijs_server_example_) $(ijs_client_example_) $(IJSGEN)ijs_examples.dev : $(IJS_MAK) $(ECHOGS_XE) \ - $(ijs_examples_) $(ijslib_) + $(ijs_examples_) $(ijslib_) $(IJS_MAK) $(MAKEDIRS) $(SETMOD) $(IJSGEN)ijs_examples $(ijs_examples_) $(ADDMOD) $(IJSGEN)ijs_examples $(ijslib_) $(IJSOBJ)ijs_client_example.$(OBJ) : $(IJSSRC)ijs_client_example.c \ - $(IJSDEP) $(ijs_h) $(ijs_client_h) + $(IJSDEP) $(ijs_h) $(ijs_client_h) $(IJS_MAK) $(MAKEDIRS) $(IJS_CC) $(IJSO_)ijs_client_example.$(OBJ) $(C_) $(IJSSRC)ijs_client_example.c -$(BINDIR)$(D)ijs_client_example : $(IJSOBJ)ijs_client_example.$(OBJ) $(ijslib_) +$(BINDIR)$(D)ijs_client_example : $(IJSOBJ)ijs_client_example.$(OBJ) $(ijslib_) $(IJS_MAK) $(MAKEDIRS) $(IJS_CC) -o bin/ijs_client_example $(IJSOBJ)ijs_client_example.$(OBJ) $(ijslib_) $(IJSOBJ)ijs_server_example.$(OBJ) : $(IJSSRC)ijs_server_example.c \ - $(IJSDEP) $(ijs_h) $(ijs_server_h) + $(IJSDEP) $(ijs_h) $(ijs_server_h) $(IJS_MAK) $(MAKEDIRS) $(IJS_CC) $(IJSO_)ijs_server_example.$(OBJ) $(C_) $(IJSSRC)ijs_server_example.c -$(BINDIR)$(D)ijs_server_example : $(IJSOBJ)ijs_server_example.$(OBJ) $(ijslib_) +$(BINDIR)$(D)ijs_server_example : $(IJSOBJ)ijs_server_example.$(OBJ) $(ijslib_) $(IJS_MAK) $(MAKEDIRS) $(IJS_CC) -o bin/ijs_server_example $(IJSOBJ)ijs_server_example.$(OBJ) $(ijslib_) diff -Nru ghostscript-9.10~dfsg/base/instcopy ghostscript-9.25~dfsg+1/base/instcopy --- ghostscript-9.10~dfsg/base/instcopy 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/instcopy 2018-09-13 10:02:01.000000000 +0000 @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -10,8 +10,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # Implement a uniform 'install' syntax independent of which of the two @@ -49,8 +49,8 @@ fi dsttmp=$dstdir/#inst.$$# -$doit cp $src $dsttmp && $doit trap "rm -f $dsttmp" 0 && +$doit cp $src $dsttmp && if [ x"$mode" != x ]; then $doit chmod $mode $dsttmp; else true; fi && $doit rm -f $dst && $doit mv $dsttmp $dst && diff -Nru ghostscript-9.10~dfsg/base/jbig2.mak ghostscript-9.25~dfsg+1/base/jbig2.mak --- ghostscript-9.10~dfsg/base/jbig2.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/jbig2.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # @@ -30,7 +30,7 @@ # Ghostscript. # Define the name of this makefile. -JBIG2_MAK=$(GLSRC)jbig2.mak +JBIG2_MAK=$(GLSRC)jbig2.mak $(TOP_MAKEFILES) JBIG2SRC=$(JBIG2SRCDIR)$(D) JBIG2GEN=$(JBIG2GENDIR)$(D) @@ -57,7 +57,7 @@ $(JBIG2OBJ)jbig2_symbol_dict.$(OBJ) \ $(JBIG2OBJ)jbig2_text.$(OBJ) \ $(JBIG2OBJ)jbig2_halftone.$(OBJ) \ - $(JBIG2OBJ)jbig2_metadata.$(OBJ) $(JBIG2_EXTRA_OBJS) + $(JBIG2_EXTRA_OBJS) libjbig2_OBJS=$(libjbig2_OBJS1) $(libjbig2_OBJS2) @@ -75,7 +75,6 @@ $(JBIG2SRC)jbig2_symbol_dict.h \ $(JBIG2SRC)jbig2_text.h \ $(JBIG2SRC)jbig2_halftone.h \ - $(JBIG2SRC)jbig2_metadata.h \ $(JBIG2SRC)config_win32.h jbig2dec_OBJS=$(JBIG2OBJ)getopt.$(OBJ) $(JBIG2OBJ)getopt1.$(OBJ) $(JBIG2OBJ)sha1.$(OBJ) @@ -93,87 +92,84 @@ JBIG2DEP=$(AK) -JBIG2_CC=$(CC_) $(CFLAGS) $(I_)$(JBIG2GENDIR) $(II)$(JB2I_)$(_I) $(JB2CF_) -DGSBUILD +JBIG2_CC=$(CC_) $(CFLAGS) $(I_)$(JBIG2GENDIR) $(II)$(JB2I_)$(_I) $(JB2CF_) -DJBIG_EXTERNAL_MEMENTO_H=\"../base/memento.h\" JBIG2O_=$(O_)$(JBIG2OBJ) # switch in the version of libjbig2.dev we're actually using -$(JBIG2GEN)jbig2dec.dev : $(TOP_MAKEFILES) $(JBIG2GEN)jbig2dec_$(SHARE_JBIG2).dev +$(JBIG2GEN)jbig2dec.dev : $(JBIG2GEN)jbig2dec_$(SHARE_JBIG2).dev $(JBIG2_MAK) $(MAKEDIRS) $(CP_) $(JBIG2GEN)jbig2dec_$(SHARE_JBIG2).dev $(JBIG2GEN)jbig2dec.dev # dev file for shared (separately built) jbig2dec library -$(JBIG2GEN)jbig2dec_1.dev : $(TOP_MAKEFILES) $(JBIG2_MAK) $(ECHOGS_XE) +$(JBIG2GEN)jbig2dec_1.dev : $(JBIG2_MAK) $(ECHOGS_XE) $(JBIG2_MAK) $(MAKEDIRS) $(SETMOD) $(JBIG2GEN)jbig2dec_1 -lib jbig2dec # dev file for compiling our own from source -$(JBIG2GEN)jbig2dec_0.dev : $(TOP_MAKEFILES) $(JBIG2_MAK) $(ECHOGS_XE) $(libjbig2_OBJS) +$(JBIG2GEN)jbig2dec_0.dev : $(JBIG2_MAK) $(ECHOGS_XE) $(libjbig2_OBJS) $(JBIG2_MAK) $(MAKEDIRS) $(SETMOD) $(JBIG2GEN)jbig2dec_0 $(libjbig2_OBJS1) $(ADDMOD) $(JBIG2GEN)jbig2dec_0 $(libjbig2_OBJS2) # explicit rules for building the source files. -$(JBIG2OBJ)snprintf.$(OBJ) : $(JBIG2SRC)snprintf.c $(JBIG2DEP) +$(JBIG2OBJ)snprintf.$(OBJ) : $(JBIG2SRC)snprintf.c $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)snprintf.$(OBJ) $(C_) $(JBIG2SRC)snprintf.c -$(JBIG2OBJ)getopt.$(OBJ) : $(JBIG2SRC)getopt.c $(JBIG2SRC)getopt.h $(JBIG2DEP) +$(JBIG2OBJ)getopt.$(OBJ) : $(JBIG2SRC)getopt.c $(JBIG2SRC)getopt.h $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)getopt.$(OBJ) $(C_) $(JBIG2SRC)getopt.c -$(JBIG2OBJ)getopt1.$(OBJ) : $(JBIG2SRC)getopt1.c $(JBIG2SRC)getopt.h $(JBIG2DEP) +$(JBIG2OBJ)getopt1.$(OBJ) : $(JBIG2SRC)getopt1.c $(JBIG2SRC)getopt.h $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)getopt1.$(OBJ) $(C_) $(JBIG2SRC)getopt1.c -$(JBIG2OBJ)jbig2.$(OBJ) : $(JBIG2SRC)jbig2.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2.$(OBJ) : $(JBIG2SRC)jbig2.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2.$(OBJ) $(C_) $(JBIG2SRC)jbig2.c -$(JBIG2OBJ)jbig2_arith.$(OBJ) : $(JBIG2SRC)jbig2_arith.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_arith.$(OBJ) : $(JBIG2SRC)jbig2_arith.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_arith.$(OBJ) $(C_) $(JBIG2SRC)jbig2_arith.c -$(JBIG2OBJ)jbig2_arith_iaid.$(OBJ) : $(JBIG2SRC)jbig2_arith_iaid.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_arith_iaid.$(OBJ) : $(JBIG2SRC)jbig2_arith_iaid.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_arith_iaid.$(OBJ) $(C_) $(JBIG2SRC)jbig2_arith_iaid.c -$(JBIG2OBJ)jbig2_arith_int.$(OBJ) : $(JBIG2SRC)jbig2_arith_int.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_arith_int.$(OBJ) : $(JBIG2SRC)jbig2_arith_int.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_arith_int.$(OBJ) $(C_) $(JBIG2SRC)jbig2_arith_int.c -$(JBIG2OBJ)jbig2_generic.$(OBJ) : $(JBIG2SRC)jbig2_generic.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_generic.$(OBJ) : $(JBIG2SRC)jbig2_generic.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_generic.$(OBJ) $(C_) $(JBIG2SRC)jbig2_generic.c -$(JBIG2OBJ)jbig2_refinement.$(OBJ) : $(JBIG2SRC)jbig2_refinement.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_refinement.$(OBJ) : $(JBIG2SRC)jbig2_refinement.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_refinement.$(OBJ) $(C_) $(JBIG2SRC)jbig2_refinement.c -$(JBIG2OBJ)jbig2_huffman.$(OBJ) : $(JBIG2SRC)jbig2_huffman.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_huffman.$(OBJ) : $(JBIG2SRC)jbig2_huffman.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_huffman.$(OBJ) $(C_) $(JBIG2SRC)jbig2_huffman.c -$(JBIG2OBJ)jbig2_image.$(OBJ) : $(JBIG2SRC)jbig2_image.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_image.$(OBJ) : $(JBIG2SRC)jbig2_image.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_image.$(OBJ) $(C_) $(JBIG2SRC)jbig2_image.c -$(JBIG2OBJ)jbig2_image_pbm.$(OBJ) : $(JBIG2SRC)jbig2_image_pbm.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_image_pbm.$(OBJ) : $(JBIG2SRC)jbig2_image_pbm.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_image_pbm.$(OBJ) $(C_) $(JBIG2SRC)jbig2_image_pbm.c -$(JBIG2OBJ)jbig2_image_png.$(OBJ) : $(JBIG2SRC)jbig2_image_png.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_image_png.$(OBJ) : $(JBIG2SRC)jbig2_image_png.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_image_png.$(OBJ) $(C_) $(JBIG2SRC)jbig2_image_png.c -$(JBIG2OBJ)jbig2_mmr.$(OBJ) : $(JBIG2SRC)jbig2_mmr.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_mmr.$(OBJ) : $(JBIG2SRC)jbig2_mmr.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_mmr.$(OBJ) $(C_) $(JBIG2SRC)jbig2_mmr.c -$(JBIG2OBJ)jbig2_page.$(OBJ) : $(JBIG2SRC)jbig2_page.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_page.$(OBJ) : $(JBIG2SRC)jbig2_page.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_page.$(OBJ) $(C_) $(JBIG2SRC)jbig2_page.c -$(JBIG2OBJ)jbig2_segment.$(OBJ) : $(JBIG2SRC)jbig2_segment.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_segment.$(OBJ) : $(JBIG2SRC)jbig2_segment.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_segment.$(OBJ) $(C_) $(JBIG2SRC)jbig2_segment.c -$(JBIG2OBJ)jbig2_symbol_dict.$(OBJ) : $(JBIG2SRC)jbig2_symbol_dict.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_symbol_dict.$(OBJ) : $(JBIG2SRC)jbig2_symbol_dict.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_symbol_dict.$(OBJ) $(C_) $(JBIG2SRC)jbig2_symbol_dict.c -$(JBIG2OBJ)jbig2_text.$(OBJ) : $(JBIG2SRC)jbig2_text.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_text.$(OBJ) : $(JBIG2SRC)jbig2_text.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_text.$(OBJ) $(C_) $(JBIG2SRC)jbig2_text.c -$(JBIG2OBJ)jbig2_halftone.$(OBJ) : $(JBIG2SRC)jbig2_halftone.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2_halftone.$(OBJ) : $(JBIG2SRC)jbig2_halftone.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2_halftone.$(OBJ) $(C_) $(JBIG2SRC)jbig2_halftone.c -$(JBIG2OBJ)jbig2_metadata.$(OBJ) : $(JBIG2SRC)jbig2_metadata.c $(libjbig2_HDRS) $(JBIG2DEP) - $(JBIG2_CC) $(JBIG2O_)jbig2_metadata.$(OBJ) $(C_) $(JBIG2SRC)jbig2_metadata.c - -$(JBIG2OBJ)jbig2dec.$(OBJ) : $(JBIG2SRC)jbig2dec.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)jbig2dec.$(OBJ) : $(JBIG2SRC)jbig2dec.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)jbig2dec.$(OBJ) $(C_) $(JBIG2SRC)jbig2dec.c -$(JBIG2OBJ)sha1.$(OBJ) : $(JBIG2SRC)sha1.c $(libjbig2_HDRS) $(JBIG2DEP) +$(JBIG2OBJ)sha1.$(OBJ) : $(JBIG2SRC)sha1.c $(libjbig2_HDRS) $(JBIG2DEP) $(JBIG2_MAK) $(MAKEDIRS) $(JBIG2_CC) $(JBIG2O_)sha1.$(OBJ) $(C_) $(JBIG2SRC)sha1.c diff -Nru ghostscript-9.10~dfsg/base/jerror_.h ghostscript-9.25~dfsg+1/base/jerror_.h --- ghostscript-9.10~dfsg/base/jerror_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/jerror_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/jmemcust.c ghostscript-9.25~dfsg+1/base/jmemcust.c --- ghostscript-9.10~dfsg/base/jmemcust.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/jmemcust.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,167 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#if !defined(SHARE_JPEG) || SHARE_JPEG==0 + +#include "jinclude.h" +#include "jpeglib.h" +#include "jmemsys.h" +#include "jerror.h" +#include "jmemcust.h" + +GLOBAL(void *) +jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + + return (void *) (cmem->j_mem_get_small)(cinfo, sizeofobject); +} + +GLOBAL(void) +jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + + (cmem->j_mem_free_small)(cinfo, object, sizeofobject); +} + +/* + * "Large" objects are treated the same as "small" ones. + * NB: although we include FAR keywords in the routine declarations, + * this file won't actually work in 80x86 small/medium model; at least, + * you probably won't be able to process useful-size images in only 64KB. + */ + +GLOBAL(void FAR *) +jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + + return (void *) (cmem->j_mem_get_large)(cinfo, sizeofobject); +} + +GLOBAL(void) +jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + + (cmem->j_mem_free_large)(cinfo, object, sizeofobject); +} + +/* + * This routine computes the total memory space available for allocation. + * Here we always say, "we got all you want bud!" + */ + +GLOBAL(long) +jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, + long max_bytes_needed, long already_allocated) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + long ret = max_bytes_needed; + + if (cmem->j_mem_avail) + ret = (cmem->j_mem_avail)(cinfo); + + return ret; +} + +/* + * Backing store (temporary file) management. + * Since jpeg_mem_available always promised the moon, + * this should never be called and we can just error out. + */ + +GLOBAL(void) +jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, + long total_bytes_needed) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + + if (cmem->j_mem_open_backing_store) { + (cmem->j_mem_open_backing_store)(cinfo, info, total_bytes_needed); + } + else + ERREXIT(cinfo, JERR_NO_BACKING_STORE); +} + +/* + * These routines take care of any system-dependent initialization and + * cleanup required. Here, there isn't any. + */ + +GLOBAL(long) +jpeg_mem_init (j_common_ptr cinfo) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + long ret = 0; + + if (cmem->j_mem_init) + ret = (cmem->j_mem_init)(cinfo); + + return ret; +} + +GLOBAL(void) +jpeg_mem_term (j_common_ptr cinfo) +{ + jpeg_cust_mem_data *cmem = GET_CUST_MEM_DATA(cinfo); + + if (cmem->j_mem_term) + (cmem->j_mem_term)(cinfo); +} + +GLOBAL(jpeg_cust_mem_data *) +jpeg_cust_mem_init(jpeg_cust_mem_data *custm, void *priv, + j_custmem_init_ptr init, + j_custmem_term_ptr term, + j_custmem_avail_ptr avail, + j_custmem_get_small_ptr get_small, + j_custmem_free_small_ptr free_small, + j_cust_mem_get_large_ptr get_large, + j_custmem_free_large_ptr free_large, + j_custmem_open_backing_store_ptr open_backing_store) +{ + jpeg_cust_mem_data *lcustm = NULL; + + /* We need at least the following for a viable memory manager */ + if (get_small && free_small && get_large && free_large) + { + lcustm = custm; + + lcustm->priv = priv; + lcustm->j_mem_init = init; + lcustm->j_mem_term = term; + lcustm->j_mem_avail = avail; + lcustm->j_mem_get_small = get_small; + lcustm->j_mem_free_small = free_small; + lcustm->j_mem_get_large = get_large; + lcustm->j_mem_free_large = free_large; + lcustm->j_mem_open_backing_store = open_backing_store; + } + return lcustm; +} + +GLOBAL(jpeg_cust_mem_data *) +jpeg_cust_mem_set_private(jpeg_cust_mem_data *custm, void *priv) +{ + if (custm) + { + custm->priv = priv; + } + return custm; +} + +#endif /* !defined(SHARE_JPEG) || SHARE_JPEG==0 */ diff -Nru ghostscript-9.10~dfsg/base/jmemcust.h ghostscript-9.25~dfsg+1/base/jmemcust.h --- ghostscript-9.10~dfsg/base/jmemcust.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/jmemcust.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,56 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +typedef JMETHOD(long, j_custmem_init_ptr, (j_common_ptr cinfo)); +typedef JMETHOD(void, j_custmem_term_ptr, (j_common_ptr cinfo)); +typedef JMETHOD(long, j_custmem_avail_ptr, (j_common_ptr cinfo)); +typedef JMETHOD(void *, j_custmem_get_small_ptr, + (j_common_ptr cinfo, size_t size)); +typedef JMETHOD(void, j_custmem_free_small_ptr, + (j_common_ptr cinfo, void *object, size_t size)); +typedef JMETHOD(void *, j_cust_mem_get_large_ptr, + (j_common_ptr cinfo, size_t size)); +typedef JMETHOD(void, j_custmem_free_large_ptr, + (j_common_ptr cinfo, void *object, size_t size)); +typedef JMETHOD(void, j_custmem_open_backing_store_ptr, + (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed)); + +typedef struct { + j_custmem_init_ptr j_mem_init; + j_custmem_term_ptr j_mem_term; + j_custmem_avail_ptr j_mem_avail; + j_custmem_get_small_ptr j_mem_get_small; + j_custmem_free_small_ptr j_mem_free_small; + j_cust_mem_get_large_ptr j_mem_get_large; + j_custmem_free_large_ptr j_mem_free_large; + j_custmem_open_backing_store_ptr j_mem_open_backing_store; + void *priv; +} jpeg_cust_mem_data; + +#define GET_CUST_MEM_DATA(c) ((jpeg_cust_mem_data *)c->client_data) + +GLOBAL(jpeg_cust_mem_data *) +jpeg_cust_mem_init(jpeg_cust_mem_data *custm, void *priv, + j_custmem_init_ptr init, + j_custmem_term_ptr term, + j_custmem_avail_ptr avail, + j_custmem_get_small_ptr get_small, + j_custmem_free_small_ptr free_small, + j_cust_mem_get_large_ptr get_large, + j_custmem_free_large_ptr free_large, + j_custmem_open_backing_store_ptr open_backing_store); + +GLOBAL(jpeg_cust_mem_data *) +jpeg_cust_mem_set_private(jpeg_cust_mem_data *custm, void *priv); diff -Nru ghostscript-9.10~dfsg/base/jpeg.mak ghostscript-9.25~dfsg+1/base/jpeg.mak --- ghostscript-9.10~dfsg/base/jpeg.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/jpeg.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # $Id: jpeg.mak 12063 2011-01-26 12:25:36Z chrisl $ # makefile for Independent JPEG Group library code. @@ -60,7 +60,7 @@ JO_=$(O_)$(JOBJ) # Define the name of this makefile. -JPEG_MAK=$(GLSRC)jpeg.mak +JPEG_MAK=$(GLSRC)jpeg.mak $(TOP_MAKEFILES) jpeg.clean : jpeg.config-clean jpeg.clean-not-config-clean @@ -95,25 +95,25 @@ jconfig_h=$(GLGEN)jconfig.h jmorecfg_h=$(GLGEN)jmorecfg.h -$(GLGEN)jconfig_.h : $(GLGEN)jconfig$(SHARE_JPEG).h $(MAKEFILE) $(MAKEDIRS) +$(GLGEN)jconfig_.h : $(GLGEN)jconfig$(SHARE_JPEG).h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(GLGEN)jconfig$(SHARE_JPEG).h $(GLGEN)jconfig_.h -$(GLGEN)jconfig0.h : $(ECHOGS_XE) $(GLSRC)gsjconf.h $(stdpre_h) $(MAKEFILE)\ +$(GLGEN)jconfig0.h : $(ECHOGS_XE) $(GLSRC)gsjconf.h $(stdpre_h) $(JPEG_MAK)\ $(MAKEDIRS) - $(EXP)$(ECHOGS_XE) -w $(GLGEN)jconfig0.h -+R $(GLSRC)stdpn.h -+R $(GLSRC)stdpre.h -+R $(GLSRC)gsjconf.h + $(EXP)$(ECHOGS_XE) -w $(GLGEN)jconfig0.h -+R $(GLSRC)stdpre.h -+R $(GLSRC)gsjconf.h $(RM_) $(GLGEN)jconfig1.h -$(GLGEN)jconfig1.h : $(ECHOGS_XE) $(JPEG_MAK) $(MAKEDIRS) +$(GLGEN)jconfig1.h : $(ECHOGS_XE) $(JPEG_MAK) $(JPEG_MAK) $(MAKEDIRS) $(EXP)$(ECHOGS_XE) -w $(GLGEN)jconfig1.h -x 23 include -x 203c jconfig.h -x 3e $(RMN_) $(GLGEN)jconfig0.h $(GLGEN)jconfig.h -$(GLGEN)jconfig.h : $(GLGEN)jconfig0.h $(MAKEDIRS) +$(GLGEN)jconfig.h : $(GLGEN)jconfig0.h $(arch_h) $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(GLGEN)jconfig0.h $(GLGEN)jconfig.h -$(GLGEN)jmorecf_.h : $(GLGEN)jmorecf$(SHARE_JPEG).h $(MAKEFILE) $(MAKEDIRS) +$(GLGEN)jmorecf_.h : $(GLGEN)jmorecf$(SHARE_JPEG).h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(GLGEN)jmorecf$(SHARE_JPEG).h $(GLGEN)jmorecf_.h -$(GLGEN)jmorecf0.h : $(GLSRC)gsjmorec.h $(GLGEN)jmcorig.h $(MAKEDIRS) +$(GLGEN)jmorecf0.h : $(GLSRC)gsjmorec.h $(GLGEN)jmcorig.h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(GLSRC)gsjmorec.h $(GLGEN)jmorecf0.h $(RM_) $(GLGEN)jmorecf1.h @@ -121,10 +121,10 @@ $(EXP)$(ECHOGS_XE) -w $(GLGEN)jmorecf1.h -x 23 include -x 203c jmorecfg.h -x 3e $(RMN_) $(GLGEN)jmorecf0.h $(GLGEN)jmorecfg.h -$(GLGEN)jmorecfg.h : $(GLGEN)jmorecf0.h $(MAKEDIRS) +$(GLGEN)jmorecfg.h : $(GLGEN)jmorecf0.h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(GLGEN)jmorecf0.h $(GLGEN)jmorecfg.h -$(GLGEN)jmcorig.h : $(JSRC)jmorecfg.h $(MAKEDIRS) +$(GLGEN)jmcorig.h : $(JSRC)jmorecfg.h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JSRC)jmorecfg.h $(GLGEN)jmcorig.h # Contrary to what some portability bigots assert as fact, C compilers are @@ -140,23 +140,23 @@ JHCOPY=$(GLGEN)jinclude.h $(GLGEN)jpeglib.h -$(GLGEN)jinclude.h : $(JSRC)jinclude.h $(MAKEDIRS) +$(GLGEN)jinclude.h : $(JSRC)jinclude.h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JSRC)jinclude.h $(GLGEN)jinclude.h # jpeglib_.h doesn't really depend on jconfig.h or jmcorig.h, # but we choose to put the dependencies here rather than in the # definition of jpeglib__h. -$(GLGEN)jpeglib_.h : $(GLGEN)jpeglib$(SHARE_JPEG).h $(MAKEDIRS) +$(GLGEN)jpeglib_.h : $(GLGEN)jpeglib$(SHARE_JPEG).h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(GLGEN)jpeglib$(SHARE_JPEG).h $(GLGEN)jpeglib_.h -$(GLGEN)jpeglib0.h : $(JSRC)jpeglib.h $(jconfig_h) $(jmorecfg_h) $(MAKEDIRS) +$(GLGEN)jpeglib0.h : $(JSRC)jpeglib.h $(jconfig_h) $(jmorecfg_h) $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JSRC)jpeglib.h $(GLGEN)jpeglib0.h $(GLGEN)jpeglib1.h : $(ECHOGS_XE) $(JPEG_MAK) $(MAKEDIRS) $(EXP)$(ECHOGS_XE) -w $(GLGEN)jpeglib1.h -x 23 include -x 203c jpeglib.h -x 3e # We also need jpeglib.h for #includes in the library itself. -$(GLGEN)jpeglib.h : $(JSRC)jpeglib.h $(MAKEDIRS) +$(GLGEN)jpeglib.h : $(JSRC)jpeglib.h $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JSRC)jpeglib.h $(GLGEN)jpeglib.h # In order to avoid having to keep the dependency lists for the IJG code @@ -165,11 +165,18 @@ # This is too conservative, but only hurts us if we are changing our own # j*.h files, which happens only rarely during development. -JDEP=$(AK) $(jconfig_h) $(jmorecfg_h) $(JHCOPY) $(MAKEDIRS) +JDEP=$(AK) $(jconfig_h) $(jmorecfg_h) $(JHCOPY) $(JPEG_MAK) $(MAKEDIRS) + # Code common to compression and decompression. +jpegc0_=$(JOBJ)jcomapi.$(OBJ) $(JOBJ)jutils.$(OBJ) $(JOBJ)jmemmgr.$(OBJ) $(JOBJ)jerror.$(OBJ) $(JOBJ)jaricom.$(OBJ) \ + $(GLOBJ)jmemcust.$(OBJ) + +# custom memory handler +$(GLOBJ)jmemcust.$(OBJ) : $(GLSRC)jmemcust.c $(JDEP) + $(JCC) $(JO_)jmemcust.$(OBJ) $(C_) $(GLSRC)jmemcust.c + -jpegc0_=$(JOBJ)jcomapi.$(OBJ) $(JOBJ)jutils.$(OBJ) $(JOBJ)jmemmgr.$(OBJ) $(JOBJ)jerror.$(OBJ) $(JOBJ)jaricom.$(OBJ) $(JGEN)jpegc0.dev : $(JPEG_MAK) $(ECHOGS_XE) $(jpegc0_) $(SETMOD) $(JGEN)jpegc0 $(jpegc0_) @@ -200,13 +207,13 @@ # Encoding (compression) code. -$(JGEN)jpege.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpege_$(SHARE_JPEG).dev +$(JGEN)jpege.dev : $(JPEG_MAK) $(JGEN)jpege_$(SHARE_JPEG).dev $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JGEN)jpege_$(SHARE_JPEG).dev $(JGEN)jpege.dev -$(JGEN)jpege_1.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(ECHOGS_XE) +$(JGEN)jpege_1.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JPEG_MAK) $(MAKEDIRS) $(SETMOD) $(JGEN)jpege_1 -lib $(JPEG_NAME) -$(JGEN)jpege_0.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpege6.dev +$(JGEN)jpege_0.dev : $(JPEG_MAK) $(JGEN)jpege6.dev $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JGEN)jpege6.dev $(JGEN)jpege_0.dev jpege6=$(JOBJ)jcapimin.$(OBJ) $(JOBJ)jcapistd.$(OBJ) $(JOBJ)jcinit.$(OBJ) @@ -215,7 +222,8 @@ jpege_2=$(JOBJ)jchuff.$(OBJ) $(JOBJ)jcmainct.$(OBJ) $(JOBJ)jcmarker.$(OBJ) $(JOBJ)jcmaster.$(OBJ) jpege_3=$(JOBJ)jcparam.$(OBJ) $(JOBJ)jcprepct.$(OBJ) $(JOBJ)jcsample.$(OBJ) $(JOBJ)jfdctint.$(OBJ) -$(JGEN)jpege6.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpege6) $(jpege_1) $(jpege_2) $(jpege_3) +$(JGEN)jpege6.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpege6) $(jpege_1) $(jpege_2) $(jpege_3) \ + $(JPEG_MAK) $(MAKEDIRS) $(SETMOD) $(JGEN)jpege6 $(jpege6) $(ADDMOD) $(JGEN)jpege6 -include $(JGEN)jpegc0.dev $(ADDMOD) $(JGEN)jpege6 -obj $(jpege_1) @@ -299,13 +307,14 @@ # Decompression code -$(JGEN)jpegd.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpegd_$(SHARE_JPEG).dev +$(JGEN)jpegd.dev : $(JPEG_MAK) $(JGEN)jpegd_$(SHARE_JPEG).dev \ + $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JGEN)jpegd_$(SHARE_JPEG).dev $(JGEN)jpegd.dev -$(JGEN)jpegd_1.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(ECHOGS_XE) +$(JGEN)jpegd_1.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JPEG_MAK) $(MAKEDIRS) $(SETMOD) $(JGEN)jpegd_1 -lib $(JPEG_NAME) -$(JGEN)jpegd_0.dev : $(TOP_MAKEFILES) $(JPEG_MAK) $(JGEN)jpegd6.dev +$(JGEN)jpegd_0.dev : $(JPEG_MAK) $(JGEN)jpegd6.dev $(JPEG_MAK) $(MAKEDIRS) $(CP_) $(JGEN)jpegd6.dev $(JGEN)jpegd_0.dev jpegd6=$(JOBJ)jdapimin.$(OBJ) $(JOBJ)jdapistd.$(OBJ) $(JOBJ)jdinput.$(OBJ) $(JOBJ)jdhuff.$(OBJ) @@ -314,7 +323,8 @@ jpegd_2=$(JOBJ)jddctmgr.$(OBJ) $(JOBJ)jdhuff.$(OBJ) $(JOBJ)jdmainct.$(OBJ) $(JOBJ)jdmarker.$(OBJ) jpegd_3=$(JOBJ)jdmaster.$(OBJ) $(JOBJ)jdpostct.$(OBJ) $(JOBJ)jdsample.$(OBJ) $(JOBJ)jidctint.$(OBJ) $(JOBJ)jdarith.$(OBJ) -$(JGEN)jpegd6.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpegd6) $(jpegd_1) $(jpegd_2) $(jpegd_3) +$(JGEN)jpegd6.dev : $(JPEG_MAK) $(ECHOGS_XE) $(JGEN)jpegc0.dev $(jpegd6) $(jpegd_1) $(jpegd_2) $(jpegd_3) \ + $(JPEG_MAK) $(MAKEDIRS) $(SETMOD) $(JGEN)jpegd6 $(jpegd6) $(ADDMOD) $(JGEN)jpegd6 -include $(JGEN)jpegc0.dev $(ADDMOD) $(JGEN)jpegd6 -obj $(jpegd_1) diff -Nru ghostscript-9.10~dfsg/base/jpegxr.mak ghostscript-9.25~dfsg+1/base/jpegxr.mak --- ghostscript-9.10~dfsg/base/jpegxr.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/jpegxr.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # makefile for ITU-T Rec. T.835 (ex T.JPEGXR_-5) | ISO/IEC 29199-5 reference software @@ -23,7 +23,7 @@ # JPEGXR_OBJDIR - directory for object files. # Define the name of this makefile -JPEGXR_MAK=$(GLSRC)jpegxr.mak +JPEGXR_MAK=$(GLSRC)jpegxr.mak $(TOP_MAKEFILES) # local aliases JPEGXR_SRC=$(JPEGXR_SRCDIR)$(D) @@ -31,7 +31,7 @@ JPEGXR_OBJ=$(JPEGXR_OBJDIR)$(D) JPEGXR_O_=$(O_)$(JPEGXR_OBJ) -JPEGXR_CC=$(CC_) $(JPEGXR_CFLAGS) +JPEGXR_CC=$(CC_) $(JPEGXR_CFLAGS) $(D_)JXR_DLL_EXPORTS=1$(_D) $(D_)NDEBUG$(_D) jpegxr.clean : jpegxr.config-clean jpegxr.clean-not-config-clean @@ -63,53 +63,54 @@ $(JPEGXR_OBJ)w_tile_frequency.$(OBJ) \ $(JPEGXR_OBJ)x_strip.$(OBJ) -jpegxr_hdrs=$(JPEGXR_SRC)jpegxr.h $(JPEGXR_SRC)jxr_priv.h +JPEGXR_DEPS=$(JPEGXR_SRC)jpegxr.h $(JPEGXR_SRC)jxr_priv.h $(JPEGXR_MAK) $(MAKEDIRS) -$(JPEGXR_OBJ)algo.$(OBJ) : $(JPEGXR_SRC)algo.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)algo.$(OBJ) : $(JPEGXR_SRC)algo.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)algo.$(OBJ) $(C_) $(JPEGXR_SRC)algo.c -$(JPEGXR_OBJ)api.$(OBJ) : $(JPEGXR_SRC)api.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)api.$(OBJ) : $(JPEGXR_SRC)api.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)api.$(OBJ) $(C_) $(JPEGXR_SRC)api.c -$(JPEGXR_OBJ)w_emit.$(OBJ) : $(JPEGXR_SRC)w_emit.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)w_emit.$(OBJ) : $(JPEGXR_SRC)w_emit.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)w_emit.$(OBJ) $(C_) $(JPEGXR_SRC)w_emit.c -$(JPEGXR_OBJ)flags.$(OBJ) : $(JPEGXR_SRC)flags.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)flags.$(OBJ) : $(JPEGXR_SRC)flags.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)flags.$(OBJ) $(C_) $(JPEGXR_SRC)flags.c -$(JPEGXR_OBJ)init.$(OBJ) : $(JPEGXR_SRC)init.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)init.$(OBJ) : $(JPEGXR_SRC)init.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)init.$(OBJ) $(C_) $(JPEGXR_SRC)init.c -$(JPEGXR_OBJ)io.$(OBJ) : $(JPEGXR_SRC)io.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)io.$(OBJ) : $(JPEGXR_SRC)io.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)io.$(OBJ) $(C_) $(JPEGXR_SRC)io.c -$(JPEGXR_OBJ)cr_parse.$(OBJ) : $(JPEGXR_SRC)cr_parse.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)cr_parse.$(OBJ) : $(JPEGXR_SRC)cr_parse.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)cr_parse.$(OBJ) $(C_) $(JPEGXR_SRC)cr_parse.c -$(JPEGXR_OBJ)cw_emit.$(OBJ) : $(JPEGXR_SRC)cw_emit.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)cw_emit.$(OBJ) : $(JPEGXR_SRC)cw_emit.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)cw_emit.$(OBJ) $(C_) $(JPEGXR_SRC)cw_emit.c -$(JPEGXR_OBJ)r_parse.$(OBJ) : $(JPEGXR_SRC)r_parse.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)r_parse.$(OBJ) : $(JPEGXR_SRC)r_parse.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)r_parse.$(OBJ) $(C_) $(JPEGXR_SRC)r_parse.c -$(JPEGXR_OBJ)jpegxr_pixelformat.$(OBJ) : $(JPEGXR_SRC)jpegxr_pixelformat.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)jpegxr_pixelformat.$(OBJ) : $(JPEGXR_SRC)jpegxr_pixelformat.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)jpegxr_pixelformat.$(OBJ) $(C_) $(JPEGXR_SRC)jpegxr_pixelformat.c -$(JPEGXR_OBJ)r_strip.$(OBJ) : $(JPEGXR_SRC)r_strip.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)r_strip.$(OBJ) : $(JPEGXR_SRC)r_strip.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)r_strip.$(OBJ) $(C_) $(JPEGXR_SRC)r_strip.c -$(JPEGXR_OBJ)r_tile_spatial.$(OBJ) : $(JPEGXR_SRC)r_tile_spatial.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)r_tile_spatial.$(OBJ) : $(JPEGXR_SRC)r_tile_spatial.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)r_tile_spatial.$(OBJ) $(C_) $(JPEGXR_SRC)r_tile_spatial.c -$(JPEGXR_OBJ)r_tile_frequency.$(OBJ) : $(JPEGXR_SRC)r_tile_frequency.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)r_tile_frequency.$(OBJ) : $(JPEGXR_SRC)r_tile_frequency.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)r_tile_frequency.$(OBJ) $(C_) $(JPEGXR_SRC)r_tile_frequency.c -$(JPEGXR_OBJ)w_strip.$(OBJ) : $(JPEGXR_SRC)w_strip.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)w_strip.$(OBJ) : $(JPEGXR_SRC)w_strip.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)w_strip.$(OBJ) $(C_) $(JPEGXR_SRC)w_strip.c -$(JPEGXR_OBJ)w_tile_spatial.$(OBJ) : $(JPEGXR_SRC)w_tile_spatial.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)w_tile_spatial.$(OBJ) : $(JPEGXR_SRC)w_tile_spatial.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)w_tile_spatial.$(OBJ) $(C_) $(JPEGXR_SRC)w_tile_spatial.c -$(JPEGXR_OBJ)w_tile_frequency.$(OBJ) : $(JPEGXR_SRC)w_tile_frequency.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)w_tile_frequency.$(OBJ) : $(JPEGXR_SRC)w_tile_frequency.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)w_tile_frequency.$(OBJ) $(C_) $(JPEGXR_SRC)w_tile_frequency.c -$(JPEGXR_OBJ)x_strip.$(OBJ) : $(JPEGXR_SRC)x_strip.c $(jpegxr_hdrs) +$(JPEGXR_OBJ)x_strip.$(OBJ) : $(JPEGXR_SRC)x_strip.c $(JPEGXR_DEPS) $(JPEGXR_CC) $(JPEGXR_O_)x_strip.$(OBJ) $(C_) $(JPEGXR_SRC)x_strip.c -# Copy the target definition we want -$(JPEGXR_GEN)jpegxr.dev : $(TOP_MAKEFILES) $(JPEGXR_MAK) \ - $(JPEGXR_GEN)jpegxr_$(SHARE_JPEGXR).dev - $(CP_) $(JPEGXR_GEN)jpegxr_$(SHARE_JPEGXR).dev $(JPEGXR_GEN)jpegxr.dev - # Define the compiled in target -$(JPEGXR_GEN)jpegxr_0.dev : $(JPEGXR_MAK) $(ECHOGS_XE) $(jpegxr_objs) +$(JPEGXR_GEN)jpegxr_0.dev : $(ECHOGS_XE) $(jpegxr_objs) $(JPEGXR_DEPS) $(SETMOD) $(JPEGXR_GEN)jpegxr_0 $(jpegxr_objs) # Define the external link target -$(JPEGXR_GEN)jpegxr_1.dev : $(JPEGXR_MAK) $(ECHOGS_XE) +$(JPEGXR_GEN)jpegxr_1.dev : $(ECHOGS_XE) $(JPEGXR_MAK) $(MAKEDIRS) $(SETMOD) $(JPEGXR_GEN)jpegxr_1 -lib jpegxr +# Copy the target definition we want +$(JPEGXR_GEN)jpegxr.dev : $(TOP_MAKEFILES) \ + $(JPEGXR_GEN)jpegxr_$(SHARE_JPEGXR).dev $(JPEGXR_MAK) $(MAKEDIRS) + $(CP_) $(JPEGXR_GEN)jpegxr_$(SHARE_JPEGXR).dev $(JPEGXR_GEN)jpegxr.dev + + diff -Nru ghostscript-9.10~dfsg/base/lcms2.mak ghostscript-9.25~dfsg+1/base/lcms2.mak --- ghostscript-9.10~dfsg/base/lcms2.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/lcms2.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for the lcms library code. @@ -29,7 +29,7 @@ # Ghostscript. # Define the name of this makefile. -LCMS2_MAK=$(GLSRC)lcms2.mak +LCMS2_MAK=$(GLSRC)lcms2.mak $(TOP_MAKEFILES) LCMS2SRC=$(LCMS2SRCDIR)$(D)src$(D) LCMS2GEN=$(LCMS2GENDIR)$(D) @@ -63,11 +63,12 @@ $(LCMS2OBJ)cmstypes.$(OBJ) \ $(LCMS2OBJ)cmsvirt.$(OBJ) \ $(LCMS2OBJ)cmswtpnt.$(OBJ) \ - $(LCMS2OBJ)cmsxform.$(OBJ) + $(LCMS2OBJ)cmsxform.$(OBJ) \ + $(LCMS2OBJ)cmsalpha.$(OBJ) -lcms2_HDRS=\ +LCMS2_DEPS=\ $(LCMS2SRCDIR)$(D)include$(D)lcms2.h \ - $(GLSRC)icc34.h + $(GLSRC)icc34.h $(LCMS2_MAK) $(MAKEDIRS) lcms2.clean : lcms2.config-clean lcms2.clean-not-config-clean @@ -80,91 +81,94 @@ # NB: we can't use the normal $(CC_) here because msvccmd.mak # adds /Za which conflicts with the lcms source. -LCMS2_CC=$(CC) $(CFLAGS) $(LCMS2_CFLAGS) $(I_)$(LCMS2SRCDIR)$(D)include $(LCMS2CF_) +LCMS2_CC=$(CC) $(D_)SHARE_LCMS=$(SHARE_LCMS)$(_D) $(CFLAGS) $(LCMS2_CFLAGS) $(I_)$(LCMS2SRCDIR)$(D)include $(LCMS2CF_) LCMS2O_=$(O_)$(LCMS2OBJ) # switch in the version of lcms2.dev we're actually using -$(LCMS2GEN)lcms2.dev : $(TOP_MAKEFILES) $(LCMS2GEN)lcms2_$(SHARE_LCMS).dev +$(LCMS2GEN)lcms2.dev : $(LCMS2GEN)lcms2_$(SHARE_LCMS).dev $(MAKEDIRS) $(CP_) $(LCMS2GEN)lcms2_$(SHARE_LCMS).dev $(LCMS2GEN)lcms2.dev # dev file for shared (separately built) lcms library -$(LCMS2GEN)lcms2_1.dev : $(TOP_MAKEFILES) $(LCMS2_MAK) $(ECHOGS_XE) +$(LCMS2GEN)lcms2_1.dev : $(LCMS2_MAK) $(ECHOGS_XE) $(MAKEDIRS) $(SETMOD) $(LCMS2GEN)lcms2_1 -lib lcms2 # dev file for compiling our own from source -$(LCMS2GEN)lcms2_0.dev : $(TOP_MAKEFILES) $(LCMS2_MAK) $(ECHOGS_XE) $(lcms2_OBJS) +$(LCMS2GEN)lcms2_0.dev : $(LCMS2_MAK) $(ECHOGS_XE) $(lcms2_OBJS) $(LCMS2_DEPS) $(SETMOD) $(LCMS2GEN)lcms2_0 $(lcms2_OBJS) # explicit rules for building the source files. -$(LCMS2OBJ)cmscam02.$(OBJ) : $(LCMS2SRC)cmscam02.c $(lcms2_HDRS) +$(LCMS2OBJ)cmscam02.$(OBJ) : $(LCMS2SRC)cmscam02.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmscam02.$(OBJ) $(C_) $(LCMS2SRC)cmscam02.c -$(LCMS2OBJ)cmscgats.$(OBJ) : $(LCMS2SRC)cmscgats.c $(lcms2_HDRS) +$(LCMS2OBJ)cmscgats.$(OBJ) : $(LCMS2SRC)cmscgats.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmscgats.$(OBJ) $(C_) $(LCMS2SRC)cmscgats.c -$(LCMS2OBJ)cmscnvrt.$(OBJ) : $(LCMS2SRC)cmscnvrt.c $(lcms2_HDRS) +$(LCMS2OBJ)cmscnvrt.$(OBJ) : $(LCMS2SRC)cmscnvrt.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmscnvrt.$(OBJ) $(C_) $(LCMS2SRC)cmscnvrt.c -$(LCMS2OBJ)cmserr.$(OBJ) : $(LCMS2SRC)cmserr.c $(lcms2_HDRS) +$(LCMS2OBJ)cmserr.$(OBJ) : $(LCMS2SRC)cmserr.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmserr.$(OBJ) $(C_) $(LCMS2SRC)cmserr.c -$(LCMS2OBJ)cmsgamma.$(OBJ) : $(LCMS2SRC)cmsgamma.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsgamma.$(OBJ) : $(LCMS2SRC)cmsgamma.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsgamma.$(OBJ) $(C_) $(LCMS2SRC)cmsgamma.c -$(LCMS2OBJ)cmsgmt.$(OBJ) : $(LCMS2SRC)cmsgmt.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsgmt.$(OBJ) : $(LCMS2SRC)cmsgmt.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsgmt.$(OBJ) $(C_) $(LCMS2SRC)cmsgmt.c -$(LCMS2OBJ)cmshalf.$(OBJ) : $(LCMS2SRC)cmshalf.c $(lcms2_HDRS) +$(LCMS2OBJ)cmshalf.$(OBJ) : $(LCMS2SRC)cmshalf.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmshalf.$(OBJ) $(C_) $(LCMS2SRC)cmshalf.c -$(LCMS2OBJ)cmsintrp.$(OBJ) : $(LCMS2SRC)cmsintrp.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsintrp.$(OBJ) : $(LCMS2SRC)cmsintrp.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsintrp.$(OBJ) $(C_) $(LCMS2SRC)cmsintrp.c -$(LCMS2OBJ)cmsio0.$(OBJ) : $(LCMS2SRC)cmsio0.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsio0.$(OBJ) : $(LCMS2SRC)cmsio0.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsio0.$(OBJ) $(C_) $(LCMS2SRC)cmsio0.c -$(LCMS2OBJ)cmsio1.$(OBJ) : $(LCMS2SRC)cmsio1.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsio1.$(OBJ) : $(LCMS2SRC)cmsio1.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsio1.$(OBJ) $(C_) $(LCMS2SRC)cmsio1.c -$(LCMS2OBJ)cmslut.$(OBJ) : $(LCMS2SRC)cmslut.c $(lcms2_HDRS) +$(LCMS2OBJ)cmslut.$(OBJ) : $(LCMS2SRC)cmslut.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmslut.$(OBJ) $(C_) $(LCMS2SRC)cmslut.c -$(LCMS2OBJ)cmsmd5.$(OBJ) : $(LCMS2SRC)cmsmd5.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsmd5.$(OBJ) : $(LCMS2SRC)cmsmd5.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsmd5.$(OBJ) $(C_) $(LCMS2SRC)cmsmd5.c -$(LCMS2OBJ)cmsmtrx.$(OBJ) : $(LCMS2SRC)cmsmtrx.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsmtrx.$(OBJ) : $(LCMS2SRC)cmsmtrx.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsmtrx.$(OBJ) $(C_) $(LCMS2SRC)cmsmtrx.c -$(LCMS2OBJ)cmsnamed.$(OBJ) : $(LCMS2SRC)cmsnamed.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsnamed.$(OBJ) : $(LCMS2SRC)cmsnamed.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsnamed.$(OBJ) $(C_) $(LCMS2SRC)cmsnamed.c -$(LCMS2OBJ)cmsopt.$(OBJ) : $(LCMS2SRC)cmsopt.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsopt.$(OBJ) : $(LCMS2SRC)cmsopt.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsopt.$(OBJ) $(C_) $(LCMS2SRC)cmsopt.c -$(LCMS2OBJ)cmspack.$(OBJ) : $(LCMS2SRC)cmspack.c $(lcms2_HDRS) +$(LCMS2OBJ)cmspack.$(OBJ) : $(LCMS2SRC)cmspack.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmspack.$(OBJ) $(C_) $(LCMS2SRC)cmspack.c -$(LCMS2OBJ)cmspcs.$(OBJ) : $(LCMS2SRC)cmspcs.c $(lcms2_HDRS) +$(LCMS2OBJ)cmspcs.$(OBJ) : $(LCMS2SRC)cmspcs.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmspcs.$(OBJ) $(C_) $(LCMS2SRC)cmspcs.c -$(LCMS2OBJ)cmsplugin.$(OBJ) : $(LCMS2SRC)cmsplugin.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsplugin.$(OBJ) : $(LCMS2SRC)cmsplugin.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsplugin.$(OBJ) $(C_) $(LCMS2SRC)cmsplugin.c -$(LCMS2OBJ)cmsps2.$(OBJ) : $(LCMS2SRC)cmsps2.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsps2.$(OBJ) : $(LCMS2SRC)cmsps2.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsps2.$(OBJ) $(C_) $(LCMS2SRC)cmsps2.c -$(LCMS2OBJ)cmssamp.$(OBJ) : $(LCMS2SRC)cmssamp.c $(lcms2_HDRS) +$(LCMS2OBJ)cmssamp.$(OBJ) : $(LCMS2SRC)cmssamp.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmssamp.$(OBJ) $(C_) $(LCMS2SRC)cmssamp.c -$(LCMS2OBJ)cmstypes.$(OBJ) : $(LCMS2SRC)cmstypes.c $(lcms2_HDRS) +$(LCMS2OBJ)cmstypes.$(OBJ) : $(LCMS2SRC)cmstypes.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmstypes.$(OBJ) $(C_) $(LCMS2SRC)cmstypes.c -$(LCMS2OBJ)cmswtpnt.$(OBJ) : $(LCMS2SRC)cmswtpnt.c $(lcms2_HDRS) +$(LCMS2OBJ)cmswtpnt.$(OBJ) : $(LCMS2SRC)cmswtpnt.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmswtpnt.$(OBJ) $(C_) $(LCMS2SRC)cmswtpnt.c -$(LCMS2OBJ)cmsvirt.$(OBJ) : $(LCMS2SRC)cmsvirt.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsvirt.$(OBJ) : $(LCMS2SRC)cmsvirt.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsvirt.$(OBJ) $(C_) $(LCMS2SRC)cmsvirt.c -$(LCMS2OBJ)cmsxform.$(OBJ) : $(LCMS2SRC)cmsxform.c $(lcms2_HDRS) +$(LCMS2OBJ)cmsxform.$(OBJ) : $(LCMS2SRC)cmsxform.c $(LCMS2_DEPS) $(LCMS2_CC) $(LCMS2O_)cmsxform.$(OBJ) $(C_) $(LCMS2SRC)cmsxform.c + +$(LCMS2OBJ)cmsalpha.$(OBJ) : $(LCMS2SRC)cmsalpha.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsalpha.$(OBJ) $(C_) $(LCMS2SRC)cmsalpha.c diff -Nru ghostscript-9.10~dfsg/base/lcms2mt.mak ghostscript-9.25~dfsg+1/base/lcms2mt.mak --- ghostscript-9.10~dfsg/base/lcms2mt.mak 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/lcms2mt.mak 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,173 @@ +# Copyright (C) 2001-2018 Artifex Software, Inc. +# All Rights Reserved. +# +# This software is provided AS-IS with no warranty, either express or +# implied. +# +# This software is distributed under license and may not be copied, +# modified or distributed except as expressly authorized under the terms +# of the license contained in the file LICENSE in this distribution. +# +# Refer to licensing information at http://www.artifex.com or contact +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. +# + +# makefile for the lcms2mt library code. +# Users of this makefile must define the following: +# SHARE_LCMS - whether to compile in or link to the library +# LCMS2MTSRCDIR - the library source directory +# +# gs.mak and friends define the following: +# LCMS2OBJDIR - the output obj directory +# LCMS2GENDIR - generated (.dev) file directory +# LCMS2I_ LCMS2_CFLAGS - include and cflags for compiling the lib + +# We define the lcms2.dev target and its dependencies +# +# This partial makefile compiles the lcms2mt library for use in +# Ghostscript. + + +# Define the name of this makefile. +LCMS2_MAK=$(GLSRC)lcms2mt.mak $(TOP_MAKEFILES) + +LCMS2SRC=$(LCMS2MTSRCDIR)$(D)src$(D) +LCMS2GEN=$(LCMS2GENDIR)$(D) +LCMS2OBJ=$(LCMS2OBJDIR)$(D) + +# This makefile was stolen from the one for lcms2. + +lcms2_OBJS=\ + $(LCMS2OBJ)cmscam02.$(OBJ) \ + $(LCMS2OBJ)cmscgats.$(OBJ) \ + $(LCMS2OBJ)cmscnvrt.$(OBJ) \ + $(LCMS2OBJ)cmserr.$(OBJ) \ + $(LCMS2OBJ)cmsgamma.$(OBJ) \ + $(LCMS2OBJ)cmsgmt.$(OBJ) \ + $(LCMS2OBJ)cmshalf.$(OBJ) \ + $(LCMS2OBJ)cmsintrp.$(OBJ) \ + $(LCMS2OBJ)cmsio0.$(OBJ) \ + $(LCMS2OBJ)cmsio1.$(OBJ) \ + $(LCMS2OBJ)cmslut.$(OBJ) \ + $(LCMS2OBJ)cmsmd5.$(OBJ) \ + $(LCMS2OBJ)cmsmtrx.$(OBJ) \ + $(LCMS2OBJ)cmsnamed.$(OBJ) \ + $(LCMS2OBJ)cmsopt.$(OBJ) \ + $(LCMS2OBJ)cmspack.$(OBJ) \ + $(LCMS2OBJ)cmspcs.$(OBJ) \ + $(LCMS2OBJ)cmsplugin.$(OBJ) \ + $(LCMS2OBJ)cmsps2.$(OBJ) \ + $(LCMS2OBJ)cmssamp.$(OBJ) \ + $(LCMS2OBJ)cmstypes.$(OBJ) \ + $(LCMS2OBJ)cmsvirt.$(OBJ) \ + $(LCMS2OBJ)cmswtpnt.$(OBJ) \ + $(LCMS2OBJ)cmsxform.$(OBJ) \ + $(LCMS2OBJ)cmsalpha.$(OBJ) + +LCMS2_DEPS=\ + $(LCMS2MTSRCDIR)$(D)include$(D)lcms2mt.h \ + $(GLSRC)icc34.h $(LCMS2_MAK) $(MAKEDIRS) + +lcms2.clean : lcms2.config-clean lcms2.clean-not-config-clean + +lcms2.clean-not-config-clean : + $(EXP)$(ECHOGS_XE) $(LCMS2MTSRCDIR) $(LCMS2OBJDIR) + $(RM_) $(lcms2_OBJS) + +lcms2.config-clean : + $(RMN_) $(LCMS2GEN)$(D)lcms2mt*.dev + +# NB: we can't use the normal $(CC_) here because msvccmd.mak +# adds /Za which conflicts with the lcms source. +LCMS2_CC=$(CC) $(D_)SHARE_LCMS=$(SHARE_LCMS)$(_D) $(GENOPT) $(CAPOPT) $(CFLAGS) $(LCMS2_CFLAGS) $(I_)$(LCMS2MTSRCDIR)$(D)include $(LCMS2CF_) +LCMS2O_=$(O_)$(LCMS2OBJ) + +# switch in the version of lcms2mt.dev we're actually using +$(LCMS2GEN)lcms2mt.dev : $(LCMS2GEN)lcms2mt_$(SHARE_LCMS).dev $(MAKEDIRS) + $(CP_) $(LCMS2GEN)lcms2mt_$(SHARE_LCMS).dev $(LCMS2GEN)lcms2mt.dev + +# dev file for shared (separately built) lcms library +$(LCMS2GEN)lcms2mt_1.dev : $(LCMS2_MAK) $(ECHOGS_XE) $(MAKEDIRS) + $(SETMOD) $(LCMS2GEN)lcms2mt_1 -lib lcms2 + +# dev file for compiling our own from source +$(LCMS2GEN)lcms2mt_0.dev : $(LCMS2_MAK) $(ECHOGS_XE) $(lcms2_OBJS) $(LCMS2_DEPS) + $(SETMOD) $(LCMS2GEN)lcms2mt_0 $(lcms2_OBJS) + +# explicit rules for building the source files. + +$(LCMS2OBJ)cmscam02.$(OBJ) : $(LCMS2SRC)cmscam02.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmscam02.$(OBJ) $(C_) $(LCMS2SRC)cmscam02.c + +$(LCMS2OBJ)cmscgats.$(OBJ) : $(LCMS2SRC)cmscgats.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmscgats.$(OBJ) $(C_) $(LCMS2SRC)cmscgats.c + +$(LCMS2OBJ)cmscnvrt.$(OBJ) : $(LCMS2SRC)cmscnvrt.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmscnvrt.$(OBJ) $(C_) $(LCMS2SRC)cmscnvrt.c + +$(LCMS2OBJ)cmserr.$(OBJ) : $(LCMS2SRC)cmserr.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmserr.$(OBJ) $(C_) $(LCMS2SRC)cmserr.c + +$(LCMS2OBJ)cmsgamma.$(OBJ) : $(LCMS2SRC)cmsgamma.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsgamma.$(OBJ) $(C_) $(LCMS2SRC)cmsgamma.c + +$(LCMS2OBJ)cmsgmt.$(OBJ) : $(LCMS2SRC)cmsgmt.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsgmt.$(OBJ) $(C_) $(LCMS2SRC)cmsgmt.c + +$(LCMS2OBJ)cmshalf.$(OBJ) : $(LCMS2SRC)cmshalf.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmshalf.$(OBJ) $(C_) $(LCMS2SRC)cmshalf.c + +$(LCMS2OBJ)cmsintrp.$(OBJ) : $(LCMS2SRC)cmsintrp.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsintrp.$(OBJ) $(C_) $(LCMS2SRC)cmsintrp.c + +$(LCMS2OBJ)cmsio0.$(OBJ) : $(LCMS2SRC)cmsio0.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsio0.$(OBJ) $(C_) $(LCMS2SRC)cmsio0.c + +$(LCMS2OBJ)cmsio1.$(OBJ) : $(LCMS2SRC)cmsio1.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsio1.$(OBJ) $(C_) $(LCMS2SRC)cmsio1.c + +$(LCMS2OBJ)cmslut.$(OBJ) : $(LCMS2SRC)cmslut.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmslut.$(OBJ) $(C_) $(LCMS2SRC)cmslut.c + +$(LCMS2OBJ)cmsmd5.$(OBJ) : $(LCMS2SRC)cmsmd5.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsmd5.$(OBJ) $(C_) $(LCMS2SRC)cmsmd5.c + +$(LCMS2OBJ)cmsmtrx.$(OBJ) : $(LCMS2SRC)cmsmtrx.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsmtrx.$(OBJ) $(C_) $(LCMS2SRC)cmsmtrx.c + +$(LCMS2OBJ)cmsnamed.$(OBJ) : $(LCMS2SRC)cmsnamed.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsnamed.$(OBJ) $(C_) $(LCMS2SRC)cmsnamed.c + +$(LCMS2OBJ)cmsopt.$(OBJ) : $(LCMS2SRC)cmsopt.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsopt.$(OBJ) $(C_) $(LCMS2SRC)cmsopt.c + +$(LCMS2OBJ)cmspack.$(OBJ) : $(LCMS2SRC)cmspack.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmspack.$(OBJ) $(C_) $(LCMS2SRC)cmspack.c + +$(LCMS2OBJ)cmspcs.$(OBJ) : $(LCMS2SRC)cmspcs.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmspcs.$(OBJ) $(C_) $(LCMS2SRC)cmspcs.c + +$(LCMS2OBJ)cmsplugin.$(OBJ) : $(LCMS2SRC)cmsplugin.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsplugin.$(OBJ) $(C_) $(LCMS2SRC)cmsplugin.c + +$(LCMS2OBJ)cmsps2.$(OBJ) : $(LCMS2SRC)cmsps2.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsps2.$(OBJ) $(C_) $(LCMS2SRC)cmsps2.c + +$(LCMS2OBJ)cmssamp.$(OBJ) : $(LCMS2SRC)cmssamp.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmssamp.$(OBJ) $(C_) $(LCMS2SRC)cmssamp.c + +$(LCMS2OBJ)cmstypes.$(OBJ) : $(LCMS2SRC)cmstypes.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmstypes.$(OBJ) $(C_) $(LCMS2SRC)cmstypes.c + +$(LCMS2OBJ)cmswtpnt.$(OBJ) : $(LCMS2SRC)cmswtpnt.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmswtpnt.$(OBJ) $(C_) $(LCMS2SRC)cmswtpnt.c + +$(LCMS2OBJ)cmsvirt.$(OBJ) : $(LCMS2SRC)cmsvirt.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsvirt.$(OBJ) $(C_) $(LCMS2SRC)cmsvirt.c + +$(LCMS2OBJ)cmsxform.$(OBJ) : $(LCMS2SRC)cmsxform.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsxform.$(OBJ) $(C_) $(LCMS2SRC)cmsxform.c + +$(LCMS2OBJ)cmsalpha.$(OBJ) : $(LCMS2SRC)cmsalpha.c $(LCMS2_DEPS) + $(LCMS2_CC) $(LCMS2O_)cmsalpha.$(OBJ) $(C_) $(LCMS2SRC)cmsalpha.c diff -Nru ghostscript-9.10~dfsg/base/lcms.mak ghostscript-9.25~dfsg+1/base/lcms.mak --- ghostscript-9.10~dfsg/base/lcms.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/lcms.mak 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. -# All Rights Reserved. -# -# This software is provided AS-IS with no warranty, either express or -# implied. -# -# This software is distributed under license and may not be copied, -# modified or distributed except as expressly authorized under the terms -# of the license contained in the file LICENSE in this distribution. -# -# Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. -# - -# makefile for the lcms library code. -# Users of this makefile must define the following: -# SHARE_LCMS - whether to compile in or link to the library -# LCMSSRCDIR - the library source directory -# -# gs.mak and friends define the following: -# LCMSOBJDIR - the output obj directory -# LCMSGENDIR - generated (.dev) file directory -# LCMSI_ LCMS_CFLAGS - include and cflags for compiling the lib - -# We define the lcms.dev target and its dependencies -# -# This partial makefile compiles the lcms library for use in -# Ghostscript. - -# Define the name of this makefile. -LCMS_MAK=$(GLSRC)lcms.mak - -LCMSSRC=$(LCMSSRCDIR)$(D)src$(D) -LCMSGEN=$(LCMSGENDIR)$(D) -LCMSOBJ=$(LCMSOBJDIR)$(D) - -# This makefile was originally written for lcms-1.18. -# Other versions may require adjustments to the OBJS list below - -lcms_OBJS=\ - $(LCMSOBJ)cmscnvrt.$(OBJ) \ - $(LCMSOBJ)cmserr.$(OBJ) \ - $(LCMSOBJ)cmsgamma.$(OBJ) \ - $(LCMSOBJ)cmsgmt.$(OBJ) \ - $(LCMSOBJ)cmsintrp.$(OBJ) \ - $(LCMSOBJ)cmsio0.$(OBJ) \ - $(LCMSOBJ)cmsio1.$(OBJ) \ - $(LCMSOBJ)cmslut.$(OBJ) \ - $(LCMSOBJ)cmsmatsh.$(OBJ) \ - $(LCMSOBJ)cmsmtrx.$(OBJ) \ - $(LCMSOBJ)cmspack.$(OBJ) \ - $(LCMSOBJ)cmspcs.$(OBJ) \ - $(LCMSOBJ)cmswtpnt.$(OBJ) \ - $(LCMSOBJ)cmsxform.$(OBJ) \ - $(LCMSOBJ)cmssamp.$(OBJ) \ - $(LCMSOBJ)cmscam97.$(OBJ) \ - $(LCMSOBJ)cmsnamed.$(OBJ) \ - $(LCMSOBJ)cmsps2.$(OBJ) \ - $(LCMSOBJ)cmscam02.$(OBJ) \ - $(LCMSOBJ)cmsvirt.$(OBJ) \ - $(LCMSOBJ)cmscgats.$(OBJ) - -# use of LCMS_USER_ALLOC avoids the lcms allocator. -lcms_HDRS=\ - $(LCMSSRCDIR)$(D)include$(D)lcms.h \ - $(GLSRC)icc34.h - -lcms.clean : lcms.config-clean lcms.clean-not-config-clean - -lcms.clean-not-config-clean : - $(EXP)$(ECHOGS_XE) $(LCMSSRCDIR) $(LCMSOBJDIR) - $(RM_) $(lcms_OBJS) - -lcms.config-clean : - $(RMN_) $(LCMSGEN)$(D)lcms*.dev - -LCMSCF_=$(D_)LCMS_USER_ALLOC$(_D_)1$(_D) - -# NB: we can't use the normal $(CC_) here because msvccmd.mak -# adds /Za which conflicts with the lcms source. -LCMS_CC=$(CC) $(CFLAGS) $(LCMS_CFLAGS) $(I_)$(GLSRC) $(I_)$(LCMSSRCDIR)$(D)include $(LCMSCF_) -LCMSO_=$(O_)$(LCMSOBJ) - -# switch in the version of lcms.dev we're actually using -$(LCMSGEN)lcms.dev : $(TOP_MAKEFILES) $(LCMSGEN)lcms_$(SHARE_LCMS).dev - $(CP_) $(LCMSGEN)lcms_$(SHARE_LCMS).dev $(LCMSGEN)lcms.dev - -# dev file for shared (separately built) lcms library -$(LCMSGEN)lcms_1.dev : $(TOP_MAKEFILES) $(LCMS_MAK) $(ECHOGS_XE) - $(SETMOD) $(LCMSGEN)lcms_1 -lib lcms - -# dev file for compiling our own from source -$(LCMSGEN)lcms_0.dev : $(TOP_MAKEFILES) $(LCMS_MAK) $(ECHOGS_XE) $(lcms_OBJS) - $(SETMOD) $(LCMSGEN)lcms_0 $(lcms_OBJS) - -# explicit rules for building the source files. - -$(LCMSOBJ)cmscnvrt.$(OBJ) : $(LCMSSRC)cmscnvrt.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmscnvrt.$(OBJ) $(C_) $(LCMSSRC)cmscnvrt.c - -$(LCMSOBJ)cmserr.$(OBJ) : $(LCMSSRC)cmserr.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmserr.$(OBJ) $(C_) $(LCMSSRC)cmserr.c - -$(LCMSOBJ)cmsgamma.$(OBJ) : $(LCMSSRC)cmsgamma.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsgamma.$(OBJ) $(C_) $(LCMSSRC)cmsgamma.c - -$(LCMSOBJ)cmsgmt.$(OBJ) : $(LCMSSRC)cmsgmt.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsgmt.$(OBJ) $(C_) $(LCMSSRC)cmsgmt.c - -$(LCMSOBJ)cmsintrp.$(OBJ) : $(LCMSSRC)cmsintrp.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsintrp.$(OBJ) $(C_) $(LCMSSRC)cmsintrp.c - -$(LCMSOBJ)cmsio0.$(OBJ) : $(LCMSSRC)cmsio0.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsio0.$(OBJ) $(C_) $(LCMSSRC)cmsio0.c - -$(LCMSOBJ)cmsio1.$(OBJ) : $(LCMSSRC)cmsio1.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsio1.$(OBJ) $(C_) $(LCMSSRC)cmsio1.c - -$(LCMSOBJ)cmslut.$(OBJ) : $(LCMSSRC)cmslut.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmslut.$(OBJ) $(C_) $(LCMSSRC)cmslut.c - -$(LCMSOBJ)cmsmatsh.$(OBJ) : $(LCMSSRC)cmsmatsh.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsmatsh.$(OBJ) $(C_) $(LCMSSRC)cmsmatsh.c - -$(LCMSOBJ)cmsmtrx.$(OBJ) : $(LCMSSRC)cmsmtrx.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsmtrx.$(OBJ) $(C_) $(LCMSSRC)cmsmtrx.c - -$(LCMSOBJ)cmspack.$(OBJ) : $(LCMSSRC)cmspack.c $(LCMSSRC)cmsxform.h $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmspack.$(OBJ) $(C_) $(LCMSSRC)cmspack.c - -$(LCMSOBJ)cmspcs.$(OBJ) : $(LCMSSRC)cmspcs.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmspcs.$(OBJ) $(C_) $(LCMSSRC)cmspcs.c - -$(LCMSOBJ)cmswtpnt.$(OBJ) : $(LCMSSRC)cmswtpnt.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmswtpnt.$(OBJ) $(C_) $(LCMSSRC)cmswtpnt.c - -$(LCMSOBJ)cmsxform.$(OBJ) : $(LCMSSRC)cmsxform.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsxform.$(OBJ) $(C_) $(LCMSSRC)cmsxform.c - -$(LCMSOBJ)cmssamp.$(OBJ) : $(LCMSSRC)cmssamp.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmssamp.$(OBJ) $(C_) $(LCMSSRC)cmssamp.c - -$(LCMSOBJ)cmscam97.$(OBJ) : $(LCMSSRC)cmscam97.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmscam97.$(OBJ) $(C_) $(LCMSSRC)cmscam97.c - -$(LCMSOBJ)cmsnamed.$(OBJ) : $(LCMSSRC)cmsnamed.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsnamed.$(OBJ) $(C_) $(LCMSSRC)cmsnamed.c - -$(LCMSOBJ)cmsps2.$(OBJ) : $(LCMSSRC)cmsps2.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsps2.$(OBJ) $(C_) $(LCMSSRC)cmsps2.c - -$(LCMSOBJ)cmscam02.$(OBJ) : $(LCMSSRC)cmscam02.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmscam02.$(OBJ) $(C_) $(LCMSSRC)cmscam02.c - -$(LCMSOBJ)cmsvirt.$(OBJ) : $(LCMSSRC)cmsvirt.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmsvirt.$(OBJ) $(C_) $(LCMSSRC)cmsvirt.c - -$(LCMSOBJ)cmscgats.$(OBJ) : $(LCMSSRC)cmscgats.c $(lcms_HDRS) - $(LCMS_CC) $(LCMSO_)cmscgats.$(OBJ) $(C_) $(LCMSSRC)cmscgats.c diff -Nru ghostscript-9.10~dfsg/base/lcupsi.mak ghostscript-9.25~dfsg+1/base/lcupsi.mak --- ghostscript-9.10~dfsg/base/lcupsi.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/lcupsi.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # $Id: lcupsi.mak 11073 2010-04-15 08:30:48Z chrisl $ # makefile for libcupsimage as part of the monolithic gs build. @@ -35,32 +35,16 @@ $(I_)$(ZSRCDIR) $(I_)$(PNGSRCDIR) $(I_)$(TIFFSRCDIR) $(I_)$(TIFFCONFDIR) $(I_)$(TI_) # Define the name of this makefile. -LCUPSI_MAK=$(GLSRC)lcupsi.mak +LCUPSI_MAK=$(GLSRC)lcupsi.mak $(TOP_MAKEFILES) LIBCUPSI_OBJS =\ - $(LIBCUPSIOBJ)image-bmp.$(OBJ) \ - $(LIBCUPSIOBJ)image-colorspace.$(OBJ) \ - $(LIBCUPSIOBJ)image-gif.$(OBJ) \ - $(LIBCUPSIOBJ)image-jpeg.$(OBJ) \ - $(LIBCUPSIOBJ)image-photocd.$(OBJ) \ - $(LIBCUPSIOBJ)image-pix.$(OBJ) \ - $(LIBCUPSIOBJ)image-png.$(OBJ) \ - $(LIBCUPSIOBJ)image-pnm.$(OBJ) \ - $(LIBCUPSIOBJ)image-sgi.$(OBJ) \ - $(LIBCUPSIOBJ)image-sgilib.$(OBJ) \ - $(LIBCUPSIOBJ)image-sun.$(OBJ) \ - $(LIBCUPSIOBJ)image-tiff.$(OBJ) \ - $(LIBCUPSIOBJ)image-zoom.$(OBJ) \ - $(LIBCUPSIOBJ)image.$(OBJ) \ $(LIBCUPSIOBJ)error.$(OBJ) \ $(LIBCUPSIOBJ)interpret.$(OBJ) \ $(LIBCUPSIOBJ)raster.$(OBJ) -LIBCUPSIHEADERS = \ - $(LIBCUPSISRC)common.h \ - $(LIBCUPSISRC)image.h \ - $(LIBCUPSISRC)image-private.h \ - $(LIBCUPSISRC)image-sgi.h +LIBCUPSI_DEPS = \ + $(LIBCUPSISRC)common.h $(LCUPSI_MAK) \ + $(MAKEDIRS) libcupsi.clean : libcupsi.config-clean libcupsi.clean-not-config-clean @@ -72,69 +56,70 @@ $(RMN_) $(LIBCUPSIGEN)$(D)lcupsi*.dev # instantiate the requested build option (shared or compiled in) -$(LIBCUPSIGEN)lcupsi.dev : $(TOP_MAKEFILES) $(LIBCUPSIGEN)lcupsi_$(SHARE_LCUPSI).dev +$(LIBCUPSIGEN)lcupsi.dev : $(LIBCUPSIGEN)lcupsi_$(SHARE_LCUPSI).dev\ + $(LCUPSI_MAK) $(MAKEDIRS) $(CP_) $(LIBCUPSIGEN)lcupsi_$(SHARE_LCUPSI).dev $(LIBCUPSIGEN)lcupsi.dev # Define the shared version. -$(LIBCUPSIGEN)lcupsi_1.dev : $(TOP_MAKEFILES) $(LCUPSI_MAK) $(ECHOGS_XE) +$(LIBCUPSIGEN)lcupsi_1.dev : $(ECHOGS_XE) $(LCUPSI_MAK) \ + $(LCUPSI_MAK) $(MAKEDIRS) $(SETMOD) $(LIBCUPSIGEN)lcupsi_1 -link $(LCUPSI_LIBS) # Define the non-shared version. -$(LIBCUPSIGEN)lcupsi_0.dev : $(TOP_MAKEFILES) $(LCUPSI_MAK) $(ECHOGS_XE) \ - $(LIBCUPSI_OBJS) +$(LIBCUPSIGEN)lcupsi_0.dev : $(ECHOGS_XE) $(LIBCUPSI_OBJS) $(LIBCUPSI_DEPS) $(SETMOD) $(LIBCUPSIGEN)lcupsi_0 $(LIBCUPSI_OBJS) # explicit rules for building the source files # for simplicity we have every source file depend on all headers -$(LIBCUPSIOBJ)image-bmp.$(OBJ) : $(LIBCUPSISRC)image-bmp.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-bmp.$(OBJ) : $(LIBCUPSISRC)image-bmp.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-bmp.$(OBJ) $(C_) $(LIBCUPSISRC)image-bmp.c -$(LIBCUPSIOBJ)image-colorspace.$(OBJ) : $(LIBCUPSISRC)image-colorspace.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-colorspace.$(OBJ) : $(LIBCUPSISRC)image-colorspace.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-colorspace.$(OBJ) $(C_) $(LIBCUPSISRC)image-colorspace.c -$(LIBCUPSIOBJ)image-gif.$(OBJ) : $(LIBCUPSISRC)image-gif.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-gif.$(OBJ) : $(LIBCUPSISRC)image-gif.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-gif.$(OBJ) $(C_) $(LIBCUPSISRC)image-gif.c -$(LIBCUPSIOBJ)image-jpeg.$(OBJ) : $(LIBCUPSISRC)image-jpeg.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-jpeg.$(OBJ) : $(LIBCUPSISRC)image-jpeg.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-jpeg.$(OBJ) $(C_) $(LIBCUPSISRC)image-jpeg.c -$(LIBCUPSIOBJ)image-photocd.$(OBJ) : $(LIBCUPSISRC)image-photocd.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-photocd.$(OBJ) : $(LIBCUPSISRC)image-photocd.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-photocd.$(OBJ) $(C_) $(LIBCUPSISRC)image-photocd.c -$(LIBCUPSIOBJ)image-pix.$(OBJ) : $(LIBCUPSISRC)image-pix.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-pix.$(OBJ) : $(LIBCUPSISRC)image-pix.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-pix.$(OBJ) $(C_) $(LIBCUPSISRC)image-pix.c -$(LIBCUPSIOBJ)image-png.$(OBJ) : $(LIBCUPSISRC)image-png.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-png.$(OBJ) : $(LIBCUPSISRC)image-png.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-png.$(OBJ) $(C_) $(LIBCUPSISRC)image-png.c -$(LIBCUPSIOBJ)image-pnm.$(OBJ) : $(LIBCUPSISRC)image-pnm.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-pnm.$(OBJ) : $(LIBCUPSISRC)image-pnm.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-pnm.$(OBJ) $(C_) $(LIBCUPSISRC)image-pnm.c -$(LIBCUPSIOBJ)image-sgi.$(OBJ) : $(LIBCUPSISRC)image-sgi.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-sgi.$(OBJ) : $(LIBCUPSISRC)image-sgi.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-sgi.$(OBJ) $(C_) $(LIBCUPSISRC)image-sgi.c -$(LIBCUPSIOBJ)image-sgilib.$(OBJ) : $(LIBCUPSISRC)image-sgilib.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-sgilib.$(OBJ) : $(LIBCUPSISRC)image-sgilib.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-sgilib.$(OBJ) $(C_) $(LIBCUPSISRC)image-sgilib.c -$(LIBCUPSIOBJ)image-sun.$(OBJ) : $(LIBCUPSISRC)image-sun.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-sun.$(OBJ) : $(LIBCUPSISRC)image-sun.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-sun.$(OBJ) $(C_) $(LIBCUPSISRC)image-sun.c -$(LIBCUPSIOBJ)image-tiff.$(OBJ) : $(LIBCUPSISRC)image-tiff.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-tiff.$(OBJ) : $(LIBCUPSISRC)image-tiff.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-tiff.$(OBJ) $(C_) $(LIBCUPSISRC)image-tiff.c -$(LIBCUPSIOBJ)image-zoom.$(OBJ) : $(LIBCUPSISRC)image-zoom.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image-zoom.$(OBJ) : $(LIBCUPSISRC)image-zoom.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image-zoom.$(OBJ) $(C_) $(LIBCUPSISRC)image-zoom.c -$(LIBCUPSIOBJ)image.$(OBJ) : $(LIBCUPSISRC)image.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)image.$(OBJ) : $(LIBCUPSISRC)image.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)image.$(OBJ) $(C_) $(LIBCUPSISRC)image.c -$(LIBCUPSIOBJ)error.$(OBJ) : $(LIBCUPSISRC)error.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)error.$(OBJ) : $(LIBCUPSISRC)error.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)error.$(OBJ) $(C_) $(LIBCUPSISRC)error.c -$(LIBCUPSIOBJ)interpret.$(OBJ) : $(LIBCUPSISRC)interpret.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)interpret.$(OBJ) : $(LIBCUPSISRC)interpret.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)interpret.$(OBJ) $(C_) $(LIBCUPSISRC)interpret.c -$(LIBCUPSIOBJ)raster.$(OBJ) : $(LIBCUPSISRC)raster.c $(LIBSCUPSIHEADERS) +$(LIBCUPSIOBJ)raster.$(OBJ) : $(LIBCUPSISRC)raster.c $(LIBCUPSI_DEPS) $(LCUPSI_CC) $(LCUPSIO_)raster.$(OBJ) $(C_) $(LIBCUPSISRC)raster.c diff -Nru ghostscript-9.10~dfsg/base/lcups.mak ghostscript-9.25~dfsg+1/base/lcups.mak --- ghostscript-9.10~dfsg/base/lcups.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/lcups.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # $Id: lcups.mak 11073 2010-04-15 08:30:48Z chrisl $ # makefile for libcups as part of the monolithic gs build. @@ -33,7 +33,7 @@ LCUPS_CC=$(CUPS_CC) $(I_)$(LIBCUPSSRC) $(I_)$(LIBCUPSGEN)$(D)cups $(I_)$(LCUPSSRCDIR)$(D)libs # Define the name of this makefile. -LCUPS_MAK=$(GLSRC)lcups.mak +LCUPS_MAK=$(GLSRC)lcups.mak $(TOP_MAKEFILES) LIBCUPS_OBJS =\ $(LIBCUPSOBJ)adminutil.$(OBJ) \ @@ -68,9 +68,7 @@ $(LIBCUPSOBJ)options.$(OBJ) \ $(LIBCUPSOBJ)page.$(OBJ) \ $(LIBCUPSOBJ)ppd.$(OBJ) \ - $(LIBCUPSOBJ)pwg-file.$(OBJ) \ $(LIBCUPSOBJ)pwg-media.$(OBJ) \ - $(LIBCUPSOBJ)pwg-ppd.$(OBJ) \ $(LIBCUPSOBJ)request.$(OBJ) \ $(LIBCUPSOBJ)snmp.$(OBJ) \ $(LIBCUPSOBJ)string.$(OBJ) \ @@ -79,11 +77,15 @@ $(LIBCUPSOBJ)cups_util.$(OBJ) \ $(LIBCUPSOBJ)cups_md5.$(OBJ) \ $(LIBCUPSOBJ)cups_snpf.$(OBJ) \ - $(LIBCUPSOBJ)usersys.$(OBJ) + $(LIBCUPSOBJ)usersys.$(OBJ) \ + $(LIBCUPSOBJ)ppd-cache.$(OBJ) \ + $(LIBCUPSOBJ)thread.$(OBJ) # $(LIBCUPSOBJ)sidechannel.$(OBJ) \ # $(LIBCUPSOBJ)getifaddrs.$(OBJ) \ +# $(LIBCUPSOBJ)pwg-ppd.$(OBJ) \ +# $(LIBCUPSOBJ)pwg-file.$(OBJ) \ -LIBCUPSHEADERS = \ +LIBCUPS_DEPS = \ $(LIBCUPSSRC)adminutil.h \ $(LIBCUPSSRC)array.h \ $(LIBCUPSSRC)backend.h \ @@ -97,7 +99,9 @@ $(LIBCUPSSRC)raster.h \ $(LIBCUPSSRC)sidechannel.h \ $(LIBCUPSSRC)transcode.h \ - $(LIBCUPSSRC)versioning.h + $(LIBCUPSSRC)versioning.h \ + $(LCUPS_MAK) \ + $(MAKEDIRS) libcups.clean : libcups.config-clean libcups.clean-not-config-clean @@ -113,163 +117,170 @@ $(RMN_) $(LIBCUPSGEN)$(D)cups_util.c # instantiate the requested build option (shared or compiled in) -$(LIBCUPSGEN)lcups.dev : $(TOP_MAKEFILES) $(LIBCUPSGEN)lcups_$(SHARE_LCUPS).dev +$(LIBCUPSGEN)lcups.dev : $(LIBCUPSGEN)lcups_$(SHARE_LCUPS).dev \ + $(LCUPS_MAK) $(MAKEDIRS) $(CP_) $(LIBCUPSGEN)lcups_$(SHARE_LCUPS).dev $(LIBCUPSGEN)lcups.dev # Define the shared version. -$(LIBCUPSGEN)lcups_1.dev : $(TOP_MAKEFILES) $(LCUPS_MAK) $(ECHOGS_XE) +$(LIBCUPSGEN)lcups_1.dev : $(ECHOGS_XE) $(LCUPS_MAK) \ + $(MAKEDIRS) $(SETMOD) $(LIBCUPSGEN)lcups_1 -link $(LCUPS_LIBS) $(ADDMOD) $(DD)lcups_1 -libpath $(CUPSLIBDIRS) $(ADDMOD) $(DD)lcups_1 -lib $(CUPSLIBS) # Define the non-shared version. -$(LIBCUPSGEN)lcups_0.dev : $(TOP_MAKEFILES) $(LCUPS_MAK) $(ECHOGS_XE) \ - $(LIBCUPS_OBJS) +$(LIBCUPSGEN)lcups_0.dev : $(ECHOGS_XE) $(LIBCUPS_OBJS) $(LIBCUPS_DEPS) $(SETMOD) $(LIBCUPSGEN)lcups_0 $(LIBCUPS_OBJS) # explicit rules for building the source files # for simplicity we have every source file depend on all headers -$(LIBCUPSGEN)$(D)cups$(D)config.h : $(LCUPSSRCDIR)$(D)libs$(D)config$(LCUPSBUILDTYPE).h +$(LIBCUPSGEN)$(D)cups$(D)config.h : $(LCUPSSRCDIR)$(D)libs$(D)config$(LCUPSBUILDTYPE).h $(LIBCUPS_DEPS) $(CP_) $(LCUPSSRCDIR)$(D)libs$(D)config$(LCUPSBUILDTYPE).h $(LIBCUPSGEN)$(D)cups$(D)config.h -$(LIBCUPSOBJ)adminutil.$(OBJ) : $(LIBCUPSSRC)adminutil.c $(LIBSCUPSHEADERS) $(LIBCUPSGEN)$(D)cups$(D)config.h +$(LIBCUPSOBJ)adminutil.$(OBJ) : $(LIBCUPSSRC)adminutil.c $(LIBCUPSGEN)$(D)cups$(D)config.h $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)adminutil.$(OBJ) $(C_) $(LIBCUPSSRC)adminutil.c -$(LIBCUPSOBJ)array.$(OBJ) : $(LIBCUPSSRC)array.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)array.$(OBJ) : $(LIBCUPSSRC)array.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)array.$(OBJ) $(C_) $(LIBCUPSSRC)array.c -$(LIBCUPSOBJ)attr.$(OBJ) : $(LIBCUPSSRC)attr.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)attr.$(OBJ) : $(LIBCUPSSRC)attr.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)attr.$(OBJ) $(C_) $(LIBCUPSSRC)attr.c -$(LIBCUPSOBJ)auth.$(OBJ) : $(LIBCUPSSRC)auth.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)auth.$(OBJ) : $(LIBCUPSSRC)auth.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)auth.$(OBJ) $(C_) $(LIBCUPSSRC)auth.c -$(LIBCUPSOBJ)backchannel.$(OBJ) : $(LIBCUPSSRC)backchannel.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)backchannel.$(OBJ) : $(LIBCUPSSRC)backchannel.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)backchannel.$(OBJ) $(C_) $(LIBCUPSSRC)backchannel.c -$(LIBCUPSOBJ)backend.$(OBJ) : $(LIBCUPSSRC)backend.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)backend.$(OBJ) : $(LIBCUPSSRC)backend.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)backend.$(OBJ) $(C_) $(LIBCUPSSRC)backend.c -$(LIBCUPSOBJ)conflicts.$(OBJ) : $(LIBCUPSSRC)conflicts.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)conflicts.$(OBJ) : $(LIBCUPSSRC)conflicts.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)conflicts.$(OBJ) $(C_) $(LIBCUPSSRC)conflicts.c -$(LIBCUPSOBJ)custom.$(OBJ) : $(LIBCUPSSRC)custom.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)custom.$(OBJ) : $(LIBCUPSSRC)custom.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)custom.$(OBJ) $(C_) $(LIBCUPSSRC)custom.c -$(LIBCUPSOBJ)debug.$(OBJ) : $(LIBCUPSSRC)debug.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)debug.$(OBJ) : $(LIBCUPSSRC)debug.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)debug.$(OBJ) $(C_) $(LIBCUPSSRC)debug.c -$(LIBCUPSOBJ)dest.$(OBJ) : $(LIBCUPSSRC)dest.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)dest.$(OBJ) : $(LIBCUPSSRC)dest.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)dest.$(OBJ) $(C_) $(LIBCUPSSRC)dest.c -$(LIBCUPSOBJ)dir.$(OBJ) : $(LIBCUPSSRC)dir.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)dir.$(OBJ) : $(LIBCUPSSRC)dir.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)dir.$(OBJ) $(C_) $(LIBCUPSSRC)dir.c -$(LIBCUPSOBJ)emit.$(OBJ) : $(LIBCUPSSRC)emit.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)emit.$(OBJ) : $(LIBCUPSSRC)emit.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)emit.$(OBJ) $(C_) $(LIBCUPSSRC)emit.c -$(LIBCUPSOBJ)encode.$(OBJ) : $(LIBCUPSSRC)encode.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)encode.$(OBJ) : $(LIBCUPSSRC)encode.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)encode.$(OBJ) $(C_) $(LIBCUPSSRC)encode.c -$(LIBCUPSOBJ)file.$(OBJ) : $(LIBCUPSSRC)file.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)file.$(OBJ) : $(LIBCUPSSRC)file.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)file.$(OBJ) $(C_) $(LIBCUPSSRC)file.c -$(LIBCUPSOBJ)getdevices.$(OBJ) : $(LIBCUPSSRC)getdevices.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)getdevices.$(OBJ) : $(LIBCUPSSRC)getdevices.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)getdevices.$(OBJ) $(C_) $(LIBCUPSSRC)getdevices.c -$(LIBCUPSOBJ)getifaddrs.$(OBJ) : $(LIBCUPSSRC)getifaddrs.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)getifaddrs.$(OBJ) : $(LIBCUPSSRC)getifaddrs.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)getifaddrs.$(OBJ) $(C_) $(LIBCUPSSRC)getifaddrs.c -$(LIBCUPSOBJ)getputfile.$(OBJ) : $(LIBCUPSSRC)getputfile.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)getputfile.$(OBJ) : $(LIBCUPSSRC)getputfile.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)getputfile.$(OBJ) $(C_) $(LIBCUPSSRC)getputfile.c -$(LIBCUPSOBJ)globals.$(OBJ) : $(LIBCUPSSRC)globals.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)globals.$(OBJ) : $(LIBCUPSSRC)globals.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)globals.$(OBJ) $(C_) $(LIBCUPSSRC)globals.c -$(LIBCUPSOBJ)http.$(OBJ) : $(LIBCUPSSRC)http.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)http.$(OBJ) : $(LIBCUPSSRC)http.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)http.$(OBJ) $(C_) $(LIBCUPSSRC)http.c -$(LIBCUPSOBJ)http-addr.$(OBJ) : $(LIBCUPSSRC)http-addr.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)http-addr.$(OBJ) : $(LIBCUPSSRC)http-addr.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)http-addr.$(OBJ) $(C_) $(LIBCUPSSRC)http-addr.c -$(LIBCUPSOBJ)http-addrlist.$(OBJ) : $(LIBCUPSSRC)http-addrlist.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)http-addrlist.$(OBJ) : $(LIBCUPSSRC)http-addrlist.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)http-addrlist.$(OBJ) $(C_) $(LIBCUPSSRC)http-addrlist.c -$(LIBCUPSOBJ)http-support.$(OBJ) : $(LIBCUPSSRC)http-support.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)http-support.$(OBJ) : $(LIBCUPSSRC)http-support.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)http-support.$(OBJ) $(C_) $(LIBCUPSSRC)http-support.c -$(LIBCUPSOBJ)ipp.$(OBJ) : $(LIBCUPSSRC)ipp.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)ipp.$(OBJ) : $(LIBCUPSSRC)ipp.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)ipp.$(OBJ) $(C_) $(LIBCUPSSRC)ipp.c -$(LIBCUPSOBJ)ipp-support.$(OBJ) : $(LIBCUPSSRC)ipp-support.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)ipp-support.$(OBJ) : $(LIBCUPSSRC)ipp-support.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)ipp-support.$(OBJ) $(C_) $(LIBCUPSSRC)ipp-support.c -$(LIBCUPSOBJ)langprintf.$(OBJ) : $(LIBCUPSSRC)langprintf.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)langprintf.$(OBJ) : $(LIBCUPSSRC)langprintf.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)langprintf.$(OBJ) $(C_) $(LIBCUPSSRC)langprintf.c -$(LIBCUPSOBJ)language.$(OBJ) : $(LIBCUPSSRC)language.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)language.$(OBJ) : $(LIBCUPSSRC)language.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)language.$(OBJ) $(C_) $(LIBCUPSSRC)language.c -$(LIBCUPSOBJ)localize.$(OBJ) : $(LIBCUPSSRC)localize.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)localize.$(OBJ) : $(LIBCUPSSRC)localize.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)localize.$(OBJ) $(C_) $(LIBCUPSSRC)localize.c -$(LIBCUPSOBJ)mark.$(OBJ) : $(LIBCUPSSRC)mark.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)mark.$(OBJ) : $(LIBCUPSSRC)mark.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)mark.$(OBJ) $(C_) $(LIBCUPSSRC)mark.c -$(LIBCUPSOBJ)cups_md5.$(OBJ) : $(LIBCUPSSRC)md5.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)cups_md5.$(OBJ) : $(LIBCUPSSRC)md5.c $(LIBCUPS_DEPS) $(CP_) $(LIBCUPSSRC)md5.c $(LIBCUPSGEN)cups_md5.c $(LCUPS_CC) $(LCUPSO_)cups_md5.$(OBJ) $(C_) $(LIBCUPSGEN)cups_md5.c -$(LIBCUPSOBJ)md5passwd.$(OBJ) : $(LIBCUPSSRC)md5passwd.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)md5passwd.$(OBJ) : $(LIBCUPSSRC)md5passwd.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)md5passwd.$(OBJ) $(C_) $(LIBCUPSSRC)md5passwd.c -$(LIBCUPSOBJ)notify.$(OBJ) : $(LIBCUPSSRC)notify.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)notify.$(OBJ) : $(LIBCUPSSRC)notify.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)notify.$(OBJ) $(C_) $(LIBCUPSSRC)notify.c -$(LIBCUPSOBJ)options.$(OBJ) : $(LIBCUPSSRC)options.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)options.$(OBJ) : $(LIBCUPSSRC)options.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)options.$(OBJ) $(C_) $(LIBCUPSSRC)options.c -$(LIBCUPSOBJ)page.$(OBJ) : $(LIBCUPSSRC)page.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)page.$(OBJ) : $(LIBCUPSSRC)page.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)page.$(OBJ) $(C_) $(LIBCUPSSRC)page.c -$(LIBCUPSOBJ)ppd.$(OBJ) : $(LIBCUPSSRC)ppd.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)ppd.$(OBJ) : $(LIBCUPSSRC)ppd.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)ppd.$(OBJ) $(C_) $(LIBCUPSSRC)ppd.c -$(LIBCUPSOBJ)pwg-file.$(OBJ) : $(LIBCUPSSRC)pwg-file.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)pwg-file.$(OBJ) : $(LIBCUPSSRC)pwg-file.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)pwg-file.$(OBJ) $(C_) $(LIBCUPSSRC)pwg-file.c -$(LIBCUPSOBJ)pwg-media.$(OBJ) : $(LIBCUPSSRC)pwg-media.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)pwg-media.$(OBJ) : $(LIBCUPSSRC)pwg-media.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)pwg-media.$(OBJ) $(C_) $(LIBCUPSSRC)pwg-media.c -$(LIBCUPSOBJ)pwg-ppd.$(OBJ) : $(LIBCUPSSRC)pwg-ppd.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)pwg-ppd.$(OBJ) : $(LIBCUPSSRC)pwg-ppd.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)pwg-ppd.$(OBJ) $(C_) $(LIBCUPSSRC)pwg-ppd.c -$(LIBCUPSOBJ)request.$(OBJ) : $(LIBCUPSSRC)request.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)request.$(OBJ) : $(LIBCUPSSRC)request.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)request.$(OBJ) $(C_) $(LIBCUPSSRC)request.c -$(LIBCUPSOBJ)sidechannel.$(OBJ) : $(LIBCUPSSRC)sidechannel.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)sidechannel.$(OBJ) : $(LIBCUPSSRC)sidechannel.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)sidechannel.$(OBJ) $(C_) $(LIBCUPSSRC)sidechannel.c -$(LIBCUPSOBJ)snmp.$(OBJ) : $(LIBCUPSSRC)snmp.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)snmp.$(OBJ) : $(LIBCUPSSRC)snmp.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)snmp.$(OBJ) $(C_) $(LIBCUPSSRC)snmp.c -$(LIBCUPSOBJ)cups_snpf.$(OBJ) : $(LIBCUPSSRC)snprintf.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)cups_snpf.$(OBJ) : $(LIBCUPSSRC)snprintf.c $(LIBCUPS_DEPS) $(CP_) $(LIBCUPSSRC)snprintf.c $(LIBCUPSGEN)cups_snpf.c $(LCUPS_CC) $(LCUPSO_)cups_snpf.$(OBJ) $(C_) $(LIBCUPSGEN)cups_snpf.c -$(LIBCUPSOBJ)string.$(OBJ) : $(LIBCUPSSRC)string.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)string.$(OBJ) : $(LIBCUPSSRC)string.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)string.$(OBJ) $(C_) $(LIBCUPSSRC)string.c -$(LIBCUPSOBJ)tempfile.$(OBJ) : $(LIBCUPSSRC)tempfile.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)tempfile.$(OBJ) : $(LIBCUPSSRC)tempfile.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)tempfile.$(OBJ) $(C_) $(LIBCUPSSRC)tempfile.c -$(LIBCUPSOBJ)transcode.$(OBJ) : $(LIBCUPSSRC)transcode.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)transcode.$(OBJ) : $(LIBCUPSSRC)transcode.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)transcode.$(OBJ) $(C_) $(LIBCUPSSRC)transcode.c -$(LIBCUPSOBJ)usersys.$(OBJ) : $(LIBCUPSSRC)usersys.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)usersys.$(OBJ) : $(LIBCUPSSRC)usersys.c $(LIBCUPS_DEPS) $(LCUPS_CC) $(LCUPSO_)usersys.$(OBJ) $(C_) $(LIBCUPSSRC)usersys.c -$(LIBCUPSOBJ)cups_util.$(OBJ) : $(LIBCUPSSRC)util.c $(LIBSCUPSHEADERS) +$(LIBCUPSOBJ)ppd-cache.$(OBJ) : $(LIBCUPSSRC)ppd-cache.c $(LIBCUPS_DEPS) + $(LCUPS_CC) $(LCUPSO_)ppd-cache.$(OBJ) $(C_) $(LIBCUPSSRC)ppd-cache.c + +$(LIBCUPSOBJ)thread.$(OBJ) : $(LIBCUPSSRC)thread.c $(LIBCUPS_DEPS) + $(LCUPS_CC) $(LCUPSO_)thread.$(OBJ) $(C_) $(LIBCUPSSRC)thread.c + +$(LIBCUPSOBJ)cups_util.$(OBJ) : $(LIBCUPSSRC)util.c $(LIBCUPS_DEPS) $(CP_) $(LIBCUPSSRC)util.c $(LIBCUPSGEN)cups_util.c $(LCUPS_CC) $(LCUPSO_)cups_util.$(OBJ) $(C_) $(LIBCUPSGEN)cups_util.c diff -Nru ghostscript-9.10~dfsg/base/ldf_jb2.mak ghostscript-9.25~dfsg+1/base/ldf_jb2.mak --- ghostscript-9.10~dfsg/base/ldf_jb2.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ldf_jb2.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for Luratech ldf_jb2 library code. @@ -29,7 +29,7 @@ # This partial makefile compiles the ldf_jb2 library for use in # Ghostscript. -LDF_JB2_MAK=$(GLSRC)ldf_jb2.mak +LDF_JB2_MAK=$(GLSRC)ldf_jb2.mak $(TOP_MAKEFILES) LDF_JB2_SRC=$(JBIG2SRCDIR)$(D) LDF_JB2_GEN=$(JBIG2OBJDIR)$(D) @@ -222,15 +222,18 @@ ldf_jb2_HDRS=$(ldf_jb2_common_HDRS) $(ldf_jb2_compress_HDRS) # switch in the selected library .dev -$(LDF_JB2_GEN)ldf_jb2.dev : $(TOP_MAKEFILES) $(LDF_JB2_MAK) $(LDF_JB2_GEN)ldf_jb2_$(SHARE_JBIG2).dev +$(LDF_JB2_GEN)ldf_jb2.dev : $(LDF_JB2_GEN)ldf_jb2_$(SHARE_JBIG2).dev \ + $(LDF_JB2_MAK) $(MAKEDIRS) $(CP_) $(LDF_JB2_GEN)ldf_jb2_$(SHARE_JBIG2).dev $(LDF_JB2_GEN)ldf_jb2.dev # external link .dev -$(LDF_JB2_GEN)ldf_jb2_1.dev : $(TOP_MAKEFILES) $(LDF_JB2_MAK) $(ECHOGS_XE) +$(LDF_JB2_GEN)ldf_jb2_1.dev : $(ECHOGS_XE) \ + $(LDF_JB2_MAK) $(MAKEDIRS) $(SETMOD) $(LDF_JB2_GEN)ldf_jb2_1 -lib ldf_jb2 # compile our own .dev -$(LDF_JB2_GEN)ldf_jb2_0.dev : $(TOP_MAKEFILES) $(LDF_JB2_MAK) $(ECHOGS_XE) $(ldf_jb2_OBJS) +$(LDF_JB2_GEN)ldf_jb2_0.dev : $(ECHOGS_XE) $(ldf_jb2_OBJS) \ + $(LDF_JB2_MAK) $(MAKEDIRS) $(SETMOD) $(LDF_JB2_GEN)ldf_jb2_0 $(ldf_jb2_common_OBJS) $(ADDMOD) $(LDF_JB2_GEN)ldf_jb2_0 $(ldf_jb2_compress_OBJS) @@ -238,256 +241,256 @@ LDF_JB2_CC=$(CC_) $(I_)$(LDF_JB2I_) $(II)$(LDF_JB2_COMMON) $(II)$(LDF_JB2_COMPRESS)$(_I) $(JB2CF_) LDF_JB2_O=$(O_)$(LDF_JB2_OBJ) -LDF_JB2_DEP=$(AK) $(LDF_JB2_MAK) +LDF_JB2_DEP=$(AK) $(LDF_JB2_MAK) $(MAKEDIRS) # explicit rules for building each source file # for simplicity we have every source file depend on all headers -$(LDF_JB2_OBJ)jb2_adt_cache.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_cache.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_cache.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_cache.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_cache.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_cache.c -$(LDF_JB2_OBJ)jb2_adt_context_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_buffer.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_context_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_buffer.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_buffer.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_buffer.c -$(LDF_JB2_OBJ)jb2_adt_context_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_decoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_context_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_decoder.c -$(LDF_JB2_OBJ)jb2_adt_context_ref_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_ref_buffer.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_context_ref_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_ref_buffer.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_ref_buffer.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_ref_buffer.c -$(LDF_JB2_OBJ)jb2_adt_context_ref_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_ref_decoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_context_ref_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_context_ref_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_ref_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_context_ref_decoder.c -$(LDF_JB2_OBJ)jb2_adt_decoder_collective_bitmap.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_collective_bitmap.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_decoder_collective_bitmap.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_collective_bitmap.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_collective_bitmap.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_collective_bitmap.c -$(LDF_JB2_OBJ)jb2_adt_decoder_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_generic_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_decoder_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_generic_region.c -$(LDF_JB2_OBJ)jb2_adt_decoder_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_halftone_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_decoder_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_halftone_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_halftone_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_halftone_region.c -$(LDF_JB2_OBJ)jb2_adt_decoder_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_pattern_dict.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_decoder_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_pattern_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_pattern_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_pattern_dict.c -$(LDF_JB2_OBJ)jb2_adt_decoder_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_symbol_dict.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_decoder_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_symbol_dict.c -$(LDF_JB2_OBJ)jb2_adt_decoder_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_text_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_decoder_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_decoder_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_decoder_text_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_decoder_text_region.c -$(LDF_JB2_OBJ)jb2_adt_external_cache.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_external_cache.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_external_cache.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_external_cache.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_external_cache.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_external_cache.c -$(LDF_JB2_OBJ)jb2_adt_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_file.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_file.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_file.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_file.c -$(LDF_JB2_OBJ)jb2_adt_file_extras.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_file_extras.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_file_extras.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_file_extras.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_file_extras.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_file_extras.c -$(LDF_JB2_OBJ)jb2_adt_handle_document.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_handle_document.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_handle_document.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_handle_document.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_handle_document.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_handle_document.c -$(LDF_JB2_OBJ)jb2_adt_huffman_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_decoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_huffman_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_decoder.c -$(LDF_JB2_OBJ)jb2_adt_huffman_table.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_huffman_table.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table.c -$(LDF_JB2_OBJ)jb2_adt_huffman_table_standard.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_standard.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_huffman_table_standard.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_standard.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table_standard.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table_standard.c -$(LDF_JB2_OBJ)jb2_adt_huffman_table_symbol.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_symbol.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_huffman_table_symbol.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_symbol.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table_symbol.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table_symbol.c -$(LDF_JB2_OBJ)jb2_adt_huffman_table_user_defined.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_user_defined.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_huffman_table_user_defined.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_table_user_defined.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_table_user_defined.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_table_user_defined.c -$(LDF_JB2_OBJ)jb2_adt_huffman_tree.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_tree.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_huffman_tree.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_huffman_tree.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_tree.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_huffman_tree.c -$(LDF_JB2_OBJ)jb2_adt_location.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_location.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_location.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_location.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_location.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_location.c -$(LDF_JB2_OBJ)jb2_adt_memory.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_memory.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_memory.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_memory.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_memory.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_memory.c -$(LDF_JB2_OBJ)jb2_adt_message.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_message.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_message.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_message.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_message.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_message.c -$(LDF_JB2_OBJ)jb2_adt_mmr_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mmr_decoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_mmr_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mmr_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mmr_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mmr_decoder.c -$(LDF_JB2_OBJ)jb2_adt_mmr_tables.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mmr_tables.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_mmr_tables.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mmr_tables.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mmr_tables.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mmr_tables.c -$(LDF_JB2_OBJ)jb2_adt_mq_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mq_decoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_mq_decoder.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mq_decoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mq_decoder.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mq_decoder.c -$(LDF_JB2_OBJ)jb2_adt_mq_state.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mq_state.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_mq_state.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_mq_state.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mq_state.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_mq_state.c -$(LDF_JB2_OBJ)jb2_adt_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pattern_dict.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pattern_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_pattern_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_pattern_dict.c -$(LDF_JB2_OBJ)jb2_adt_pdf_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pdf_file.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_pdf_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pdf_file.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_pdf_file.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_pdf_file.c -$(LDF_JB2_OBJ)jb2_adt_pdf_stream.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pdf_stream.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_pdf_stream.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_pdf_stream.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_pdf_stream.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_pdf_stream.c -$(LDF_JB2_OBJ)jb2_adt_props_decompress.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_props_decompress.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_props_decompress.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_props_decompress.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_props_decompress.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_props_decompress.c -$(LDF_JB2_OBJ)jb2_adt_read_bit_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_read_bit_buffer.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_read_bit_buffer.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_read_bit_buffer.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_read_bit_buffer.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_read_bit_buffer.c -$(LDF_JB2_OBJ)jb2_adt_read_data.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_read_data.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_read_data.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_read_data.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_read_data.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_read_data.c -$(LDF_JB2_OBJ)jb2_adt_render_common.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_common.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_render_common.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_common.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_common.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_common.c -$(LDF_JB2_OBJ)jb2_adt_render_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_generic_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_render_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_generic_region.c -$(LDF_JB2_OBJ)jb2_adt_render_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_halftone_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_render_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_halftone_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_halftone_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_halftone_region.c -$(LDF_JB2_OBJ)jb2_adt_render_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_text_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_render_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_render_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_render_text_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_render_text_region.c -$(LDF_JB2_OBJ)jb2_adt_segment.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment.c -$(LDF_JB2_OBJ)jb2_adt_segment_array.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_array.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_array.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_array.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_array.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_array.c -$(LDF_JB2_OBJ)jb2_adt_segment_end_of_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_file.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_end_of_file.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_file.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_end_of_file.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_end_of_file.c -$(LDF_JB2_OBJ)jb2_adt_segment_end_of_page.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_page.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_end_of_page.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_page.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_end_of_page.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_end_of_page.c -$(LDF_JB2_OBJ)jb2_adt_segment_end_of_stripe.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_stripe.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_end_of_stripe.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_end_of_stripe.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_end_of_stripe.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_end_of_stripe.c -$(LDF_JB2_OBJ)jb2_adt_segment_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_generic_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_generic_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_generic_region.c -$(LDF_JB2_OBJ)jb2_adt_segment_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_halftone_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_halftone_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_halftone_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_halftone_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_halftone_region.c -$(LDF_JB2_OBJ)jb2_adt_segment_page_info.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_page_info.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_page_info.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_page_info.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_page_info.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_page_info.c -$(LDF_JB2_OBJ)jb2_adt_segment_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_pattern_dict.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_pattern_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_pattern_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_pattern_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_pattern_dict.c -$(LDF_JB2_OBJ)jb2_adt_segment_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_region.c -$(LDF_JB2_OBJ)jb2_adt_segment_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_symbol_dict.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_symbol_dict.c -$(LDF_JB2_OBJ)jb2_adt_segment_table.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_table.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_table.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_table.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_table.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_table.c -$(LDF_JB2_OBJ)jb2_adt_segment_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_text_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_text_region.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_text_region.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_text_region.c -$(LDF_JB2_OBJ)jb2_adt_segment_types.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_types.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_segment_types.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_segment_types.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_segment_types.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_segment_types.c -$(LDF_JB2_OBJ)jb2_adt_symbol.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_symbol.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_symbol.c -$(LDF_JB2_OBJ)jb2_adt_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol_dict.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_symbol_dict.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_symbol_dict.c -$(LDF_JB2_OBJ)jb2_adt_symbol_instance.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol_instance.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_symbol_instance.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_symbol_instance.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol_instance.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_symbol_instance.c -$(LDF_JB2_OBJ)jb2_adt_write_bits.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_bits.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_write_bits.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_bits.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_write_bits.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_write_bits.c -$(LDF_JB2_OBJ)jb2_adt_write_data.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_data.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_write_data.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_data.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_write_data.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_write_data.c -$(LDF_JB2_OBJ)jb2_adt_write_pdf.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_pdf.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_write_pdf.$(OBJ) : $(LDF_JB2_COMMON)jb2_adt_write_pdf.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_write_pdf.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_adt_write_pdf.c -$(LDF_JB2_OBJ)jb2_common.$(OBJ) : $(LDF_JB2_COMMON)jb2_common.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_common.$(OBJ) : $(LDF_JB2_COMMON)jb2_common.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_common.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_common.c -$(LDF_JB2_OBJ)jb2_license_dummy.$(OBJ) : $(LDF_JB2_COMMON)jb2_license_dummy.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_license_dummy.$(OBJ) : $(LDF_JB2_COMMON)jb2_license_dummy.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_license_dummy.$(OBJ) $(C_) $(LDF_JB2_COMMON)jb2_license_dummy.c -$(LDF_JB2_OBJ)jb2_adt_component.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_component.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component.c -$(LDF_JB2_OBJ)jb2_adt_component_class.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_class.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_component_class.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_class.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component_class.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component_class.c -$(LDF_JB2_OBJ)jb2_adt_component_group.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_group.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_component_group.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_group.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component_group.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component_group.c -$(LDF_JB2_OBJ)jb2_adt_component_match.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_match.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_component_match.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_component_match.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_component_match.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_component_match.c -$(LDF_JB2_OBJ)jb2_adt_context_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_context_encoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_context_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_context_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_context_encoder.c -$(LDF_JB2_OBJ)jb2_adt_context_ref_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_context_ref_encoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_context_ref_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_context_ref_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_context_ref_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_context_ref_encoder.c -$(LDF_JB2_OBJ)jb2_adt_encoder_generic_region.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_generic_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_encoder_generic_region.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_generic_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_encoder_generic_region.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_encoder_generic_region.c -$(LDF_JB2_OBJ)jb2_adt_encoder_symbol_dict.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_symbol_dict.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_encoder_symbol_dict.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_symbol_dict.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_encoder_symbol_dict.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_encoder_symbol_dict.c -$(LDF_JB2_OBJ)jb2_adt_encoder_text_region.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_text_region.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_encoder_text_region.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_encoder_text_region.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_encoder_text_region.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_encoder_text_region.c -$(LDF_JB2_OBJ)jb2_adt_handle_compress.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_handle_compress.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_handle_compress.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_handle_compress.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_handle_compress.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_handle_compress.c -$(LDF_JB2_OBJ)jb2_adt_huffman_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_huffman_encoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_huffman_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_huffman_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_huffman_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_huffman_encoder.c -$(LDF_JB2_OBJ)jb2_adt_mmr_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_mmr_encoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_mmr_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_mmr_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mmr_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_mmr_encoder.c -$(LDF_JB2_OBJ)jb2_adt_mq_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_mq_encoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_mq_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_mq_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_mq_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_mq_encoder.c -$(LDF_JB2_OBJ)jb2_adt_props_compress.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_props_compress.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_props_compress.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_props_compress.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_props_compress.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_props_compress.c -$(LDF_JB2_OBJ)jb2_adt_run_array.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_run_array.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_run_array.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_run_array.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_run_array.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_run_array.c -$(LDF_JB2_OBJ)jb2_adt_stack.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stack.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_stack.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stack.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stack.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stack.c -$(LDF_JB2_OBJ)jb2_adt_stripe_clean_up.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_clean_up.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_stripe_clean_up.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_clean_up.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_clean_up.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_clean_up.c -$(LDF_JB2_OBJ)jb2_adt_stripe_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_encoder.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_stripe_encoder.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_encoder.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_encoder.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_encoder.c -$(LDF_JB2_OBJ)jb2_adt_stripe_half_tone.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_half_tone.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_stripe_half_tone.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_half_tone.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_half_tone.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_half_tone.c -$(LDF_JB2_OBJ)jb2_adt_stripe_preprocessing.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_preprocessing.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_stripe_preprocessing.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_preprocessing.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_preprocessing.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_preprocessing.c -$(LDF_JB2_OBJ)jb2_adt_stripe_text.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_text.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_stripe_text.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_stripe_text.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_stripe_text.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_stripe_text.c -$(LDF_JB2_OBJ)jb2_adt_symbol_unify.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_symbol_unify.c $(LDF_JB2_DEP) $(ldf_jb2_HDRS) +$(LDF_JB2_OBJ)jb2_adt_symbol_unify.$(OBJ) : $(LDF_JB2_COMPRESS)jb2_adt_symbol_unify.c $(ldf_jb2_HDRS) $(LDF_JB2_DEP) $(LDF_JB2_CC) $(LDF_JB2_O)jb2_adt_symbol_unify.$(OBJ) $(C_) $(LDF_JB2_COMPRESS)jb2_adt_symbol_unify.c diff -Nru ghostscript-9.10~dfsg/base/lib.mak ghostscript-9.25~dfsg+1/base/lib.mak --- ghostscript-9.10~dfsg/base/lib.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/lib.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # (Platform-independent) makefile for Ghostscript graphics library # and other support code. @@ -18,6 +18,19 @@ # GLSRCDIR - the source directory # GLGENDIR - the directory for source files generated during building # GLOBJDIR - the object code directory +# DEVSRCDIR - source directory for the device drivers +# AUXDIR - the directory to build the "aux" (host executable) files +# JSRCDIR - JPEG library source directory +# JGENDIR - JPEG library object code directory +# ZSRCDIR - zlib source directory +# ZGENDIR - zlib object code directory +# LCMSGENDIR - Little CMS object code directory +# One of: +# LCMS2MTSRCDIR - Artifex (Thread Safe) Little CMS 2 source directory +# LCMS2SRCDIR - Little CMS verion 2 source directory +# +# For dependencies: +# MAKEDIRS GLSRC=$(GLSRCDIR)$(D) GLGEN=$(GLGENDIR)$(D) @@ -27,7 +40,8 @@ AUXO_=$(O_)$(AUX) GLI_=$(GLGENDIR) $(II)$(GLSRCDIR) $(II)$(DEVSRCDIR) GLF_= -GLCCFLAGS=$(I_)$(GLI_)$(_I) $(GLF_) $(D_)WHICH_CMS="$(WHICH_CMS)"$(_D) +GLINCLUDES=$(I_)$(GLI_)$(_I) +GLCCFLAGS=$(GLINCLUDES) $(GLF_) $(D_)WHICH_CMS="$(WHICH_CMS)"$(_D) GLCC=$(CC_) $(GLCCFLAGS) GLCCAUX=$(CCAUX_) $(GLCCFLAGS) GLJCC=$(CC_) $(I_)$(GLI_) $(II)$(JI_)$(_I) $(JCF_) $(GLF_) @@ -38,20 +52,20 @@ GLLWFJPXCC=$(CC_) $(I_)$(LWF_JPXI_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_) GLJPXOPJCC=$(CC_) $(I_)$(JPX_OPENJPEG_I_)$(D).. $(I_)$(JPX_OPENJPEG_I_) $(II)$(GLI_)$(_I) $(JPXCF_) $(GLF_) GLCCSHARED=$(CC_SHARED) $(GLCCFLAGS) -# We can't use $(CC_) for GLLCMSCC becuase that includes /Za on +# We can't use $(CC_) for GLLCMS2MTCC because that includes /Za on # msvc builds, and lcms configures itself to depend on msvc extensions # (inline asm, including windows.h) when compiled under msvc. -GLLCMSCC=$(CC) $(CFLAGS) $(I_)$(GLI_) $(II)$(LCMSSRCDIR)$(D)include$(_I) $(GLF_) -lcms_h=$(LCMSSRCDIR)$(D)include$(D)lcms.h +GLLCMS2MTCC=$(CC) $(LCMS2MT_CFLAGS) $(CFLAGS) $(I_)$(GLI_) $(II)$(LCMS2MTSRCDIR)$(D)include$(_I) $(GLF_) +lcms2mt_h=$(LCMS2MTSRCDIR)$(D)include$(D)lcms2mt.h +lcms2mt_plugin_h=$(LCMS2MTSRCDIR)$(D)include$(D)lcms2mt_plugin.h icc34_h=$(GLSRC)icc34.h -# We can't use $(CC_) for GLLCMS2CC becuase that includes /Za on +# We can't use $(CC_) for GLLCMS2CC because that includes /Za on # msvc builds, and lcms configures itself to depend on msvc extensions # (inline asm, including windows.h) when compiled under msvc. -GLLCMS2CC=$(CC) $(CFLAGS) $(I_)$(GLI_) $(II)$(LCMS2SRCDIR)$(D)include$(_I) $(GLF_) +GLLCMS2CC=$(CC) $(LCMS2_CFLAGS) $(CFLAGS) $(I_)$(GLI_) $(II)$(LCMS2SRCDIR)$(D)include$(_I) $(GLF_) lcms2_h=$(LCMS2SRCDIR)$(D)include$(D)lcms2.h lcms2_plugin_h=$(LCMS2SRCDIR)$(D)include$(D)lcms2_plugin.h -ConvertUTF_h=$(GLSRC)ConvertUTF.h gdevdcrd_h=$(GLSRC)gdevdcrd.h gdevpccm_h=$(GLSRC)gdevpccm.h @@ -61,7 +75,7 @@ # All top-level makefiles define GLD. #GLD=$(GLGEN) # Define the name of this makefile. -LIB_MAK=$(GLSRC)lib.mak +LIB_MAK=$(GLSRC)lib.mak $(TOP_MAKEFILES) # Define the inter-dependencies of the .h files. # Since not all versions of `make' defer expansion of macros, @@ -70,8 +84,7 @@ # Generic files arch_h=$(GLGEN)arch.h -stdpn_h=$(GLSRC)stdpn.h -stdpre_h=$(GLSRC)stdpre.h $(stdpn_h) +stdpre_h=$(GLSRC)stdpre.h stdint__h=$(GLSRC)stdint_.h $(std_h) $(GLGEN)arch.h : $(GENARCH_XE) @@ -107,6 +120,8 @@ # declare here for use by string__h gssprintf_h=$(GLSRC)gssprintf.h +gsstrtok_h=$(GLSRC)gsstrtok.h +gsstrl_h=$(GLSRC)gsstrl.h dos__h=$(GLSRC)dos_.h ctype__h=$(GLSRC)ctype_.h $(std_h) @@ -115,16 +130,18 @@ fcntl__h=$(GLSRC)fcntl_.h $(std_h) locale__h=$(GLSRC)locale_.h $(std_h) $(MAKEFILE) memento_h=$(GLSRC)memento.h $(std_h) -malloc__h=$(GLSRC)malloc_.h $(std_h) $(memento_h) +bobbin_h=$(GLSRC)bobbin.h $(std_h) +malloc__h=$(GLSRC)malloc_.h $(std_h) $(memento_h) $(bobbin_h) math__h=$(GLSRC)math_.h $(std_h) $(vmsmath_h) memory__h=$(GLSRC)memory_.h $(std_h) setjmp__h=$(GLSRC)setjmp_.h stat__h=$(GLSRC)stat_.h $(std_h) stdio__h=$(GLSRC)stdio_.h $(std_h) $(gssprintf_h) -string__h=$(GLSRC)string_.h $(std_h) +string__h=$(GLSRC)string_.h $(std_h) $(gsstrtok_h) time__h=$(GLSRC)time_.h $(std_h) $(gconfig__h) unistd__h=$(GLSRC)unistd_.h $(std_h) windows__h=$(GLSRC)windows_.h +assert__h=$(GLSRC)assert_.h # Out of order pipe__h=$(GLSRC)pipe_.h $(stdio__h) @@ -154,7 +171,7 @@ gsmemory_h=$(GLSRC)gsmemory.h $(gstypes_h) $(gslibctx_h) gsmemret_h=$(GLSRC)gsmemret.h $(gsmemory_h) gsnogc_h=$(GLSRC)gsnogc.h $(gsgc_h) -gsrefct_h=$(GLSRC)gsrefct.h +gsrefct_h=$(GLSRC)gsrefct.h $(memento_h) gsserial_h=$(GLSRC)gsserial.h gsstype_h=$(GLSRC)gsstype.h gx_h=$(GLSRC)gx.h $(stdio__h) $(gdebug_h)\ @@ -163,10 +180,8 @@ gxclthrd_h=$(GLSRC)gxclthrd.h $(gxsync_h) # Out of order -gsmemlok_h=$(GLSRC)gsmemlok.h $(gsmemory_h) $(gxsync_h) gsnotify_h=$(GLSRC)gsnotify.h $(gsstype_h) gsstruct_h=$(GLSRC)gsstruct.h $(gsstype_h) -vdtrace_h=$(GLSRC)vdtrace.h ###### Support @@ -188,78 +203,99 @@ gsrect_h=$(GLSRC)gsrect.h $(gxfixed_h) gxalloc_h=$(GLSRC)gxalloc.h $(gsalloc_h) $(gxobj_h) gxbitops_h=$(GLSRC)gxbitops.h $(gsbitops_h) -gxcindex_h=$(GLSRC)gxcindex.h $(gsbitops_h) +gxcindex_h=$(GLSRC)gxcindex.h $(gsbitops_h) $(stdint__h) gxfont42_h=$(GLSRC)gxfont42.h gstrans_h=$(GLSRC)gstrans.h $(gstparam_h) $(gxcomp_h) $(gsmatrix_h) $(gxblend_h) # Streams scommon_h=$(GLSRC)scommon.h $(gsmemory_h) $(gstypes_h) $(gsstype_h) $(stdint__h) stream_h=$(GLSRC)stream.h $(scommon_h) $(srdline_h) $(gxiodev_h) +ramfs_h=$(GLSRC)ramfs.h $(stream_h) ### Memory manager $(GLOBJ)gsalloc.$(OBJ) : $(GLSRC)gsalloc.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gsexit_h) $(gsmdebug_h) $(gsstruct_h) $(gxalloc_h)\ - $(stream_h) $(malloc__h) $(MAKEDIRS) + $(stream_h) $(malloc__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsalloc.$(OBJ) $(C_) $(GLSRC)gsalloc.c $(GLOBJ)gsmalloc.$(OBJ) : $(GLSRC)gsmalloc.c $(malloc__h)\ $(gdebug_h)\ $(gserrors_h)\ $(gsmalloc_h) $(gsmdebug_h) $(gsmemret_h)\ - $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(MAKEDIRS) + $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsmalloc.$(OBJ) $(C_) $(GLSRC)gsmalloc.c +# Memento uses windows.h on windows. This requires that /Za not be +# used (as this disables Microsoft extensions, which breaks windows.h). +# GLCC has the /Za pickled into it on windows, so we can't use GLCC. +# Therefore use our own compiler invocation. +MEMENTO_CC=$(CC) $(GENOPT) $(GLINCLUDES) $(CFLAGS) + # We have an extra dependency here on malloc__h. This is deliberate to allow # windows users to set #define MEMENTO in the top of malloc_h and have # rebuilds work. $(GLOBJ)memento.$(OBJ) : $(GLSRC)memento.c $(valgrind_h) $(memento_h)\ - $(malloc__h) $(MAKEDIRS) - $(GLCC) $(GLO_)memento.$(OBJ) $(C_) $(GLSRC)memento.c + $(malloc__h) $(LIB_MAK) $(MAKEDIRS) + $(MEMENTO_CC) $(GLO_)memento.$(OBJ) $(C_) $(GLSRC)memento.c $(AUX)memento.$(OBJ) : $(GLSRC)memento.c $(valgrind_h) $(memento_h)\ - $(malloc__h) $(MAKEDIRS) + $(malloc__h) $(LIB_MAK) $(MAKEDIRS) $(GLCCAUX) $(AUXO_)memento.$(OBJ) $(C_) $(GLSRC)memento.c +# Bobbin uses windows.h on windows. This requires that /Za not be +# used (as this disables Microsoft extensions, which breaks windows.h). +# GLCC has the /Za pickled into it on windows, so we can't use GLCC. +# Therefore use our own compiler invocation. +BOBBIN_CC=$(CC) $(GENOPT) $(GLINCLUDES) $(CFLAGS) + +$(GLOBJ)bobbin.$(OBJ) : $(GLSRC)bobbin.c $(bobbin_h)\ + $(LIB_MAK) $(MAKEDIRS) + $(BOBBIN_CC) $(GLO_)bobbin.$(OBJ) $(C_) $(GLSRC)bobbin.c + +$(AUX)bobbin.$(OBJ) : $(GLSRC)bobbin.c $(valgrind_h) $(bobbin_h)\ + $(LIB_MAK) $(MAKEDIRS) + $(GLCCAUX) $(AUXO_)bobbin.$(OBJ) $(C_) $(GLSRC)bobbin.c + $(GLOBJ)gsmemory.$(OBJ) : $(GLSRC)gsmemory.c $(memory__h)\ $(gdebug_h)\ - $(gsmdebug_h) $(gsmemory_h) $(gsrefct_h) $(gsstruct_h) $(gstypes_h) $(MAKEDIRS) + $(gsmdebug_h) $(gsmemory_h) $(gsrefct_h) $(gsstruct_h) $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsmemory.$(OBJ) $(C_) $(GLSRC)gsmemory.c $(GLOBJ)gsmemret.$(OBJ) : $(GLSRC)gsmemret.c $(AK) $(gx_h)\ - $(gserrors_h) $(gsmemret_h) $(MAKEDIRS) + $(gserrors_h) $(gsmemret_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsmemret.$(OBJ) $(C_) $(GLSRC)gsmemret.c # gsnogc is not part of the base configuration. # We make it available as a .dev so it can be used in configurations that # don't include the garbage collector, as well as by the "async" logic. gsnogc_=$(GLOBJ)gsnogc.$(OBJ) -$(GLD)gsnogc.dev : $(LIB_MAK) $(ECHOGS_XE) $(gsnogc_) +$(GLD)gsnogc.dev : $(ECHOGS_XE) $(gsnogc_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)gsnogc $(gsnogc_) $(GLOBJ)gsnogc.$(OBJ) : $(GLSRC)gsnogc.c $(AK) $(gx_h)\ - $(gsmdebug_h) $(gsnogc_h) $(gsstruct_h) $(gxalloc_h) $(MAKEDIRS) + $(gsmdebug_h) $(gsnogc_h) $(gsstruct_h) $(gxalloc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsnogc.$(OBJ) $(C_) $(GLSRC)gsnogc.c ### Bitmap processing $(GLOBJ)gsbitcom.$(OBJ) : $(GLSRC)gsbitcom.c $(AK) $(std_h)\ - $(gdebug_h) $(gsbitops_h) $(gstypes_h) $(MAKEDIRS) + $(gdebug_h) $(gsbitops_h) $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsbitcom.$(OBJ) $(C_) $(GLSRC)gsbitcom.c $(GLOBJ)gsbitops.$(OBJ) : $(GLSRC)gsbitops.c $(AK) $(memory__h)\ $(stdio__h) $(gdebug_h) $(gsbittab_h) $(gserrors_h) $(gstypes_h)\ - $(gxbitops_h) $(gxcindex_h) $(MAKEDIRS) + $(gxbitops_h) $(gxcindex_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsbitops.$(OBJ) $(C_) $(GLSRC)gsbitops.c $(GLOBJ)gsbittab.$(OBJ) : $(GLSRC)gsbittab.c $(AK) $(stdpre_h)\ - $(gsbittab_h) $(MAKEDIRS) + $(gsbittab_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsbittab.$(OBJ) $(C_) $(GLSRC)gsbittab.c # gsflip is not part of the standard configuration: it's rather large, # and no standard facility requires it. $(GLOBJ)gsflip.$(OBJ) : $(GLSRC)gsflip.c $(AK) $(gx_h) $(gserrors_h)\ - $(gsbitops_h) $(gsbittab_h) $(gsflip_h) $(MAKEDIRS) + $(gsbitops_h) $(gsbittab_h) $(gsflip_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsflip.$(OBJ) $(C_) $(GLSRC)gsflip.c ### Multi-threading @@ -268,7 +304,7 @@ # needs them even if the underlying primitives are dummies. $(GLOBJ)gxsync.$(OBJ) : $(GLSRC)gxsync.c $(AK) $(gx_h) $(gserrors_h)\ - $(memory__h) $(gsmemory_h) $(gxsync_h) $(MAKEDIRS) + $(memory__h) $(gsmemory_h) $(gxsync_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxsync.$(OBJ) $(C_) $(GLSRC)gxsync.c ### Miscellaneous @@ -276,37 +312,38 @@ # Support for platform code $(GLOBJ)gpmisc.$(OBJ) : $(GLSRC)gpmisc.c\ $(unistd__h) $(fcntl__h) $(stat__h) $(stdio__h)\ - $(memory__h) $(string__h) $(gp_h) $(gpgetenv_h) $(gpmisc_h) $(MAKEDIRS) + $(memory__h) $(string__h) $(gp_h) $(gpgetenv_h) $(gpmisc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gpmisc.$(OBJ) $(C_) $(GLSRC)gpmisc.c $(AUX)gpmisc.$(OBJ) : $(GLSRC)gpmisc.c\ $(unistd__h) $(fcntl__h) $(stat__h) $(stdio__h)\ - $(memory__h) $(string__h) $(gp_h) $(gpgetenv_h) $(gpmisc_h) $(MAKEDIRS) + $(memory__h) $(string__h) $(gp_h) $(gpgetenv_h) $(gpmisc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCCAUX) $(AUXO_)gpmisc.$(OBJ) $(C_) $(GLSRC)gpmisc.c # Command line argument list management $(GLOBJ)gsargs.$(OBJ) : $(GLSRC)gsargs.c\ $(ctype__h) $(stdio__h) $(string__h)\ $(gsargs_h) $(gsexit_h) $(gsmemory_h)\ - $(gserrors_h) $(MAKEDIRS) + $(gserrors_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsargs.$(OBJ) $(C_) $(GLSRC)gsargs.c $(GLOBJ)gsmisc.$(OBJ) : $(GLSRC)gsmisc.c $(AK) $(gx_h) $(gserrors_h)\ $(vmsmath_h) $(std_h)\ $(ctype__h) $(malloc__h) $(math__h) $(memory__h) $(string__h)\ $(gpcheck_h) $(gxfarith_h) $(gxfixed_h) $(stdint__h) $(stdio__h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsmisc.$(OBJ) $(C_) $(GLSRC)gsmisc.c $(AUX)gsmisc.$(OBJ) : $(GLSRC)gsmisc.c $(AK) $(gx_h) $(gserrors_h)\ $(vmsmath_h) $(std_h)\ $(ctype__h) $(malloc__h) $(math__h) $(memory__h) $(string__h)\ $(gpcheck_h) $(gxfarith_h) $(gxfixed_h) $(stdint__h) $(stdio__h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCCAUX) $(C_) $(AUXO_)gsmisc.$(OBJ) $(GLSRC)gsmisc.c $(GLOBJ)gslibctx.$(OBJ) : $(GLSRC)gslibctx.c $(AK) $(gp_h) $(gsmemory_h)\ - $(gslibctx_h) $(stdio__h) $(string__h) $(gsicc_manage_h) + $(gslibctx_h) $(stdio__h) $(string__h) $(gsicc_manage_h) $(gserrors_h) \ + $(gscdefs_h) $(GLCC) $(GLO_)gslibctx.$(OBJ) $(C_) $(GLSRC)gslibctx.c $(AUX)gslibctx.$(OBJ) : $(GLSRC)gslibctx.c $(AK) $(gp_h) $(gsmemory_h)\ @@ -314,57 +351,58 @@ $(GLCCAUX) $(C_) $(AUXO_)gslibctx.$(OBJ) $(GLSRC)gslibctx.c $(GLOBJ)gsnotify.$(OBJ) : $(GLSRC)gsnotify.c $(AK) $(gx_h)\ - $(gserrors_h) $(gsnotify_h) $(gsstruct_h) $(MAKEDIRS) + $(gserrors_h) $(gsnotify_h) $(gsstruct_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsnotify.$(OBJ) $(C_) $(GLSRC)gsnotify.c $(GLOBJ)gsserial.$(OBJ) : $(GLSRC)gsserial.c $(stdpre_h) $(gstypes_h)\ - $(gsserial_h) $(MAKEDIRS) + $(gsserial_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsserial.$(OBJ) $(C_) $(GLSRC)gsserial.c $(GLOBJ)gsutil.$(OBJ) : $(GLSRC)gsutil.c $(AK) $(memory__h)\ $(string__h) $(gstypes_h) $(gserrors_h) $(gsmemory_h)\ - $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gzstate_h) $(gxdcolor_h) $(MAKEDIRS) + $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gzstate_h) $(gxdcolor_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsutil.$(OBJ) $(C_) $(GLSRC)gsutil.c $(AUX)gsutil.$(OBJ) : $(GLSRC)gsutil.c $(AK) $(memory__h) $(string__h)\ $(gstypes_h) $(gserrors_h) $(gsmemory_h)\ - $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gzstate_h) $(gxdcolor_h) $(MAKEDIRS) + $(gsrect_h) $(gsuid_h) $(gsutil_h) $(gzstate_h) $(gxdcolor_h) $(LIB_MAK) $(MAKEDIRS) $(GLCCAUX) $(C_) $(AUXO_)gsutil.$(OBJ) $(GLSRC)gsutil.c -$(GLOBJ)gssprintf.$(OBJ) : $(GLSRC)gssprintf.c $(gssprintf_h) $(triodef_h) $(trio_h) \ -$(triop_h) $(triostr_h) $(trionan_h) - $(GLCC) $(I_)$(TRIOSRCDIR)$(_I) $(GLO_)gssprintf.$(OBJ) $(C_) $(GLSRC)gssprintf.c +$(GLOBJ)gssprintf.$(OBJ) : $(GLSRC)gssprintf.c $(gssprintf_h) $(stdio__h) \ + $(stdint__h) $(string__h) $(math__h) + $(GLCC) $(GLO_)gssprintf.$(OBJ) $(C_) $(GLSRC)gssprintf.c + +$(GLOBJ)gsstrtok.$(OBJ) : $(GLSRC)gsstrtok.c $(gsstrtok_h) $(string__h) + $(GLCC) $(GLO_)gsstrtok.$(OBJ) $(C_) $(GLSRC)gsstrtok.c + +$(GLOBJ)gsstrl.$(OBJ) : $(GLSRC)gsstrl.c $(gsstrl_h) $(string__h) + $(GLCC) $(GLO_)gsstrl.$(OBJ) $(C_) $(GLSRC)gsstrl.c # MD5 digest -md5_h=$(GLSRC)md5.h +gsmd5_h=$(GLSRC)gsmd5.h # We have to use a slightly different compilation approach in order to # get std.h included when compiling md5.c. -md5_=$(GLOBJ)md5.$(OBJ) -$(GLOBJ)md5.$(OBJ) : $(GLSRC)md5.c $(AK) $(md5_h) $(std_h) $(MAKEDIRS) $(EXP)$(ECHOGS_XE) - $(EXP)$(ECHOGS_XE) -w $(GLGEN)md5.h -x 23 include -x 2022 memory_.h -x 22 - $(EXP)$(ECHOGS_XE) -a $(GLGEN)md5.h -+R $(GLSRC)md5.h - $(CP_) $(GLSRC)md5.c $(GLGEN)md5.c - $(GLCC) $(GLO_)md5.$(OBJ) $(C_) $(GLGEN)md5.c - $(RM_) $(GLGEN)md5.c $(GLGEN)md5.h +md5_=$(GLOBJ)gsmd5.$(OBJ) +$(GLOBJ)gsmd5.$(OBJ) : $(GLSRC)gsmd5.c $(AK) $(gsmd5_h) $(std_h) $(EXP)$(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(ECHOGS_XE) -w $(GLGEN)gsmd5.h -x 23 include -x 2022 memory_.h -x 22 + $(EXP)$(ECHOGS_XE) -a $(GLGEN)gsmd5.h -+R $(GLSRC)gsmd5.h + $(CP_) $(GLSRC)gsmd5.c $(GLGEN)gsmd5.c + $(GLCC) $(GLO_)gsmd5.$(OBJ) $(C_) $(GLGEN)gsmd5.c + $(RM_) $(GLGEN)gsmd5.c $(GLGEN)gsmd5.h # SHA-256 digest sha2_h=$(GLSRC)sha2.h $(std_h) $(stdint__h) sha2_=$(GLOBJ)sha2.$(OBJ) $(GLOBJ)sha2.$(OBJ) : $(GLSRC)sha2.c $(AK) $(std_h) $(string__h)\ - $(sha2_h) $(MAKEDIRS) + $(sha2_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sha2.$(OBJ) $(C_) $(GLSRC)sha2.c # AES cipher aes_h=$(GLSRC)aes.h aes_=$(GLOBJ)aes.$(OBJ) -$(GLOBJ)aes.$(OBJ) : $(GLSRC)aes.c $(AK) $(string__h) $(aes_h) $(MAKEDIRS) +$(GLOBJ)aes.$(OBJ) : $(GLSRC)aes.c $(AK) $(string__h) $(aes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)aes.$(OBJ) $(C_) $(GLSRC)aes.c -# Visual Debugging -$(GLOBJ)vdtrace.$(OBJ) : $(GLSRC)vdtrace.c $(math__h)\ - $(gxfixed_h) $(vdtrace_h) $(MAKEDIRS) - $(GLCC) $(GLO_)vdtrace.$(OBJ) $(C_) $(GLSRC)vdtrace.c - ###### Low-level facilities and utilities ### Include files @@ -383,7 +421,6 @@ gscpm_h=$(GLSRC)gscpm.h gscsepnm_h=$(GLSRC)gscsepnm.h gsdevice_h=$(GLSRC)gsdevice.h -gsdfilt_h=$(GLSRC)gsdfilt.h gsfcmap_h=$(GLSRC)gsfcmap.h $(gsccode_h) gsfname_h=$(GLSRC)gsfname.h gsfont_h=$(GLSRC)gsfont.h @@ -413,7 +450,7 @@ gsxfont_h=$(GLSRC)gsxfont.h # Out of order gschar_h=$(GLSRC)gschar.h $(gsccode_h) $(gscpm_h) -gsiparam_h=$(GLSRC)gsiparam.h $(gsccolor_h) $(gsmatrix_h) $(gsstype_h) +gsiparam_h=$(GLSRC)gsiparam.h $(gsccolor_h) $(gsmatrix_h) $(gsstype_h) $(gxbitmap_h) gsimage_h=$(GLSRC)gsimage.h $(gsiparam_h) gsline_h=$(GLSRC)gsline.h $(gslparam_h) gspath_h=$(GLSRC)gspath.h $(gspenum_h) @@ -440,7 +477,7 @@ gxhttile_h=$(GLSRC)gxhttile.h gxhttype_h=$(GLSRC)gxhttype.h gxiclass_h=$(GLSRC)gxiclass.h -gxiodev_h=$(GLSRC)gxiodev.h $(stat__h) +gxiodev_h=$(GLSRC)gxiodev.h $(gsstruct_h) $(stat__h) gxline_h=$(GLSRC)gxline.h $(gslparam_h) $(gsmatrix_h) $(math__h) gxlum_h=$(GLSRC)gxlum.h gxmatrix_h=$(GLSRC)gxmatrix.h $(gsmatrix_h) @@ -452,8 +489,9 @@ gxpcache_h=$(GLSRC)gxpcache.h gxsample_h=$(GLSRC)gxsample.h gxsamplp_h=$(GLSRC)gxsamplp.h +gxscanc_h=$(GLSRC)gxscanc.h gxstate_h=$(GLSRC)gxstate.h $(gscspace_h) -gxtext_h=$(GLSRC)gxtext.h $(gsrefct_h) $(gstext_h) +gxtext_h=$(GLSRC)gxtext.h $(gsrefct_h) $(gstext_h) $(gxfixed_h) gxtmap_h=$(GLSRC)gxtmap.h gxxfont_h=$(GLSRC)gxxfont.h $(gsccode_h) $(gsmatrix_h) $(gsuid_h) $(gsxfont_h) # The following are out of order because they include other files. @@ -461,7 +499,7 @@ gxcdevn_h=$(GLSRC)gxcdevn.h $(gsrefct_h) $(gxcindex_h) gxchar_h=$(GLSRC)gxchar.h $(gschar_h) $(gxtext_h) gxchrout_h=$(GLSRC)gxchrout.h -gsdcolor_h=$(GLSRC)gsdcolor.h $(gsccolor_h)\ +gsdcolor_h=$(GLSRC)gsdcolor.h $(gsccolor_h) $(gscms_h)\ $(gxarith_h) $(gxbitmap_h) $(gxcindex_h) $(gxhttile_h) gxdcolor_h=$(GLSRC)gxdcolor.h\ $(gscsel_h) $(gsdcolor_h) $(gsropt_h) $(gsstruct_h) $(stdint__h) @@ -509,15 +547,17 @@ gxfmap_h=$(GLSRC)gxfmap.h $(gsrefct_h) $(gsstype_h) $(gxfrac_h) $(gxtmap_h) gxcmap_h=$(GLSRC)gxcmap.h $(gscsel_h) $(gxcindex_h) $(gxcvalue_h) $(gxfmap_h)\ $(gscspace_h) -gxistate_h=$(GLSRC)gxistate.h\ + +gxgstate_h=$(GLSRC)gxgstate.h\ $(gscsel_h) $(gsrefct_h) $(gsropt_h) $(gstparam_h) $(gxcvalue_h) $(gxcmap_h)\ $(gxfixed_h) $(gxline_h) $(gxmatrix_h) $(gxtmap_h) $(gscspace_h) $(gstrans_h)\ $(gsnamecl_h) $(gscms_h) -gxclist_h=$(GLSRC)gxclist.h $(gscspace_h)\ - $(gxband_h) $(gxbcache_h) $(gxclio_h) $(gxdevbuf_h) $(gxistate_h)\ - $(gxrplane_h) $(gscms_h) + gxcolor2_h=$(GLSRC)gxcolor2.h\ $(gscolor2_h) $(gsmatrix_h) $(gsrefct_h) $(gxbitmap_h) +gxclist_h=$(GLSRC)gxclist.h $(gscspace_h)\ + $(gxband_h) $(gxbcache_h) $(gxclio_h) $(gxdevbuf_h) $(gxgstate_h)\ + $(gxrplane_h) $(gscms_h) $(gxcolor2_h) gxcspace_h=$(GLSRC)gxcspace.h\ $(gscspace_h) $(gsccolor_h) $(gscsel_h) $(gxfrac_h) $(gxcindex_h) gxht_h=$(GLSRC)gxht.h $(gsht1_h) $(gsrefct_h) $(gxhttype_h) $(gxtmap_h) $(gscspace_h) @@ -529,8 +569,8 @@ gscolor_h=$(GLSRC)gscolor.h $(gxtmap_h) gsstate_h=$(GLSRC)gsstate.h\ $(gscolor_h) $(gscpm_h) $(gscsel_h) $(gsdevice_h) $(gsht_h) $(gsline_h) -gscolorbuffer_h=$(GLSRC)gscolorbuffer.h gsicc_create_h=$(GLSRC)gsicc_create.h $(gscie_h) +gximdecode_h=$(GLSRC)gximdecode.h $(gx_h) $(gxfixed_h) $(gximage_h) $(gxsample_h) $(gxfrac_h) gzacpath_h=$(GLSRC)gzacpath.h $(gxcpath_h) gzcpath_h=$(GLSRC)gzcpath.h $(gxcpath_h) $(gzpath_h) @@ -539,7 +579,7 @@ gzline_h=$(GLSRC)gzline.h $(gxline_h) gzpath_h=$(GLSRC)gzpath.h $(gsmatrix_h) $(gsrefct_h) $(gsstype_h) $(gxpath_h) gzstate_h=$(GLSRC)gzstate.h $(gscpm_h) $(gscspace_h) $(gsrefct_h) $(gsstate_h)\ - $(gxdcolor_h) $(gxistate_h) $(gxstate_h) + $(gxdcolor_h) $(gxgstate_h) $(gxstate_h) gdevbbox_h=$(GLSRC)gdevbbox.h gdevmem_h=$(GLSRC)gdevmem.h $(gxbitops_h) @@ -547,6 +587,7 @@ gdevmrop_h=$(GLSRC)gdevmrop.h gdevmrun_h=$(GLSRC)gdevmrun.h $(gxdevmem_h) gdevplnx_h=$(GLSRC)gdevplnx.h $(gxrplane_h) +gdevepo_h=$(GLSRC)gdevepo.h $(gxdevice_h) sa85d_h=$(GLSRC)sa85d.h sa85x_h=$(GLSRC)sa85x.h $(sa85d_h) @@ -556,10 +597,10 @@ sfilter_h=$(GLSRC)sfilter.h $(gstypes_h) sdct_h=$(GLSRC)sdct.h $(setjmp__h) $(gscms_h) shc_h=$(GLSRC)shc.h $(gsbittab_h) $(scommon_h) -sisparam_h=$(GLSRC)sisparam.h +sisparam_h=$(GLSRC)sisparam.h $(gxdda_h) $(gxfixed_h) sjpeg_h=$(GLSRC)sjpeg.h slzwx_h=$(GLSRC)slzwx.h -smd5_h=$(GLSRC)smd5.h $(md5_h) +smd5_h=$(GLSRC)smd5.h $(gsmd5_h) sarc4_h=$(GLSRC)sarc4.h $(scommon_h) saes_h=$(GLSRC)saes.h $(scommon_h) $(aes_h) sjbig2_h=$(GLSRC)sjbig2.h $(stdint__h) $(scommon_h) @@ -572,6 +613,7 @@ spprint_h=$(GLSRC)spprint.h spsdf_h=$(GLSRC)spsdf.h $(gsparam_h) srlx_h=$(GLSRC)srlx.h +spwgx_h=$(GLSRC)spwgx.h sstring_h=$(GLSRC)sstring.h strimpl_h=$(GLSRC)strimpl.h $(scommon_h) $(gstypes_h) $(gsstruct_h) szlibx_h=$(GLSRC)szlibx.h @@ -597,10 +639,9 @@ gxfilltr_h=$(GLSRC)gxfilltr.h gxfillsl_h=$(GLSRC)gxfillsl.h gxfillts_h=$(GLSRC)gxfillts.h -gxfdrop_h=$(GLSRC)gxfdrop.h gxdtfill_h=$(GLSRC)gxdtfill.h -ttfoutl_h=$(GLSRC)ttfoutl.h +ttfoutl_h=$(GLSRC)ttfoutl.h $(memento_h) gxttfb_h = $(GLSRC)gxttfb.h $(ttfoutl_h) gzspotan_h = $(GLSRC)gzspotan.h $(gxdevcli_h) @@ -610,6 +651,9 @@ gsequivc_h=$(GLSRC)gsequivc.h gdevdevn_h=$(GLSRC)gdevdevn.h $(gsequivc_h) +gdevdevnprn_h=$(GLSRC)gdevdevnprn.h + +gdevoflt_h=$(GLSRC)gdevoflt.h $(gxdevice_h) png__h=$(GLSRC)png_.h $(MAKEFILE) x__h=$(GLSRC)x_.h @@ -620,32 +664,31 @@ # rather than in libcore, which is clearly wrong. $(GLOBJ)gconfig.$(OBJ) : $(gconfig_h) $(GLSRC)gconf.c $(AK) $(gx_h)\ $(gscdefs_h) $(gconf_h)\ - $(gxdevice_h) $(gxiclass_h) $(gxiodev_h) $(gxiparam_h) $(TOP_MAKEFILES)\ - $(MAKEDDIRS) + $(gxdevice_h) $(gxiclass_h) $(gxiodev_h) $(gxiparam_h) $(LIB_MAK) $(MAKEDIRS) $(RM_) $(GLGEN)gconfig.c $(CP_) $(GLSRC)gconf.c $(GLGEN)gconfig.c $(GLCC) $(GLO_)gconfig.$(OBJ) $(C_) $(GLGEN)gconfig.c $(GLOBJ)gscdefs.$(OBJ) : $(GLSRC)gscdef.c\ - $(std_h) $(gscdefs_h) $(gconfigd_h) $(TOP_MAKEFILES) $(MAKEDIRS) + $(std_h) $(gscdefs_h) $(gconfigd_h) $(LIB_MAK) $(MAKEDIRS) $(RM_) $(GLGEN)gscdefs.c $(CP_) $(GLSRC)gscdef.c $(GLGEN)gscdefs.c $(GLCC) $(GLO_)gscdefs.$(OBJ) $(C_) $(GLGEN)gscdefs.c $(AUX)gscdefs.$(OBJ) : $(GLSRC)gscdef.c\ - $(std_h) $(gscdefs_h) $(gconfigd_h) $(TOP_MAKEFILES) $(MAKEDIRS) + $(std_h) $(gscdefs_h) $(gconfigd_h) $(LIB_MAK) $(MAKEDIRS) $(RM_) $(AUX)gscdefs.c $(CP_) $(GLSRC)gscdef.c $(AUX)gscdefs.c $(GLCCAUX) $(C_) $(AUXO_)gscdefs.$(OBJ) $(AUX)gscdefs.c $(GLOBJ)gxacpath.$(OBJ) : $(GLSRC)gxacpath.c $(AK) $(gx_h)\ $(gserrors_h) $(gsdcolor_h) $(gsrop_h) $(gsstate_h) $(gsstruct_h) $(gsutil_h)\ - $(gxdevice_h) $(gxfixed_h) $(gxistate_h) $(gxpaint_h)\ - $(gzacpath_h) $(gzcpath_h) $(gzpath_h) $(gxdevsop_h) $(MAKEDIRS) + $(gxdevice_h) $(gxfixed_h) $(gxgstate_h) $(gxpaint_h)\ + $(gzacpath_h) $(gzcpath_h) $(gzpath_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxacpath.$(OBJ) $(C_) $(GLSRC)gxacpath.c $(GLOBJ)gxbcache.$(OBJ) : $(GLSRC)gxbcache.c $(AK) $(gx_h) $(memory__h)\ - $(gsmdebug_h) $(gxbcache_h) $(MAKEDIRS) + $(gsmdebug_h) $(gxbcache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxbcache.$(OBJ) $(C_) $(GLSRC)gxbcache.c $(GLOBJ)gxccache.$(OBJ) : $(GLSRC)gxccache.c $(AK) $(gx_h)\ @@ -654,36 +697,36 @@ $(gzstate_h) $(gzpath_h) $(gxdevice_h) $(gxdevmem_h)\ $(gzcpath_h) $(gxchar_h) $(gxfont_h) $(gxfcache_h)\ $(gxxfont_h) $(gximask_h) $(gscspace_h) $(gsimage_h) $(gxhttile_h)\ - $(gsptype1_h) $(MAKEDIRS) + $(gsptype1_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxccache.$(OBJ) $(C_) $(GLSRC)gxccache.c $(GLOBJ)gxccman.$(OBJ) : $(GLSRC)gxccman.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gpcheck_h)\ $(gsbitops_h) $(gsstruct_h) $(gsutil_h) $(gxfixed_h) $(gxmatrix_h)\ $(gxdevice_h) $(gxdevmem_h) $(gxfont_h) $(gxfcache_h) $(gxchar_h)\ - $(gxpath_h) $(gxxfont_h) $(gzstate_h) $(gxttfb_h) $(gxfont42_h) $(MAKEDIRS) + $(gxpath_h) $(gxxfont_h) $(gzstate_h) $(gxttfb_h) $(gxfont42_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxccman.$(OBJ) $(C_) $(GLSRC)gxccman.c $(GLOBJ)gxchar.$(OBJ) : $(GLSRC)gxchar.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gspath_h) $(gsstruct_h) $(gxfcid_h)\ $(gxfixed_h) $(gxarith_h) $(gxmatrix_h) $(gxcoord_h) $(gxdevice_h) $(gxdevmem_h)\ $(gxfont_h) $(gxfont0_h) $(gxchar_h) $(gxfcache_h) $(gzpath_h) $(gzstate_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxchar.$(OBJ) $(C_) $(GLSRC)gxchar.c $(GLOBJ)gxchrout.$(OBJ) : $(GLSRC)gxchrout.c $(AK) $(gx_h) $(math__h)\ - $(gxchrout_h) $(gxfarith_h) $(gxistate_h) $(MAKEDIRS) + $(gxchrout_h) $(gxfarith_h) $(gxgstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxchrout.$(OBJ) $(C_) $(GLSRC)gxchrout.c $(GLOBJ)gxcht.$(OBJ) : $(GLSRC)gxcht.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsutil_h) $(gxdevsop_h)\ $(gxarith_h) $(gxcmap_h) $(gxdcolor_h) $(gxdevice_h) $(gxfixed_h)\ - $(gxistate_h) $(gxmatrix_h) $(gzht_h) $(gsserial_h) $(MAKEDIRS) + $(gxgstate_h) $(gxmatrix_h) $(gzht_h) $(gsserial_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxcht.$(OBJ) $(C_) $(GLSRC)gxcht.c $(GLOBJ)gxclip.$(OBJ) : $(GLSRC)gxclip.c $(AK) $(gx_h)\ $(gxclip_h) $(gxcpath_h) $(gxdevice_h) $(gxpath_h) $(gzcpath_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclip.$(OBJ) $(C_) $(GLSRC)gxclip.c $(GLOBJ)gxcmap.$(OBJ) : $(GLSRC)gxcmap.c $(AK) $(gx_h) $(gserrors_h)\ @@ -692,92 +735,88 @@ $(gxdcconv_h) $(gxdevice_h) $(gxcmap_h) $(gxlum_h)\ $(gzstate_h) $(gxdither_h) $(gxcdevn_h) $(string__h)\ $(gsicc_manage_h) $(gdevdevn_h) $(gsicc_cache_h)\ - $(gscms_h) $(gsicc_h) $(gxdevsop_h) $(MAKEDIRS) + $(gscms_h) $(gsicc_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxcmap.$(OBJ) $(C_) $(GLSRC)gxcmap.c $(GLOBJ)gxcpath.$(OBJ) : $(GLSRC)gxcpath.c $(AK) $(gx_h) $(gserrors_h)\ $(gscoord_h) $(gsline_h) $(gsstruct_h) $(gsutil_h)\ - $(gxdevice_h) $(gxfixed_h) $(gxistate_h) $(gxpaint_h)\ - $(gzpath_h) $(gzcpath_h) $(gzacpath_h) $(MAKEDIRS) + $(gxdevice_h) $(gxfixed_h) $(gxgstate_h) $(gxpaint_h)\ + $(gzpath_h) $(gzcpath_h) $(gzacpath_h) $(string__h) \ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxcpath.$(OBJ) $(C_) $(GLSRC)gxcpath.c $(GLOBJ)gxdcconv.$(OBJ) : $(GLSRC)gxdcconv.c $(AK) $(gx_h)\ $(gsdcolor_h) $(gxcmap_h) $(gxdcconv_h) $(gxdevice_h)\ - $(gxfarith_h) $(gxistate_h) $(gxlum_h) $(gsstate_h) $(MAKEDIRS) + $(gxfarith_h) $(gxgstate_h) $(gxlum_h) $(gsstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxdcconv.$(OBJ) $(C_) $(GLSRC)gxdcconv.c $(GLOBJ)gxdcolor.$(OBJ) : $(GLSRC)gxdcolor.c $(AK) $(gx_h)\ $(memory__h) $(gsbittab_h) $(gserrors_h) $(gxdcolor_h) $(gxpcolor_h)\ - $(gxdevice_h) $(gxdevcli_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevcli_h) $(gxclist_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxdcolor.$(OBJ) $(C_) $(GLSRC)gxdcolor.c $(GLOBJ)gxhldevc.$(OBJ) : $(GLSRC)gxhldevc.c $(AK) $(gx_h)\ $(gzstate_h) $(gscspace_h) $(gxcspace_h) $(gxhldevc_h) $(memory__h)\ - $(gxpcolor_h) $(gsptype2_h) $(gsptype1_h) $(MAKEDIRS) + $(gxpcolor_h) $(gsptype2_h) $(gsptype1_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxhldevc.$(OBJ) $(C_) $(GLSRC)gxhldevc.c $(GLOBJ)gxfill.$(OBJ) : $(GLSRC)gxfill.c $(AK) $(gx_h) $(gserrors_h)\ - $(gsstruct_h) $(gxdevsop_h)\ + $(gsstruct_h) $(gxdevsop_h) $(assert__h)\ $(gxdcolor_h) $(gxdevice_h) $(gxfixed_h) $(gxhttile_h)\ - $(gxistate_h) $(gxpaint_h) $(gxfdrop_h) $(gxfill_h) $(gxpath_h)\ + $(gxgstate_h) $(gxpaint_h) $(gxfill_h) $(gxpath_h)\ $(gsptype1_h) $(gsptype2_h) $(gxpcolor_h) $(gsstate_h)\ $(gzcpath_h) $(gzpath_h) $(gzspotan_h) $(gdevddrw_h) $(memory__h)\ - $(stdint__h) $(vdtrace_h) $(gxfilltr_h) $(gxfillsl_h) $(gxfillts_h) $(MAKEDIRS) + $(stdint__h) $(gxfilltr_h) $(gxfillsl_h) $(gxfillts_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxfill.$(OBJ) $(C_) $(GLSRC)gxfill.c -$(GLOBJ)gxfdrop.$(OBJ) : $(GLSRC)gxfdrop.c $(AK) $(gx_h) $(gserrors_h)\ - $(gsstruct_h) $(gzpath_h) $(gxfixed_h) $(gxdevice_h) $(gxdcolor_h)\ - $(gxfill_h) $(gxfdrop_h) $(vdtrace_h) $(MAKEDIRS) - $(GLCC) $(GLO_)gxfdrop.$(OBJ) $(C_) $(GLSRC)gxfdrop.c - $(GLOBJ)gxht.$(OBJ) : $(GLSRC)gxht.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsbitops_h) $(gsstruct_h) $(gsutil_h)\ - $(gxdcolor_h) $(gxdevice_h) $(gxfixed_h) $(gxistate_h) $(gzht_h)\ - $(gsserial_h) $(MAKEDIRS) + $(gxdcolor_h) $(gxdevice_h) $(gxfixed_h) $(gxgstate_h) $(gzht_h)\ + $(gsserial_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxht.$(OBJ) $(C_) $(GLSRC)gxht.c $(GLOBJ)gxhtbit.$(OBJ) : $(GLSRC)gxhtbit.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsbitops_h) $(gscdefs_h)\ - $(gxbitmap_h) $(gxdht_h) $(gxdhtres_h) $(gxhttile_h) $(gxtmap_h) $(MAKEDIRS) + $(gxbitmap_h) $(gxdht_h) $(gxdhtres_h) $(gxhttile_h) $(gxtmap_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxhtbit.$(OBJ) $(C_) $(GLSRC)gxhtbit.c $(GLOBJ)gxht_thresh.$(OBJ) : $(GLSRC)gxht_thresh.c $(AK) $(memory__h)\ - $(gx_h) $(gxistate_h) $(gsiparam_h) $(math__h) $(gxfixed_h) $(gximage_h)\ - $(gxdevice_h) $(gxdht_h) $(gxht_thresh_h) $(gzht_h) $(gxdevsop_h) $(MAKEDIRS) + $(gx_h) $(gxgstate_h) $(gsiparam_h) $(math__h) $(gxfixed_h) $(gximage_h)\ + $(gxdevice_h) $(gxdht_h) $(gxht_thresh_h) $(gzht_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxht_thresh.$(OBJ) $(C_) $(GLSRC)gxht_thresh.c $(GLOBJ)gxidata.$(OBJ) : $(GLSRC)gxidata.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gxcpath_h) $(gxdevice_h) $(gximage_h) $(gsicc_cache_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxidata.$(OBJ) $(C_) $(GLSRC)gxidata.c $(GLOBJ)gxifast.$(OBJ) : $(GLSRC)gxifast.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gpcheck_h) $(gdevmem_h) $(gsbittab_h) $(gsccolor_h)\ $(gspaint_h) $(gsutil_h) $(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h)\ - $(gxdevice_h) $(gxdevmem_h) $(gxfixed_h) $(gximage_h) $(gxistate_h) \ - $(gxmatrix_h) $(gzht_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gxfixed_h) $(gximage_h) $(gxgstate_h) \ + $(gxmatrix_h) $(gzht_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxifast.$(OBJ) $(C_) $(GLSRC)gxifast.c $(GLOBJ)gximage.$(OBJ) : $(GLSRC)gximage.c $(AK) $(gx_h) $(gserrors_h)\ $(gscspace_h) $(gsmatrix_h) $(gsutil_h)\ - $(gxcolor2_h) $(gxiparam_h) $(stream_h) $(memory__h) $(MAKEDIRS) + $(gxcolor2_h) $(gxiparam_h) $(stream_h) $(memory__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximage.$(OBJ) $(C_) $(GLSRC)gximage.c $(GLOBJ)gximage1.$(OBJ) : $(GLSRC)gximage1.c $(AK) $(gx_h)\ - $(gserrors_h) $(gximage_h) $(gxiparam_h) $(stream_h) $(memory__h) $(MAKEDIRS) + $(gserrors_h) $(gximage_h) $(gxiparam_h) $(stream_h) $(memory__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximage1.$(OBJ) $(C_) $(GLSRC)gximage1.c $(GLOBJ)gximono.$(OBJ) : $(GLSRC)gximono.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gpcheck_h) $(gdevmem_h) $(gsccolor_h) $(gspaint_h) $(gsutil_h)\ $(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h)\ - $(gxdevmem_h) $(gxfixed_h) $(gximage_h) $(gxistate_h) $(gxmatrix_h)\ - $(gzht_h) $(vdtrace_h) $(gsicc_h) $(gsicc_cache_h) $(gsicc_cms_h)\ - $(gxcie_h) $(gscie_h) $(gxht_thresh_h) $(gxdda_h) $(gxdevsop_h) $(MAKEDIRS) + $(gxdevmem_h) $(gxfixed_h) $(gximage_h) $(gxgstate_h) $(gxmatrix_h)\ + $(gzht_h) $(gsicc_h) $(gsicc_cache_h) $(gsicc_cms_h)\ + $(gxcie_h) $(gscie_h) $(gxht_thresh_h) $(gxdda_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximono.$(OBJ) $(C_) $(GLSRC)gximono.c $(GLOBJ)gximask.$(OBJ) : $(GLSRC)gximask.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsptype1_h) $(gsptype2_h) $(gxdevice_h) $(gxdcolor_h)\ - $(gxcpath_h) $(gximask_h) $(gzacpath_h) $(gzcpath_h) $(gxdevsop_h) $(MAKEDIRS) + $(gxcpath_h) $(gximask_h) $(gzacpath_h) $(gzcpath_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximask.$(OBJ) $(C_) $(GLSRC)gximask.c $(GLOBJ)gxipixel.$(OBJ) : $(GLSRC)gxipixel.c $(AK) $(gx_h)\ @@ -785,126 +824,129 @@ $(gsccolor_h) $(gscdefs_h) $(gspaint_h) $(gsstruct_h) $(gsutil_h)\ $(gxfixed_h) $(gxfrac_h) $(gxarith_h) $(gxiparam_h) $(gxmatrix_h)\ $(gxdevice_h) $(gzpath_h) $(gzstate_h) $(gsicc_cache_h) $(gsicc_cms_h)\ - $(gzcpath_h) $(gxdevmem_h) $(gximage_h) $(gdevmrop_h) $(MAKEDIRS) + $(gzcpath_h) $(gxdevmem_h) $(gximage_h) $(gdevmrop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxipixel.$(OBJ) $(C_) $(GLSRC)gxipixel.c $(GLOBJ)gxi12bit.$(OBJ) : $(GLSRC)gxi12bit.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gpcheck_h)\ $(gsccolor_h) $(gspaint_h)\ $(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h)\ - $(gxdevmem_h) $(gxfixed_h) $(gxfrac_h) $(gximage_h) $(gxistate_h)\ - $(gxmatrix_h) $(vdtrace_h) $(gsicc_h) $(gsicc_cache_h) $(gsicc_cms_h)\ - $(gxcie_h) $(gscie_h) $(gxdevsop_h) $(MAKEDIRS) + $(gxdevmem_h) $(gxfixed_h) $(gxfrac_h) $(gximage_h) $(gxgstate_h)\ + $(gxmatrix_h) $(gsicc_h) $(gsicc_cache_h) $(gsicc_cms_h)\ + $(gxcie_h) $(gscie_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxi12bit.$(OBJ) $(C_) $(GLSRC)gxi12bit.c $(GLOBJ)gxi16bit.$(OBJ) : $(GLSRC)gxi16bit.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gpcheck_h) $(gsccolor_h) $(gspaint_h)\ $(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h)\ - $(gxdevmem_h) $(gxfixed_h) $(gxfrac_h) $(gximage_h) $(gxistate_h)\ - $(gxmatrix_h) $(MAKEDIRS) + $(gxdevmem_h) $(gxfixed_h) $(gxfrac_h) $(gximage_h) $(gxgstate_h)\ + $(gxmatrix_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxi16bit.$(OBJ) $(C_) $(GLSRC)gxi16bit.c # gxmclip is used for Patterns and ImageType 3 images: # it isn't included in the base library. $(GLOBJ)gxmclip.$(OBJ) : $(GLSRC)gxmclip.c $(AK) $(gx_h) $(gserrors_h)\ - $(gxdevice_h) $(gxdevmem_h) $(gxmclip_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gxmclip_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxmclip.$(OBJ) $(C_) $(GLSRC)gxmclip.c $(GLOBJ)gxpaint.$(OBJ) : $(GLSRC)gxpaint.c $(AK) $(gx_h)\ $(gxdevice_h) $(gxhttile_h) $(gxpaint_h) $(gxpath_h) $(gzstate_h) $(gxfont_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxpaint.$(OBJ) $(C_) $(GLSRC)gxpaint.c $(GLOBJ)gxpath.$(OBJ) : $(GLSRC)gxpath.c $(AK) $(gx_h) $(gserrors_h)\ - $(gsstruct_h) $(gxfixed_h) $(gzpath_h) $(vdtrace_h) $(MAKEDIRS) + $(gsstruct_h) $(gxfixed_h) $(gzpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxpath.$(OBJ) $(C_) $(GLSRC)gxpath.c $(GLOBJ)gxpath2.$(OBJ) : $(GLSRC)gxpath2.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(gspath_h) $(gsstruct_h) $(gxfixed_h) $(gxarith_h) $(gzpath_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxpath2.$(OBJ) $(C_) $(GLSRC)gxpath2.c $(GLOBJ)gxpcopy.$(OBJ) : $(GLSRC)gxpcopy.c $(AK) $(gx_h) $(gserrors_h)\ - $(math__h) $(gxfarith_h) $(gxfixed_h) $(gxistate_h) $(gzpath_h) $(vdtrace_h)\ - $(MAKEDIRS) + $(math__h) $(gxfarith_h) $(gxfixed_h) $(gxgstate_h) $(gzpath_h) \ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxpcopy.$(OBJ) $(C_) $(GLSRC)gxpcopy.c $(GLOBJ)gxpdash.$(OBJ) : $(GLSRC)gxpdash.c $(AK) $(gx_h) $(math__h)\ - $(gscoord_h) $(gsline_h) $(gsmatrix_h) $(gxarith_h) $(gxistate_h)\ - $(gxfixed_h) $(gzline_h) $(gzpath_h) $(MAKEDIRS) + $(gscoord_h) $(gsline_h) $(gsmatrix_h) $(gxarith_h) $(gxgstate_h)\ + $(gxfixed_h) $(gzline_h) $(gzpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxpdash.$(OBJ) $(C_) $(GLSRC)gxpdash.c $(GLOBJ)gxpflat.$(OBJ) : $(GLSRC)gxpflat.c $(AK) $(gx_h)\ $(gserrors_h) $(gxarith_h) $(gxfixed_h) $(gzpath_h) $(memory__h) $(string__h)\ - $(vdtrace_h) $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxpflat.$(OBJ) $(C_) $(GLSRC)gxpflat.c $(GLOBJ)gxsample.$(OBJ) : $(GLSRC)gxsample.c $(AK) $(gx_h)\ - $(gxsample_h) $(gxfixed_h) $(gximage_h) $(gxsamplp_h) $(MAKEDIRS) + $(gxsample_h) $(gxfixed_h) $(gximage_h) $(gxsamplp_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxsample.$(OBJ) $(C_) $(GLSRC)gxsample.c +$(GLOBJ)gxscanc.$(OBJ) : $(GLSRC)gxscanc.c $(GX) $(gxscanc_h) $(gx_h) + $(GLCC) $(GLO_)gxscanc.$(OBJ) $(C_) $(GLSRC)gxscanc.c + $(GLOBJ)gxstroke.$(OBJ) : $(GLSRC)gxstroke.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(gpcheck_h) $(gsstate_h)\ $(gscoord_h) $(gsdcolor_h) $(gsdevice_h) $(gsptype1_h)\ $(gxdevice_h) $(gxfarith_h) $(gxfixed_h)\ - $(gxhttile_h) $(gxistate_h) $(gxmatrix_h) $(gxpaint_h)\ - $(gzcpath_h) $(gzline_h) $(gzpath_h) $(vdtrace_h) $(MAKEDIRS) + $(gxhttile_h) $(gxgstate_h) $(gxmatrix_h) $(gxpaint_h)\ + $(gzcpath_h) $(gzline_h) $(gzpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxstroke.$(OBJ) $(C_) $(GLSRC)gxstroke.c ###### Higher-level facilities $(GLOBJ)gsalpha.$(OBJ) : $(GLSRC)gsalpha.c $(AK) $(gx_h)\ - $(gsalpha_h) $(gxdcolor_h) $(gzstate_h) $(MAKEDIRS) + $(gsalpha_h) $(gxdcolor_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsalpha.$(OBJ) $(C_) $(GLSRC)gsalpha.c # gscedata.[ch] are generated automatically by lib/encs2c.ps. $(GLOBJ)gscedata.$(OBJ) : $(GLSRC)gscedata.c\ - $(stdpre_h) $(gstypes_h) $(gscedata_h) $(MAKEDIRS) + $(stdpre_h) $(gstypes_h) $(gscedata_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscedata.$(OBJ) $(C_) $(GLSRC)gscedata.c $(GLOBJ)gscencs.$(OBJ) : $(GLSRC)gscencs.c\ - $(memory__h) $(gscedata_h) $(gscencs_h) $(gserrors_h) $(MAKEDIRS) + $(memory__h) $(gscedata_h) $(gscencs_h) $(gserrors_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscencs.$(OBJ) $(C_) $(GLSRC)gscencs.c $(GLOBJ)gschar.$(OBJ) : $(GLSRC)gschar.c $(AK) $(gx_h) $(gserrors_h)\ $(gscoord_h) $(gsmatrix_h) $(gsstruct_h)\ - $(gxdevice_h) $(gxdevmem_h) $(gxchar_h) $(gxfont_h) $(gzstate_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gxchar_h) $(gxfont_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gschar.$(OBJ) $(C_) $(GLSRC)gschar.c $(GLOBJ)gscolor.$(OBJ) : $(GLSRC)gscolor.c $(AK) $(gx_h) $(gserrors_h)\ $(gsccolor_h) $(gsstruct_h) $(gsutil_h) $(gscolor2_h)\ - $(gxcmap_h) $(gxcspace_h) $(gxdcconv_h) $(gxdevice_h) $(gzstate_h) $(MAKEDIRS) + $(gxcmap_h) $(gxcspace_h) $(gxdcconv_h) $(gxdevice_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscolor.$(OBJ) $(C_) $(GLSRC)gscolor.c $(GLOBJ)gscoord.$(OBJ) : $(GLSRC)gscoord.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(gsccode_h) $(gxcoord_h) $(gxdevice_h) $(gxfarith_h) $(gxfixed_h)\ - $(gxfont_h) $(gxmatrix_h) $(gxpath_h) $(gzstate_h) $(MAKEDIRS) + $(gxfont_h) $(gxmatrix_h) $(gxpath_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscoord.$(OBJ) $(C_) $(GLSRC)gscoord.c $(GLOBJ)gscparam.$(OBJ) : $(GLSRC)gscparam.c $(AK) $(gx_h)\ - $(gserrors_h) $(memory__h) $(string__h) $(gsparam_h) $(gsstruct_h) $(MAKEDIRS) + $(gserrors_h) $(memory__h) $(string__h) $(gsparam_h) $(gsstruct_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscparam.$(OBJ) $(C_) $(GLSRC)gscparam.c $(GLOBJ)gscspace.$(OBJ) : $(GLSRC)gscspace.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gsstruct_h) $(gsccolor_h) $(gsutil_h)\ - $(gxcmap_h) $(gxcspace_h) $(gxistate_h) $(gsovrc_h) $(gsstate_h)\ + $(gxcmap_h) $(gxcspace_h) $(gxgstate_h) $(gsovrc_h) $(gsstate_h)\ $(gsdevice_h) $(gxdevcli_h) $(gzstate_h) $(gsnamecl_h) $(stream_h)\ - $(gsicc_h) $(gsicc_manage_h) $(MAKEDIRS) + $(gsicc_h) $(gsicc_manage_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscspace.$(OBJ) $(C_) $(GLSRC)gscspace.c $(GLOBJ)gscicach.$(OBJ) : $(GLSRC)gscicach.c $(AK) $(gx_h)\ $(gserrors_h) $(gsccolor_h) $(gxcspace_h) $(gxdcolor_h) $(gscicach_h)\ - $(memory__h) $(MAKEDIRS) + $(memory__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscicach.$(OBJ) $(C_) $(GLSRC)gscicach.c $(GLOBJ)gsovrc.$(OBJ) : $(GLSRC)gsovrc.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsutil_h) $(gxcomp_h) $(gxdevice_h) $(gsdevice_h) $(gxgetbit_h)\ - $(gsovrc_h) $(gxdcolor_h) $(gxoprect_h) $(gsbitops_h) $(gxistate_h) $(MAKEDIRS) + $(gsovrc_h) $(gxdcolor_h) $(gxoprect_h) $(gsbitops_h) $(gxgstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsovrc.$(OBJ) $(C_) $(GLSRC)gsovrc.c $(GLOBJ)gxoprect.$(OBJ) : $(GLSRC)gxoprect.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gsutil_h) $(gxdevice_h) $(gsdevice_h)\ - $(gxgetbit_h) $(gxoprect_h) $(gsbitops_h) $(MAKEDIRS) + $(gxgetbit_h) $(gxoprect_h) $(gsbitops_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxoprect.$(OBJ) $(C_) $(GLSRC)gxoprect.c $(GLOBJ)gsdevice.$(OBJ) : $(GLSRC)gsdevice.c $(AK) $(gx_h)\ @@ -912,124 +954,117 @@ $(gscdefs_h) $(gsfname_h) $(gsstruct_h) $(gspath_h)\ $(gspaint_h) $(gsmatrix_h) $(gscoord_h) $(gzstate_h)\ $(gxcmap_h) $(gxdevice_h) $(gxdevmem_h) $(gxiodev_h) $(gxcspace_h)\ - $(gsicc_manage_h) $(gscms_h) $(MAKEDIRS) + $(gsicc_manage_h) $(gscms_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsdevice.$(OBJ) $(C_) $(GLSRC)gsdevice.c -$(GLOBJ)gsdfilt.$(OBJ) : $(GLSRC)gsdfilt.c $(AK) $(gx_h) $(gserrors_h)\ - $(ctype__h) $(memory__h) $(string__h) $(gp_h)\ - $(gscdefs_h) $(gscoord_h) $(gsdfilt_h) $(gsfname_h) $(gsmatrix_h)\ - $(gspaint_h) $(gspath_h) $(gsstruct_h)\ - $(gxcmap_h) $(gxdevice_h) $(gxdevmem_h) $(gxiodev_h) $(gzstate_h) $(MAKEDIRS) - $(GLCC) $(GLO_)gsdfilt.$(OBJ) $(C_) $(GLSRC)gsdfilt.c - $(GLOBJ)gsdevmem.$(OBJ) : $(GLSRC)gsdevmem.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h) $(gsdevice_h) $(gxarith_h)\ - $(gxdevice_h) $(gxdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsdevmem.$(OBJ) $(C_) $(GLSRC)gsdevmem.c $(GLOBJ)gsdparam.$(OBJ) : $(GLSRC)gsdparam.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(string__h)\ $(gsdevice_h) $(gsparam_h) $(gxdevice_h) $(gxfixed_h)\ - $(gsicc_manage_h) $(MAKEDIRS) + $(gsicc_manage_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsdparam.$(OBJ) $(C_) $(GLSRC)gsdparam.c $(GLOBJ)gsfname.$(OBJ) : $(GLSRC)gsfname.c $(AK) $(memory__h)\ $(gserrors_h) $(gsfname_h) $(gsmemory_h) $(gstypes_h)\ - $(gxiodev_h) $(MAKEDIRS) + $(gxiodev_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfname.$(OBJ) $(C_) $(GLSRC)gsfname.c $(GLOBJ)gsfont.$(OBJ) : $(GLSRC)gsfont.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsstruct_h) $(gsutil_h)\ $(gxdevice_h) $(gxfixed_h) $(gxmatrix_h) $(gxfont_h) $(gxfcache_h)\ - $(gzpath_h) $(gzstate_h) $(MAKEDIRS) + $(gzpath_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfont.$(OBJ) $(C_) $(GLSRC)gsfont.c $(GLOBJ)gsgdata.$(OBJ) : $(GLSRC)gsgdata.c $(AK) $(gx_h) $(gserrors_h)\ - $(memory__h) $(gsgdata_h) $(gsmatrix_h) $(gsstruct_h) $(gxfont_h) $(MAKEDIRS) + $(memory__h) $(gsgdata_h) $(gsmatrix_h) $(gsstruct_h) $(gxfont_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsgdata.$(OBJ) $(C_) $(GLSRC)gsgdata.c $(GLOBJ)gsgcache.$(OBJ) : $(GLSRC)gsgcache.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gsstruct_h) $(gsgdata_h) $(gsgcache_h)\ - $(gxfont_h) $(gxfont42_h) $(MAKEDIRS) + $(gxfont_h) $(gxfont42_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsgcache.$(OBJ) $(C_) $(GLSRC)gsgcache.c $(GLOBJ)gsht.$(OBJ) : $(GLSRC)gsht.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxarith_h)\ - $(gxdevice_h) $(gzht_h) $(gzstate_h) $(gxfmap_h) $(MAKEDIRS) + $(gxdevice_h) $(gzht_h) $(gzstate_h) $(gxfmap_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsht.$(OBJ) $(C_) $(GLSRC)gsht.c $(GLOBJ)gshtscr.$(OBJ) : $(GLSRC)gshtscr.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(gsstruct_h) $(gxarith_h) $(gxdevice_h) $(gzht_h) $(gzstate_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gshtscr.$(OBJ) $(C_) $(GLSRC)gshtscr.c $(GLOBJ)gsimage.$(OBJ) : $(GLSRC)gsimage.c $(AK) $(gx_h) $(gserrors_h)\ - $(memory__h) $(math__h) $(gscspace_h) $(gsimage_h) $(gsmatrix_h)\ + $(memory__h) $(math__h) $(gscspace_h) $(gsimage_h) $(gsmatrix_h) $(gximage_h)\ $(gsstruct_h) $(gxarith_h) $(gxdevice_h) $(gxiparam_h) $(gxpath_h)\ - $(gximask_h) $(gzstate_h) $(vdtrace_h) $(gxdevsop_h) $(gsutil_h) $(MAKEDIRS) + $(gximask_h) $(gzstate_h) $(gxdevsop_h) $(gsutil_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsimage.$(OBJ) $(C_) $(GLSRC)gsimage.c $(GLOBJ)gsimpath.$(OBJ) : $(GLSRC)gsimpath.c $(AK) $(gx_h)\ - $(gserrors_h) $(gsmatrix_h) $(gspaint_h) $(gspath_h) $(gsstate_h) $(MAKEDIRS) + $(gserrors_h) $(gsmatrix_h) $(gspaint_h) $(gspath_h) $(gsstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsimpath.$(OBJ) $(C_) $(GLSRC)gsimpath.c $(GLOBJ)gsinit.$(OBJ) : $(GLSRC)gsinit.c $(AK) $(memory__h) $(stdio__h)\ $(gdebug_h) $(gp_h) $(gscdefs_h) $(gslib_h) $(gsmalloc_h) $(gsmemory_h)\ - $(gxfapi_h) $(MAKEDIRS) $(valgrind_h) + $(gxfapi_h) $(valgrind_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsinit.$(OBJ) $(C_) $(GLSRC)gsinit.c $(GLOBJ)gsiodev.$(OBJ) : $(GLSRC)gsiodev.c $(AK) $(gx_h) $(gserrors_h)\ $(errno__h) $(string__h) $(unistd__h) $(gsfname_h)\ - $(gp_h) $(gscdefs_h) $(gsparam_h) $(gsstruct_h) $(gxiodev_h) $(MAKEDIRS) + $(gp_h) $(gscdefs_h) $(gsparam_h) $(gsstruct_h) $(gxiodev_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsiodev.$(OBJ) $(C_) $(GLSRC)gsiodev.c -$(GLOBJ)gsistate.$(OBJ) : $(GLSRC)gsistate.c $(AK) $(gx_h)\ +$(GLOBJ)gsgstate.$(OBJ) : $(GLSRC)gsgstate.c $(AK) $(gx_h)\ $(gserrors_h) $(gscie_h) $(gscspace_h) $(gsstruct_h) $(gsutil_h) $(gxfmap_h)\ - $(gxbitmap_h) $(gxcmap_h) $(gxdht_h) $(gxistate_h) $(gzht_h) $(gzline_h)\ - $(gsicc_cache_h) $(gsicc_manage_h) $(gsicc_profilecache_h) $(MAKEDIRS) - $(GLCC) $(GLO_)gsistate.$(OBJ) $(C_) $(GLSRC)gsistate.c + $(gxbitmap_h) $(gxcmap_h) $(gxdht_h) $(gxgstate_h) $(gzht_h) $(gzline_h)\ + $(gsicc_cache_h) $(gsicc_manage_h) $(gsicc_profilecache_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)gsgstate.$(OBJ) $(C_) $(GLSRC)gsgstate.c $(GLOBJ)gsline.$(OBJ) : $(GLSRC)gsline.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h)\ $(gscoord_h) $(gsline_h) $(gxfixed_h) $(gxmatrix_h) $(gzstate_h) $(gzline_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsline.$(OBJ) $(C_) $(GLSRC)gsline.c $(GLOBJ)gsmatrix.$(OBJ) : $(GLSRC)gsmatrix.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h)\ - $(gxfarith_h) $(gxfixed_h) $(gxmatrix_h) $(stream_h) $(MAKEDIRS) + $(gxfarith_h) $(gxfixed_h) $(gxmatrix_h) $(stream_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsmatrix.$(OBJ) $(C_) $(GLSRC)gsmatrix.c $(GLOBJ)gspaint.$(OBJ) : $(GLSRC)gspaint.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(gpcheck_h)\ $(gsropt_h) $(gxfixed_h) $(gxmatrix_h) $(gspaint_h) $(gspath_h)\ $(gzpath_h) $(gxpaint_h) $(gzstate_h) $(gxdevice_h) $(gxdevmem_h)\ - $(gzcpath_h) $(gxhldevc_h) $(gsutil_h) $(gxdevsop_h) $(MAKEDIRS) + $(gzcpath_h) $(gxhldevc_h) $(gsutil_h) $(gxdevsop_h) $(gsicc_cms_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gspaint.$(OBJ) $(C_) $(GLSRC)gspaint.c $(GLOBJ)gsparam.$(OBJ) : $(GLSRC)gsparam.c $(AK) $(gx_h) $(gserrors_h)\ - $(memory__h) $(string__h) $(gsparam_h) $(gsstruct_h) $(MAKEDIRS) + $(memory__h) $(string__h) $(gsparam_h) $(gsstruct_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsparam.$(OBJ) $(C_) $(GLSRC)gsparam.c # gsparamx is not included in the base configuration. $(GLOBJ)gsparamx.$(OBJ) : $(AK) $(GLSRC)gsparamx.c $(string__h)\ $(gserrors_h) $(gsmemory_h) $(gsparam_h) $(gsparamx_h)\ - $(gstypes_h) $(MAKEDIRS) + $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsparamx.$(OBJ) $(C_) $(GLSRC)gsparamx.c # Future replacement for gsparams.c $(GLOBJ)gsparam2.$(OBJ) : $(GLSRC)gsparam2.c $(AK) $(gx_h)\ - $(gserrors_h) $(memory__h) $(gsparams_h) $(MAKEDIRS) + $(gserrors_h) $(memory__h) $(gsparams_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsparam2.$(OBJ) $(C_) $(GLSRC)gsparam2.c $(GLOBJ)gsparams.$(OBJ) : $(GLSRC)gsparams.c $(AK) $(gx_h)\ - $(gserrors_h) $(memory__h) $(gsparams_h) $(MAKEDIRS) + $(gserrors_h) $(memory__h) $(gsparams_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsparams.$(OBJ) $(C_) $(GLSRC)gsparams.c $(GLOBJ)gspath.$(OBJ) : $(GLSRC)gspath.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(gscoord_h) $(gspath_h)\ $(gxdevice_h) $(gxdevmem_h) $(gxfixed_h) $(gxmatrix_h)\ - $(gzcpath_h) $(gzpath_h) $(gzstate_h) $(gxpaint_h) $(MAKEDIRS) + $(gzcpath_h) $(gzpath_h) $(gzstate_h) $(gxpaint_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gspath.$(OBJ) $(C_) $(GLSRC)gspath.c $(GLOBJ)gsstate.$(OBJ) : $(GLSRC)gsstate.c $(AK) $(gx_h) $(gserrors_h)\ @@ -1037,25 +1072,25 @@ $(gsalpha_h) $(gscolor2_h) $(gscoord_h) $(gscie_h)\ $(gxclipsr_h) $(gxcmap_h) $(gxdevice_h) $(gxpcache_h)\ $(gzht_h) $(gzline_h) $(gspath_h) $(gzpath_h) $(gzcpath_h)\ - $(gsovrc_h) $(gxcolor2_h) $(gxpcolor_h) $(gsicc_manage_h) $(MAKEDIRS) + $(gsovrc_h) $(gxcolor2_h) $(gxpcolor_h) $(gsicc_manage_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsstate.$(OBJ) $(C_) $(GLSRC)gsstate.c $(GLOBJ)gstext.$(OBJ) : $(GLSRC)gstext.c $(AK) $(memory__h) $(gdebug_h)\ $(gserrors_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h)\ $(gxfcache_h) $(gxdevcli_h) $(gxdcolor_h) $(gxfont_h) $(gxpath_h)\ - $(gxtext_h) $(gzstate_h) $(gsutil_h) $(MAKEDIRS) + $(gxtext_h) $(gzstate_h) $(gsutil_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gstext.$(OBJ) $(C_) $(GLSRC)gstext.c # We make gsiodevs a separate module so the PS interpreter can replace it. $(GLD)gsiodevs.dev : $(ECHOGS_XE) $(LIB_MAK) $(GLOBJ)gsiodevs.$(OBJ)\ - $(GLD)sfile.dev + $(GLD)sfile.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)gsiodevs $(GLOBJ)gsiodevs.$(OBJ) $(ADDMOD) $(GLD)gsiodevs -include $(GLD)sfile $(ADDMOD) $(GLD)gsiodevs -iodev stdin stdout stderr $(GLOBJ)gsiodevs.$(OBJ) : $(GLSRC)gsiodevs.c $(AK) $(gx_h)\ - $(gserrors_h) $(gxiodev_h) $(stream_h) $(strimpl_h) $(MAKEDIRS) + $(gserrors_h) $(gxiodev_h) $(stream_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsiodevs.$(OBJ) $(C_) $(GLSRC)gsiodevs.c ###### Internal devices @@ -1063,74 +1098,71 @@ ### Device support # PC display color mapping $(GLOBJ)gdevpccm.$(OBJ) : $(GLSRC)gdevpccm.c $(AK)\ - $(gx_h) $(gsmatrix_h) $(gxdevice_h) $(gdevpccm_h) + $(gx_h) $(gsmatrix_h) $(gxdevice_h) $(gdevpccm_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevpccm.$(OBJ) $(C_) $(GLSRC)gdevpccm.c -$(GLOBJ)ConvertUTF.$(OBJ) : $(GLSRC)ConvertUTF.c $(ConvertUTF_h) - $(GLCC) $(GLO_)ConvertUTF.$(OBJ) $(C_) $(GLSRC)ConvertUTF.c - ### Memory devices $(GLOBJ)gdevmem.$(OBJ) : $(GLSRC)gdevmem.c $(AK) $(gx_h) $(gserrors_h) \ $(memory__h)\ $(gsdevice_h) $(gsrect_h) $(gsstruct_h) $(gstrans_h)\ - $(gxarith_h) $(gxgetbit_h) $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxarith_h) $(gxgetbit_h) $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevmem.$(OBJ) $(C_) $(GLSRC)gdevmem.c $(GLOBJ)gdevm1.$(OBJ) : $(GLSRC)gdevm1.c $(AK) $(gx_h) $(memory__h)\ - $(gsrop_h) $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS)\ + $(gsrop_h) $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS)\ $(gserrors_h) $(GLCC) $(GLO_)gdevm1.$(OBJ) $(C_) $(GLSRC)gdevm1.c $(GLOBJ)gdevm2.$(OBJ) : $(GLSRC)gdevm2.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm2.$(OBJ) $(C_) $(GLSRC)gdevm2.c $(GLOBJ)gdevm4.$(OBJ) : $(GLSRC)gdevm4.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm4.$(OBJ) $(C_) $(GLSRC)gdevm4.c $(GLOBJ)gdevm8.$(OBJ) : $(GLSRC)gdevm8.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm8.$(OBJ) $(C_) $(GLSRC)gdevm8.c $(GLOBJ)gdevm16.$(OBJ) : $(GLSRC)gdevm16.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm16.$(OBJ) $(C_) $(GLSRC)gdevm16.c $(GLOBJ)gdevm24.$(OBJ) : $(GLSRC)gdevm24.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(vdtrace_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm24.$(OBJ) $(C_) $(GLSRC)gdevm24.c $(GLOBJ)gdevm32.$(OBJ) : $(GLSRC)gdevm32.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm32.$(OBJ) $(C_) $(GLSRC)gdevm32.c $(GLOBJ)gdevm40.$(OBJ) : $(GLSRC)gdevm40.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm40.$(OBJ) $(C_) $(GLSRC)gdevm40.c $(GLOBJ)gdevm48.$(OBJ) : $(GLSRC)gdevm48.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm48.$(OBJ) $(C_) $(GLSRC)gdevm48.c $(GLOBJ)gdevm56.$(OBJ) : $(GLSRC)gdevm56.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm56.$(OBJ) $(C_) $(GLSRC)gdevm56.c $(GLOBJ)gdevm64.$(OBJ) : $(GLSRC)gdevm64.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevm64.$(OBJ) $(C_) $(GLSRC)gdevm64.c $(GLOBJ)gdevmx.$(OBJ) : $(GLSRC)gdevmx.c $(AK) $(gx_h) $(memory__h)\ - $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevmx.$(OBJ) $(C_) $(GLSRC)gdevmx.c - + $(GLOBJ)gdevmpla.$(OBJ) : $(GLSRC)gdevmpla.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gsbitops_h) $(gxdcolor_h) $(gxpcolor_h)\ $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) $(gdevmem_h) $(gdevmpla_h)\ $(gxdevsop_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevmpla.$(OBJ) $(C_) $(GLSRC)gdevmpla.c ### Alpha-channel devices @@ -1138,7 +1170,7 @@ $(GLOBJ)gdevabuf.$(OBJ) : $(GLSRC)gdevabuf.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h)\ $(gxdevice_h) $(gxdevmem_h) $(gdevmem_h) $(gzstate_h) $(gxdevcli_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevabuf.$(OBJ) $(C_) $(GLSRC)gdevabuf.c ### Other built-in devices @@ -1148,27 +1180,27 @@ # the bboxutil.dev pseudo device to allow inclusion without putting # the bbox device on the list of devices. -$(GLD)bboxutil.dev : $(ECHOGS_XE) $(LIB_MAK) $(GLOBJ)gdevbbox.$(OBJ) +$(GLD)bboxutil.dev : $(ECHOGS_XE) $(LIB_MAK) $(GLOBJ)gdevbbox.$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)bboxutil $(GLOBJ)gdevbbox.$(OBJ) -$(GLD)bbox.dev : $(ECHOGS_XE) $(LIB_MAK) $(GLOBJ)gdevbbox.$(OBJ) +$(GLD)bbox.dev : $(ECHOGS_XE) $(LIB_MAK) $(GLOBJ)gdevbbox.$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(SETDEV2) $(GLD)bbox $(GLOBJ)gdevbbox.$(OBJ) $(GLOBJ)gdevbbox.$(OBJ) : $(GLSRC)gdevbbox.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h) $(gdevbbox_h) $(gsdevice_h) $(gsparam_h)\ - $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h) $(gxiparam_h) $(gxistate_h)\ - $(gxpaint_h) $(gxpath_h) $(MAKEDIRS) + $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h) $(gxiparam_h) $(gxgstate_h)\ + $(gxpaint_h) $(gxpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevbbox.$(OBJ) $(C_) $(GLSRC)gdevbbox.c $(GLOBJ)gdevhit.$(OBJ) : $(GLSRC)gdevhit.c $(AK) $(std_h)\ $(gserrors_h) $(gsmemory_h) $(gstypes_h) $(gxdevice_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevhit.$(OBJ) $(C_) $(GLSRC)gdevhit.c # A device that stores its data using run-length encoding. $(GLOBJ)gdevmrun.$(OBJ) : $(GLSRC)gdevmrun.c $(AK) $(gx_h)\ - $(gserrors_h) $(memory__h) $(gxdevice_h) $(gdevmrun_h) $(MAKEDIRS) + $(gserrors_h) $(memory__h) $(gxdevice_h) $(gdevmrun_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevmrun.$(OBJ) $(C_) $(GLSRC)gdevmrun.c # A device that extracts a single plane from multi-plane color. @@ -1177,7 +1209,7 @@ $(gserrors_h) $(gsbitops_h) $(gsrop_h) $(gsstruct_h) $(gsutil_h)\ $(gdevplnx_h)\ $(gxcmap_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdither_h)\ - $(gxgetbit_h) $(gxiparam_h) $(gxistate_h) $(MAKEDIRS) + $(gxgetbit_h) $(gxiparam_h) $(gxgstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevplnx.$(OBJ) $(C_) $(GLSRC)gdevplnx.c ### Default driver procedure implementations @@ -1185,35 +1217,35 @@ $(GLOBJ)gdevdbit.$(OBJ) : $(GLSRC)gdevdbit.c $(AK) $(gx_h)\ $(gserrors_h) $(gpcheck_h)\ $(gdevmem_h) $(gsbittab_h) $(gsrect_h) $(gsropt_h)\ - $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(MAKEDIRS) + $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdbit.$(OBJ) $(C_) $(GLSRC)gdevdbit.c $(GLOBJ)gdevddrw.$(OBJ) : $(GLSRC)gdevddrw.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h) $(stdint__h) $(gpcheck_h) $(gsrect_h)\ - $(gxdcolor_h) $(gxdevice_h) $(gxfixed_h) $(gxiparam_h) $(gxistate_h)\ - $(gxmatrix_h) $(gxhldevc_h) $(gdevddrw_h) $(gxdtfill_h) $(vdtrace_h)\ - $(MAKEDIRS) + $(gxdcolor_h) $(gxdevice_h) $(gxfixed_h) $(gxiparam_h) $(gxgstate_h)\ + $(gxmatrix_h) $(gxhldevc_h) $(gdevddrw_h) $(gxdtfill_h) \ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevddrw.$(OBJ) $(C_) $(GLSRC)gdevddrw.c $(GLOBJ)gdevdsha.$(OBJ) : $(GLSRC)gdevdsha.c $(AK) $(gx_h)\ - $(gserrors_h) $(gxdevice_h) $(gxcindex_h) $(vdtrace_h)\ - $(gxdevsop_h) $(MAKEDIRS) + $(gserrors_h) $(gxdevice_h) $(gxcindex_h) \ + $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdsha.$(OBJ) $(C_) $(GLSRC)gdevdsha.c $(GLOBJ)gdevdflt.$(OBJ) : $(GLSRC)gdevdflt.c $(AK) $(gx_h)\ $(gserrors_h) $(gsropt_h) $(gxcomp_h) $(gxdevice_h) $(gxdevsop_h) $(math__h)\ - $(MAKEDIRS) + $(gsstruct_h) $(gxobj_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdflt.$(OBJ) $(C_) $(GLSRC)gdevdflt.c $(GLOBJ)gdevdgbr.$(OBJ) : $(GLSRC)gdevdgbr.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gxdevsop_h)\ $(gdevmem_h) $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) $(gxlum_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdgbr.$(OBJ) $(C_) $(GLSRC)gdevdgbr.c $(GLOBJ)gdevnfwd.$(OBJ) : $(GLSRC)gdevnfwd.c $(AK) $(gx_h)\ $(gserrors_h) $(gxdevice_h) $(gxcmap_h) $(memory__h) $(gxdevsop_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevnfwd.$(OBJ) $(C_) $(GLSRC)gdevnfwd.c # ---------------- Font API ---------------- # @@ -1222,33 +1254,34 @@ # stub for UFST bridge support : -$(GLD)gxfapiu.dev : $(LIB_MAK) $(ECHOGS_XE) +$(GLD)gxfapiu.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)gxfapiu -wrfont_h=$(stdpre_h) $(GLSRC)wrfont.h +wrfont_h=$(stdpre_h) $(std_h) $(GLSRC)wrfont.h write_t1_h=$(gxfapi_h) $(GLSRC)write_t1.h write_t2_h=$(gxfapi_h) $(GLSRC)write_t2.h $(GLOBJ)write_t1.$(OBJ) : $(GLSRC)write_t1.c $(AK)\ - $(wrfont_h) $(write_t1_h) + $(wrfont_h) $(write_t1_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(FT_CFLAGS) $(GLO_)write_t1.$(OBJ) $(C_) $(GLSRC)write_t1.c $(GLOBJ)write_t2.$(OBJ) : $(GLSRC)write_t2.c $(AK)\ - $(wrfont_h) $(write_t2_h) $(gxfont_h) $(gxfont1_h) $(gzstate_h) $(stdpre_h) + $(wrfont_h) $(write_t2_h) $(gxfont_h) $(gxfont1_h) $(gzstate_h) $(stdpre_h) \ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(FT_CFLAGS) $(GLO_)write_t2.$(OBJ) $(C_) $(GLSRC)write_t2.c $(GLOBJ)wrfont.$(OBJ) : $(GLSRC)wrfont.c $(AK)\ - $(wrfont_h) $(stdio__h) + $(wrfont_h) $(stdio__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(FT_CFLAGS) $(GLO_)wrfont.$(OBJ) $(C_) $(GLSRC)wrfont.c # stub for UFST bridge : -$(GLD)fapiu.dev : $(INT_MAK) $(ECHOGS_XE) +$(GLD)fapiu.dev : $(INT_MAK) $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)fapiu # stub for Bitstream bridge (see fapi_bs.mak): -$(GLD)fapib.dev : $(INT_MAK) $(ECHOGS_XE) +$(GLD)fapib.dev : $(INT_MAK) $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)fapib # FreeType bridge : @@ -1258,7 +1291,7 @@ $(GLD)fapif1.dev : $(INT_MAK) $(ECHOGS_XE) $(GLOBJ)fapi_ft.$(OBJ) \ $(GLOBJ)write_t1.$(OBJ) $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ) \ - $(GLD)freetype.dev + $(GLD)freetype.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)fapif1 $(GLOBJ)fapi_ft.$(OBJ) $(GLOBJ)write_t1.$(OBJ) $(ADDMOD) $(GLD)fapif1 $(GLOBJ)write_t2.$(OBJ) $(GLOBJ)wrfont.$(OBJ) $(ADDMOD) $(GLD)fapif1 -include $(GLD)freetype @@ -1267,23 +1300,23 @@ $(GLOBJ)fapi_ft.$(OBJ) : $(GLSRC)fapi_ft.c $(AK)\ $(stdio__h) $(malloc__h) $(write_t1_h) $(write_t2_h) $(math__h) $(gserrors_h)\ $(gsmemory_h) $(gsmalloc_h) $(gxfixed_h) $(gdebug_h) $(gxbitmap_h) $(gsmchunk_h) \ - $(stream_h) $(gxiodev_h) $(gsfname_h) $(gxfapi_h) + $(stream_h) $(gxiodev_h) $(gsfname_h) $(gxfapi_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(FT_CFLAGS) $(GLO_)fapi_ft.$(OBJ) $(C_) $(GLSRC)fapi_ft.c # stub for FreeType bridge : -$(GLD)fapif0.dev : $(INT_MAK) $(ECHOGS_XE) +$(GLD)fapif0.dev : $(INT_MAK) $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)fapif0 $(GLOBJ)gxfapi.$(OBJ) : $(GLSRC)gxfapi.c $(memory__h) $(gsmemory_h) $(gserrors_h) $(gxdevice_h) \ $(gxfont_h) $(gxfont1_h) $(gxpath_h) $(gxfcache_h) $(gxchrout_h) $(gximask_h) \ $(gscoord_h) $(gspaint_h) $(gspath_h) $(gzstate_h) $(gxfcid_h) $(gxchar_h) \ - $(gdebug_h) $(gsimage_h) $(gxfapi_h) $(gsbittab_h) + $(gdebug_h) $(gsimage_h) $(gxfapi_h) $(gsbittab_h) $(gzpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxfapi.$(OBJ) $(C_) $(GLSRC)gxfapi.c $(GLD)gxfapi.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLOBJ)gxfapi.$(OBJ) $(GLD)fapiu$(UFST_BRIDGE).dev \ - $(GLD)fapif$(FT_BRIDGE).dev $(GLD)fapib$(BITSTREAM_BRIDGE).dev + $(GLD)fapif$(FT_BRIDGE).dev $(GLD)fapib$(BITSTREAM_BRIDGE).dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)gxfapi $(GLOBJ)gxfapi.$(OBJ) $(ADDMOD) $(GLD)gxfapi -include $(GLD)fapiu$(UFST_BRIDGE) $(ADDMOD) $(GLD)gxfapi -include $(GLD)fapif$(FT_BRIDGE) @@ -1292,54 +1325,81 @@ ### Other device support # Provide a mapping between StandardEncoding and ISOLatin1Encoding. -$(GLOBJ)gdevemap.$(OBJ) : $(GLSRC)gdevemap.c $(AK) $(std_h) $(MAKEDIRS) +$(GLOBJ)gdevemap.$(OBJ) : $(GLSRC)gdevemap.c $(AK) $(std_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevemap.$(OBJ) $(C_) $(GLSRC)gdevemap.c +# ----------- Trapping routines ------------ # +claptrap_h=$(GLSRC)claptrap.h $(std_h) $(stdpre_h) +claptrap_impl_h=$(GLSRC)claptrap-impl.h +claptrap=$(GLOBJ)claptrap.$(OBJ) $(GLOBJ)claptrap-init.$(OBJ) \ + $(GLOBJ)claptrap-planar.$(OBJ) + +$(GLOBJ)claptrap.$(OBJ) : $(GLSRC)claptrap.c $(AK) \ + $(claptrap_h) $(claptrap_impl_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)claptrap.$(OBJ) $(C_) $(GLSRC)claptrap.c + +$(GLOBJ)claptrap-init.$(OBJ) : $(GLSRC)claptrap-init.c $(AK) \ + $(claptrap_h) $(claptrap_impl_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)claptrap-init.$(OBJ) $(C_) $(GLSRC)claptrap-init.c + +$(GLOBJ)claptrap-planar.$(OBJ) : $(GLSRC)claptrap-planar.c $(AK) \ + $(claptrap_h) $(claptrap_impl_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)claptrap-planar.$(OBJ) $(C_) $(GLSRC)claptrap-planar.c + +# ----------- ETS routines ------------ # +ets_h=$(GLSRC)ets.h +ets_impl_h=$(GLSRC)ets_tm.h +ets=$(GLOBJ)ets.$(OBJ) + +$(GLOBJ)ets.$(OBJ) : $(GLSRC)ets.c $(AK) \ + $(ets_h) $(ets_impl_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)ets.$(OBJ) $(C_) $(GLSRC)ets.c + # ----------- Downsampling routines ------------ # gxdownscale_h=$(GLSRC)gxdownscale.h $(gsmemory_h) $(gxdevcli_h) $(ctype__h) \ - $(gstypes_h) $(gxgetbit_h) -downscale_=$(GLOBJ)gxdownscale.$(OBJ) + $(gstypes_h) $(gxgetbit_h) $(claptrap_h) +downscale_=$(GLOBJ)gxdownscale.$(OBJ) $(claptrap) $(ets) -$(GLOBJ)gxdownscale.$(OBJ) : $(GLSRC)gxdownscale.c $(AK) \ - $(gxdownscale_h) $(gserrors_h) $(gdevprn_h) $(MAKEDIRS) +$(GLOBJ)gxdownscale.$(OBJ) : $(GLSRC)gxdownscale.c $(AK) $(string__h) \ + $(gxdownscale_h) $(gserrors_h) $(gdevprn_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxdownscale.$(OBJ) $(C_) $(GLSRC)gxdownscale.c ###### Create a pseudo-"feature" for the entire graphics library. LIB0s=$(GLOBJ)gpmisc.$(OBJ) $(GLOBJ)stream.$(OBJ) $(GLOBJ)strmio.$(OBJ) -LIB1s=$(GLOBJ)gsalloc.$(OBJ) $(GLOBJ)gsalpha.$(OBJ) $(GLOBJ)gxdownscale.$(OBJ) $(downscale_) $(GLOBJ)gdevprn.$(OBJ) -LIB2s=$(GLOBJ)gsbitcom.$(OBJ) $(GLOBJ)gsbitops.$(OBJ) $(GLOBJ)gsbittab.$(OBJ) +LIB1s=$(GLOBJ)gsalloc.$(OBJ) $(GLOBJ)gsalpha.$(OBJ) $(GLOBJ)gxdownscale.$(OBJ) $(downscale_) $(GLOBJ)gdevprn.$(OBJ) $(GLOBJ)gdevflp.$(OBJ) $(GLOBJ)gdevkrnlsclass.$(OBJ) $(GLOBJ)gdevepo.$(OBJ) +LIB2s=$(GLOBJ)gdevmplt.$(OBJ) $(GLOBJ)gsbitcom.$(OBJ) $(GLOBJ)gsbitops.$(OBJ) $(GLOBJ)gsbittab.$(OBJ) $(GLOBJ)gdevoflt.$(OBJ) $(GLOBJ)gdevsclass.$(OBJ) # Note: gschar.c is no longer required for a standard build; # we include it only for backward compatibility for library clients. LIB3s=$(GLOBJ)gscedata.$(OBJ) $(GLOBJ)gscencs.$(OBJ) $(GLOBJ)gschar.$(OBJ) $(GLOBJ)gscolor.$(OBJ) LIB4s=$(GLOBJ)gscoord.$(OBJ) $(GLOBJ)gscparam.$(OBJ) $(GLOBJ)gscspace.$(OBJ) $(GLOBJ)gscicach.$(OBJ) $(GLOBJ)gsovrc.$(OBJ) $(GLOBJ)gxoprect.$(OBJ) -LIB5s=$(GLOBJ)gsdevice.$(OBJ) $(GLOBJ)gsdevmem.$(OBJ) $(GLOBJ)gsdparam.$(OBJ) $(GLOBJ)gsdfilt.$(OBJ) +LIB5s=$(GLOBJ)gsdevice.$(OBJ) $(GLOBJ)gsdevmem.$(OBJ) $(GLOBJ)gsdparam.$(OBJ) LIB6s=$(GLOBJ)gsfname.$(OBJ) $(GLOBJ)gsfont.$(OBJ) $(GLOBJ)gsgdata.$(OBJ) $(GLOBJ)gsgcache.$(OBJ) -LIB7s=$(GLOBJ)gsht.$(OBJ) $(GLOBJ)gshtscr.$(OBJ) +LIB7s=$(GLOBJ)gsht.$(OBJ) $(GLOBJ)gshtscr.$(OBJ) $(GLOBJ)gen_ordered.$(OBJ) LIB8s=$(GLOBJ)gsimage.$(OBJ) $(GLOBJ)gsimpath.$(OBJ) $(GLOBJ)gsinit.$(OBJ) -LIB9s=$(GLOBJ)gsiodev.$(OBJ) $(GLOBJ)gsistate.$(OBJ) $(GLOBJ)gsline.$(OBJ) -LIB10s=$(GLOBJ)gsmalloc.$(OBJ) $(GLOBJ)memento.$(OBJ) $(GLOBJ)gsmatrix.$(OBJ) +LIB9s=$(GLOBJ)gsiodev.$(OBJ) $(GLOBJ)gsgstate.$(OBJ) $(GLOBJ)gsline.$(OBJ) +LIB10s=$(GLOBJ)gsmalloc.$(OBJ) $(GLOBJ)memento.$(OBJ) $(GLOBJ)bobbin.$(OBJ) $(GLOBJ)gsmatrix.$(OBJ) LIB11s=$(GLOBJ)gsmemory.$(OBJ) $(GLOBJ)gsmemret.$(OBJ) $(GLOBJ)gsmisc.$(OBJ) $(GLOBJ)gsnotify.$(OBJ) $(GLOBJ)gslibctx.$(OBJ) LIB12s=$(GLOBJ)gspaint.$(OBJ) $(GLOBJ)gsparam.$(OBJ) $(GLOBJ)gspath.$(OBJ) LIB13s=$(GLOBJ)gsserial.$(OBJ) $(GLOBJ)gsstate.$(OBJ) $(GLOBJ)gstext.$(OBJ)\ - $(GLOBJ)gsutil.$(OBJ) $(TRIOOBJS) $(GLOBJ)gssprintf.$(OBJ) + $(GLOBJ)gsutil.$(OBJ) $(GLOBJ)gssprintf.$(OBJ) $(GLOBJ)gsstrtok.$(OBJ) $(GLOBJ)gsstrl.$(OBJ) LIB1x=$(GLOBJ)gxacpath.$(OBJ) $(GLOBJ)gxbcache.$(OBJ) $(GLOBJ)gxccache.$(OBJ) LIB2x=$(GLOBJ)gxccman.$(OBJ) $(GLOBJ)gxchar.$(OBJ) $(GLOBJ)gxcht.$(OBJ) LIB3x=$(GLOBJ)gxclip.$(OBJ) $(GLOBJ)gxcmap.$(OBJ) $(GLOBJ)gxcpath.$(OBJ) LIB4x=$(GLOBJ)gxdcconv.$(OBJ) $(GLOBJ)gxdcolor.$(OBJ) $(GLOBJ)gxhldevc.$(OBJ) -LIB5x=$(GLOBJ)gxfill.$(OBJ) $(GLOBJ)gxfdrop.$(OBJ) $(GLOBJ)gxht.$(OBJ) $(GLOBJ)gxhtbit.$(OBJ)\ +LIB5x=$(GLOBJ)gxfill.$(OBJ) $(GLOBJ)gxht.$(OBJ) $(GLOBJ)gxhtbit.$(OBJ)\ $(GLOBJ)gxht_thresh.$(OBJ) -LIB6x=$(GLOBJ)gxidata.$(OBJ) $(GLOBJ)gxifast.$(OBJ) $(GLOBJ)gximage.$(OBJ) +LIB6x=$(GLOBJ)gxidata.$(OBJ) $(GLOBJ)gxifast.$(OBJ) $(GLOBJ)gximage.$(OBJ) $(GLOBJ)gximdecode.$(OBJ) LIB7x=$(GLOBJ)gximage1.$(OBJ) $(GLOBJ)gximono.$(OBJ) $(GLOBJ)gxipixel.$(OBJ) $(GLOBJ)gximask.$(OBJ) LIB8x=$(GLOBJ)gxi12bit.$(OBJ) $(GLOBJ)gxi16bit.$(OBJ) $(GLOBJ)gxiscale.$(OBJ) $(GLOBJ)gxpaint.$(OBJ) $(GLOBJ)gxpath.$(OBJ) $(GLOBJ)gxpath2.$(OBJ) LIB9x=$(GLOBJ)gxpcopy.$(OBJ) $(GLOBJ)gxpdash.$(OBJ) $(GLOBJ)gxpflat.$(OBJ) -LIB10x=$(GLOBJ)gxsample.$(OBJ) $(GLOBJ)gxstroke.$(OBJ) $(GLOBJ)gxsync.$(OBJ) $(GLOBJ)vdtrace.$(OBJ) +LIB10x=$(GLOBJ)gxsample.$(OBJ) $(GLOBJ)gxstroke.$(OBJ) $(GLOBJ)gxsync.$(OBJ) LIB1d=$(GLOBJ)gdevabuf.$(OBJ) $(GLOBJ)gdevdbit.$(OBJ) $(GLOBJ)gdevddrw.$(OBJ) $(GLOBJ)gdevdflt.$(OBJ) LIB2d=$(GLOBJ)gdevdgbr.$(OBJ) $(GLOBJ)gdevnfwd.$(OBJ) $(GLOBJ)gdevmem.$(OBJ) $(GLOBJ)gdevplnx.$(OBJ) LIB3d=$(GLOBJ)gdevm1.$(OBJ) $(GLOBJ)gdevm2.$(OBJ) $(GLOBJ)gdevm4.$(OBJ) $(GLOBJ)gdevm8.$(OBJ) LIB4d=$(GLOBJ)gdevm16.$(OBJ) $(GLOBJ)gdevm24.$(OBJ) $(GLOBJ)gdevm32.$(OBJ) $(GLOBJ)gdevmpla.$(OBJ) LIB5d=$(GLOBJ)gdevm40.$(OBJ) $(GLOBJ)gdevm48.$(OBJ) $(GLOBJ)gdevm56.$(OBJ) $(GLOBJ)gdevm64.$(OBJ) $(GLOBJ)gdevmx.$(OBJ) -LIB6d=$(GLOBJ)gdevdsha.$(OBJ) +LIB6d=$(GLOBJ)gdevdsha.$(OBJ) $(GLOBJ)gxscanc.$(OBJ) LIBs=$(LIB0s) $(LIB1s) $(LIB2s) $(LIB3s) $(LIB4s) $(LIB5s) $(LIB6s) $(LIB7s)\ $(LIB8s) $(LIB9s) $(LIB10s) $(LIB11s) $(LIB12s) $(LIB13s) LIBx=$(LIB1x) $(LIB2x) $(LIB3x) $(LIB4x) $(LIB5x) $(LIB6x) $(LIB7x) $(LIB8x) $(LIB9x) $(LIB10x) @@ -1349,7 +1409,7 @@ # but not in the link, to catch compilation problems. LIB_O=$(GLOBJ)gdevmpla.$(OBJ) $(GLOBJ)gdevmrun.$(OBJ) $(GLOBJ)gshtx.$(OBJ) $(GLOBJ)gsnogc.$(OBJ) $(GLD)libs.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBs) $(LIB_O) $(GLD)gsiodevs.dev $(GLD)translib.dev \ - $(GLD)clist.dev $(GLD)gxfapi.dev + $(GLD)clist.dev $(GLD)gxfapi.dev $(GLD)romfs1.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)libs $(LIB0s) $(ADDMOD) $(GLD)libs $(LIB1s) $(ADDMOD) $(GLD)libs $(LIB2s) @@ -1370,9 +1430,10 @@ $(ADDMOD) $(GLD)libs -include $(GLD)gsiodevs $(ADDMOD) $(GLD)libs -include $(GLD)translib $(ADDMOD) $(GLD)libs -include $(GLD)clist + $(ADDMOD) $(GLD)libs -include $(GLD)romfs1 $(ADDMOD) $(GLD)libs $(GLD)gxfapi $(ADDMOD) $(GLD)libs -init fapi -$(GLD)libx.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBx) +$(GLD)libx.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBx) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)libx $(LIB1x) $(ADDMOD) $(GLD)libx $(LIB2x) $(ADDMOD) $(GLD)libx $(LIB3x) @@ -1387,7 +1448,7 @@ $(ADDMOD) $(GLD)libx -imageclass 1_simple 3_mono $(ADDMOD) $(GLD)libx -imagetype 1 mask1 -$(GLD)libd.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBd) +$(GLD)libd.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIBd) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)libd $(LIB1d) $(ADDMOD) $(GLD)libd $(LIB2d) $(ADDMOD) $(GLD)libd $(LIB3d) @@ -1397,7 +1458,7 @@ $(GLD)libcore.dev : $(LIB_MAK) $(ECHOGS_XE)\ $(GLD)libs.dev $(GLD)libx.dev $(GLD)libd.dev\ - $(GLD)iscale.dev $(GLD)roplib.dev $(GLD)strdline.dev + $(GLD)iscale.dev $(GLD)roplib.dev $(GLD)strdline.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)libcore $(ADDMOD) $(GLD)libcore -dev2 nullpage $(ADDMOD) $(GLD)libcore -include $(GLD)libs $(GLD)libx $(GLD)libd @@ -1409,16 +1470,16 @@ # and file streams. $(GLOBJ)stream.$(OBJ) : $(GLSRC)stream.c $(AK) $(stdio__h) $(memory__h)\ - $(gdebug_h) $(gpcheck_h) $(stream_h) $(strimpl_h) $(MAKEDIRS) + $(gdebug_h) $(gpcheck_h) $(stream_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)stream.$(OBJ) $(C_) $(GLSRC)stream.c # Default, stream-based readline. strdline_=$(GLOBJ)gp_strdl.$(OBJ) -$(GLD)strdline.dev : $(LIB_MAK) $(ECHOGS_XE) $(strdline_) +$(GLD)strdline.dev : $(LIB_MAK) $(ECHOGS_XE) $(strdline_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)strdline $(strdline_) $(GLOBJ)gp_strdl.$(OBJ) : $(GLSRC)gp_strdl.c $(AK) $(std_h) $(gp_h)\ - $(gsmemory_h) $(gstypes_h) $(MAKEDIRS) + $(gsmemory_h) $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_strdl.$(OBJ) $(C_) $(GLSRC)gp_strdl.c # ---------------- File streams ---------------- # @@ -1428,26 +1489,26 @@ sfile_=$(GLOBJ)sfx$(FILE_IMPLEMENTATION).$(OBJ) $(GLOBJ)sfxcommon.$(OBJ)\ $(GLOBJ)stream.$(OBJ) -$(GLD)sfile.dev : $(LIB_MAK) $(ECHOGS_XE) $(sfile_) +$(GLD)sfile.dev : $(LIB_MAK) $(ECHOGS_XE) $(sfile_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sfile $(sfile_) $(GLOBJ)sfxcommon.$(OBJ) : $(GLSRC)sfxcommon.c $(AK) $(stdio__h)\ $(memory__h) $(unistd__h) $(gsmemory_h) $(gp_h) $(stream_h)\ - $(gserrors_h) $(MAKEDIRS) + $(gserrors_h) $(assert__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sfxcommon.$(OBJ) $(C_) $(GLSRC)sfxcommon.c $(GLOBJ)sfxstdio.$(OBJ) : $(GLSRC)sfxstdio.c $(AK) $(stdio__h)\ $(memory__h) $(unistd__h) $(gdebug_h) $(gpcheck_h) $(stream_h) $(strimpl_h)\ - $(gp_h) $(gserrors_h) $(gsmemory_h) $(MAKEDIRS) + $(gp_h) $(gserrors_h) $(gsmemory_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sfxstdio.$(OBJ) $(C_) $(GLSRC)sfxstdio.c $(GLOBJ)sfxfd.$(OBJ) : $(GLSRC)sfxfd.c $(AK)\ $(stdio__h) $(errno__h) $(memory__h) $(unistd__h)\ - $(gdebug_h) $(gpcheck_h) $(stream_h) $(strimpl_h) $(MAKEDIRS) + $(gdebug_h) $(gpcheck_h) $(stream_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sfxfd.$(OBJ) $(C_) $(GLSRC)sfxfd.c $(GLOBJ)sfxboth.$(OBJ) : $(GLSRC)sfxboth.c $(GLSRC)sfxstdio.c $(GLSRC)sfxfd.c\ - $(AK) $(MAKEDIRS) + $(AK) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sfxboth.$(OBJ) $(C_) $(GLSRC)sfxboth.c strmio_h=$(GLSRC)strmio.h @@ -1455,51 +1516,51 @@ $(GLOBJ)strmio.$(OBJ) : $(GLSRC)strmio.c $(AK) $(malloc__h)\ $(memory__h) $(gdebug_h) $(gsfname_h) $(gslibctx_h) $(gsstype_h)\ $(gsmalloc_h) $(gsmemret_h) $(strmio_h) $(stream_h) $(gxiodev_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)strmio.$(OBJ) $(C_) $(GLSRC)strmio.c # ---------------- BCP filters ---------------- # $(GLOBJ)sbcp.$(OBJ) : $(GLSRC)sbcp.c $(AK) $(stdio__h)\ - $(sbcp_h) $(strimpl_h) $(MAKEDIRS) + $(sbcp_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sbcp.$(OBJ) $(C_) $(GLSRC)sbcp.c # ---------------- CCITTFax filters ---------------- # # These are used by clists, some drivers, and Level 2 in general. cfe_=$(GLOBJ)scfe.$(OBJ) $(GLOBJ)scfetab.$(OBJ) $(GLOBJ)shc.$(OBJ) -$(GLD)cfe.dev : $(LIB_MAK) $(ECHOGS_XE) $(cfe_) +$(GLD)cfe.dev : $(LIB_MAK) $(ECHOGS_XE) $(cfe_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)cfe $(cfe_) $(GLOBJ)scfe.$(OBJ) : $(GLSRC)scfe.c $(AK) $(memory__h) $(stdio__h)\ - $(gdebug_h) $(scf_h) $(strimpl_h) $(scfx_h) $(MAKEDIRS) + $(gdebug_h) $(scf_h) $(strimpl_h) $(scfx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)scfe.$(OBJ) $(C_) $(GLSRC)scfe.c $(GLOBJ)scfetab.$(OBJ) : $(GLSRC)scfetab.c $(AK) $(std_h) $(scommon_h)\ - $(scf_h) $(MAKEDIRS) + $(scf_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)scfetab.$(OBJ) $(C_) $(GLSRC)scfetab.c $(GLOBJ)shc.$(OBJ) : $(GLSRC)shc.c $(AK) $(std_h) $(scommon_h) $(shc_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)shc.$(OBJ) $(C_) $(GLSRC)shc.c cfd_=$(GLOBJ)scfd.$(OBJ) $(GLOBJ)scfdtab.$(OBJ) -$(GLD)cfd.dev : $(LIB_MAK) $(ECHOGS_XE) $(cfd_) +$(GLD)cfd.dev : $(LIB_MAK) $(ECHOGS_XE) $(cfd_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)cfd $(cfd_) $(GLOBJ)scfd.$(OBJ) : $(GLSRC)scfd.c $(AK) $(memory__h) $(stdio__h)\ - $(gdebug_h) $(scf_h) $(strimpl_h) $(scfx_h) $(MAKEDIRS) + $(gdebug_h) $(scf_h) $(strimpl_h) $(scfx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)scfd.$(OBJ) $(C_) $(GLSRC)scfd.c $(GLOBJ)scfdtab.$(OBJ) : $(GLSRC)scfdtab.c $(AK) $(std_h) $(scommon_h)\ - $(scf_h) $(MAKEDIRS) + $(scf_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)scfdtab.$(OBJ) $(C_) $(GLSRC)scfdtab.c # scfparam is used by the filter operator and the PS/PDF writer. # It is not included automatically in cfe or cfd. $(GLOBJ)scfparam.$(OBJ) : $(GLSRC)scfparam.c $(AK) $(std_h)\ $(gserrors_h) $(gsmemory_h) $(gsparam_h) $(gstypes_h)\ - $(scommon_h) $(scf_h) $(scfx_h) $(MAKEDIRS) + $(scommon_h) $(scf_h) $(scfx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)scfparam.$(OBJ) $(C_) $(GLSRC)scfparam.c # ---------------- DCT (JPEG) filters ---------------- # @@ -1512,20 +1573,20 @@ sdctc_=$(GLOBJ)sdctc.$(OBJ) $(GLOBJ)sjpegc.$(OBJ) $(GLOBJ)sdctc.$(OBJ) : $(GLSRC)sdctc.c $(AK) $(stdio__h) $(jpeglib__h)\ - $(strimpl_h) $(sdct_h) $(MAKEDIRS) + $(strimpl_h) $(sdct_h) $(sjpeg_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sdctc.$(OBJ) $(C_) $(GLSRC)sdctc.c $(GLOBJ)sjpegc_1.$(OBJ) : $(GLSRC)sjpegc.c $(AK) $(stdio__h) $(string__h)\ $(gx_h) $(jpeglib__h) $(gconfig__h) \ - $(gserrors_h) $(sjpeg_h) $(sdct_h) $(strimpl_h) $(MAKEDIRS) + $(gserrors_h) $(sjpeg_h) $(sdct_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sjpegc_1.$(OBJ) $(C_) $(GLSRC)sjpegc.c $(GLOBJ)sjpegc_0.$(OBJ) : $(GLSRC)sjpegc.c $(AK) $(stdio__h) $(string__h)\ $(gx_h) $(jerror__h) $(jpeglib__h) $(gconfig__h) $(JSRCDIR)$(D)jmemsys.h\ - $(gserrors_h) $(sjpeg_h) $(sdct_h) $(strimpl_h) $(MAKEDIRS) + $(gserrors_h) $(sjpeg_h) $(sdct_h) $(strimpl_h) $(gsmchunk_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sjpegc_0.$(OBJ) $(C_) $(GLSRC)sjpegc.c -$(GLOBJ)sjpegc.$(OBJ) : $(GLOBJ)sjpegc_$(SHARE_JPEG).$(OBJ) +$(GLOBJ)sjpegc.$(OBJ) : $(GLOBJ)sjpegc_$(SHARE_JPEG).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)sjpegc_$(SHARE_JPEG).$(OBJ) $(GLOBJ)sjpegc.$(OBJ) # sdcparam is used by the filter operator and the PS/PDF writer. @@ -1533,198 +1594,215 @@ $(GLOBJ)sdcparam.$(OBJ) : $(GLSRC)sdcparam.c $(AK) $(memory__h)\ $(jpeglib__h)\ $(gserrors_h) $(gsmemory_h) $(gsparam_h) $(gstypes_h)\ - $(sdcparam_h) $(sdct_h) $(sjpeg_h) $(strimpl_h) $(MAKEDIRS) + $(sdcparam_h) $(sdct_h) $(sjpeg_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sdcparam.$(OBJ) $(C_) $(GLSRC)sdcparam.c # Encoding (compression) sdcte_=$(sdctc_) $(GLOBJ)sdcte.$(OBJ) $(GLOBJ)sjpege.$(OBJ) -$(GLD)sdcte.dev : $(LIB_MAK) $(ECHOGS_XE) $(sdcte_) $(JGENDIR)$(D)jpege.dev +$(GLD)sdcte.dev : $(LIB_MAK) $(ECHOGS_XE) $(sdcte_) $(JGENDIR)$(D)jpege.dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sdcte $(sdcte_) $(ADDMOD) $(GLD)sdcte -include $(JGENDIR)$(D)jpege.dev $(GLOBJ)sdcte_1.$(OBJ) : $(GLSRC)sdcte.c $(AK)\ $(memory__h) $(stdio__h) $(jpeglib__h)\ - $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(MAKEDIRS) + $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sdcte_1.$(OBJ) $(C_) $(GLSRC)sdcte.c $(GLOBJ)sdcte_0.$(OBJ) : $(GLSRC)sdcte.c $(AK)\ $(memory__h) $(stdio__h) $(jerror__h) $(jpeglib__h)\ - $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(MAKEDIRS) + $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sdcte_0.$(OBJ) $(C_) $(GLSRC)sdcte.c -$(GLOBJ)sdcte.$(OBJ) : $(GLOBJ)sdcte_$(SHARE_JPEG).$(OBJ) $(MAKEDIRS) +$(GLOBJ)sdcte.$(OBJ) : $(GLOBJ)sdcte_$(SHARE_JPEG).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)sdcte_$(SHARE_JPEG).$(OBJ) $(GLOBJ)sdcte.$(OBJ) $(GLOBJ)sjpege_1.$(OBJ) : $(GLSRC)sjpege.c $(AK)\ $(stdio__h) $(string__h) $(gx_h)\ $(jpeglib__h)\ - $(sjpeg_h) $(sdct_h) $(strimpl_h) $(MAKEDIRS) + $(sjpeg_h) $(sdct_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sjpege_1.$(OBJ) $(C_) $(GLSRC)sjpege.c $(GLOBJ)sjpege_0.$(OBJ) : $(GLSRC)sjpege.c $(AK)\ $(stdio__h) $(string__h) $(gx_h)\ $(jerror__h) $(jpeglib__h)\ - $(sjpeg_h) $(sdct_h) $(strimpl_h) $(MAKEDIRS) + $(sjpeg_h) $(sdct_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sjpege_0.$(OBJ) $(C_) $(GLSRC)sjpege.c -$(GLOBJ)sjpege.$(OBJ) : $(GLOBJ)sjpege_$(SHARE_JPEG).$(OBJ) $(MAKEDIRS) +$(GLOBJ)sjpege.$(OBJ) : $(GLOBJ)sjpege_$(SHARE_JPEG).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)sjpege_$(SHARE_JPEG).$(OBJ) $(GLOBJ)sjpege.$(OBJ) # sdeparam is used by the filter operator and the PS/PDF writer. # It is not included automatically in sdcte. sdeparam_=$(GLOBJ)sdeparam.$(OBJ) $(GLOBJ)sdcparam.$(OBJ) -$(GLD)sdeparam.dev : $(LIB_MAK) $(ECHOGS_XE) $(sdeparam_) +$(GLD)sdeparam.dev : $(LIB_MAK) $(ECHOGS_XE) $(sdeparam_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sdeparam $(sdeparam_) $(GLOBJ)sdeparam.$(OBJ) : $(GLSRC)sdeparam.c $(AK) $(memory__h)\ $(jpeglib__h)\ $(gserrors_h) $(gsmemory_h) $(gsparam_h) $(gstypes_h)\ - $(sdcparam_h) $(sdct_h) $(sjpeg_h) $(strimpl_h) $(MAKEDIRS) + $(sdcparam_h) $(sdct_h) $(sjpeg_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sdeparam.$(OBJ) $(C_) $(GLSRC)sdeparam.c # Decoding (decompression) sdctd_=$(sdctc_) $(GLOBJ)sdctd.$(OBJ) $(GLOBJ)sjpegd.$(OBJ) -$(GLD)sdctd.dev : $(LIB_MAK) $(ECHOGS_XE) $(sdctd_) $(JGENDIR)$(D)jpegd.dev +$(GLD)sdctd.dev : $(LIB_MAK) $(ECHOGS_XE) $(sdctd_) $(JGENDIR)$(D)jpegd.dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sdctd $(sdctd_) $(ADDMOD) $(GLD)sdctd -include $(JGENDIR)$(D)jpegd.dev $(GLOBJ)sdctd_1.$(OBJ) : $(GLSRC)sdctd.c $(AK)\ $(memory__h) $(stdio__h) $(jpeglib__h)\ - $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(MAKEDIRS) + $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sdctd_1.$(OBJ) $(C_) $(GLSRC)sdctd.c $(GLOBJ)sdctd_0.$(OBJ) : $(GLSRC)sdctd.c $(AK)\ $(memory__h) $(stdio__h) $(jerror__h) $(jpeglib__h)\ - $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(MAKEDIRS) + $(gdebug_h) $(gsmemory_h) $(strimpl_h) $(sdct_h) $(sjpeg_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sdctd_0.$(OBJ) $(C_) $(GLSRC)sdctd.c -$(GLOBJ)sdctd.$(OBJ) : $(GLOBJ)sdctd_$(SHARE_JPEG).$(OBJ) $(MAKEDIRS) +$(GLOBJ)sdctd.$(OBJ) : $(GLOBJ)sdctd_$(SHARE_JPEG).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)sdctd_$(SHARE_JPEG).$(OBJ) $(GLOBJ)sdctd.$(OBJ) $(GLOBJ)sjpegd_1.$(OBJ) : $(GLSRC)sjpegd.c $(AK)\ $(stdio__h) $(string__h) $(gx_h)\ $(jpeglib__h) $(gserrors_h)\ - $(sjpeg_h) $(sdct_h) $(strimpl_h) $(MAKEDIRS) + $(sjpeg_h) $(sdct_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sjpegd_1.$(OBJ) $(C_) $(GLSRC)sjpegd.c $(GLOBJ)sjpegd_0.$(OBJ) : $(GLSRC)sjpegd.c $(AK)\ $(stdio__h) $(string__h) $(gx_h)\ $(jerror__h) $(jpeglib__h)\ - $(sjpeg_h) $(sdct_h) $(strimpl_h) $(MAKEDIRS) + $(sjpeg_h) $(sdct_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLJCC) $(GLO_)sjpegd_0.$(OBJ) $(C_) $(GLSRC)sjpegd.c -$(GLOBJ)sjpegd.$(OBJ) : $(GLOBJ)sjpegd_$(SHARE_JPEG).$(OBJ) $(MAKEDIRS) +$(GLOBJ)sjpegd.$(OBJ) : $(GLOBJ)sjpegd_$(SHARE_JPEG).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)sjpegd_$(SHARE_JPEG).$(OBJ) $(GLOBJ)sjpegd.$(OBJ) +# One .dev for both encoding and decoding +$(GLD)sdct.dev: $(GLD)sdctd.dev $(GLD)sdcte.dev $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)sdct -include $(GLD)sdctd.dev $(GLD)sdcte.dev + # sddparam is used by the filter operator. # It is not included automatically in sdctd. sddparam_=$(GLOBJ)sddparam.$(OBJ) $(GLOBJ)sdcparam.$(OBJ) -$(GLD)sddparam.dev : $(LIB_MAK) $(ECHOGS_XE) $(sddparam_) +$(GLD)sddparam.dev : $(LIB_MAK) $(ECHOGS_XE) $(sddparam_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sddparam $(sddparam_) $(GLOBJ)sddparam.$(OBJ) : $(GLSRC)sddparam.c $(AK) $(std_h)\ $(jpeglib__h)\ $(gserrors_h) $(gsmemory_h) $(gsparam_h) $(gstypes_h)\ - $(sdcparam_h) $(sdct_h) $(sjpeg_h) $(strimpl_h) $(MAKEDIRS) + $(sdcparam_h) $(sdct_h) $(sjpeg_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sddparam.$(OBJ) $(C_) $(GLSRC)sddparam.c # ---------------- LZW filters ---------------- # # These are used by Level 2 in general. lzwe_=$(GLOBJ)slzwe.$(OBJ) $(GLOBJ)slzwc.$(OBJ) -$(GLD)lzwe.dev : $(LIB_MAK) $(ECHOGS_XE) $(lzwe_) +$(GLD)lzwe.dev : $(LIB_MAK) $(ECHOGS_XE) $(lzwe_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)lzwe $(lzwe_) # We need slzwe.dev as a synonym for lzwe.dev for BAND_LIST_STORAGE = memory. -$(GLD)slzwe.dev : $(GLD)lzwe.dev +$(GLD)slzwe.dev : $(GLD)lzwe.dev $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLD)lzwe.dev $(GLD)slzwe.dev $(GLOBJ)slzwe.$(OBJ) : $(GLSRC)slzwe.c $(AK) $(stdio__h) $(gdebug_h)\ - $(slzwx_h) $(strimpl_h) $(MAKEDIRS) + $(slzwx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)slzwe.$(OBJ) $(C_) $(GLSRC)slzwe.c $(GLOBJ)slzwc.$(OBJ) : $(GLSRC)slzwc.c $(AK) $(std_h)\ - $(slzwx_h) $(strimpl_h) $(MAKEDIRS) + $(slzwx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)slzwc.$(OBJ) $(C_) $(GLSRC)slzwc.c lzwd_=$(GLOBJ)slzwd.$(OBJ) $(GLOBJ)slzwc.$(OBJ) -$(GLD)lzwd.dev : $(LIB_MAK) $(ECHOGS_XE) $(lzwd_) +$(GLD)lzwd.dev : $(LIB_MAK) $(ECHOGS_XE) $(lzwd_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)lzwd $(lzwd_) # We need slzwd.dev as a synonym for lzwd.dev for BAND_LIST_STORAGE = memory. -$(GLD)slzwd.dev : $(GLD)lzwd.dev +$(GLD)slzwd.dev : $(GLD)lzwd.dev $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLD)lzwd.dev $(GLD)slzwd.dev $(GLOBJ)slzwd.$(OBJ) : $(GLSRC)slzwd.c $(AK) $(stdio__h) $(gdebug_h)\ - $(slzwx_h) $(strimpl_h) $(MAKEDIRS) + $(slzwx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)slzwd.$(OBJ) $(C_) $(GLSRC)slzwd.c # ---------------- MD5 digest filter ---------------- # smd5_=$(GLOBJ)smd5.$(OBJ) -$(GLD)smd5.dev : $(LIB_MAK) $(ECHOGS_XE) $(smd5_) $(md5_) +$(GLD)smd5.dev : $(LIB_MAK) $(ECHOGS_XE) $(smd5_) $(md5_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)smd5 $(smd5_) $(md5_) $(GLOBJ)smd5.$(OBJ) : $(GLSRC)smd5.c $(AK) $(memory__h)\ - $(smd5_h) $(strimpl_h) $(stream_h) $(MAKEDIRS) + $(smd5_h) $(strimpl_h) $(stream_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)smd5.$(OBJ) $(C_) $(GLSRC)smd5.c # -------------- SHA-256 digest filter -------------- # ssha2_h=$(GLSRC)ssha2.h $(sha2_h) ssha2_=$(GLOBJ)ssha2.$(OBJ) -$(GLD)ssha2.dev : $(LIB_MAK) $(ECHOGS_XE) $(ssha2_) $(sha2_) +$(GLD)ssha2.dev : $(LIB_MAK) $(ECHOGS_XE) $(ssha2_) $(sha2_) \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)ssha2 $(ssha2_) $(sha2_) $(GLOBJ)ssha2.$(OBJ) : $(GLSRC)ssha2.c $(AK) $(memory__h)\ - $(strimpl_h) $(stream_h) $(ssha2_h) $(MAKEDIRS) + $(strimpl_h) $(stream_h) $(ssha2_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ssha2.$(OBJ) $(C_) $(GLSRC)ssha2.c # -------------- Arcfour cipher filter --------------- # sarc4_=$(GLOBJ)sarc4.$(OBJ) -$(GLD)sarc4.dev : $(LIB_MAK) $(ECHOGS_XE) $(sarc4_) +$(GLD)sarc4.dev : $(LIB_MAK) $(ECHOGS_XE) $(sarc4_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sarc4 $(sarc4_) $(GLOBJ)sarc4.$(OBJ) : $(GLSRC)sarc4.c $(AK) $(memory__h)\ - $(gserrors_h) $(sarc4_h) $(strimpl_h) $(MAKEDIRS) + $(gserrors_h) $(sarc4_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sarc4.$(OBJ) $(C_) $(GLSRC)sarc4.c # -------------- AES cipher filter --------------- # saes_=$(GLOBJ)saes.$(OBJ) -$(GLD)saes.dev : $(LIB_MAK) $(ECHOGS_XE) $(saes_) $(aes_) +$(GLD)saes.dev : $(LIB_MAK) $(ECHOGS_XE) $(saes_) $(aes_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)saes $(saes_) $(aes_) $(GLOBJ)saes.$(OBJ) : $(GLSRC)saes.c $(AK) $(memory__h)\ - $(gserrors_h) $(strimpl_h) $(saes_h) $(MAKEDIRS) + $(gserrors_h) $(strimpl_h) $(saes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)saes.$(OBJ) $(C_) $(GLSRC)saes.c # ---------------- JBIG2 compression filter ---------------- # -$(GLD)sjbig2.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLD)sjbig2_$(JBIG2_LIB).dev +$(GLD)sjbig2.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLD)sjbig2_$(JBIG2_LIB).dev \ + $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLD)sjbig2_$(JBIG2_LIB).dev $(GLD)sjbig2.dev # jbig2dec version sjbig2_jbig2dec=$(GLOBJ)sjbig2.$(OBJ) $(GLD)sjbig2_jbig2dec.dev : $(LIB_MAK) $(ECHOGS_XE) \ - $(GLD)jbig2dec.dev $(sjbig2_jbig2dec) + $(GLD)jbig2dec.dev $(sjbig2_jbig2dec) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sjbig2_jbig2dec $(sjbig2_jbig2dec) $(ADDMOD) $(GLD)sjbig2_jbig2dec -include $(GLD)jbig2dec.dev +$(GLD)sjbig2_.dev : $(LIB_MAK) $(ECHOGS_XE) \ + $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)sjbig2_ + # jbig2dec.dev is defined in jbig2.mak $(GLOBJ)sjbig2.$(OBJ) : $(GLSRC)sjbig2.c $(AK) \ $(stdint__h) $(memory__h) $(stdio__h) $(gserrors_h) $(gdebug_h) \ - $(sjbig2_h) $(strimpl_h) $(MAKEDIRS) + $(sjbig2_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLJBIG2CC) $(GLO_)sjbig2.$(OBJ) $(C_) $(GLSRC)sjbig2.c +$(GLOBJ)snojbig2.$(OBJ) : $(GLSRC)snojbig2.c $(AK) \ + $(stdint__h) $(memory__h) $(stdio__h) $(gserrors_h) $(gdebug_h) \ + $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) + $(GLJBIG2CC) $(GLO_)snojbig2.$(OBJ) $(C_) $(GLSRC)snojbig2.c + # luratech version sjbig2_luratech=$(GLOBJ)sjbig2_luratech.$(OBJ) @@ -1737,121 +1815,149 @@ $(GLOBJ)sjbig2_luratech.$(OBJ) : $(GLSRC)sjbig2_luratech.c $(AK) \ $(memory__h) $(malloc__h) $(gserrors_h) $(gdebug_h) \ - $(strimpl_h) $(sjbig2_luratech_h) $(MAKEDIRS) + $(strimpl_h) $(sjbig2_luratech_h) $(LIB_MAK) $(MAKEDIRS) $(GLLDFJB2CC) $(GLO_)sjbig2_luratech.$(OBJ) \ $(C_) $(GLSRC)sjbig2_luratech.c # ---------------- JPEG 2000 compression filter ---------------- # -$(GLD)sjpx.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLD)sjpx_$(JPX_LIB).dev +$(GLD)sjpx.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLD)sjpx_$(JPX_LIB).dev $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLD)sjpx_$(JPX_LIB).dev $(GLD)sjpx.dev $(GLOBJ)sjpx.$(OBJ) : $(GLSRC)sjpx.c $(AK) \ $(memory__h) $(gsmalloc_h) \ - $(gdebug_h) $(strimpl_h) $(sjpx_h) $(MAKEDIRS) + $(gdebug_h) $(strimpl_h) $(sjpx_h) $(LIB_MAK) $(MAKEDIRS) $(GLJASCC) $(GLO_)sjpx.$(OBJ) $(C_) $(GLSRC)sjpx.c # luratech version sjpx_luratech=$(GLOBJ)sjpx_luratech.$(OBJ) $(GLD)sjpx_luratech.dev : $(LIB_MAK) $(ECHOGS_XE) \ - $(GLD)lwf_jp2.dev $(sjpx_luratech) + $(GLD)lwf_jp2.dev $(sjpx_luratech) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sjpx_luratech $(sjpx_luratech) $(ADDMOD) $(GLD)sjpx_luratech -include $(GLD)lwf_jp2.dev -$(GLD)luratech_jp2.dev : $(TOP_MAKEFILES) $(LIB_MAK) $(ECHOGS_XE) +$(GLD)luratech_jp2.dev : $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)luratech_jp2 $(GLD)liblwf_jp2.a $(GLOBJ)sjpx_luratech.$(OBJ) : $(GLSRC)sjpx_luratech.c $(AK) \ $(memory__h) $(gserrors_h) \ - $(gdebug_h) $(strimpl_h) $(sjpx_luratech_h) $(MAKEDIRS) + $(gdebug_h) $(strimpl_h) $(sjpx_luratech_h) $(LIB_MAK) $(MAKEDIRS) $(GLLWFJPXCC) $(GLO_)sjpx_luratech.$(OBJ) \ $(C_) $(GLSRC)sjpx_luratech.c # openjpeg version sjpx_openjpeg=$(GLOBJ)sjpx_openjpeg.$(OBJ) $(GLD)sjpx_openjpeg.dev : $(LIB_MAK) $(ECHOGS_XE) \ - $(GLD)openjpeg.dev $(sjpx_openjpeg) + $(GLD)openjpeg.dev $(sjpx_openjpeg) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sjpx_openjpeg $(sjpx_openjpeg) $(ADDMOD) $(GLD)sjpx_openjpeg -include $(GLD)openjpeg.dev $(GLOBJ)sjpx_openjpeg.$(OBJ) : $(GLSRC)sjpx_openjpeg.c $(AK) \ $(memory__h) $(gserror_h) $(gserrors_h) \ - $(gdebug_h) $(strimpl_h) $(sjpx_openjpeg_h) $(MAKEDIRS) + $(gdebug_h) $(strimpl_h) $(sjpx_openjpeg_h) $(LIB_MAK) $(MAKEDIRS) $(GLJPXOPJCC) $(GLO_)sjpx_openjpeg.$(OBJ) \ - $(C_) -DOPJ_STATIC $(GLSRC)sjpx_openjpeg.c + $(C_) $(GLSRC)sjpx_openjpeg.c + +# no jpx version +sjpx_none=$(GLOBJ)sjpx_none.$(OBJ) +$(GLD)sjpx_.dev : $(LIB_MAK) $(ECHOGS_XE) \ + $(sjpx_none) $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)sjpx_ $(sjpx_none) + +$(GLOBJ)sjpx_none.$(OBJ) : $(GLSRC)sjpx_none.c $(AK) \ + $(memory__h) $(LIB_MAK) $(MAKEDIRS) + $(GLJPXOPJCC) $(GLO_)sjpx_none.$(OBJ) $(C_) $(GLSRC)sjpx_none.c # ---------------- Pixel-difference filters ---------------- # # The Predictor facility of the LZW and Flate filters uses these. pdiff_=$(GLOBJ)spdiff.$(OBJ) -$(GLD)pdiff.dev : $(LIB_MAK) $(ECHOGS_XE) $(pdiff_) +$(GLD)pdiff.dev : $(LIB_MAK) $(ECHOGS_XE) $(pdiff_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)pdiff $(pdiff_) $(GLOBJ)spdiff.$(OBJ) : $(GLSRC)spdiff.c $(AK) $(memory__h) $(stdio__h)\ - $(spdiffx_h) $(strimpl_h) $(MAKEDIRS) + $(spdiffx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)spdiff.$(OBJ) $(C_) $(GLSRC)spdiff.c # ---------------- PNG pixel prediction filters ---------------- # # The Predictor facility of the LZW and Flate filters uses these. pngp_=$(GLOBJ)spngp.$(OBJ) -$(GLD)pngp.dev : $(LIB_MAK) $(ECHOGS_XE) $(pngp_) +$(GLD)pngp.dev : $(LIB_MAK) $(ECHOGS_XE) $(pngp_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)pngp $(pngp_) $(GLOBJ)spngp.$(OBJ) : $(GLSRC)spngp.c $(AK) $(memory__h)\ - $(spngpx_h) $(strimpl_h) $(MAKEDIRS) + $(spngpx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)spngp.$(OBJ) $(C_) $(GLSRC)spngp.c # ---------------- RunLength filters ---------------- # # These are used by clists and also by Level 2 in general. rle_=$(GLOBJ)srle.$(OBJ) -$(GLD)rle.dev : $(LIB_MAK) $(ECHOGS_XE) $(rle_) +$(GLD)rle.dev : $(LIB_MAK) $(ECHOGS_XE) $(rle_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)rle $(rle_) $(GLOBJ)srle.$(OBJ) : $(GLSRC)srle.c $(AK) $(stdio__h) $(memory__h)\ - $(srlx_h) $(strimpl_h) $(MAKEDIRS) + $(srlx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)srle.$(OBJ) $(C_) $(GLSRC)srle.c rld_=$(GLOBJ)srld.$(OBJ) -$(GLD)rld.dev : $(LIB_MAK) $(ECHOGS_XE) $(rld_) +$(GLD)rld.dev : $(LIB_MAK) $(ECHOGS_XE) $(rld_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)rld $(rld_) $(GLOBJ)srld.$(OBJ) : $(GLSRC)srld.c $(AK) $(stdio__h) $(memory__h)\ - $(srlx_h) $(strimpl_h) $(MAKEDIRS) + $(srlx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)srld.$(OBJ) $(C_) $(GLSRC)srld.c +# ---------------- PWG RunLength decode filter ---------------- # + +pwgd_=$(GLOBJ)spwgd.$(OBJ) +$(GLD)pwgd.dev : $(LIB_MAK) $(ECHOGS_XE) $(pwgd_) $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)pwgd $(pwgd_) + +$(GLOBJ)spwgd.$(OBJ) : $(GLSRC)spwgd.c $(AK) $(stdio__h) $(memory__h)\ + $(spwgx_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)spwgd.$(OBJ) $(C_) $(GLSRC)spwgd.c + # ---------------- String encoding/decoding filters ---------------- # # These are used by the PostScript and PDF writers, and also by the # PostScript interpreter. $(GLOBJ)sa85d.$(OBJ) : $(GLSRC)sa85d.c $(AK) $(std_h)\ - $(sa85d_h) $(scanchar_h) $(strimpl_h) $(MAKEDIRS) + $(sa85d_h) $(scanchar_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sa85d.$(OBJ) $(C_) $(GLSRC)sa85d.c $(GLOBJ)scantab.$(OBJ) : $(GLSRC)scantab.c $(AK) $(stdpre_h)\ - $(scanchar_h) $(scommon_h) $(MAKEDIRS) + $(scanchar_h) $(scommon_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)scantab.$(OBJ) $(C_) $(GLSRC)scantab.c $(GLOBJ)sfilter2.$(OBJ) : $(GLSRC)sfilter2.c $(AK) $(memory__h)\ $(stdio__h) $(gdebug_h) $(sa85x_h) $(scanchar_h) $(sbtx_h) $(strimpl_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sfilter2.$(OBJ) $(C_) $(GLSRC)sfilter2.c +$(GLOBJ)sfilter1.$(OBJ) : $(GLSRC)sfilter1.c $(AK) $(stdio__h) $(memory__h)\ + $(sfilter_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)sfilter1.$(OBJ) $(C_) $(GLSRC)sfilter1.c + +$(GLD)psfilters.dev : $(ECHOGS_XE) $(LIB_MAK) $(GLOBJ)sfilter2.$(OBJ)\ + $(GLOBJ)sfilter1.$(OBJ) $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)psfilters $(GLOBJ)sfilter1.$(OBJ) $(GLOBJ)sfilter2.$(OBJ) + $(GLOBJ)sstring.$(OBJ) : $(GLSRC)sstring.c $(AK)\ $(stdio__h) $(memory__h) $(string__h)\ - $(scanchar_h) $(sstring_h) $(strimpl_h) $(MAKEDIRS) + $(scanchar_h) $(sstring_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sstring.$(OBJ) $(C_) $(GLSRC)sstring.c $(GLOBJ)spprint.$(OBJ) : $(GLSRC)spprint.c $(AK)\ $(math__h) $(stdio__h) $(string__h)\ - $(spprint_h) $(stream_h) $(MAKEDIRS) + $(spprint_h) $(stream_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)spprint.$(OBJ) $(C_) $(GLSRC)spprint.c $(GLOBJ)spsdf.$(OBJ) : $(GLSRC)spsdf.c $(AK) $(stdio__h) $(string__h)\ $(gserrors_h) $(gsmemory_h) $(gstypes_h)\ $(sa85x_h) $(scanchar_h) $(spprint_h) $(spsdf_h)\ - $(sstring_h) $(stream_h) $(strimpl_h) $(MAKEDIRS) + $(sstring_h) $(stream_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)spsdf.$(OBJ) $(C_) $(GLSRC)spsdf.c # ---------------- zlib filters ---------------- # @@ -1863,74 +1969,97 @@ $(GLOBJ)szlibc_1.$(OBJ) : $(GLSRC)szlibc.c $(AK) $(std_h)\ $(gserrors_h) $(gsmemory_h) \ $(gsstruct_h) $(gstypes_h)\ - $(strimpl_h) $(szlibxx_h_1) $(MAKEDIRS) + $(strimpl_h) $(szlibxx_h_1) $(LIB_MAK) $(MAKEDIRS) $(GLZCC) $(GLO_)szlibc_1.$(OBJ) $(C_) $(GLSRC)szlibc.c $(GLOBJ)szlibc_0.$(OBJ) : $(GLSRC)szlibc.c $(AK) $(std_h)\ $(gserrors_h) $(gsmemory_h) $(zconf_h)\ $(gsstruct_h) $(gstypes_h) $(zlib_h)\ - $(strimpl_h) $(szlibxx_h_0) $(MAKEDIRS) + $(strimpl_h) $(szlibxx_h_0) $(LIB_MAK) $(MAKEDIRS) $(GLZCC) $(GLO_)szlibc_0.$(OBJ) $(C_) $(GLSRC)szlibc.c -$(GLOBJ)szlibc.$(OBJ) : $(GLOBJ)szlibc_$(SHARE_ZLIB).$(OBJ) $(MAKEDIRS) +$(GLOBJ)szlibc.$(OBJ) : $(GLOBJ)szlibc_$(SHARE_ZLIB).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)szlibc_$(SHARE_ZLIB).$(OBJ) $(GLOBJ)szlibc.$(OBJ) szlibe_=$(szlibc_) $(GLOBJ)szlibe.$(OBJ) -$(GLD)szlibe.dev : $(LIB_MAK) $(ECHOGS_XE) $(ZGENDIR)$(D)zlibe.dev $(szlibe_) +$(GLD)szlibe.dev : $(LIB_MAK) $(ECHOGS_XE) $(ZGENDIR)$(D)zlibe.dev $(szlibe_) \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)szlibe $(szlibe_) $(ADDMOD) $(GLD)szlibe -include $(ZGENDIR)$(D)zlibe.dev $(GLOBJ)szlibe_1.$(OBJ) : $(GLSRC)szlibe.c $(AK) $(std_h)\ - $(strimpl_h) $(szlibxx_h_1) $(MAKEDIRS) + $(strimpl_h) $(szlibxx_h_1) $(LIB_MAK) $(MAKEDIRS) $(GLZCC) $(GLO_)szlibe_1.$(OBJ) $(C_) $(GLSRC)szlibe.c $(GLOBJ)szlibe_0.$(OBJ) : $(GLSRC)szlibe.c $(AK) $(std_h)\ - $(strimpl_h) $(szlibxx_h_0) $(zlib_h) $(MAKEDIRS) + $(strimpl_h) $(szlibxx_h_0) $(zlib_h) $(LIB_MAK) $(MAKEDIRS) $(GLZCC) $(GLO_)szlibe_0.$(OBJ) $(C_) $(GLSRC)szlibe.c -$(GLOBJ)szlibe.$(OBJ) : $(GLOBJ)szlibe_$(SHARE_ZLIB).$(OBJ) $(MAKEDIRS) +$(GLOBJ)szlibe.$(OBJ) : $(GLOBJ)szlibe_$(SHARE_ZLIB).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)szlibe_$(SHARE_ZLIB).$(OBJ) $(GLOBJ)szlibe.$(OBJ) szlibd_=$(szlibc_) $(GLOBJ)szlibd.$(OBJ) -$(GLD)szlibd.dev : $(LIB_MAK) $(ECHOGS_XE) $(ZGENDIR)$(D)zlibd.dev $(szlibd_) +$(GLD)szlibd.dev : $(LIB_MAK) $(ECHOGS_XE) $(ZGENDIR)$(D)zlibd.dev $(szlibd_) \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)szlibd $(szlibd_) $(ADDMOD) $(GLD)szlibd -include $(ZGENDIR)$(D)zlibd.dev $(GLOBJ)szlibd_1.$(OBJ) : $(GLSRC)szlibd.c $(AK) $(std_h) $(memory__h)\ - $(strimpl_h) $(szlibxx_h_1) $(MAKEDIRS) + $(strimpl_h) $(szlibxx_h_1) $(LIB_MAK) $(MAKEDIRS) $(GLZCC) $(GLO_)szlibd_1.$(OBJ) $(C_) $(GLSRC)szlibd.c $(GLOBJ)szlibd_0.$(OBJ) : $(GLSRC)szlibd.c $(AK) $(std_h) $(memory__h)\ - $(strimpl_h) $(szlibxx_h_0) $(zlib_h) $(MAKEDIRS) + $(strimpl_h) $(szlibxx_h_0) $(zlib_h) $(LIB_MAK) $(MAKEDIRS) $(GLZCC) $(GLO_)szlibd_0.$(OBJ) $(C_) $(GLSRC)szlibd.c -$(GLOBJ)szlibd.$(OBJ) : $(GLOBJ)szlibd_$(SHARE_ZLIB).$(OBJ) $(MAKEDIRS) +$(GLOBJ)szlibd.$(OBJ) : $(GLOBJ)szlibd_$(SHARE_ZLIB).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)szlibd_$(SHARE_ZLIB).$(OBJ) $(GLOBJ)szlibd.$(OBJ) # ---------------- Page devices ---------------- # # We include this here, rather than in devs.mak, because it is more like # a feature than a simple device. -gdevprn_h=$(GLSRC)gdevprn.h $(memory__h) $(string__h) $(gp_h) $(gx_h)\ - $(gserrors_h) $(gsmatrix_h) $(gsparam_h) $(gsutil_h)\ - $(gxclist_h) $(gxdevice_h) $(gxdevmem_h) $(gxrplane_h) $(gxclthrd_h) +gdevprn_h=$(GLSRC)gdevprn.h $(gdevflp_h) $(gdevepo_h) $(gdevmplt_h) $(memory__h) $(string__h) $(gp_h) $(gx_h)\ + $(gserrors_h) $(gsmatrix_h) $(gsparam_h) $(gsutil_h) $(gxclpage_h)\ + $(gxclist_h) $(gxdevice_h) $(gxdevmem_h) $(gxrplane_h) $(gxclthrd_h) $(gxflp_h) $(gdevsclass_h)\ + $(gdevoflt_h) $(gdevkrnlsclass_h) + +page_=$(GLOBJ)gdevprn.$(OBJ) $(GLOBJ)gdevppla.$(OBJ) $(GLOBJ)gdevmplt.$(OBJ) $(GLOBJ)gdevflp.$(OBJ)\ + $(downscale_) $(GLOBJ)gdevoflt.$(OBJ) $(GLOBJ)gdevsclass.$(OBJ) $(GLOBJ)gdevepo.$(OBJ) -page_=$(GLOBJ)gdevprn.$(OBJ) $(downscale_) -$(GLD)page.dev : $(LIB_MAK) $(ECHOGS_XE) $(page_) +$(GLD)page.dev : $(LIB_MAK) $(ECHOGS_XE) $(page_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)page $(page_) $(ADDMOD) $(GLD)page -include $(GLD)clist $(GLOBJ)gdevprn.$(OBJ) : $(GLSRC)gdevprn.c $(ctype__h)\ $(gdevprn_h) $(gp_h) $(gsdevice_h) $(gsfname_h) $(gsparam_h)\ $(gxclio_h) $(gxgetbit_h) $(gdevplnx_h) $(gstrans_h) \ - $(gxdownscale_h) $(gdevdevn_h) + $(gxdownscale_h) $(gdevdevn_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevprn.$(OBJ) $(C_) $(GLSRC)gdevprn.c +$(GLOBJ)gdevmplt.$(OBJ) : $(GLSRC)gdevmplt.c $(gdevmplt_h) $(std_h) + $(GLCC) $(GLO_)gdevmplt.$(OBJ) $(C_) $(GLSRC)gdevmplt.c + +$(GLOBJ)gdevflp.$(OBJ) : $(GLSRC)gdevflp.c $(gdevflp_h) $(std_h) + $(GLCC) $(GLO_)gdevflp.$(OBJ) $(C_) $(GLSRC)gdevflp.c + +$(GLOBJ)gdevepo.$(OBJ) : $(GLSRC)gdevepo.c $(gdevepo_h) $(std_h) + $(GLCC) $(GLO_)gdevepo.$(OBJ) $(C_) $(GLSRC)gdevepo.c + +$(GLOBJ)gdevoflt.$(OBJ) : $(GLSRC)gdevoflt.c $(gdevoflp_h) $(std_h) + $(GLCC) $(GLO_)gdevoflt.$(OBJ) $(C_) $(GLSRC)gdevoflt.c + +$(GLOBJ)gdevsclass.$(OBJ) : $(GLSRC)gdevsclass.c $(gdevsclass_h) $(std_h) + $(GLCC) $(GLO_)gdevsclass.$(OBJ) $(C_) $(GLSRC)gdevsclass.c + +$(GLOBJ)gdevkrnlsclass.$(OBJ) : $(GLSRC)gdevkrnlsclass.c $(gdevkrnlsclass) $(std_h) + $(GLCC) $(GLO_)gdevkrnlsclass.$(OBJ) $(C_) $(GLSRC)gdevkrnlsclass.c + # Planar page devices gdevppla_h=$(GLSRC)gdevppla.h $(GLOBJ)gdevppla.$(OBJ) : $(GLSRC)gdevppla.c\ - $(gdevmpla_h) $(gdevppla_h) $(gdevprn_h) $(gxdevsop_h) + $(gdevmpla_h) $(gdevppla_h) $(gdevprn_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevppla.$(OBJ) $(C_) $(GLSRC)gdevppla.c # ---------------- Masked images ---------------- # @@ -1943,24 +2072,24 @@ gximage3_h=$(GLSRC)gximage3.h $(gsiparm3_h) $(gxiparam_h) $(GLOBJ)gxclipm.$(OBJ) : $(GLSRC)gxclipm.c $(AK) $(gx_h) $(memory__h)\ - $(gsbittab_h) $(gxclipm_h) $(gxdevice_h) $(gxdevmem_h) $(gxdcolor_h) $(MAKEDIRS) + $(gsbittab_h) $(gxclipm_h) $(gxdevice_h) $(gxdevmem_h) $(gxdcolor_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclipm.$(OBJ) $(C_) $(GLSRC)gxclipm.c $(GLOBJ)gximage3.$(OBJ) : $(GLSRC)gximage3.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h)\ $(gsbitops_h) $(gscspace_h) $(gsstruct_h)\ - $(gxclipm_h) $(gxdevice_h) $(gxdevmem_h) $(gximage3_h) $(gxistate_h)\ - $(MAKEDIRS) + $(gxclipm_h) $(gxdevice_h) $(gxdevmem_h) $(gximage3_h) $(gxgstate_h)\ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximage3.$(OBJ) $(C_) $(GLSRC)gximage3.c $(GLOBJ)gximage4.$(OBJ) : $(GLSRC)gximage4.c $(memory__h) $(AK)\ $(gx_h) $(gserrors_h)\ $(gscspace_h) $(gsiparm4_h) $(gxiparam_h) $(gximage_h)\ - $(stream_h) $(MAKEDIRS) + $(stream_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximage4.$(OBJ) $(C_) $(GLSRC)gximage4.c imasklib_=$(GLOBJ)gxclipm.$(OBJ) $(GLOBJ)gximage3.$(OBJ) $(GLOBJ)gximage4.$(OBJ) $(GLOBJ)gxmclip.$(OBJ) -$(GLD)imasklib.dev : $(LIB_MAK) $(ECHOGS_XE) $(imasklib_) +$(GLD)imasklib.dev : $(LIB_MAK) $(ECHOGS_XE) $(imasklib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)imasklib $(imasklib_) $(ADDMOD) $(GLD)imasklib -imagetype 3 4 @@ -1968,7 +2097,7 @@ gxcldev_h=$(GLSRC)gxcldev.h $(gxclist_h) $(gsropt_h) $(gxht_h) $(gxtmap_h) $(gxdht_h)\ $(strimpl_h) $(scfx_h) $(srlx_h) $(gsdcolor_h) -gxclpage_h=$(GLSRC)gxclpage.h $(gxclio_h) +gxclpage_h=$(GLSRC)gxclpage.h $(gxclist_h) gxclpath_h=$(GLSRC)gxclpath.h clbase1_=$(GLOBJ)gxclist.$(OBJ) $(GLOBJ)gxclbits.$(OBJ) $(GLOBJ)gxclpage.$(OBJ) @@ -1977,7 +2106,7 @@ # gxclrect.c requires rop_proc_table, so we need gsroptab here. clbase4_=$(GLOBJ)gsroptab.$(OBJ) $(GLOBJ)gsroprun.$(OBJ) $(GLOBJ)stream.$(OBJ) clpath_=$(GLOBJ)gxclimag.$(OBJ) $(GLOBJ)gxclpath.$(OBJ) $(GLOBJ)gxdhtserial.$(OBJ) -clthread_=$(GLOBJ)gxclthrd.$(OBJ) $(GLOBJ)gsmchunk.$(OBJ) $(GLOBJ)gsmemlok.$(OBJ) +clthread_=$(GLOBJ)gxclthrd.$(OBJ) $(GLOBJ)gsmchunk.$(OBJ) clist_=$(clbase1_) $(clbase2_) $(clbase3_) $(clbase4_) $(clpath_) $(clthread_) # The old code selected one of clmemory, clfile depending on BAND_LIST_STORAGE. @@ -1987,7 +2116,8 @@ $(GLD)clist.dev : $(LIB_MAK) $(ECHOGS_XE) $(clist_)\ $(GLD)cl$(BAND_LIST_STORAGE).dev $(GLD)clmemory.dev $(GLD)$(SYNC).dev\ - $(GLD)cfe.dev $(GLD)cfd.dev $(GLD)rle.dev $(GLD)rld.dev $(GLD)psl2cs.dev + $(GLD)cfe.dev $(GLD)cfd.dev $(GLD)rle.dev $(GLD)rld.dev $(GLD)psl2cs.dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)clist $(clbase1_) $(ADDMOD) $(GLD)clist -obj $(clbase2_) $(ADDMOD) $(GLD)clist -obj $(clbase3_) @@ -2001,17 +2131,18 @@ $(GLOBJ)gxclist.$(OBJ) : $(GLSRC)gxclist.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gp_h) $(gpcheck_h) $(gsparams_h) $(valgrind_h)\ $(gxcldev_h) $(gxclpath_h) $(gxdevice_h) $(gxdevmem_h) $(gxdcolor_h)\ - $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h) $(gxdevsop_h) $(MAKEDIRS) + $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclist.$(OBJ) $(C_) $(GLSRC)gxclist.c $(GLOBJ)gxclbits.$(OBJ) : $(GLSRC)gxclbits.c $(AK) $(gx_h)\ - $(gserrors_h) $(memory__h) $(gpcheck_h) $(gdevprn_h)\ + $(gserrors_h) $(memory__h) $(gpcheck_h) $(gdevprn_h) $(gxpcolor_h)\ $(gsbitops_h) $(gxcldev_h) $(gxdevice_h) $(gxdevmem_h) $(gxfmap_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclbits.$(OBJ) $(C_) $(GLSRC)gxclbits.c $(GLOBJ)gxclpage.$(OBJ) : $(GLSRC)gxclpage.c $(AK)\ - $(gdevprn_h) $(gxcldev_h) $(gxclpage_h) $(MAKEDIRS) + $(gdevprn_h) $(gdevdevn_h) $(gxcldev_h) $(gxclpage_h) $(gsicc_cache_h) $(string__h)\ + $(gsparams_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclpage.$(OBJ) $(C_) $(GLSRC)gxclpage.c $(GLOBJ)gxclrast.$(OBJ) : $(GLSRC)gxclrast.c $(AK) $(gx_h)\ @@ -2026,32 +2157,32 @@ $(stream_h) $(strimpl_h) $(gxcomp_h)\ $(gsserial_h) $(gxdhtserial_h) $(gzht_h)\ $(gxshade_h) $(gxshade4_h) $(gsicc_manage_h)\ - $(gsicc_h) $(MAKEDIRS) + $(gsicc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclrast.$(OBJ) $(C_) $(GLSRC)gxclrast.c $(GLOBJ)gxclread.$(OBJ) : $(GLSRC)gxclread.c $(AK) $(gx_h)\ - $(gserrors_h) $(memory__h) $(gp_h) $(gpcheck_h) $(gsmemlok_h)\ + $(gserrors_h) $(memory__h) $(gp_h) $(gpcheck_h)\ $(gdevplnx_h) $(gdevprn_h)\ $(gscoord_h) $(gsdevice_h)\ $(gxcldev_h) $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) $(gxhttile_h)\ $(gsmemory_h) \ - $(stream_h) $(strimpl_h) $(vdtrace_h) $(gsicc_cache_h) $(MAKEDIRS) + $(stream_h) $(strimpl_h) $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclread.$(OBJ) $(C_) $(GLSRC)gxclread.c $(GLOBJ)gxclrect.$(OBJ) : $(GLSRC)gxclrect.c $(AK) $(gx_h)\ $(gserrors_h)\ $(gsutil_h) $(gxcldev_h) $(gxdevice_h) $(gxdevmem_h) $(gxclpath_h)\ - $(gxdevsop_h) $(MAKEDIRS) + $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclrect.$(OBJ) $(C_) $(GLSRC)gxclrect.c $(GLOBJ)gxclimag.$(OBJ) : $(GLSRC)gxclimag.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h) $(string__h) $(gscdefs_h) $(gscspace_h)\ - $(gxarith_h) $(gxcldev_h) $(gxclpath_h) $(gxcspace_h)\ + $(gxarith_h) $(gxcldev_h) $(gxclpath_h) $(gxcspace_h) $(gxpcolor_h)\ $(gxdevice_h) $(gxdevmem_h) $(gxfmap_h) $(gxiparam_h) $(gxpath_h)\ $(sisparam_h) $(stream_h) $(strimpl_h) $(gxcomp_h) $(gsserial_h)\ $(gxdhtserial_h) $(gsptype1_h) $(gsicc_manage_h) $(gsicc_cache_h)\ - $(gxdevsop_h) $(gscindex_h) $(gsicc_cms_h) $(gxsample_h)\ - $(gximage_h) $(gxfrac_h) $(MAKEDIRS) + $(gxdevsop_h) $(gscindex_h) $(gsicc_cms_h) $(gximdecode_h)\ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclimag.$(OBJ) $(C_) $(GLSRC)gxclimag.c $(GLOBJ)gxclpath.$(OBJ) : $(GLSRC)gxclpath.c $(AK) $(gx_h)\ @@ -2059,35 +2190,37 @@ $(math__h) $(memory__h) $(gpcheck_h) $(gsptype2_h) $(gsptype1_h)\ $(gxdevice_h) $(gxdevmem_h) $(gxcldev_h) $(gxclpath_h) $(gxcolor2_h)\ $(gxdcolor_h) $(gxpaint_h) $(gxdevsop_h)\ - $(gzpath_h) $(gzcpath_h) $(stream_h) $(gsserial_h) $(MAKEDIRS) + $(gzpath_h) $(gzcpath_h) $(stream_h) $(gsserial_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclpath.$(OBJ) $(C_) $(GLSRC)gxclpath.c $(GLOBJ)gxdhtserial.$(OBJ) : $(GLSRC)gxdhtserial.c $(memory__h) $(AK)\ $(gx_h) $(gserrors_h)\ $(gscdefs_h) $(gsstruct_h) $(gsutil_h) $(gzstate_h) $(gxdevice_h) $(gzht_h)\ - $(gxdhtres_h) $(gsserial_h) $(gxdhtserial_h) $(MAKEDIRS) + $(gxdhtres_h) $(gsserial_h) $(gxdhtserial_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxdhtserial.$(OBJ) $(C_) $(GLSRC)gxdhtserial.c $(GLOBJ)gxclutil.$(OBJ) : $(GLSRC)gxclutil.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(string__h) $(gp_h) $(gpcheck_h) $(gsparams_h)\ - $(gxcldev_h) $(gxclpath_h) $(gxdevice_h) $(gxdevmem_h) $(MAKEDIRS) + $(gxcldev_h) $(gxclpath_h) $(gxdevice_h) $(gxdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclutil.$(OBJ) $(C_) $(GLSRC)gxclutil.c # Implement band lists on files. clfile_=$(GLOBJ)gxclfile.$(OBJ) -$(GLD)clfile.dev : $(LIB_MAK) $(ECHOGS_XE) $(clfile_) +$(GLD)clfile.dev : $(LIB_MAK) $(ECHOGS_XE) $(clfile_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)clfile $(clfile_) $(ADDMOD) $(GLD)clfile -init gxclfile $(GLOBJ)gxclfile.$(OBJ) : $(GLSRC)gxclfile.c $(stdio__h) $(string__h)\ - $(gp_h) $(gsmemory_h) $(gserrors_h) $(gxclio_h) $(unistd__h) $(valgrind_h) + $(gp_h) $(gsmemory_h) $(gserrors_h) $(gxclio_h) $(unistd__h) $(valgrind_h) \ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclfile.$(OBJ) $(C_) $(GLSRC)gxclfile.c # Implement band lists in memory (RAM). clmemory_=$(GLOBJ)gxclmem.$(OBJ) $(GLOBJ)gxcl$(BAND_LIST_COMPRESSOR).$(OBJ) -$(GLD)clmemory.dev : $(LIB_MAK) $(ECHOGS_XE) $(clmemory_) $(GLD)s$(BAND_LIST_COMPRESSOR)e.dev $(GLD)s$(BAND_LIST_COMPRESSOR)d.dev +$(GLD)clmemory.dev : $(LIB_MAK) $(ECHOGS_XE) $(clmemory_) $(GLD)s$(BAND_LIST_COMPRESSOR)e.dev \ + $(GLD)s$(BAND_LIST_COMPRESSOR)d.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)clmemory $(clmemory_) $(ADDMOD) $(GLD)clmemory -include $(GLD)s$(BAND_LIST_COMPRESSOR)e $(ADDMOD) $(GLD)clmemory -include $(GLD)s$(BAND_LIST_COMPRESSOR)d @@ -2096,17 +2229,17 @@ gxclmem_h=$(GLSRC)gxclmem.h $(gxclio_h) $(strimpl_h) $(GLOBJ)gxclmem.$(OBJ) : $(GLSRC)gxclmem.c $(AK) $(gx_h) $(gserrors_h)\ - $(LIB_MAK) $(memory__h) $(gxclmem_h) $(gssprintf_h) $(MAKEDIRS) $(valgrind_h) + $(LIB_MAK) $(memory__h) $(gxclmem_h) $(gssprintf_h) $(valgrind_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclmem.$(OBJ) $(C_) $(GLSRC)gxclmem.c # Implement the compression method for RAM-based band lists. $(GLOBJ)gxcllzw.$(OBJ) : $(GLSRC)gxcllzw.c $(std_h) $(AK)\ - $(gsmemory_h) $(gstypes_h) $(gxclmem_h) $(slzwx_h) $(MAKEDIRS) + $(gsmemory_h) $(gstypes_h) $(gxclmem_h) $(slzwx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxcllzw.$(OBJ) $(C_) $(GLSRC)gxcllzw.c $(GLOBJ)gxclzlib.$(OBJ) : $(GLSRC)gxclzlib.c $(std_h) $(AK)\ - $(gsmemory_h) $(gstypes_h) $(gxclmem_h) $(szlibx_h) $(MAKEDIRS) + $(gsmemory_h) $(gstypes_h) $(gxclmem_h) $(szlibx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclzlib.$(OBJ) $(C_) $(GLSRC)gxclzlib.c # Support for multi-threaded rendering from the clist. The chunk memory wrapper @@ -2114,25 +2247,26 @@ # memory allocator must implement the mutex (non-gc memory is usually gsmalloc) $(GLOBJ)gxclthrd.$(OBJ) : $(GLSRC)gxclthrd.c $(gxsync_h) $(AK)\ $(gxclthrd_h) $(gdevplnx_h) $(gdevprn_h) $(gp_h)\ - $(gpcheck_h) $(gsdevice_h) $(gserrors_h) $(gsmchunk_h) $(gsmemlok_h)\ + $(gpcheck_h) $(gsdevice_h) $(gserrors_h) $(gsmchunk_h)\ $(gsmemory_h) $(gx_h) $(gxcldev_h) $(gdevdevn_h) $(gsicc_cache_h)\ - $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) $(memory__h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) $(memory__h) $(gscms_h) $(gsicc_manage_h)\ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclthrd.$(OBJ) $(C_) $(GLSRC)gxclthrd.c $(GLOBJ)gsmchunk.$(OBJ) : $(GLSRC)gsmchunk.c $(AK) $(gx_h)\ $(gsstype_h) $(gserrors_h) $(gsmchunk_h) $(memory__h) $(gxsync_h) $(malloc__h)\ - $(MAKEDIRS) + $(gsstruct_h) $(gxobj_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsmchunk.$(OBJ) $(C_) $(GLSRC)gsmchunk.c # ---------------- Vector devices ---------------- # # We include this here for the same reasons as page.dev. -gdevvec_h=$(GLSRC)gdevvec.h $(gdevbbox_h) $(gp_h)\ - $(gsropt_h) $(gxdevice_h) $(gxiparam_h) $(gxistate_h) $(gxhldevc_h) $(stream_h) +gdevvec_h=$(GLSRC)gdevvec.h $(gdevbbox_h) $(gp_h) $(gdevflp_h) $(gdevepo_h) $(gdevoflt_h) $(gdevkrnlsclass_h)\ + $(gsropt_h) $(gxdevice_h) $(gxiparam_h) $(gxgstate_h) $(gxhldevc_h) $(stream_h) vector_=$(GLOBJ)gdevvec.$(OBJ) $(GLD)vector.dev : $(LIB_MAK) $(ECHOGS_XE) $(vector_)\ - $(GLD)bboxutil.dev $(GLD)sfile.dev + $(GLD)bboxutil.dev $(GLD)sfile.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)vector $(vector_) $(ADDMOD) $(GLD)vector -include $(GLD)bboxutil $(GLD)sfile @@ -2140,39 +2274,39 @@ $(math__h) $(memory__h) $(string__h)\ $(gdevvec_h) $(gp_h) $(gscspace_h) $(gxiparam_h) $(gsparam_h) $(gsutil_h)\ $(gxdcolor_h) $(gxfixed_h) $(gxpaint_h)\ - $(gzcpath_h) $(gzpath_h) $(MAKEDIRS) + $(gzcpath_h) $(gzpath_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevvec.$(OBJ) $(C_) $(GLSRC)gdevvec.c # ---------------- Image scaling filters ---------------- # iscale_=$(GLOBJ)siinterp.$(OBJ) $(GLOBJ)siscale.$(OBJ) $(GLOBJ)sidscale.$(OBJ) -$(GLD)iscale.dev : $(LIB_MAK) $(ECHOGS_XE) $(iscale_) +$(GLD)iscale.dev : $(LIB_MAK) $(ECHOGS_XE) $(iscale_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)iscale $(iscale_) $(GLOBJ)siinterp.$(OBJ) : $(GLSRC)siinterp.c $(AK)\ $(memory__h) $(gxdda_h) $(gxfixed_h) $(gxfrac_h)\ - $(siinterp_h) $(strimpl_h) $(MAKEDIRS) + $(siinterp_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)siinterp.$(OBJ) $(C_) $(GLSRC)siinterp.c $(GLOBJ)siscale.$(OBJ) : $(GLSRC)siscale.c $(AK)\ - $(math__h) $(memory__h) $(stdio__h) $(stdint__h) $(gdebug_h)\ - $(siscale_h) $(strimpl_h) $(MAKEDIRS) + $(math__h) $(memory__h) $(stdio__h) $(stdint__h) $(gdebug_h) $(gxfrac_h)\ + $(siscale_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)siscale.$(OBJ) $(C_) $(GLSRC)siscale.c $(GLOBJ)sidscale.$(OBJ) : $(GLSRC)sidscale.c $(AK)\ $(math__h) $(memory__h) $(stdio__h) $(gdebug_h) $(gxdda_h) $(gxfixed_h)\ - $(sidscale_h) $(strimpl_h) $(gxfrac_h) $(MAKEDIRS) + $(sidscale_h) $(strimpl_h) $(gxfrac_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)sidscale.$(OBJ) $(C_) $(GLSRC)sidscale.c # -------------- imagemask scaling filter --------------- # simscale_=$(GLOBJ)simscale.$(OBJ) -$(GLD)simscale.dev : $(LIB_MAK) $(ECHOGS_XE) $(simscale_) +$(GLD)simscale.dev : $(LIB_MAK) $(ECHOGS_XE) $(simscale_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)simscale $(simscale_) $(GLOBJ)simscale.$(OBJ) : $(GLSRC)simscale.c $(AK) $(memory__h)\ $(gserrors_h) $(simscale_h) $(strimpl_h) $(sisparam_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)simscale.$(OBJ) $(C_) $(GLSRC)simscale.c # ---------------- Extended halftone support ---------------- # @@ -2181,12 +2315,12 @@ gshtx_h=$(GLSRC)gshtx.h $(gsht1_h) $(gsmemory_h) $(gxtmap_h) $(gscspace_h) htxlib_=$(GLOBJ)gshtx.$(OBJ) -$(GLD)htxlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(htxlib_) +$(GLD)htxlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(htxlib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)htxlib $(htxlib_) $(GLOBJ)gshtx.$(OBJ) : $(GLSRC)gshtx.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsstruct_h) $(gsutil_h)\ - $(gxfmap_h) $(gshtx_h) $(gzht_h) $(gzstate_h) $(MAKEDIRS) + $(gxfmap_h) $(gshtx_h) $(gzht_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gshtx.$(OBJ) $(C_) $(GLSRC)gshtx.c # ----- Ternary raster operations and device level transparency ------# @@ -2195,7 +2329,7 @@ roplib2_=$(GLOBJ)gdevmr1.$(OBJ) $(GLOBJ)gdevmr2n.$(OBJ) $(GLOBJ)gdevmr8n.$(OBJ) roplib3_=$(GLOBJ)gdevrops.$(OBJ) $(GLOBJ)gsrop.$(OBJ) $(GLOBJ)gsroptab.$(OBJ) roplib_=$(roplib1_) $(roplib2_) $(roplib3_) -$(GLD)roplib.dev : $(LIB_MAK) $(ECHOGS_XE) $(roplib_) +$(GLD)roplib.dev : $(LIB_MAK) $(ECHOGS_XE) $(roplib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)roplib $(roplib1_) $(ADDMOD) $(GLD)roplib $(roplib2_) $(ADDMOD) $(GLD)roplib $(roplib3_) @@ -2204,70 +2338,47 @@ $(gserrors_h) $(memory__h) $(gxdevsop_h)\ $(gsbittab_h) $(gsropt_h)\ $(gxcindex_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdevrop_h)\ - $(gxgetbit_h) $(gdevmem_h) $(gdevmrop_h) $(gdevmpla_h) $(MAKEDIRS) + $(gxgetbit_h) $(gdevmem_h) $(gdevmrop_h) $(gdevmpla_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdrop.$(OBJ) $(C_) $(GLSRC)gdevdrop.c $(GLOBJ)gdevmr1.$(OBJ) : $(GLSRC)gdevmr1.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsbittab_h) $(gsropt_h)\ $(gxcindex_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdevrop_h)\ - $(gdevmem_h) $(gdevmrop_h) $(MAKEDIRS) + $(gdevmem_h) $(gdevmrop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevmr1.$(OBJ) $(C_) $(GLSRC)gdevmr1.c $(GLOBJ)gdevmr2n.$(OBJ) : $(GLSRC)gdevmr2n.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gsbittab_h) $(gsropt_h)\ $(gxcindex_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdevrop_h)\ - $(gdevmem_h) $(gdevmrop_h) $(MAKEDIRS) + $(gdevmem_h) $(gdevmrop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevmr2n.$(OBJ) $(C_) $(GLSRC)gdevmr2n.c $(GLOBJ)gdevmr8n.$(OBJ) : $(GLSRC)gdevmr8n.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gsbittab_h) $(gsropt_h)\ $(gxcindex_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxdevrop_h)\ - $(gdevmem_h) $(gdevmrop_h) $(vdtrace_h) $(MAKEDIRS) + $(gdevmem_h) $(gdevmrop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevmr8n.$(OBJ) $(C_) $(GLSRC)gdevmr8n.c $(GLOBJ)gdevrops.$(OBJ) : $(GLSRC)gdevrops.c $(AK) $(gx_h)\ - $(gserrors_h) $(gxdcolor_h) $(gxdevice_h) $(gdevmrop_h) $(MAKEDIRS) + $(gserrors_h) $(gxdcolor_h) $(gxdevice_h) $(gdevmrop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevrops.$(OBJ) $(C_) $(GLSRC)gdevrops.c $(GLOBJ)gsrop.$(OBJ) : $(GLSRC)gsrop.c $(AK) $(gx_h) $(gserrors_h)\ - $(gsrop_h) $(gzstate_h) $(MAKEDIRS) + $(gsrop_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsrop.$(OBJ) $(C_) $(GLSRC)gsrop.c $(GLOBJ)gsroptab.$(OBJ) : $(GLSRC)gsroptab.c $(AK) $(stdpre_h)\ - $(gsropt_h) $(MAKEDIRS) + $(gsropt_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsroptab.$(OBJ) $(C_) $(GLSRC)gsroptab.c gsroprun1_h=$(GLSRC)gsroprun1.h gsroprun8_h=$(GLSRC)gsroprun8.h gsroprun24_h=$(GLSRC)gsroprun24.h $(GLOBJ)gsroprun.$(OBJ) : $(GLSRC)gsroprun.c $(std_h) $(stdpre_h) $(gsropt_h)\ - $(gsroprun1_h) $(gsroprun8_h) $(gsroprun24_h) $(gp_h) $(arch_h) + $(gsroprun1_h) $(gsroprun8_h) $(gsroprun24_h) $(gp_h) $(arch_h) \ + $(gscindex_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsroprun.$(OBJ) $(C_) $(GLSRC)gsroprun.c -# ---------------- Async rendering ---------------- # - -gxpageq_h=$(GLSRC)gxpageq.h $(gsmemory_h) $(gxband_h) $(gxsync_h) -gdevprna_h=$(GLSRC)gdevprna.h $(gdevprn_h) $(gxsync_h) - -async_=$(GLOBJ)gdevprna.$(OBJ) $(GLOBJ)gxpageq.$(OBJ) $(GLOBJ)gsmemlok.$(OBJ) -async_inc=$(GLD)clist.dev $(GLD)gsnogc.dev $(GLD)$(SYNC).dev -$(GLD)async.dev : $(LIB_MAK) $(ECHOGS_XE) $(async_) $(async_inc) - $(SETMOD) $(GLD)async $(async_) - $(ADDMOD) $(GLD)async -include $(async_inc) - -$(GLOBJ)gdevprna.$(OBJ) : $(GLSRC)gdevprna.c $(AK) $(gdevprna_h)\ - $(gsalloc_h) $(gsdevice_h) $(gsmemlok_h) $(gsmemret_h) $(gsnogc_h)\ - $(gxcldev_h) $(gxclpath_h) $(gxpageq_h) $(gzht_h) $(MAKEDIRS) - $(GLCC) $(GLO_)gdevprna.$(OBJ) $(C_) $(GLSRC)gdevprna.c - -$(GLOBJ)gxpageq.$(OBJ) : $(GLSRC)gxpageq.c $(AK) $(gx_h) $(gserrors_h)\ - $(gsstruct_h) $(gxdevice_h) $(gxclist_h) $(gxpageq_h) $(MAKEDIRS) - $(GLCC) $(GLO_)gxpageq.$(OBJ) $(C_) $(GLSRC)gxpageq.c - -$(GLOBJ)gsmemlok.$(OBJ) : $(GLSRC)gsmemlok.c $(AK) $(gx_h)\ - $(gserrors_h) $(gsmemlok_h) $(MAKEDIRS) - $(GLCC) $(GLO_)gsmemlok.$(OBJ) $(C_) $(GLSRC)gsmemlok.c - # ---------------- TrueType and PostScript Type 42 fonts ---------------- # ttflib_=$(GLOBJ)gstype42.$(OBJ) $(GLOBJ)gxchrout.$(OBJ) \ @@ -2275,7 +2386,7 @@ $(GLOBJ)ttinterp.$(OBJ) $(GLOBJ)ttload.$(OBJ) $(GLOBJ)ttobjs.$(OBJ) \ $(GLOBJ)gxttfb.$(OBJ) $(GLOBJ)gzspotan.$(OBJ) -$(GLD)ttflib.dev : $(LIB_MAK) $(ECHOGS_XE) $(ttflib_) +$(GLD)ttflib.dev : $(LIB_MAK) $(ECHOGS_XE) $(ttflib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)ttflib $(ttflib_) # "gxfont42_h=$(GLSRC)gxfont42.h" already defined above @@ -2286,7 +2397,8 @@ $(gsccode_h) $(gsline_h) $(gsmatrix_h) $(gsstruct_h) $(gsutil_h)\ $(gxchrout_h) $(gxfixed_h) $(gxfont_h) $(gxfont42_h)\ $(gxpath_h) $(gxttf_h) $(gxttfb_h) $(gxtext_h) $(gxchar_h) $(gxfcache_h)\ - $(gxistate_h) $(gzstate_h) $(stream_h) $(stdint__h) $(MAKEDIRS) + $(gxgstate_h) $(gzstate_h) $(stream_h) $(stdint__h) \ + $(strimpl_h) $(stream_h) $(strmio_h) $(szlibx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gstype42.$(OBJ) $(C_) $(GLSRC)gstype42.c ttfsfnt_h=$(GLSRC)ttfsfnt.h $(stdint__h) @@ -2306,47 +2418,47 @@ gxhintn_h=$(GLSRC)gxhintn.h $(stdint__h) $(GLOBJ)ttcalc.$(OBJ) : $(GLSRC)ttcalc.c $(AK) $(ttmisc_h) $(ttcalc_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ttcalc.$(OBJ) $(C_) $(GLSRC)ttcalc.c $(GLOBJ)ttfinp.$(OBJ) : $(GLSRC)ttfinp.c $(AK) $(ttmisc_h)\ - $(ttfoutl_h) $(ttfsfnt_h) $(ttfinp_h) $(MAKEDIRS) + $(ttfoutl_h) $(ttfsfnt_h) $(ttfinp_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ttfinp.$(OBJ) $(C_) $(GLSRC)ttfinp.c $(GLOBJ)ttfmain.$(OBJ) : $(GLSRC)ttfmain.c $(AK) $(ttmisc_h) $(ttfinp_h)\ $(ttfoutl_h) $(ttfmemd_h) $(ttfsfnt_h) $(ttobjs_h) $(ttinterp_h) $(ttcalc_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ttfmain.$(OBJ) $(C_) $(GLSRC)ttfmain.c $(GLOBJ)ttfmemd.$(OBJ) : $(GLSRC)ttfmemd.c $(AK) $(ttmisc_h)\ - $(ttfmemd_h) $(ttfoutl_h) $(ttobjs_h) $(gsstruct_h) $(MAKEDIRS) + $(ttfmemd_h) $(ttfoutl_h) $(ttobjs_h) $(gsstruct_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ttfmemd.$(OBJ) $(C_) $(GLSRC)ttfmemd.c $(GLOBJ)ttinterp.$(OBJ) : $(GLSRC)ttinterp.c $(AK) $(ttmisc_h)\ $(ttfoutl_h) $(tttypes_h) $(ttcalc_h) $(ttinterp_h) $(ttfinp_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ttinterp.$(OBJ) $(C_) $(GLSRC)ttinterp.c $(GLOBJ)ttload.$(OBJ) : $(GLSRC)ttload.c $(AK) $(ttmisc_h)\ $(ttfoutl_h) $(tttypes_h) $(ttcalc_h) $(ttobjs_h) $(ttload_h) $(ttfinp_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ttload.$(OBJ) $(C_) $(GLSRC)ttload.c $(GLOBJ)ttobjs.$(OBJ) : $(GLSRC)ttobjs.c $(AK) $(ttmisc_h)\ $(ttfoutl_h) $(ttobjs_h) $(ttcalc_h) $(ttload_h) $(ttinterp_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)ttobjs.$(OBJ) $(C_) $(GLSRC)ttobjs.c $(GLOBJ)gxttfb.$(OBJ) : $(GLSRC)gxttfb.c $(AK) $(gx_h) $(gserrors_h) \ $(gxfixed_h) $(gxpath_h) $(gxfont_h) $(gxfont42_h) $(gxttfb_h) $(gxfcache_h)\ $(gxmatrix_h) $(gxhintn_h) $(gzpath_h) $(ttfmemd_h)\ $(gsstruct_h) $(gsfont_h) $(gdebug_h) $(memory__h) $(math__h)\ - $(gxistate_h) $(gxpaint_h) $(gzspotan_h) $(MAKEDIRS) + $(gxgstate_h) $(gxpaint_h) $(gzspotan_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxttfb.$(OBJ) $(C_) $(GLSRC)gxttfb.c $(GLOBJ)gzspotan.$(OBJ) : $(GLSRC)gzspotan.c $(AK) $(gx_h)\ $(gserrors_h) $(gsdevice_h) $(gzspotan_h) $(gxfixed_h) $(gxdevice_h)\ - $(gxfdrop_h) $(gzpath_h) $(memory__h) $(math__h) $(vdtrace_h) $(MAKEDIRS) + $(gzpath_h) $(memory__h) $(math__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gzspotan.$(OBJ) $(C_) $(GLSRC)gzspotan.c @@ -2360,54 +2472,57 @@ cidlib_=$(GLOBJ)gsfcid.$(OBJ) $(GLOBJ)gsfcid2.$(OBJ) # cidlib requires ttflib for CIDFontType 2 fonts. -$(GLD)cidlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cidlib_) $(GLD)ttflib.dev +$(GLD)cidlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cidlib_) $(GLD)ttflib.dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)cidlib $(cidlib_) $(ADDMOD) $(GLD)cidlib -include $(GLD)ttflib $(GLOBJ)gsfcid.$(OBJ) : $(GLSRC)gsfcid.c $(AK) $(gx_h) $(memory__h)\ - $(gsmatrix_h) $(gsstruct_h) $(gxfcid_h) $(gserrors_h) $(MAKEDIRS) + $(gsmatrix_h) $(gsstruct_h) $(gxfcid_h) $(gserrors_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfcid.$(OBJ) $(C_) $(GLSRC)gsfcid.c $(GLOBJ)gsfcid2.$(OBJ) : $(GLSRC)gsfcid2.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsstruct_h) $(gsutil_h) $(gxfcid_h) $(gxfcmap_h) $(gxfont_h)\ - $(gxfont0c_h) $(MAKEDIRS) + $(gxfont0c_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfcid2.$(OBJ) $(C_) $(GLSRC)gsfcid2.c cmaplib_=$(GLOBJ)gsfcmap.$(OBJ) $(GLOBJ)gsfcmap1.$(OBJ) -$(GLD)cmaplib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cmaplib_) $(GLD)cidlib.dev +$(GLD)cmaplib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cmaplib_) $(GLD)cidlib.dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)cmaplib $(cmaplib_) $(ADDMOD) $(GLD)cmaplib -include $(GLD)cidlib $(GLOBJ)gsfcmap.$(OBJ) : $(GLSRC)gsfcmap.c $(AK) $(gx_h) $(gserrors_h)\ - $(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxfcmap_h) $(MAKEDIRS) + $(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxfcmap_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfcmap.$(OBJ) $(C_) $(GLSRC)gsfcmap.c $(GLOBJ)gsfcmap1.$(OBJ) : $(GLSRC)gsfcmap1.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(string__h)\ - $(gsstruct_h) $(gsutil_h) $(gxfcmap1_h) $(MAKEDIRS) + $(gsstruct_h) $(gsutil_h) $(gxfcmap1_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfcmap1.$(OBJ) $(C_) $(GLSRC)gsfcmap1.c psf0lib_=$(GLOBJ)gschar0.$(OBJ) $(GLOBJ)gsfont0.$(OBJ) -$(GLD)psf0lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLD)cmaplib.dev $(psf0lib_) +$(GLD)psf0lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(GLD)cmaplib.dev $(psf0lib_) \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)psf0lib $(psf0lib_) $(ADDMOD) $(GLD)psf0lib -include $(GLD)cmaplib $(GLOBJ)gschar0.$(OBJ) : $(GLSRC)gschar0.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsfcmap_h) $(gsstruct_h)\ $(gxdevice_h) $(gxfcmap_h) $(gxfixed_h) $(gxfont_h) $(gxfont0_h)\ - $(gxfcid_h) $(gxtext_h) $(MAKEDIRS) + $(gxfcid_h) $(gxtext_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gschar0.$(OBJ) $(C_) $(GLSRC)gschar0.c $(GLOBJ)gsfont0.$(OBJ) : $(GLSRC)gsfont0.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsmatrix_h) $(gsstruct_h) $(gxfixed_h) $(gxdevmem_h)\ - $(gxfcache_h) $(gxfont_h) $(gxfont0_h) $(gxdevice_h) $(MAKEDIRS) + $(gxfcache_h) $(gxfont_h) $(gxfont0_h) $(gxdevice_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfont0.$(OBJ) $(C_) $(GLSRC)gsfont0.c # gsfont0c is not needed for the PS interpreter, other than for testing, # but it is used by pdfwrite and by the PCL interpreter. $(GLOBJ)gsfont0c.$(OBJ) : $(GLSRC)gsfont0c.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gxfont_h) $(gxfont0_h) $(gxfont0c_h)\ - $(gxfcid_h) $(gxfcmap_h) $(MAKEDIRS) + $(gxfcid_h) $(gxfcmap_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfont0c.$(OBJ) $(C_) $(GLSRC)gsfont0c.c # ---------------- Pattern color ---------------- # @@ -2426,7 +2541,7 @@ $(gsimage_h) $(gsiparm4_h) $(gspath_h) $(gsrop_h) $(gsstruct_h) $(gsutil_h)\ $(gxarith_h) $(gxcolor2_h) $(gxcoord_h) $(gxclip2_h) $(gxcspace_h)\ $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxfixed_h) $(gxmatrix_h)\ - $(gxpath_h) $(gxpcolor_h) $(gzstate_h) $(stream_h) $(MAKEDIRS) + $(gxpath_h) $(gxpcolor_h) $(gzstate_h) $(stream_h) $(gsovrc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gspcolor.$(OBJ) $(C_) $(GLSRC)gspcolor.c $(GLOBJ)gsptype1.$(OBJ) : $(GLSRC)gsptype1.c $(AK)\ @@ -2435,19 +2550,19 @@ $(gxarith_h) $(gxfixed_h) $(gxmatrix_h) $(gxcoord_h) $(gxcspace_h)\ $(gxcolor2_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h) $(gxclip2_h)\ $(gspath_h) $(gxpath_h) $(gxpcolor_h) $(gxp1impl_h) $(gxclist_h) $(gzstate_h)\ - $(gsimage_h) $(gsiparm4_h) $(gsovrc_h) $(MAKEDIRS) + $(gsimage_h) $(gsiparm4_h) $(gsovrc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsptype1.$(OBJ) $(C_) $(GLSRC)gsptype1.c $(GLOBJ)gxclip2.$(OBJ) : $(GLSRC)gxclip2.c $(AK) $(gx_h) $(gpcheck_h)\ $(gserrors_h) $(memory__h) $(gsstruct_h) $(gxclip2_h) $(gxdevice_h) $(gxdevmem_h)\ - $(gxdcolor_h) $(gdevmpla_h) $(MAKEDIRS) + $(gxdcolor_h) $(gdevmpla_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxclip2.$(OBJ) $(C_) $(GLSRC)gxclip2.c $(GLOBJ)gxp1fill.$(OBJ) : $(GLSRC)gxp1fill.c $(AK) $(gx_h)\ $(gserrors_h) $(string__h) $(math__h) $(gsrop_h) $(gsmatrix_h)\ $(gxcolor2_h) $(gxclip2_h) $(gxcspace_h) $(gxdcolor_h) $(gxdevcli_h)\ $(gxdevmem_h) $(gxpcolor_h) $(gxp1impl_h) $(gxcldev_h) $(gxblend_h)\ - $(gsicc_cache_h) $(gxdevsop_h) $(gdevp14_h) $(MAKEDIRS) + $(gsicc_cache_h) $(gxdevsop_h) $(gdevp14_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxp1fill.$(OBJ) $(C_) $(GLSRC)gxp1fill.c $(GLOBJ)gxpcmap.$(OBJ) : $(GLSRC)gxpcmap.c $(AK) $(gx_h) $(gserrors_h)\ @@ -2455,7 +2570,7 @@ $(gsstruct_h) $(gsutil_h) $(gp_h) \ $(gxcolor2_h) $(gxcspace_h) $(gxdcolor_h) $(gxdevice_h) $(gxdevmem_h)\ $(gxfixed_h) $(gxmatrix_h) $(gxpcolor_h) $(gxclist_h) $(gxcldev_h)\ - $(gzstate_h) $(gdevp14_h) $(gdevmpla_h) $(MAKEDIRS) + $(gzstate_h) $(gdevp14_h) $(gdevmpla_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxpcmap.$(OBJ) $(C_) $(GLSRC)gxpcmap.c # ---------------- PostScript Type 1 (and Type 4) fonts ---------------- # @@ -2471,21 +2586,21 @@ $(GLOBJ)gxtype1.$(OBJ) : $(GLSRC)gxtype1.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(gsccode_h) $(gsline_h) $(gsstruct_h) $(memory__h)\ $(gxarith_h) $(gxchrout_h) $(gxcoord_h) $(gxfixed_h) $(gxmatrix_h)\ - $(gxfont_h) $(gxfont1_h) $(gxistate_h) $(gxtype1_h)\ - $(gzpath_h) $(MAKEDIRS) + $(gxfont_h) $(gxfont1_h) $(gxgstate_h) $(gxtype1_h)\ + $(gzpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxtype1.$(OBJ) $(C_) $(GLSRC)gxtype1.c $(GLOBJ)gxhintn.$(OBJ) : $(GLSRC)gxhintn.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(math__h)\ $(gxfixed_h) $(gxarith_h) $(gstypes_h) $(gxmatrix_h)\ $(gxpath_h) $(gzpath_h) $(gxhintn_h) $(gxfont_h) $(gxfont1_h) $(gxtype1_h)\ - $(vdtrace_h) $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxhintn.$(OBJ) $(C_) $(GLSRC)gxhintn.c $(GLOBJ)gxhintn1.$(OBJ) : $(GLSRC)gxhintn1.c $(AK) $(gx_h)\ $(memory__h) $(math__h)\ $(gxfixed_h) $(gxarith_h) $(gstypes_h) $(gxmatrix_h)\ - $(gzpath_h) $(gxhintn_h) $(vdtrace_h) $(MAKEDIRS) + $(gzpath_h) $(gxhintn_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxhintn1.$(OBJ) $(C_) $(GLSRC)gxhintn1.c # CharString and eexec encryption @@ -2493,64 +2608,66 @@ # Note that seexec is not needed for rasterizing Type 1/2/4 fonts, # only for reading or writing them. seexec_=$(GLOBJ)seexec.$(OBJ) $(GLOBJ)gscrypt1.$(OBJ) -$(GLD)seexec.dev : $(LIB_MAK) $(ECHOGS_XE) $(seexec_) +$(GLD)seexec.dev : $(LIB_MAK) $(ECHOGS_XE) $(seexec_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)seexec $(seexec_) $(GLOBJ)seexec.$(OBJ) : $(GLSRC)seexec.c $(AK) $(stdio__h)\ - $(gscrypt1_h) $(scanchar_h) $(sfilter_h) $(strimpl_h) $(MAKEDIRS) + $(gscrypt1_h) $(scanchar_h) $(sfilter_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)seexec.$(OBJ) $(C_) $(GLSRC)seexec.c $(GLOBJ)gscrypt1.$(OBJ) : $(GLSRC)gscrypt1.c $(AK) $(stdpre_h)\ - $(gscrypt1_h) $(gstypes_h) $(std_h) $(MAKEDIRS) + $(gscrypt1_h) $(gstypes_h) $(std_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscrypt1.$(OBJ) $(C_) $(GLSRC)gscrypt1.c # Type 1 charstrings psf1lib_=$(GLOBJ)gstype1.$(OBJ) -$(GLD)psf1lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(psf1lib_) $(type1lib_) +$(GLD)psf1lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(psf1lib_) $(type1lib_) \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)psf1lib $(psf1lib_) $(ADDMOD) $(GLD)psf1lib $(type1lib_) $(GLOBJ)gstype1.$(OBJ) : $(GLSRC)gstype1.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h) $(gsstruct_h) $(gxhintn_h)\ $(gxarith_h) $(gxcoord_h) $(gxfixed_h) $(gxmatrix_h)\ - $(gxfont_h) $(gxfont1_h) $(gxistate_h) $(gxtype1_h)\ - $(gxpath_h) $(MAKEDIRS) + $(gxfont_h) $(gxfont1_h) $(gxgstate_h) $(gxtype1_h)\ + $(gxpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gstype1.$(OBJ) $(C_) $(GLSRC)gstype1.c # Type 2 charstrings psf2lib_=$(GLOBJ)gstype2.$(OBJ) -$(GLD)psf2lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(psf2lib_) $(type1lib_) +$(GLD)psf2lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(psf2lib_) $(type1lib_) \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)psf2lib $(psf2lib_) $(ADDMOD) $(GLD)psf2lib $(type1lib_) $(GLOBJ)gstype2.$(OBJ) : $(GLSRC)gstype2.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h) $(gsstruct_h)\ $(gxarith_h) $(gxcoord_h) $(gxfixed_h) $(gxmatrix_h)\ - $(gxfont_h) $(gxfont1_h) $(gxistate_h) $(gxtype1_h)\ - $(gxpath_h) $(gxhintn_h) $(MAKEDIRS) + $(gxfont_h) $(gxfont1_h) $(gxgstate_h) $(gxtype1_h)\ + $(gxpath_h) $(gxhintn_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gstype2.$(OBJ) $(C_) $(GLSRC)gstype2.c # -------- Level 1 color extensions (CMYK color and colorimage) -------- # cmyklib_=$(GLOBJ)gscolor1.$(OBJ) $(GLOBJ)gsht1.$(OBJ) -$(GLD)cmyklib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cmyklib_) +$(GLD)cmyklib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cmyklib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)cmyklib $(cmyklib_) $(GLOBJ)gscolor1.$(OBJ) : $(GLSRC)gscolor1.c $(AK) $(gx_h)\ $(gserrors_h) $(gsccolor_h) $(gscolor1_h) $(gsstruct_h) $(gsutil_h)\ $(gscolor2_h) $(gxcmap_h) $(gxcspace_h) $(gxdcconv_h) $(gxdevice_h) $(gzht_h)\ - $(gzstate_h) $(gxhttype_h) $(MAKEDIRS) + $(gzstate_h) $(gxhttype_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscolor1.$(OBJ) $(C_) $(GLSRC)gscolor1.c $(GLOBJ)gsht1.$(OBJ) : $(GLSRC)gsht1.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(string__h) $(gsstruct_h) $(gsutil_h) $(gxdevice_h) $(gzht_h)\ - $(gzstate_h) $(MAKEDIRS) + $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsht1.$(OBJ) $(C_) $(GLSRC)gsht1.c colimlib_=$(GLOBJ)gxicolor.$(OBJ) -$(GLD)colimlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(colimlib_) +$(GLD)colimlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(colimlib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)colimlib $(colimlib_) $(ADDMOD) $(GLD)colimlib -imageclass 4_color @@ -2559,38 +2676,38 @@ $(gxfixed_h) $(gxfrac_h) $(gxmatrix_h)\ $(gsccolor_h) $(gspaint_h) $(gzstate_h)\ $(gxdevice_h) $(gxcmap_h) $(gxdcconv_h) $(gxdcolor_h)\ - $(gxistate_h) $(gxdevmem_h) $(gxcpath_h) $(gximage_h)\ + $(gxgstate_h) $(gxdevmem_h) $(gxcpath_h) $(gximage_h)\ $(gsicc_h) $(gsicc_cache_h) $(gsicc_cms_h) $(gxcie_h)\ - $(gscie_h) $(gzht_h) $(gxht_thresh_h) $(gxdevsop_h) $(MAKEDIRS) + $(gscie_h) $(gzht_h) $(gxht_thresh_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxicolor.$(OBJ) $(C_) $(GLSRC)gxicolor.c # ---- Level 1 path miscellany (arcs, pathbbox, path enumeration) ---- # path1lib_=$(GLOBJ)gspath1.$(OBJ) -$(GLD)path1lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(path1lib_) +$(GLD)path1lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(path1lib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)path1lib $(path1lib_) $(GLOBJ)gspath1.$(OBJ) : $(GLSRC)gspath1.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(gscoord_h) $(gspath_h) $(gsstruct_h)\ $(gxfarith_h) $(gxfixed_h) $(gxmatrix_h) $(gzstate_h) $(gzpath_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gspath1.$(OBJ) $(C_) $(GLSRC)gspath1.c # --------------- Level 2 color space and color image support --------------- # psl2cs_=$(GLOBJ)gscolor2.$(OBJ) -$(GLD)psl2cs.dev : $(LIB_MAK) $(ECHOGS_XE) $(psl2cs_) +$(GLD)psl2cs.dev : $(LIB_MAK) $(ECHOGS_XE) $(psl2cs_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)psl2cs $(psl2cs_) $(GLOBJ)gscolor2.$(OBJ) : $(GLSRC)gscolor2.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h)\ $(gxarith_h) $(gxfixed_h) $(gxmatrix_h) $(gxcspace_h)\ $(gxcolor2_h) $(gzstate_h) $(gxpcolor_h) $(stream_h) $(gxcie_h)\ - $(gxfrac_h) $(MAKEDIRS) + $(gxfrac_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscolor2.$(OBJ) $(C_) $(GLSRC)gscolor2.c $(GLD)psl2lib.dev : $(LIB_MAK) $(ECHOGS_XE) \ - $(GLD)colimlib.dev $(GLD)psl2cs.dev + $(GLD)colimlib.dev $(GLD)psl2cs.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)psl2lib -include $(GLD)colimlib $(GLD)psl2cs $(ADDMOD) $(GLD)psl2lib -imageclass 2_fracs @@ -2598,22 +2715,22 @@ $(gserrors_h) $(math__h) $(memory__h) $(stdint__h) $(gpcheck_h)\ $(gsccolor_h) $(gspaint_h) $(sidscale_h) $(gxdevsop_h)\ $(gxarith_h) $(gxcmap_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h)\ - $(gxdevmem_h) $(gxfixed_h) $(gxfrac_h) $(gximage_h) $(gxistate_h)\ - $(gxmatrix_h) $(siinterp_h) $(siscale_h) $(stream_h) $(vdtrace_h)\ + $(gxdevmem_h) $(gxfixed_h) $(gxfrac_h) $(gximage_h) $(gxgstate_h)\ + $(gxmatrix_h) $(siinterp_h) $(siscale_h) $(stream_h) \ $(gscindex_h) $(gxcolor2_h) $(gscspace_h) $(gsicc_cache_h)\ - $(gsicc_manage_h) $(gsicc_h) $(MAKEDIRS) + $(gsicc_manage_h) $(gsicc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxiscale.$(OBJ) $(C_) $(GLSRC)gxiscale.c # ---------------- Display Postscript / Level 2 support ---------------- # dps2lib_=$(GLOBJ)gsdps1.$(OBJ) -$(GLD)dps2lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(dps2lib_) +$(GLD)dps2lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(dps2lib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)dps2lib $(dps2lib_) $(GLOBJ)gsdps1.$(OBJ) : $(GLSRC)gsdps1.c $(AK) $(gx_h) $(gserrors_h)\ $(gsmatrix_h) $(gscoord_h) $(gspaint_h) $(gxdevice_h) $(gsutil_h)\ $(math__h) $(gxfixed_h) $(gspath_h) $(gspath2_h) $(gxhldevc_h)\ - $(gzpath_h) $(gzcpath_h) $(gzstate_h) $(gxmatrix_h) $(gxdevsop_h) $(MAKEDIRS) + $(gzpath_h) $(gzcpath_h) $(gzstate_h) $(gxmatrix_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsdps1.$(OBJ) $(C_) $(GLSRC)gsdps1.c # ---------------- Functions ---------------- # @@ -2621,27 +2738,27 @@ # the implementation of Separation colors also uses them. gsdsrc_h=$(GLSRC)gsdsrc.h $(gsstruct_h) -gsfunc_h=$(GLSRC)gsfunc.h $(gstypes_h) +gsfunc_h=$(GLSRC)gsfunc.h $(gstypes_h) $(memento_h) gsfunc0_h=$(GLSRC)gsfunc0.h $(gsdsrc_h) $(gsfunc_h) gxfunc_h=$(GLSRC)gxfunc.h $(gsfunc_h) $(gsstruct_h) # Generic support, and FunctionType 0. funclib_=$(GLOBJ)gsdsrc.$(OBJ) $(GLOBJ)gsfunc.$(OBJ) $(GLOBJ)gsfunc0.$(OBJ) -$(GLD)funclib.dev : $(LIB_MAK) $(ECHOGS_XE) $(funclib_) +$(GLD)funclib.dev : $(LIB_MAK) $(ECHOGS_XE) $(funclib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)funclib $(funclib_) $(GLOBJ)gsdsrc.$(OBJ) : $(GLSRC)gsdsrc.c $(AK) $(gx_h) $(memory__h)\ - $(gsdsrc_h) $(gserrors_h) $(stream_h) $(MAKEDIRS) + $(gsdsrc_h) $(gserrors_h) $(stream_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsdsrc.$(OBJ) $(C_) $(GLSRC)gsdsrc.c $(GLOBJ)gsfunc.$(OBJ) : $(GLSRC)gsfunc.c $(AK) $(gx_h) $(memory__h)\ - $(gserrors_h) $(gsparam_h) $(gxfunc_h) $(stream_h) $(MAKEDIRS) + $(gserrors_h) $(gsparam_h) $(gxfunc_h) $(stream_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfunc.$(OBJ) $(C_) $(GLSRC)gsfunc.c $(GLOBJ)gsfunc0.$(OBJ) : $(GLSRC)gsfunc0.c $(AK) $(gx_h) $(math__h)\ $(gserrors_h) $(gsfunc0_h) $(gsparam_h) $(gxfarith_h) $(gxfunc_h) $(stream_h)\ $(gscolor_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfunc0.$(OBJ) $(C_) $(GLSRC)gsfunc0.c # FunctionType 4 may be is used for tintTransform and similar functions, @@ -2650,14 +2767,15 @@ gsfunc4_h=$(GLSRC)gsfunc4.h $(gsfunc_h) func4lib_=$(GLOBJ)gsfunc4.$(OBJ) $(GLOBJ)spprint.$(OBJ) -$(GLD)func4lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(func4lib_) $(GLD)funclib.dev +$(GLD)func4lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(func4lib_) $(GLD)funclib.dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)func4lib $(func4lib_) $(ADDMOD) $(GLD)func4lib -include $(GLD)funclib $(GLOBJ)gsfunc4.$(OBJ) : $(GLSRC)gsfunc4.c $(AK) $(gx_h) $(math__h)\ $(memory__h) $(gsdsrc_h) $(gserrors_h) $(gsfunc4_h)\ $(gxfarith_h) $(gxfunc_h) $(stream_h)\ - $(sfilter_h) $(spprint_h) $(strimpl_h) $(MAKEDIRS) + $(sfilter_h) $(spprint_h) $(strimpl_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfunc4.$(OBJ) $(C_) $(GLSRC)gsfunc4.c # ---------------- DevicePixel color space ---------------- # @@ -2665,13 +2783,14 @@ gscpixel_h=$(GLSRC)gscpixel.h cspixlib_=$(GLOBJ)gscpixel.$(OBJ) -$(GLD)cspixlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cspixlib_) +$(GLD)cspixlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cspixlib_) \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)cspixlib $(cspixlib_) $(GLOBJ)gscpixel.$(OBJ) : $(GLSRC)gscpixel.c $(AK) $(gx_h)\ $(gserrors_h) $(gsrefct_h) $(gxcspace_h) $(gscpixel_h) $(gxdevice_h)\ - $(gxistate_h) $(gsovrc_h) $(gsstate_h) $(gzstate_h) $(stream_h)\ - $(MAKEDIRS) + $(gxgstate_h) $(gsovrc_h) $(gsstate_h) $(gzstate_h) $(stream_h)\ + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscpixel.$(OBJ) $(C_) $(GLSRC)gscpixel.c # ---------------- CIE color ---------------- # @@ -2679,44 +2798,44 @@ cielib1_=$(GLOBJ)gscie.$(OBJ) $(GLOBJ)gsciemap.$(OBJ) $(GLOBJ)gscscie.$(OBJ) cielib2_=$(GLOBJ)gscrd.$(OBJ) $(GLOBJ)gscrdp.$(OBJ) $(GLOBJ)gxctable.$(OBJ) cielib_=$(cielib1_) $(cielib2_) -$(GLD)cielib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cielib_) +$(GLD)cielib.dev : $(LIB_MAK) $(ECHOGS_XE) $(cielib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)cielib $(cielib1_) $(ADDMOD) $(GLD)cielib $(cielib2_) $(GLOBJ)gscie.$(OBJ) : $(GLSRC)gscie.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h) $(gscolor2_h) $(gsmatrix_h) $(gsstruct_h)\ $(gxarith_h) $(gxcie_h) $(gxcmap_h) $(gxcspace_h) $(gxdevice_h) $(gzstate_h)\ - $(gsicc_h) $(MAKEDIRS) + $(gsicc_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscie.$(OBJ) $(C_) $(GLSRC)gscie.c $(GLOBJ)gsciemap.$(OBJ) : $(GLSRC)gsciemap.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h)\ $(gxarith_h) $(gxcie_h) $(gxcmap_h) $(gxcspace_h) $(gxdevice_h) \ - $(gxistate_h) $(gscolor2_h) $(gsicc_create_h) $(gsicc_manage_h)\ - $(gsicc_h) $(gscspace_h) $(MAKEDIRS) + $(gxgstate_h) $(gscolor2_h) $(gsicc_create_h) $(gsicc_manage_h)\ + $(gsicc_h) $(gscspace_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsciemap.$(OBJ) $(C_) $(GLSRC)gsciemap.c $(GLOBJ)gscrd.$(OBJ) : $(GLSRC)gscrd.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h) $(string__h)\ $(gscdefs_h) $(gscolor2_h) $(gscrd_h) $(gsdevice_h)\ $(gsmatrix_h) $(gsparam_h) $(gsstruct_h) $(gsutil_h) $(gxcspace_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscrd.$(OBJ) $(C_) $(GLSRC)gscrd.c $(GLOBJ)gscrdp.$(OBJ) : $(GLSRC)gscrdp.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h) $(string__h)\ $(gscolor2_h) $(gscrdp_h) $(gsdevice_h) $(gsmatrix_h) $(gsstruct_h)\ - $(gxarith_h) $(gxcspace_h) $(MAKEDIRS) + $(gxarith_h) $(gxcspace_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscrdp.$(OBJ) $(C_) $(GLSRC)gscrdp.c $(GLOBJ)gscscie.$(OBJ) : $(GLSRC)gscscie.c $(AK) $(gx_h) $(gserrors_h)\ - $(math__h) $(gscolor2_h) $(gsmatrix_h) $(gsstruct_h)\ + $(math__h) $(gscolor2_h) $(gsmatrix_h) $(gsstruct_h) $(gsicc_manage_h)\ $(gxarith_h) $(gxcie_h) $(gxcmap_h) $(gxcspace_h) $(gxdevice_h) $(gzstate_h)\ - $(stream_h) $(MAKEDIRS) + $(stream_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscscie.$(OBJ) $(C_) $(GLSRC)gscscie.c $(GLOBJ)gxctable.$(OBJ) : $(GLSRC)gxctable.c $(AK) $(gx_h)\ - $(gxfixed_h) $(gxfrac_h) $(gxctable_h) $(MAKEDIRS) + $(gxfixed_h) $(gxfrac_h) $(gxctable_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxctable.$(OBJ) $(C_) $(GLSRC)gxctable.c # ---------------- ICCBased color ---------------- # @@ -2727,16 +2846,17 @@ $(GLOBJ)gsicc_replacecm.$(OBJ) $(GLOBJ)gsicc_monitorcm.$(OBJ) sicclib_=$(GLOBJ)gsicc.$(OBJ) -$(GLD)sicclib.dev : $(LIB_MAK) $(ECHOGS_XE) $(sicclib_) $(gsicc_)\ - $(GLD)cielib.dev $(LCMSGENDIR)$(D)$(WHICH_CMS).dev +$(GLD)sicclib.dev : $(LIB_MAK) $(ECHOGS_XE) $(sicclib_) $(gsicc_) $(md5_)\ + $(GLD)cielib.dev $(LCMSGENDIR)$(D)$(WHICH_CMS).dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)sicclib $(sicclib_) $(ADDMOD) $(GLD)sicclib $(gsicc_) + $(ADDMOD) $(GLD)sicclib $(md5_) $(ADDMOD) $(GLD)sicclib -include $(LCMSGENDIR)$(D)$(WHICH_CMS).dev $(GLOBJ)gsicc.$(OBJ) : $(GLSRC)gsicc.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h) $(gsstruct_h) $(stream_h) $(gxcspace_h) $(gxarith_h)\ $(gxcie_h) $(gzstate_h) $(gsicc_h) $(gsicc_cache_h) $(gsicc_cms_h)\ - $(gsicc_manage_h) $(gxdevice_h) $(MAKEDIRS) + $(gsicc_manage_h) $(gxdevice_h) $(gsccolor_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc.$(OBJ) $(C_) $(GLSRC)gsicc.c gscms_h=$(GLSRC)gscms.h $(std_h) $(stdpre_h) $(gstypes_h) $(gsutil_h)\ @@ -2749,63 +2869,63 @@ $(GLOBJ)gsicc_monitorcm.$(OBJ) : $(GLSRC)gsicc_monitorcm.c $(AK) $(std_h)\ $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gxdevcli_h)\ $(gxcspace_h) $(gsicc_cms_h) $(gxcvalue_h)\ - $(gsicc_cache_h) $(gxdevsop_h) $(gdevp14_h) $(string__h) $(MAKEDIRS) + $(gsicc_cache_h) $(gxdevsop_h) $(gdevp14_h) $(string__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc_monitorcm.$(OBJ) $(C_) $(GLSRC)gsicc_monitorcm.c $(GLOBJ)gsicc_nocm.$(OBJ) : $(GLSRC)gsicc_nocm.c $(AK) $(std_h) $(gx_h)\ $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(scommon_h) $(strmio_h)\ - $(string__h) $(gxistate_h) $(gxcspace_h) $(gsicc_cms_h)\ - $(gsicc_cache_h) $(MAKEDIRS) + $(string__h) $(gxgstate_h) $(gxcspace_h) $(gsicc_cms_h)\ + $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc_nocm.$(OBJ) $(C_) $(GLSRC)gsicc_nocm.c $(GLOBJ)gsicc_replacecm.$(OBJ) : $(GLSRC)gsicc_replacecm.c $(AK) $(std_h) $(gx_h)\ $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(scommon_h) $(strmio_h)\ - $(string__h) $(gxistate_h) $(gxcspace_h) $(gsicc_cms_h)\ - $(gsicc_cache_h) $(MAKEDIRS) + $(string__h) $(gxgstate_h) $(gxcspace_h) $(gsicc_cms_h)\ + $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc_replacecm.$(OBJ) $(C_) $(GLSRC)gsicc_replacecm.c $(GLOBJ)gsicc_manage.$(OBJ) : $(GLSRC)gsicc_manage.c $(AK) $(gx_h)\ $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(scommon_h) $(strmio_h)\ - $(gxistate_h) $(gxcspace_h) $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h)\ + $(gxgstate_h) $(gxcspace_h) $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h)\ $(gsicc_profilecache_h) $(gserrors_h) $(string__h) $(gxclist_h) $(gxcldev_h)\ $(gzstate_h) $(gsicc_create_h) $(gpmisc_h) $(gxdevice_h) $(std_h)\ - $(gsicc_cms_h) $(gp_h) $(MAKEDIRS) + $(gsicc_cms_h) $(gp_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc_manage.$(OBJ) $(C_) $(GLSRC)gsicc_manage.c $(GLOBJ)gsicc_cache.$(OBJ) : $(GLSRC)gsicc_cache.c $(AK) $(gx_h)\ $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(scommon_h) $(smd5_h)\ - $(gxistate_h) $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h) $(gzstate_h)\ + $(gxgstate_h) $(gscms_h) $(gsicc_manage_h) $(gsicc_cache_h) $(gzstate_h)\ $(gserrors_h) $(gsmalloc_h) $(string__h) $(gxsync_h) $(std_h) $(gsicc_cms_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc_cache.$(OBJ) $(C_) $(GLSRC)gsicc_cache.c $(GLOBJ)gsicc_profilecache.$(OBJ) : $(GLSRC)gsicc_profilecache.c $(AK)\ $(std_h) $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(scommon_h)\ $(gscms_h) $(gsicc_profilecache_h) $(gzstate_h) $(gserrors_h) $(gx_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsicc_profilecache.$(OBJ) $(C_) $(GLSRC)gsicc_profilecache.c -$(GLOBJ)gsicc_lcms_1.$(OBJ) : $(GLSRC)gsicc_lcms.c\ - $(gsicc_cms_h) $(gslibctx_h) $(gserrors_h) - $(GLLCMSCC) $(GLO_)gsicc_lcms_1.$(OBJ) $(C_) $(GLSRC)gsicc_lcms.c - -$(GLOBJ)gsicc_lcms_0.$(OBJ) : $(GLSRC)gsicc_lcms.c\ - $(gsicc_cms_h) $(lcms_h) $(gslibctx_h) $(gserrors_h) - $(GLLCMSCC) $(GLO_)gsicc_lcms_0.$(OBJ) $(C_) $(GLSRC)gsicc_lcms.c - -$(GLOBJ)gsicc_lcms.$(OBJ) : $(GLOBJ)gsicc_lcms_$(SHARE_LCMS).$(OBJ) $(gp_h) - $(CP_) $(GLOBJ)gsicc_lcms_$(SHARE_LCMS).$(OBJ) $(GLOBJ)gsicc_lcms.$(OBJ) - - +$(GLOBJ)gsicc_lcms2mt_1.$(OBJ) : $(GLSRC)gsicc_lcms2mt.c\ + $(memory__h) $(gsicc_cms_h) $(gslibctx_h) $(gserrors_h) $(gxdevice_h) $(LIB_MAK) $(MAKEDIRS) + $(GLLCMS2MTCC) $(GLO_)gsicc_lcms2mt_1.$(OBJ) $(C_) $(GLSRC)gsicc_lcms2mt.c +$(GLOBJ)gsicc_lcms2mt_0.$(OBJ) : $(GLSRC)gsicc_lcms2mt.c\ + $(memory__h) $(gsicc_cms_h) $(lcms2mt_h) $(gslibctx_h) $(lcms2mt_plugin_h) $(gserrors_h) \ + $(gxdevice_h) $(LIB_MAK) $(MAKEDIRS) + $(GLLCMS2MTCC) $(GLO_)gsicc_lcms2mt_0.$(OBJ) $(C_) $(GLSRC)gsicc_lcms2mt.c +$(GLOBJ)gsicc_lcms2mt.$(OBJ) : $(GLOBJ)gsicc_lcms2mt_$(SHARE_LCMS).$(OBJ) $(gp_h) \ + $(gxsync_h) $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLOBJ)gsicc_lcms2mt_$(SHARE_LCMS).$(OBJ) $(GLOBJ)gsicc_lcms2mt.$(OBJ) $(GLOBJ)gsicc_lcms2_1.$(OBJ) : $(GLSRC)gsicc_lcms2.c\ - $(gsicc_cms_h) $(gslibctx_h) $(gserrors_h) + $(memory__h) $(gsicc_cms_h) $(gslibctx_h) $(gserrors_h) $(gxdevice_h) $(LIB_MAK) $(MAKEDIRS) $(GLLCMS2CC) $(GLO_)gsicc_lcms2_1.$(OBJ) $(C_) $(GLSRC)gsicc_lcms2.c $(GLOBJ)gsicc_lcms2_0.$(OBJ) : $(GLSRC)gsicc_lcms2.c\ - $(gsicc_cms_h) $(lcms2_h) $(gslibctx_h) $(lcms2_plugin_h) $(gserrors_h) + $(memory__h) $(gsicc_cms_h) $(lcms2_h) $(gslibctx_h) $(lcms2_plugin_h) $(gserrors_h) \ + $(gxdevice_h) $(LIB_MAK) $(MAKEDIRS) $(GLLCMS2CC) $(GLO_)gsicc_lcms2_0.$(OBJ) $(C_) $(GLSRC)gsicc_lcms2.c -$(GLOBJ)gsicc_lcms2.$(OBJ) : $(GLOBJ)gsicc_lcms2_$(SHARE_LCMS).$(OBJ) $(gp_h) +$(GLOBJ)gsicc_lcms2.$(OBJ) : $(GLOBJ)gsicc_lcms2_$(SHARE_LCMS).$(OBJ) $(gp_h) \ + $(gxsync_h) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)gsicc_lcms2_$(SHARE_LCMS).$(OBJ) $(GLOBJ)gsicc_lcms2.$(OBJ) # Note that gsicc_create requires compile with lcms to obtain icc34.h @@ -2814,18 +2934,18 @@ # This object is here instead of in psi since it is used lazily by the # remap operations. $(GLOBJ)gsicc_create_1.$(OBJ) : $(GLSRC)gsicc_create.c $(AK) $(string__h)\ - $(gsmemory_h) $(gx_h) $(gxistate_h) $(gstypes_h) $(gscspace_h)\ + $(gsmemory_h) $(gx_h) $(gxgstate_h) $(gstypes_h) $(gscspace_h)\ $(gscie_h) $(gsicc_create_h) $(gxarith_h) $(gsicc_manage_h) $(gsicc_cache_h)\ - $(math__h) $(gscolor2_h) $(gxcie_h) $(MAKEDIRS) - $(GLLCMSCC) $(GLO_)gsicc_create_1.$(OBJ) $(C_) $(GLSRC)gsicc_create.c + $(math__h) $(gscolor2_h) $(gxcie_h) $(LIB_MAK) $(MAKEDIRS) + $(GLLCMS2MTCC) $(GLO_)gsicc_create_1.$(OBJ) $(C_) $(GLSRC)gsicc_create.c $(GLOBJ)gsicc_create_0.$(OBJ) : $(GLSRC)gsicc_create.c $(AK) $(string__h)\ - $(gsmemory_h) $(gx_h) $(gxistate_h) $(gstypes_h) $(gscspace_h)\ + $(gsmemory_h) $(gx_h) $(gxgstate_h) $(gstypes_h) $(gscspace_h)\ $(gscie_h) $(gsicc_create_h) $(gxarith_h) $(gsicc_manage_h) $(gsicc_cache_h)\ - $(math__h) $(gscolor2_h) $(gxcie_h) $(icc34_h) $(MAKEDIRS) - $(GLLCMSCC) $(GLO_)gsicc_create_0.$(OBJ) $(C_) $(GLSRC)gsicc_create.c + $(math__h) $(gscolor2_h) $(gxcie_h) $(icc34_h) $(LIB_MAK) $(MAKEDIRS) + $(GLLCMS2MTCC) $(GLO_)gsicc_create_0.$(OBJ) $(C_) $(GLSRC)gsicc_create.c -$(GLOBJ)gsicc_create.$(OBJ) : $(GLOBJ)gsicc_create_$(SHARE_LCMS).$(OBJ) $(MAKEDIRS) +$(GLOBJ)gsicc_create.$(OBJ) : $(GLOBJ)gsicc_create_$(SHARE_LCMS).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)gsicc_create_$(SHARE_LCMS).$(OBJ) $(GLOBJ)gsicc_create.$(OBJ) @@ -2834,35 +2954,33 @@ # ---------------- Separation colors ---------------- # seprlib_=$(GLOBJ)gscsepr.$(OBJ) $(GLOBJ)gsnamecl.$(OBJ) $(GLOBJ)gsncdummy.$(OBJ) -$(GLD)seprlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(seprlib_) +$(GLD)seprlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(seprlib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)seprlib $(seprlib_) $(GLOBJ)gscsepr.$(OBJ) : $(GLSRC)gscsepr.c $(AK) $(gx_h) $(gserrors_h)\ $(memory__h) $(gsfunc_h) $(gsrefct_h) $(gsmatrix_h) $(gscsepr_h) $(gxcspace_h)\ $(gxfixed_h) $(gxcolor2_h) $(gzstate_h) $(gscdevn_h) $(gxcdevn_h)\ $(gxcmap_h) $(gxdevcli_h) $(gsovrc_h) $(stream_h) $(gsicc_cache_h) $(gxdevice_h)\ - $(MAKEDIRS) + $(gxcie_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscsepr.$(OBJ) $(C_) $(GLSRC)gscsepr.c $(GLOBJ)gsnamecl.$(OBJ) : $(GLSRC)gsnamecl.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gscspace_h) $(math__h) $(stdpre_h) $(gsutil_h)\ - $(gscdefs_h) $(gxdevice_h) $(gsnamecl_h) $(gzstate_h) $(MAKEDIRS) + $(gscdefs_h) $(gxdevice_h) $(gsnamecl_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsnamecl.$(OBJ) $(C_) $(GLSRC)gsnamecl.c $(GLOBJ)gsncdummy.$(OBJ) : $(GLSRC)gsncdummy.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(gxcspace_h) $(stdpre_h)\ $(memory__h) $(gscdefs_h) $(gscspace_h) $(gscie_h) $(gsicc_h)\ $(gxdevice_h) $(gzstate_h) $(gsutil_h) $(gxcie_h) $(gsncdummy_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsncdummy.$(OBJ) $(C_) $(GLSRC)gsncdummy.c -# ---------------- Color Buffer Proc. Support Used In Trans. ---------------- # +# ------------- Image Color Decode. Used in color mon and xpswrite --------- # -$(GLOBJ)gscolorbuffer.$(OBJ) : $(GLSRC)gscolorbuffer.c $(AK)\ - $(string__h)\ - $(stdpre_h) $(gstypes_h) $(gsmemory_h) $(gxblend_h) $(gscolorbuffer_h)\ - $(MAKEDIRS) - $(GLCC) $(GLO_)gscolorbuffer.$(OBJ) $(C_) $(GLSRC)gscolorbuffer.c +$(GLOBJ)gximdecode.$(OBJ) : $(GLSRC)gximdecode.c $(gximdecode_h) $(string__h)\ + $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)gximdecode.$(OBJ) $(C_) $(GLSRC)gximdecode.c # ================ Display Postscript extensions ================ # @@ -2872,20 +2990,21 @@ # Display PostScript needs the DevicePixel color space to implement # the PixelCopy option of ImageType 2 images. dpslib_=$(GLOBJ)gsdps.$(OBJ) $(GLOBJ)gximage2.$(OBJ) -$(GLD)dpslib.dev : $(LIB_MAK) $(ECHOGS_XE) $(dpslib_) $(GLD)cspixlib.dev +$(GLD)dpslib.dev : $(LIB_MAK) $(ECHOGS_XE) $(dpslib_) $(GLD)cspixlib.dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)dpslib $(dpslib_) $(ADDMOD) $(GLD)dpslib -imagetype 2 $(ADDMOD) $(GLD)dpslib -include $(GLD)cspixlib $(GLOBJ)gsdps.$(OBJ) : $(GLSRC)gsdps.c $(AK) $(gx_h)\ $(gsdps_h) $(gserrors_h) $(gspath_h)\ - $(gxdevice_h) $(gzcpath_h) $(gzpath_h) $(gzstate_h) $(MAKEDIRS) + $(gxdevice_h) $(gzcpath_h) $(gzpath_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsdps.$(OBJ) $(C_) $(GLSRC)gsdps.c $(GLOBJ)gximage2.$(OBJ) : $(GLSRC)gximage2.c $(AK) $(gx_h)\ $(math__h) $(memory__h) $(gserrors_h) $(gscolor2_h)\ $(gscpixel_h) $(gscoord_h) $(gscspace_h) $(gsdevice_h) $(gsiparm2_h)\ - $(gsmatrix_h) $(gxgetbit_h) $(gxiparam_h) $(gxpath_h) $(MAKEDIRS) + $(gsmatrix_h) $(gxgetbit_h) $(gxiparam_h) $(gxpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximage2.$(OBJ) $(C_) $(GLSRC)gximage2.c # ---------------- NeXT Display PostScript ---------------- # @@ -2896,14 +3015,14 @@ $(GLOBJ)gsalphac.$(OBJ) : $(GLSRC)gsalphac.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gsalphac_h) $(gsiparam_h) $(gsutil_h)\ $(gxalpha_h) $(gxcomp_h) $(gxdevice_h) $(gxgetbit_h) $(gxlum_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsalphac.$(OBJ) $(C_) $(GLSRC)gsalphac.c -$(GLOBJ)gximagec.$(OBJ) : $(GLSRC)gximagec.c $(AK) $(MAKEDIRS) +$(GLOBJ)gximagec.$(OBJ) : $(GLSRC)gximagec.c $(AK) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximagec.$(OBJ) $(C_) $(GLSRC)gximagec.c dpnxtlib_=$(GLOBJ)gsalphac.$(OBJ) -$(GLD)dpnxtlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(dpnxtlib_) +$(GLD)dpnxtlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(dpnxtlib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)dpnxtlib $(dpnxtlib_) $(ADDCOMP) $(GLD)dpnxtlib alpha @@ -2913,24 +3032,25 @@ $(memory__h) $(string__h) $(gsicc_h)\ $(gscdevn_h) $(gsfunc_h) $(gsmatrix_h) $(gsrefct_h) $(gsstruct_h)\ $(gxcspace_h) $(gxcdevn_h) $(gxfarith_h) $(gxfrac_h) $(gsnamecl_h) $(gxcmap_h)\ - $(gxistate_h) $(gscoord_h) $(gzstate_h) $(gxdevcli_h) $(gsovrc_h) $(stream_h)\ - $(gsicc_manage_h) $(gsicc_cache_h) $(gxdevice_h) $(MAKEDIRS) + $(gxgstate_h) $(gscoord_h) $(gzstate_h) $(gxdevcli_h) $(gsovrc_h) $(stream_h)\ + $(gsicc_manage_h) $(gsicc_cache_h) $(gxdevice_h) $(gxcie_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscdevn.$(OBJ) $(C_) $(GLSRC)gscdevn.c $(GLOBJ)gxdevndi.$(OBJ) : $(GLSRC)gxdevndi.c $(AK) $(gx_h)\ $(gsstruct_h) $(gsdcolor_h) $(gxfrac_h)\ - $(gxcmap_h) $(gxdevice_h) $(gxdither_h) $(gxlum_h) $(gzht_h) $(MAKEDIRS) + $(gxcmap_h) $(gxdevice_h) $(gxdither_h) $(gxlum_h) $(gzht_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxdevndi.$(OBJ) $(C_) $(GLSRC)gxdevndi.c $(GLOBJ)gsclipsr.$(OBJ) : $(GLSRC)gsclipsr.c $(AK) $(gx_h)\ $(gserrors_h) $(gsclipsr_h) $(gsstruct_h) $(gxclipsr_h) $(gxfixed_h)\ - $(gxpath_h) $(gzstate_h) $(MAKEDIRS) + $(gxpath_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsclipsr.$(OBJ) $(C_) $(GLSRC)gsclipsr.c psl3lib_=$(GLOBJ)gsclipsr.$(OBJ) $(GLOBJ)gscdevn.$(OBJ) $(GLOBJ)gxdevndi.$(OBJ) $(GLD)psl3lib.dev : $(LIB_MAK) $(ECHOGS_XE) $(psl3lib_)\ - $(GLD)imasklib.dev $(GLD)shadelib.dev $(GLD)gxfapiu$(UFST_BRIDGE).dev + $(GLD)imasklib.dev $(GLD)shadelib.dev $(GLD)gxfapiu$(UFST_BRIDGE).dev \ + $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)psl3lib $(psl3lib_) $(ADDMOD) $(GLD)psl3lib -include $(GLD)imasklib $(GLD)shadelib $(ADDMOD) $(GLD)psl3lib -include $(GLD)gxfapiu$(UFST_BRIDGE) @@ -2940,11 +3060,11 @@ gstrap_h=$(GLSRC)gstrap.h $(gsparam_h) $(GLOBJ)gstrap.$(OBJ) : $(GLSRC)gstrap.c $(AK) $(gx_h) $(gserrors_h)\ - $(string__h) $(gsparamx_h) $(gstrap_h) $(MAKEDIRS) + $(string__h) $(gsparamx_h) $(gstrap_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gstrap.$(OBJ) $(C_) $(GLSRC)gstrap.c traplib_=$(GLOBJ)gsparamx.$(OBJ) $(GLOBJ)gstrap.$(OBJ) -$(GLD)traplib.dev : $(LIB_MAK) $(ECHOGS_XE) $(traplib_) +$(GLD)traplib.dev : $(LIB_MAK) $(ECHOGS_XE) $(traplib_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)traplib $(traplib_) ### ------------------------ The DeviceN device ------------------------ ### @@ -2952,16 +3072,16 @@ devn_=$(GLOBJ)gdevdevn.$(OBJ) -$(DD)spotcmyk.dev : $(LIB_MAK) $(devn_) $(GLD)page.dev $(GDEV) +$(DD)spotcmyk.dev : $(LIB_MAK) $(devn_) $(GLD)page.dev $(GDEV) $(LIB_MAK) $(MAKEDIRS) $(SETDEV) $(DD)spotcmyk $(devn_) -$(DD)devicen.dev : $(LIB_MAK) $(devn_) $(GLD)page.dev $(GDEV) +$(DD)devicen.dev : $(LIB_MAK) $(devn_) $(GLD)page.dev $(GDEV) $(LIB_MAK) $(MAKEDIRS) $(SETDEV) $(DD)devicen $(devn_) $(GLOBJ)gdevdevn.$(OBJ) : $(GLSRC)gdevdevn.c $(gx_h) $(math__h) $(string__h)\ $(gdevprn_h) $(gsparam_h) $(gscrd_h) $(gscrdp_h) $(gxlum_h) $(gdevdcrd_h)\ $(gstypes_h) $(gxdcconv_h) $(gdevdevn_h) $(gsequivc_h) $(gdevp14_h)\ - $(gxblend_h) + $(gxblend_h) $(gdevdevnprn_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdevn.$(OBJ) $(C_) $(GLSRC)gdevdevn.c @@ -2970,13 +3090,13 @@ $(GLOBJ)gdevdcrd.$(OBJ) : $(GLSRC)gdevdcrd.c $(AK)\ $(math__h) $(memory__h) $(string__h)\ $(gscrd_h) $(gscrdp_h) $(gserrors_h) $(gsparam_h) $(gscspace_h)\ - $(gx_h) $(gxdevcli_h) $(gdevdcrd_h) + $(gx_h) $(gxdevcli_h) $(gdevdcrd_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevdcrd.$(OBJ) $(C_) $(GLSRC)gdevdcrd.c $(GLOBJ)gsequivc.$(OBJ) : $(GLSRC)gsequivc.c $(math__h)\ $(PDEVH) $(gsparam_h) $(gstypes_h) $(gxdconv_h) $(gdevdevn_h)\ $(gsequivc_h) $(gzstate_h) $(gsstate_h) $(gscspace_h) $(gxcspace_h)\ - $(gsicc_manage_h) $(gxdevsop_h) + $(gsicc_manage_h) $(gxdevsop_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsequivc.$(OBJ) $(C_) $(GLSRC)gsequivc.c @@ -2992,43 +3112,44 @@ $(math__h) $(memory__h) $(gdevp14_h) $(gstrans_h)\ $(gsutil_h) $(gxdevcli_h) $(gzstate_h) $(gscspace_h)\ $(gxclist_h) $(gsicc_manage_h) $(gdevdevn_h) $(gxarith_h) $(gxblend_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gstrans.$(OBJ) $(C_) $(GLSRC)gstrans.c $(GLOBJ)gximag3x.$(OBJ) : $(GLSRC)gximag3x.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h) $(gdevbbox_h)\ $(gsbitops_h) $(gscpixel_h) $(gscspace_h) $(gsstruct_h)\ - $(gxdevice_h) $(gxdevmem_h) $(gximag3x_h) $(gxistate_h) $(MAKEDIRS) + $(gxdevice_h) $(gxdevmem_h) $(gximag3x_h) $(gxgstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gximag3x.$(OBJ) $(C_) $(GLSRC)gximag3x.c $(GLOBJ)gxblend.$(OBJ) : $(GLSRC)gxblend.c $(AK) $(gx_h) $(memory__h)\ - $(gstparam_h) $(gxblend_h) $(gxcolor2_h) $(gsicc_cache_h)\ - $(gsicc_manage_h) $(gp_h) $(MAKEDIRS) + $(gstparam_h) $(gxblend_h) $(gxcolor2_h) $(gsicc_cache_h) $(gsrect_h)\ + $(gsicc_manage_h) $(gdevp14_h) $(gp_h) $(math__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxblend.$(OBJ) $(C_) $(GLSRC)gxblend.c $(GLOBJ)gxblend1.$(OBJ) : $(GLSRC)gxblend1.c $(AK) $(gx_h) $(memory__h)\ $(gstparam_h) $(gsrect_h) $(gxdcconv_h) $(gxblend_h) $(gxdevcli_h)\ - $(gxistate_h) $(gdevdevn_h) $(gdevp14_h) $(vdtrace_h) $(png__h) $(gp_h)\ - $(MAKEDIRS) + $(gxgstate_h) $(gdevdevn_h) $(gdevp14_h) $(png__h) $(gp_h)\ + $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxblend1.$(OBJ) $(C_) $(GLSRC)gxblend1.c $(GLOBJ)gdevp14.$(OBJ) : $(GLSRC)gdevp14.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(memory__h) $(gscdefs_h) $(gxdevice_h) $(gsdevice_h)\ - $(gsstruct_h) $(gscoord_h) $(gxistate_h) $(gxdcolor_h) $(gxiparam_h)\ - $(gstparam_h) $(gxblend_h) $(gxtext_h) $(gsdfilt_h) $(gsimage_h)\ - $(gsrect_h) $(gzstate_h) $(gdevdevn_h) $(gdevp14_h) $(gsovrc_h) $(gxcmap_h)\ + $(gsstruct_h) $(gscoord_h) $(gxgstate_h) $(gxdcolor_h) $(gxiparam_h)\ + $(gstparam_h) $(gxblend_h) $(gxtext_h) $(gsimage_h)\ + $(gsrect_h) $(gzstate_h) $(gdevdevn_h) $(gdevp14_h) $(gdevprn_h) $(gsovrc_h) $(gxcmap_h)\ $(gscolor1_h) $(gstrans_h) $(gsutil_h) $(gxcldev_h) $(gxclpath_h)\ - $(gxdcconv_h) $(vdtrace_h) $(gscolorbuffer_h) $(gsptype2_h) $(gxpcolor_h)\ + $(gxdcconv_h) $(gsptype2_h) $(gxpcolor_h)\ $(gsptype1_h) $(gzcpath_h) $(gxpaint_h) $(gsicc_manage_h) $(gxclist_h)\ $(gxiclass_h) $(gximage_h) $(gsmatrix_h) $(gsicc_cache_h) $(gxdevsop_h)\ - $(gsicc_h) $(MAKEDIRS) + $(gsicc_h) $(gscms_h) $(gdevmem_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevp14.$(OBJ) $(C_) $(GLSRC)gdevp14.c translib_=$(GLOBJ)gstrans.$(OBJ) $(GLOBJ)gximag3x.$(OBJ)\ $(GLOBJ)gxblend.$(OBJ) $(GLOBJ)gxblend1.$(OBJ) $(GLOBJ)gdevp14.$(OBJ) $(GLOBJ)gdevdevn.$(OBJ)\ - $(GLOBJ)gdevdcrd.$(OBJ) $(GLOBJ)gscolorbuffer.$(OBJ) + $(GLOBJ)gsequivc.$(OBJ) $(GLOBJ)gdevdcrd.$(OBJ) + $(GLD)translib.dev : $(LIB_MAK) $(ECHOGS_XE) $(translib_)\ - $(GLD)cspixlib.dev $(GLD)bboxutil.dev $(GLD)cielib.dev + $(GLD)cspixlib.dev $(GLD)bboxutil.dev $(GLD)cielib.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)translib $(translib_) $(ADDMOD) $(GLD)translib -imagetype 3x $(ADDMOD) $(GLD)translib -include $(GLD)cspixlib $(GLD)bboxutil @@ -3047,114 +3168,225 @@ $(GLOBJ)gscolor3.$(OBJ) : $(GLSRC)gscolor3.c $(AK) $(gx_h)\ $(gserrors_h) $(gscolor3_h) $(gsmatrix_h) $(gsptype2_h) $(gscie_h)\ $(gxdevsop_h) $(gxcolor2_h) $(gxcspace_h) $(gxpaint_h) $(gxdcolor_h)\ - $(gxpcolor_h) $(gxshade_h) $(gzpath_h) $(gzstate_h) $(MAKEDIRS) + $(gxpcolor_h) $(gxshade_h) $(gzpath_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gscolor3.$(OBJ) $(C_) $(GLSRC)gscolor3.c $(GLOBJ)gsfunc3.$(OBJ) : $(GLSRC)gsfunc3.c $(AK) $(gx_h) $(gserrors_h)\ $(gsfunc3_h) $(gsparam_h) $(gxfunc_h) $(stream_h) $(gxarith_h) $(math__h)\ - $(memory__h) $(MAKEDIRS) + $(memory__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsfunc3.$(OBJ) $(C_) $(GLSRC)gsfunc3.c $(GLOBJ)gsptype2.$(OBJ) : $(GLSRC)gsptype2.c $(AK) $(gx_h)\ $(gserrors_h) $(gscspace_h) $(gsshade_h) $(gsmatrix_h) $(gsstate_h)\ $(gxdevsop_h) $(gxcolor2_h) $(gxdcolor_h) $(gsptype2_h) $(gxpcolor_h)\ - $(gxstate_h) $(gzpath_h) $(gzcpath_h) $(gzstate_h) $(MAKEDIRS) + $(gxstate_h) $(gzpath_h) $(gzcpath_h) $(gzstate_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsptype2.$(OBJ) $(C_) $(GLSRC)gsptype2.c $(GLOBJ)gsshade.$(OBJ) : $(GLSRC)gsshade.c $(AK) $(gx_h) $(gserrors_h)\ $(gscspace_h) $(gsstruct_h) $(gsptype2_h)\ - $(gxcspace_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevcli_h) $(gxistate_h)\ + $(gxcspace_h) $(gxcpath_h) $(gxdcolor_h) $(gxdevcli_h) $(gxgstate_h)\ $(gxpaint_h) $(gxpath_h) $(gxshade_h) $(gxshade4_h)\ - $(gzcpath_h) $(gzpath_h) $(MAKEDIRS) + $(gzcpath_h) $(gzpath_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsshade.$(OBJ) $(C_) $(GLSRC)gsshade.c $(GLOBJ)gxshade.$(OBJ) : $(GLSRC)gxshade.c $(AK) $(gx_h) $(gserrors_h)\ $(math__h) $(gsrect_h) $(gxcspace_h) $(gscindex_h) $(gscie_h) \ - $(gxdevcli_h) $(gxistate_h) $(gxdht_h) $(gxpaint_h) $(gxshade_h) $(gxshade4_h)\ - $(gsicc_h) $(gsicc_cache_h) $(MAKEDIRS) + $(gxdevcli_h) $(gxgstate_h) $(gxdht_h) $(gxpaint_h) $(gxshade_h) $(gxshade4_h)\ + $(gsicc_h) $(gsicc_cache_h) $(gxcdevn_h) $(gximage_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxshade.$(OBJ) $(C_) $(GLSRC)gxshade.c $(GLOBJ)gxshade1.$(OBJ) : $(GLSRC)gxshade1.c $(AK) $(gx_h)\ - $(gserrors_h) $(math__h) $(memory__h) $(vdtrace_h)\ + $(gserrors_h) $(math__h) $(memory__h) \ $(gscoord_h) $(gsmatrix_h) $(gspath_h) $(gsptype2_h)\ - $(gxcspace_h) $(gxdcolor_h) $(gxfarith_h) $(gxfixed_h) $(gxistate_h)\ + $(gxcspace_h) $(gxdcolor_h) $(gxfarith_h) $(gxfixed_h) $(gxgstate_h)\ $(gxpath_h) $(gxshade_h) $(gxshade4_h) $(gxdevcli_h) $(gsicc_cache_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxshade1.$(OBJ) $(C_) $(GLSRC)gxshade1.c $(GLOBJ)gxshade4.$(OBJ) : $(GLSRC)gxshade4.c $(AK) $(gx_h)\ $(gserrors_h) $(math__h) $(memory__h)\ $(gscoord_h) $(gsmatrix_h) $(gsptype2_h)\ - $(gxcspace_h) $(gxdcolor_h) $(gxdevcli_h) $(gxistate_h) $(gxpath_h)\ - $(gxshade_h) $(gxshade4_h) $(vdtrace_h) $(gsicc_cache_h) $(MAKEDIRS) + $(gxcspace_h) $(gxdcolor_h) $(gxdevcli_h) $(gxgstate_h) $(gxpath_h)\ + $(gxshade_h) $(gxshade4_h) $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxshade4.$(OBJ) $(C_) $(GLSRC)gxshade4.c $(GLOBJ)gxshade6.$(OBJ) : $(GLSRC)gxshade6.c $(AK) $(gx_h)\ $(gserrors_h) $(memory__h) $(gxdevsop_h) $(stdint__h) $(gscoord_h)\ - $(gscicach_h) $(gsmatrix_h) $(gxcspace_h) $(gxdcolor_h) $(gxistate_h)\ + $(gscicach_h) $(gsmatrix_h) $(gxcspace_h) $(gxdcolor_h) $(gxgstate_h)\ $(gxshade_h) $(gxshade4_h) $(gxdevcli_h) $(gxarith_h) $(gzpath_h) $(math__h)\ - $(vdtrace_h) $(gsicc_cache_h) $(MAKEDIRS) + $(gsicc_cache_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gxshade6.$(OBJ) $(C_) $(GLSRC)gxshade6.c shadelib_1=$(GLOBJ)gscolor3.$(OBJ) $(GLOBJ)gsfunc3.$(OBJ) $(GLOBJ)gsptype2.$(OBJ) $(GLOBJ)gsshade.$(OBJ) shadelib_2=$(GLOBJ)gxshade.$(OBJ) $(GLOBJ)gxshade1.$(OBJ) $(GLOBJ)gxshade4.$(OBJ) $(GLOBJ)gxshade6.$(OBJ) shadelib_=$(shadelib_1) $(shadelib_2) $(GLD)shadelib.dev : $(LIB_MAK) $(ECHOGS_XE) $(shadelib_)\ - $(GLD)funclib.dev $(GLD)patlib.dev + $(GLD)funclib.dev $(GLD)patlib.dev $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)shadelib $(shadelib_1) $(ADDMOD) $(GLD)shadelib -obj $(shadelib_2) $(ADDMOD) $(GLD)shadelib -include $(GLD)funclib $(GLD)patlib +$(GLOBJ)gen_ordered.$(OBJ) : $(GLSRC)gen_ordered.c $(GLSRC)gen_ordered.h\ + $(std_h) $(gsmemory_h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)gen_ordered.$(OBJ) $(C_) $(D_)GS_LIB_BUILD$(_D) \ + $(GLSRC)gen_ordered.c + # ---------------- Support for %rom% IODevice ----------------- # # This is used to access compressed, compiled-in support files gsiorom_h=$(GLSRC)gsiorom.h romfs_=$(GLOBJ)gsiorom.$(OBJ) -$(GLD)romfs1.dev : $(LIB_MAK) $(ECHOGS_XE) $(romfs_) +$(GLD)romfs1.dev : $(LIB_MAK) $(ECHOGS_XE) $(romfs_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)romfs1 $(romfs_) $(ADDMOD) $(GLD)romfs1 -iodev rom # A dummy romfs when we aren't using COMPILE_INITS -$(GLD)romfs0.dev : $(LIB_MAK) $(ECHOGS_XE) +$(GLD)romfs0.dev : $(LIB_MAK) $(ECHOGS_XE) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)romfs0 - -$(GLGEN)gsromfs1_.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(MAKEDIRS) +# psi +$(GLGEN)gsromfs1_.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(LIB_MAK) $(MAKEDIRS) $(EXP)$(MKROMFS_XE) -o $(GLGEN)gsromfs1_.c \ -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ - $(PCLXL_ROMFS_ARGS) $(PJL_ROMFS_ARGS) $(XPS_ROMFS_ARGS) \ - $(PS_ROMFS_ARGS) $(GL_ROMFS_ARGS) + $(PS_ROMFS_ARGS) $(PS_FONT_ROMFS_ARGS) $(GL_ROMFS_ARGS) -$(GLGEN)gsromfs1_1.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(MAKEDIRS) +$(GLGEN)gsromfs1_1.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(LIB_MAK) $(MAKEDIRS) $(EXP)$(MKROMFS_XE) -o $(GLGEN)gsromfs1_1.c \ -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(UFST_ROMFS_ARGS) $(PS_ROMFS_ARGS) $(GL_ROMFS_ARGS) + +$(GLGEN)gsromfs1.c : $(GLGEN)gsromfs1_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)gsromfs1_$(UFST_BRIDGE).c $(GLGEN)gsromfs1.c + +# pcl +$(GLGEN)pclromfs1_.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pclromfs1_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(PCLXL_FONT_ROMFS_ARGS) $(PCLXL_ROMFS_ARGS) $(PJL_ROMFS_ARGS) \ + $(PJL_ROMFS_ARGS) $(GL_ROMFS_ARGS) + +$(GLGEN)pclromfs1_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pclromfs1_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(UFST_ROMFS_ARGS) $(PCLXL_ROMFS_ARGS) $(PJL_ROMFS_ARGS) \ + $(GL_ROMFS_ARGS) + +$(GLGEN)pclromfs1.c : $(GLGEN)pclromfs1_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)pclromfs1_$(UFST_BRIDGE).c $(GLGEN)pclromfs1.c + +$(GLGEN)pclromfs0_.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pclromfs0_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)pclromfs0_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pclromfs0_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)pclromfs0.c : $(GLGEN)pclromfs0_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)pclromfs0_$(UFST_BRIDGE).c $(GLGEN)pclromfs0.c + +# xps +$(GLGEN)xpsromfs1_.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)xpsromfs1_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(XPS_ROMFS_ARGS) $(XPS_FONT_ROMFS_ARGS) $(GL_ROMFS_ARGS) + +$(GLGEN)xpsromfs1_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)xpsromfs1_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(XPS_ROMFS_ARGS) $(GL_ROMFS_ARGS) + +$(GLGEN)xpsromfs1.c : $(GLGEN)xpsromfs1_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)xpsromfs1_$(UFST_BRIDGE).c $(GLGEN)xpsromfs1.c + +$(GLGEN)xpsromfs0_.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)xpsromfs0_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)xpsromfs0_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)xpsromfs0_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)xpsromfs0.c : $(GLGEN)xpsromfs0_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)xpsromfs0_$(UFST_BRIDGE).c $(GLGEN)xpsromfs0.c + +# pdl +$(GLGEN)pdlromfs1_.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdlromfs1_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(PCLXL_ROMFS_ARGS) $(PCLXL_FONT_ROMFS_ARGS) $(PJL_ROMFS_ARGS) \ + $(XPS_ROMFS_ARGS) $(XPS_FONT_ROMFS_ARGS) \ + $(PS_ROMFS_ARGS) $(PS_FONT_ROMFS_ARGS) $(GL_ROMFS_ARGS) + +$(GLGEN)pdlromfs1_1.c : $(MKROMFS_XE) $(PS_ROMFS_DEPS) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdlromfs1_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ $(UFST_ROMFS_ARGS) $(PCLXL_ROMFS_ARGS) $(PJL_ROMFS_ARGS) $(XPS_ROMFS_ARGS) \ $(PS_ROMFS_ARGS) $(GL_ROMFS_ARGS) -$(GLGEN)gsromfs1.c : $(GLGEN)gsromfs1_$(UFST_BRIDGE).c $(MAKEDIRS) - $(CP_) $(GLGEN)gsromfs1_$(UFST_BRIDGE).c $(GLGEN)gsromfs1.c +$(GLGEN)pdlromfs1.c : $(GLGEN)pdlromfs1_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)pdlromfs1_$(UFST_BRIDGE).c $(GLGEN)pdlromfs1.c + +$(GLGEN)pdlromfs0_.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdlromfs0_.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)pdlromfs0_1.c : $(MKROMFS_XE) $(LIB_MAK) $(MAKEDIRS) + $(EXP)$(MKROMFS_XE) -o $(GLGEN)pdlromfs0_1.c \ + -X .svn -X CVS -P $(GLSRCDIR)$(D)..$(D) iccprofiles$(D)* \ + $(GL_ROMFS_ARGS) + +$(GLGEN)pdlromfs0.c : $(GLGEN)pdlromfs0_$(UFST_BRIDGE).c $(LIB_MAK) $(MAKEDIRS) + $(CP_) $(GLGEN)pdlromfs0_$(UFST_BRIDGE).c $(GLGEN)pdlromfs0.c + # the following module is only included if the romfs.dev FEATURE is enabled $(GLOBJ)gsiorom_1.$(OBJ) : $(GLSRC)gsiorom.c $(gsiorom_h) \ $(std_h) $(gx_h) $(gserrors_h) $(gsstruct_h) $(gxiodev_h) $(stat__h)\ $(gpcheck_h) $(gsutil_h) $(stdint__h) $(stream_h) $(string__h) \ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsiorom_1.$(OBJ) $(I_)$(ZI_)$(_I) $(C_) $(GLSRC)gsiorom.c $(GLOBJ)gsiorom_0.$(OBJ) : $(GLSRC)gsiorom.c $(gsiorom_h) \ $(std_h) $(gx_h) $(gserrors_h) $(gsstruct_h) $(gxiodev_h) $(stat__h)\ $(gpcheck_h) $(gsutil_h) $(stdint__h) $(stream_h) $(string__h) $(zlib_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsiorom_0.$(OBJ) $(I_)$(ZI_)$(_I) $(C_) $(GLSRC)gsiorom.c -$(GLOBJ)gsiorom.$(OBJ) : $(GLOBJ)gsiorom_$(SHARE_ZLIB).$(OBJ) $(MAKEDIRS) +$(GLOBJ)gsiorom.$(OBJ) : $(GLOBJ)gsiorom_$(SHARE_ZLIB).$(OBJ) $(LIB_MAK) $(MAKEDIRS) $(CP_) $(GLOBJ)gsiorom_$(SHARE_ZLIB).$(OBJ) $(GLOBJ)gsiorom.$(OBJ) -$(GLOBJ)gsromfs1.$(OBJ) : $(GLOBJ)gsromfs1.c $(time__h) $(MAKEDIRS) - $(GLCC) $(GLO_)gsromfs1.$(OBJ) $(C_) $(GLOBJ)gsromfs1.c - # A dummy gsromfs module for COMPILE_INITS=0 -$(GLOBJ)gsromfs0.$(OBJ) : $(GLSRC)gsromfs0.c $(stdint__h) $(MAKEDIRS) +$(GLOBJ)gsromfs0.$(OBJ) : $(GLSRC)gsromfs0.c $(stdint__h) $(time__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsromfs0.$(OBJ) $(C_) $(GLSRC)gsromfs0.c +$(GLOBJ)gsromfs1.$(OBJ) : $(GLOBJ)gsromfs1.c $(time__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)gsromfs1.$(OBJ) $(C_) $(GLOBJ)gsromfs1.c + +# A pclromfs module with only ICC profiles for COMPILE_INITS=0 +$(GLOBJ)pclromfs0.$(OBJ) : $(GLGEN)pclromfs0.c $(stdint__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)pclromfs0.$(OBJ) $(C_) $(GLGEN)pclromfs0.c + +$(GLOBJ)pclromfs1.$(OBJ) : $(GLOBJ)pclromfs1.c $(time__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)pclromfs1.$(OBJ) $(C_) $(GLOBJ)pclromfs1.c + +# A xpsromfs module with only ICC profiles for COMPILE_INITS=0 +$(GLOBJ)xpsromfs0.$(OBJ) : $(GLGEN)xpsromfs0.c $(stdint__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)xpsromfs0.$(OBJ) $(C_) $(GLGEN)xpsromfs0.c + +$(GLOBJ)xpsromfs1.$(OBJ) : $(GLOBJ)xpsromfs1.c $(time__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)xpsromfs1.$(OBJ) $(C_) $(GLOBJ)xpsromfs1.c + +# A pdlromfs module with only ICC profiles for COMPILE_INITS=0 +$(GLOBJ)pdlromfs0.$(OBJ) : $(GLGEN)pdlromfs0.c $(stdint__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)pdlromfs0.$(OBJ) $(C_) $(GLGEN)pdlromfs0.c + +$(GLOBJ)pdlromfs1.$(OBJ) : $(GLOBJ)pdlromfs1.c $(time__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)pdlromfs1.$(OBJ) $(C_) $(GLOBJ)pdlromfs1.c + # Define the ZLIB modules needed by mnkromfs here to factor it out of top makefiles # Also put the .h dependencies here for the same reason MKROMFS_ZLIB_OBJS=$(AUX)compress.$(OBJ) $(AUX)deflate.$(OBJ) \ @@ -3164,117 +3396,122 @@ MKROMFS_COMMON_DEPS=$(stdpre_h) $(stdint__h) $(gsiorom_h) $(arch_h)\ $(gsmemret_h) $(gsmalloc_h) $(gsstype_h) $(gp_h) $(time__h) +# ---------------- Support for %ram% IODevice ----------------- # +gsioram_h=$(GLSRC)gsioram.h +ramfs_=$(GLOBJ)gsioram.$(OBJ) $(GLOBJ)ramfs.$(OBJ) +$(GLD)ramfs.dev : $(LIB_MAK) $(ECHOGS_XE) $(ramfs_) $(LIB_MAK) $(MAKEDIRS) + $(SETMOD) $(GLD)ramfs $(ramfs_) + $(ADDMOD) $(GLD)ramfs -iodev ram + $(ADDMOD) $(GLD)ramfs -obj $(GLOBJ)ramfs.$(OBJ) + +$(GLOBJ)ramfs.$(OBJ) : $(GLSRC)ramfs.c $(gp_h) $(gscdefs_h) $(gserrors_h)\ + $(gsparam_h) $(gsstruct_h) $(gx_h) $(ramfs_h) $(string__h) $(unistd__h)\ + $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)ramfs.$(OBJ) $(C_) $(GLSRC)ramfs.c + +$(GLOBJ)gsioram.$(OBJ) : $(GLSRC)gsioram.c $(gp_h) $(gscdefs_h) $(gserrors_h)\ + $(gsparam_h) $(gsstruct_h) $(gsutil_h) $(gx_h) $(gxiodev_h) $(ramfs_h)\ + $(stream_h) $(string__h) $(unistd__h) $(LIB_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)gsioram.$(OBJ) $(C_) $(GLSRC)gsioram.c + + # ---------------- Support for %disk IODevices ---------------- # # The following module is included only if the diskn.dev FEATURE is included $(GLOBJ)gsiodisk.$(OBJ) : $(GLSRC)gsiodisk.c $(AK) $(gx_h)\ $(gserrors_h) $(errno__h) $(string__h) $(unistd__h)\ $(gp_h) $(gscdefs_h) $(gsparam_h) $(gsstruct_h) $(gxiodev_h) $(gsutil_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gsiodisk.$(OBJ) $(C_) $(GLSRC)gsiodisk.c -# ------------ Support for %macresource% IODevice ------------- # -# This is used to load native-format fonts on MacOS -# Define the macres.dev FEATURE -macres_=$(GLOBJ)gsiomacres.$(OBJ) -$(GLD)macres.dev : $(LIB_MAK) $(ECHOGS_XE) $(macres_) - $(SETMOD) $(GLD)macres $(macres_) - $(ADDMOD) $(GLD)macres -iodev macresource - -# The following module is included only if the macres.dev FEATURE is enabled -$(GLOBJ)gsiomacres.$(OBJ) : $(GLSRC)gsiomacres.c $(gdebug_h) $(gp_h)\ - $(std_h) $(gstypes_h) $(gsmemory_h) $(gxiodev_h) $(ierrors_h)\ - $(malloc__h) $(stdio__h) $(stream_h) $(string__h) $(MAKEDIRS) - $(GLCC) $(GLO_)gsiomacres.$(OBJ) $(C_) $(GLSRC)gsiomacres.c - # ================ Platform-specific modules ================ # # Platform-specific code doesn't really belong here: this is code that is # shared among multiple platforms. # Standard implementation of gp_getenv. $(GLOBJ)gp_getnv.$(OBJ) : $(GLSRC)gp_getnv.c $(AK) $(stdio__h)\ - $(string__h) $(gp_h) $(gsmemory_h) $(gstypes_h) $(MAKEDIRS) + $(string__h) $(gp_h) $(gsmemory_h) $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_getnv.$(OBJ) $(C_) $(GLSRC)gp_getnv.c $(AUX)gp_getnv.$(OBJ) : $(GLSRC)gp_getnv.c $(AK) $(stdio__h)\ - $(string__h) $(gp_h) $(gsmemory_h) $(gstypes_h) $(MAKEDIRS) + $(string__h) $(gp_h) $(gsmemory_h) $(gstypes_h) $(LIB_MAK) $(MAKEDIRS) $(GLCCAUX) $(AUXO_)gp_getnv.$(OBJ) $(C_) $(GLSRC)gp_getnv.c # Standard implementation of gp_defaultpapersize. -$(GLOBJ)gp_paper.$(OBJ) : $(GLSRC)gp_paper.c $(AK) $(gp_h) $(gx_h) $(MAKEDIRS) +$(GLOBJ)gp_paper.$(OBJ) : $(GLSRC)gp_paper.c $(AK) $(gp_h) $(gx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_paper.$(OBJ) $(C_) $(GLSRC)gp_paper.c # Unix implementation of gp_defaultpapersize. $(GLOBJ)gp_upapr.$(OBJ) : $(GLSRC)gp_upapr.c $(malloc__h) $(AK) $(gp_h)\ - $(gx_h) $(string__h) $(MAKEDIRS) + $(gx_h) $(string__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_upapr.$(OBJ) $(C_) $(GLSRC)gp_upapr.c # File system implementation. # MS-DOS file system, also used by Desqview/X. $(GLOBJ)gp_dosfs.$(OBJ) : $(GLSRC)gp_dosfs.c $(AK) $(dos__h) $(gp_h)\ - $(gpmisc_h) $(gx_h) $(MAKEDIRS) + $(gpmisc_h) $(gx_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_dosfs.$(OBJ) $(C_) $(GLSRC)gp_dosfs.c # MS-DOS file enumeration, *not* used by Desqview/X. $(GLOBJ)gp_dosfe.$(OBJ) : $(GLSRC)gp_dosfe.c $(AK)\ $(dos__h) $(memory__h) $(stdio__h) $(string__h)\ - $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(gp_h) $(gsutil_h) $(MAKEDIRS) + $(gstypes_h) $(gsmemory_h) $(gsstruct_h) $(gp_h) $(gsutil_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_dosfe.$(OBJ) $(C_) $(GLSRC)gp_dosfe.c # Unix(-like) file system, also used by Desqview/X. $(GLOBJ)gp_unifs.$(OBJ) : $(GLSRC)gp_unifs.c $(AK)\ $(memory__h) $(string__h) $(stdio__h) $(unistd__h) \ $(gx_h) $(gp_h) $(gpmisc_h) $(gsstruct_h) $(gsutil_h) \ - $(stat__h) $(dirent__h) $(MAKEDIRS) + $(stat__h) $(dirent__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_unifs.$(OBJ) $(C_) $(GLSRC)gp_unifs.c $(AUX)gp_unifs.$(OBJ) : $(GLSRC)gp_unifs.c $(AK)\ $(memory__h) $(string__h) $(stdio__h) $(unistd__h) \ $(gx_h) $(gp_h) $(gpmisc_h) $(gsstruct_h) $(gsutil_h) \ - $(stat__h) $(dirent__h) $(MAKEDIRS) + $(stat__h) $(dirent__h) $(LIB_MAK) $(MAKEDIRS) $(GLCCAUX) $(AUXO_)gp_unifs.$(OBJ) $(C_) $(GLSRC)gp_unifs.c # Unix(-like) file name syntax, *not* used by Desqview/X. $(GLOBJ)gp_unifn.$(OBJ) : $(GLSRC)gp_unifn.c $(AK) $(gx_h) $(gp_h)\ - $(gpmisc_h) $(gsutil_h) $(MAKEDIRS) + $(gpmisc_h) $(gsutil_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_unifn.$(OBJ) $(C_) $(GLSRC)gp_unifn.c $(AUX)gp_unifn.$(OBJ) : $(GLSRC)gp_unifn.c $(AK) $(gx_h) $(gp_h)\ - $(gpmisc_h) $(gsutil_h) $(MAKEDIRS) + $(gpmisc_h) $(gsutil_h) $(LIB_MAK) $(MAKEDIRS) $(GLCCAUX) $(AUXO_)gp_unifn.$(OBJ) $(C_) $(GLSRC)gp_unifn.c # Pipes. These are actually the same on all platforms that have them. pipe_=$(GLOBJ)gdevpipe.$(OBJ) -$(GLD)pipe.dev : $(LIB_MAK) $(ECHOGS_XE) $(pipe_) +$(GLD)pipe.dev : $(LIB_MAK) $(ECHOGS_XE) $(pipe_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)pipe $(pipe_) $(ADDMOD) $(GLD)pipe -iodev pipe $(GLOBJ)gdevpipe.$(OBJ) : $(GLSRC)gdevpipe.c $(AK)\ $(errno__h) $(pipe__h) $(stdio__h) $(string__h) \ $(gserrors_h) $(gsmemory_h) $(gstypes_h) $(gxiodev_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gdevpipe.$(OBJ) $(C_) $(GLSRC)gdevpipe.c # Thread / semaphore / monitor implementation. # Dummy implementation. nosync_=$(GLOBJ)gp_nsync.$(OBJ) -$(GLD)nosync.dev : $(LIB_MAK) $(ECHOGS_XE) $(nosync_) +$(GLD)nosync.dev : $(LIB_MAK) $(ECHOGS_XE) $(nosync_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)nosync $(nosync_) $(GLOBJ)gp_nsync.$(OBJ) : $(GLSRC)gp_nsync.c $(AK) $(std_h)\ - $(gpsync_h) $(gserrors_h) $(MAKEDIRS) + $(gpsync_h) $(gserrors_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_nsync.$(OBJ) $(C_) $(GLSRC)gp_nsync.c # POSIX pthreads-based implementation. pthreads_=$(GLOBJ)gp_psync.$(OBJ) -$(GLD)posync.dev : $(LIB_MAK) $(ECHOGS_XE) $(pthreads_) +$(GLD)posync.dev : $(LIB_MAK) $(ECHOGS_XE) $(pthreads_) $(LIB_MAK) $(MAKEDIRS) $(SETMOD) $(GLD)posync $(pthreads_) $(ADDMOD) $(GLD)posync -replace $(GLD)nosync -$(GLOBJ)gp_psync.$(OBJ) : $(GLSRC)gp_psync.c $(AK) $(malloc__h)\ - $(std_h) $(gpsync_h) $(gserrors_h) $(MAKEDIRS) +$(GLOBJ)gp_psync.$(OBJ) : $(GLSRC)gp_psync.c $(AK) $(malloc__h) $(string__h) \ + $(std_h) $(gpsync_h) $(gserrors_h) $(assert__h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_psync.$(OBJ) $(C_) $(GLSRC)gp_psync.c # Other stuff. @@ -3282,9 +3519,15 @@ # Other MS-DOS facilities. $(GLOBJ)gp_msdos.$(OBJ) : $(GLSRC)gp_msdos.c $(AK)\ $(dos__h) $(stdio__h) $(string__h)\ - $(gsmemory_h) $(gstypes_h) $(gp_h) $(MAKEDIRS) + $(gsmemory_h) $(gstypes_h) $(gp_h) $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_msdos.$(OBJ) $(C_) $(GLSRC)gp_msdos.c +# Dummy XPS printing function - the only real one is in the Windows +# platform code +$(GLOBJ)gp_nxpsprn.$(OBJ) : $(GLSRC)gp_nxpsprn.c $(gp_h) $(LIB_MAK) \ + $(AK) $(MAKEDIRS) + $(GLCC) $(GLO_)gp_nxpsprn.$(OBJ) $(C_) $(GLSRC)gp_nxpsprn.c + # ================ Dependencies for auxiliary programs ================ # GENARCH_DEPS=$(stdpre_h) @@ -3315,5 +3558,5 @@ $(gshtx_h) $(gsiparm3_h) $(gsiparm4_h) $(gslib_h) $(gsparam_h)\ $(gspaint_h) $(gspath_h) $(gspath2_h) $(gsstruct_h) $(gsutil_h)\ $(gxalloc_h) $(gxdcolor_h) $(gxdevice_h) $(gxht_h) $(gdevbbox_h)\ - $(MAKEDIRS) + $(LIB_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gslib.$(OBJ) $(C_) $(GLSRC)gslib.c diff -Nru ghostscript-9.10~dfsg/base/locale_.h ghostscript-9.25~dfsg+1/base/locale_.h --- ghostscript-9.10~dfsg/base/locale_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/locale_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/lwf_jp2.mak ghostscript-9.25~dfsg+1/base/lwf_jp2.mak --- ghostscript-9.10~dfsg/base/lwf_jp2.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/lwf_jp2.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for Luratech lwf_jp2 library code. @@ -29,7 +29,7 @@ # This partial makefile compiles the lwf_jp2 library for use in # Ghostscript. -LWF_JP2_MAK=$(GLSRC)lwf_jp2.mak +LWF_JP2_MAK=$(GLSRC)lwf_jp2.mak $(TOP_MAKEFILES) LWF_JP2_SRC=$(JPXSRCDIR)$(D)library$(D)source$(D) LWF_JP2_GEN=$(JPXOBJDIR)$(D) @@ -175,219 +175,222 @@ $(LWF_JP2_SRC)lwf_jp2.h # switch in the selected library .dev -$(LWF_JP2_GEN)lwf_jp2.dev : $(TOP_MAKEFILES) $(LWF_JP2_GEN)lwf_jp2_$(SHARE_JPX).dev +$(LWF_JP2_GEN)lwf_jp2.dev : $(LWF_JP2_GEN)lwf_jp2_$(SHARE_JPX).dev \ + $(LWF_JP2_MAK) $(MAKEDIRS) $(CP_) $(LWF_JP2_GEN)lwf_jp2_$(SHARE_JPX).dev $(LWF_JP2_GEN)lwf_jp2.dev # external link .dev -$(LWF_JP2_GEN)lwf_jp2_1.dev : $(TOP_MAKEFILES) $(LWF_JP2_MAK) $(ECHOGS_XE) +$(LWF_JP2_GEN)lwf_jp2_1.dev : $(LWF_JP2_MAK) $(ECHOGS_XE) \ + $(MAKEDIRS) $(SETMOD) $(LWF_JP2_GEN)lwf_jp2_1 -lib lwf_jp2 # compile our own .dev -$(LWF_JP2_GEN)lwf_jp2_0.dev : $(TOP_MAKEFILES) $(LWF_JP2_MAK) $(ECHOGS_XE) $(lwf_jp2_OBJS) +$(LWF_JP2_GEN)lwf_jp2_0.dev : $(LWF_JP2_MAK) $(ECHOGS_XE) $(lwf_jp2_OBJS) \ + $(MAKEDIRS) $(SETMOD) $(LWF_JP2_GEN)lwf_jp2_0 $(lwf_jp2_OBJS) # define our specific compiler LWF_JP2_CC=$(CC_) $(CFLAGS) $(I_)$(LWF_JPXI_)$(_I) $(JPXCF_) LWF_JP2_O=$(O_)$(LWF_JP2_OBJ) -LWF_JP2_DEP=$(AK) $(LWF_JP2_MAK) +LWF_JP2_DEP=$(AK) $(LWF_JP2_MAK) $(MAKEDIRS) # explicit rules for building each source file # for simplicity we have every source file depend on all headers -$(LWF_JP2_OBJ)jp2_adt_band_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_band_array.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_band_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_band_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_band_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_band_array.c -$(LWF_JP2_OBJ)jp2_adt_band_buffer.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_band_buffer.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_band_buffer.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_band_buffer.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_band_buffer.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_band_buffer.c -$(LWF_JP2_OBJ)jp2_adt_block_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_block_array.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_block_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_block_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_block_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_block_array.c -$(LWF_JP2_OBJ)jp2_adt_cache.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_cache.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_cache.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_cache.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_cache.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_cache.c -$(LWF_JP2_OBJ)jp2_adt_comp.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_comp.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_comp.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_comp.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_comp.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_comp.c -$(LWF_JP2_OBJ)jp2_adt_component_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_component_array.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_component_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_component_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_component_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_component_array.c -$(LWF_JP2_OBJ)jp2_adt_decomp.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_decomp.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_decomp.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_decomp.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_decomp.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_decomp.c -$(LWF_JP2_OBJ)jp2_adt_ebcot_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_ebcot_decoder.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_ebcot_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_ebcot_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_ebcot_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_ebcot_decoder.c -$(LWF_JP2_OBJ)jp2_adt_external_cache.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_external_cache.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_external_cache.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_external_cache.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_external_cache.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_external_cache.c -$(LWF_JP2_OBJ)jp2_adt_image.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_image.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_image.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_image.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_image.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_image.c -$(LWF_JP2_OBJ)jp2_adt_memory.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_memory.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_memory.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_memory.c -$(LWF_JP2_OBJ)jp2_adt_mq_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_mq_decoder.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_mq_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_mq_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_mq_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_mq_decoder.c -$(LWF_JP2_OBJ)jp2_adt_mq_state.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_mq_state.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_mq_state.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_mq_state.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_mq_state.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_mq_state.c -$(LWF_JP2_OBJ)jp2_adt_packet_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_packet_decoder.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_packet_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_packet_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_packet_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_packet_decoder.c -$(LWF_JP2_OBJ)jp2_adt_precinct_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_precinct_array.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_precinct_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_precinct_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_precinct_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_precinct_array.c -$(LWF_JP2_OBJ)jp2_adt_rate.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_rate.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_rate.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_rate.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_rate.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_rate.c -$(LWF_JP2_OBJ)jp2_adt_rate_list.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_rate_list.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_rate_list.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_rate_list.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_rate_list.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_rate_list.c -$(LWF_JP2_OBJ)jp2_adt_read_bits.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_read_bits.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_read_bits.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_read_bits.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_read_bits.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_read_bits.c -$(LWF_JP2_OBJ)jp2_adt_read_data.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_read_data.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_read_data.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_read_data.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_read_data.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_read_data.c -$(LWF_JP2_OBJ)jp2_adt_reader_requirements.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_reader_requirements.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_reader_requirements.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_reader_requirements.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_reader_requirements.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_reader_requirements.c -$(LWF_JP2_OBJ)jp2_adt_resolution_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_resolution_array.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_resolution_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_resolution_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_resolution_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_resolution_array.c -$(LWF_JP2_OBJ)jp2_adt_tile_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_tile_array.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_tile_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_tile_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_tile_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_tile_array.c -$(LWF_JP2_OBJ)jp2_adt_tlm_marker_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_tlm_marker_array.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_tlm_marker_array.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_tlm_marker_array.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_tlm_marker_array.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_tlm_marker_array.c -$(LWF_JP2_OBJ)jp2_adt_write_data.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_write_data.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_adt_write_data.$(OBJ) : $(LWF_JP2_SRC)jp2_adt_write_data.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_adt_write_data.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_adt_write_data.c -$(LWF_JP2_OBJ)jp2_buffer.$(OBJ) : $(LWF_JP2_SRC)jp2_buffer.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_buffer.$(OBJ) : $(LWF_JP2_SRC)jp2_buffer.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_buffer.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_buffer.c -$(LWF_JP2_OBJ)jp2c_code_cb.$(OBJ) : $(LWF_JP2_SRC)jp2c_code_cb.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_code_cb.$(OBJ) : $(LWF_JP2_SRC)jp2c_code_cb.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_code_cb.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_code_cb.c -$(LWF_JP2_OBJ)jp2c_coder.$(OBJ) : $(LWF_JP2_SRC)jp2c_coder.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_coder.$(OBJ) : $(LWF_JP2_SRC)jp2c_coder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_coder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_coder.c -$(LWF_JP2_OBJ)jp2c_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2c_codestream.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2c_codestream.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_codestream.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_codestream.c -$(LWF_JP2_OBJ)jp2c_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2c_file_format.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2c_file_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_file_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_file_format.c -$(LWF_JP2_OBJ)jp2c_format.$(OBJ) : $(LWF_JP2_SRC)jp2c_format.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_format.$(OBJ) : $(LWF_JP2_SRC)jp2c_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_format.c -$(LWF_JP2_OBJ)jp2c_memory.$(OBJ) : $(LWF_JP2_SRC)jp2c_memory.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_memory.$(OBJ) : $(LWF_JP2_SRC)jp2c_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_memory.c -$(LWF_JP2_OBJ)jp2_code_cb.$(OBJ) : $(LWF_JP2_SRC)jp2_code_cb.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_code_cb.$(OBJ) : $(LWF_JP2_SRC)jp2_code_cb.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_code_cb.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_code_cb.c -$(LWF_JP2_OBJ)jp2_common.$(OBJ) : $(LWF_JP2_SRC)jp2_common.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_common.$(OBJ) : $(LWF_JP2_SRC)jp2_common.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_common.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_common.c -$(LWF_JP2_OBJ)jp2c_progression.$(OBJ) : $(LWF_JP2_SRC)jp2c_progression.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_progression.$(OBJ) : $(LWF_JP2_SRC)jp2c_progression.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_progression.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_progression.c -$(LWF_JP2_OBJ)jp2c_quant.$(OBJ) : $(LWF_JP2_SRC)jp2c_quant.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_quant.$(OBJ) : $(LWF_JP2_SRC)jp2c_quant.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_quant.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_quant.c -$(LWF_JP2_OBJ)jp2c_wavelet.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_wavelet.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_wavelet.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_wavelet.c -$(LWF_JP2_OBJ)jp2c_wavelet_lifting.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet_lifting.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_wavelet_lifting.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet_lifting.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_wavelet_lifting.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_wavelet_lifting.c -$(LWF_JP2_OBJ)jp2c_wavelet_lifting_mmx.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet_lifting_mmx.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_wavelet_lifting_mmx.$(OBJ) : $(LWF_JP2_SRC)jp2c_wavelet_lifting_mmx.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_wavelet_lifting_mmx.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_wavelet_lifting_mmx.c -$(LWF_JP2_OBJ)jp2c_weights.$(OBJ) : $(LWF_JP2_SRC)jp2c_weights.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_weights.$(OBJ) : $(LWF_JP2_SRC)jp2c_weights.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_weights.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_weights.c -$(LWF_JP2_OBJ)jp2c_write.$(OBJ) : $(LWF_JP2_SRC)jp2c_write.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2c_write.$(OBJ) : $(LWF_JP2_SRC)jp2c_write.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2c_write.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2c_write.c -$(LWF_JP2_OBJ)jp2d_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2d_codestream.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2d_codestream.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_codestream.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_codestream.c -$(LWF_JP2_OBJ)jp2d_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2d_decoder.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_decoder.$(OBJ) : $(LWF_JP2_SRC)jp2d_decoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_decoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_decoder.c -$(LWF_JP2_OBJ)jp2_demo.$(OBJ) : $(LWF_JP2_SRC)jp2_demo.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_demo.$(OBJ) : $(LWF_JP2_SRC)jp2_demo.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_demo.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_demo.c -$(LWF_JP2_OBJ)jp2d_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2d_file_format.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2d_file_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_file_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_file_format.c -$(LWF_JP2_OBJ)jp2d_format.$(OBJ) : $(LWF_JP2_SRC)jp2d_format.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_format.$(OBJ) : $(LWF_JP2_SRC)jp2d_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_format.c -$(LWF_JP2_OBJ)jp2d_image.$(OBJ) : $(LWF_JP2_SRC)jp2d_image.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_image.$(OBJ) : $(LWF_JP2_SRC)jp2d_image.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_image.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_image.c -$(LWF_JP2_OBJ)jp2d_memory.$(OBJ) : $(LWF_JP2_SRC)jp2d_memory.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_memory.$(OBJ) : $(LWF_JP2_SRC)jp2d_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_memory.c -$(LWF_JP2_OBJ)jp2d_partial_decoding.$(OBJ) : $(LWF_JP2_SRC)jp2d_partial_decoding.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_partial_decoding.$(OBJ) : $(LWF_JP2_SRC)jp2d_partial_decoding.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_partial_decoding.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_partial_decoding.c -$(LWF_JP2_OBJ)jp2d_progression.$(OBJ) : $(LWF_JP2_SRC)jp2d_progression.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_progression.$(OBJ) : $(LWF_JP2_SRC)jp2d_progression.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_progression.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_progression.c -$(LWF_JP2_OBJ)jp2d_quant.$(OBJ) : $(LWF_JP2_SRC)jp2d_quant.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_quant.$(OBJ) : $(LWF_JP2_SRC)jp2d_quant.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_quant.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_quant.c -$(LWF_JP2_OBJ)jp2d_scale.$(OBJ) : $(LWF_JP2_SRC)jp2d_scale.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_scale.$(OBJ) : $(LWF_JP2_SRC)jp2d_scale.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_scale.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_scale.c -$(LWF_JP2_OBJ)jp2d_wavelet.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_wavelet.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_wavelet.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_wavelet.c -$(LWF_JP2_OBJ)jp2d_wavelet_lifting.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet_lifting.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_wavelet_lifting.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet_lifting.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_wavelet_lifting.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_wavelet_lifting.c -$(LWF_JP2_OBJ)jp2d_wavelet_lifting_mmx.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet_lifting_mmx.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_wavelet_lifting_mmx.$(OBJ) : $(LWF_JP2_SRC)jp2d_wavelet_lifting_mmx.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_wavelet_lifting_mmx.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_wavelet_lifting_mmx.c -$(LWF_JP2_OBJ)jp2d_write.$(OBJ) : $(LWF_JP2_SRC)jp2d_write.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2d_write.$(OBJ) : $(LWF_JP2_SRC)jp2d_write.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2d_write.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2d_write.c -$(LWF_JP2_OBJ)jp2_icc.$(OBJ) : $(LWF_JP2_SRC)jp2_icc.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_icc.$(OBJ) : $(LWF_JP2_SRC)jp2_icc.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_icc.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_icc.c -$(LWF_JP2_OBJ)jp2_license.$(OBJ) : $(LWF_JP2_SRC)jp2_license.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_license.$(OBJ) : $(LWF_JP2_SRC)jp2_license.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_license.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_license.c -$(LWF_JP2_OBJ)jp2_packet.$(OBJ) : $(LWF_JP2_SRC)jp2_packet.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_packet.$(OBJ) : $(LWF_JP2_SRC)jp2_packet.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_packet.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_packet.c -$(LWF_JP2_OBJ)jp2_tag_tree.$(OBJ) : $(LWF_JP2_SRC)jp2_tag_tree.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2_tag_tree.$(OBJ) : $(LWF_JP2_SRC)jp2_tag_tree.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2_tag_tree.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2_tag_tree.c -$(LWF_JP2_OBJ)jp2t_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2t_codestream.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2t_codestream.$(OBJ) : $(LWF_JP2_SRC)jp2t_codestream.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_codestream.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_codestream.c -$(LWF_JP2_OBJ)jp2t_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2t_file_format.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2t_file_format.$(OBJ) : $(LWF_JP2_SRC)jp2t_file_format.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_file_format.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_file_format.c -$(LWF_JP2_OBJ)jp2t_image.$(OBJ) : $(LWF_JP2_SRC)jp2t_image.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2t_image.$(OBJ) : $(LWF_JP2_SRC)jp2t_image.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_image.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_image.c -$(LWF_JP2_OBJ)jp2t_memory.$(OBJ) : $(LWF_JP2_SRC)jp2t_memory.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2t_memory.$(OBJ) : $(LWF_JP2_SRC)jp2t_memory.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_memory.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_memory.c -$(LWF_JP2_OBJ)jp2t_progression.$(OBJ) : $(LWF_JP2_SRC)jp2t_progression.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2t_progression.$(OBJ) : $(LWF_JP2_SRC)jp2t_progression.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_progression.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_progression.c -$(LWF_JP2_OBJ)jp2t_transcoder.$(OBJ) : $(LWF_JP2_SRC)jp2t_transcoder.c $(LWF_JP2_DEP) $(lwf_jp2_HDRS) +$(LWF_JP2_OBJ)jp2t_transcoder.$(OBJ) : $(LWF_JP2_SRC)jp2t_transcoder.c $(lwf_jp2_HDRS) $(LWF_JP2_DEP) $(LWF_JP2_CC) $(LWF_JP2_O)jp2t_transcoder.$(OBJ) $(C_) $(LWF_JP2_SRC)jp2t_transcoder.c diff -Nru ghostscript-9.10~dfsg/base/macgenmcpxml.sh ghostscript-9.25~dfsg+1/base/macgenmcpxml.sh --- ghostscript-9.10~dfsg/base/macgenmcpxml.sh 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/macgenmcpxml.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,436 +0,0 @@ -#!/bin/sh -# Copyright (C) 2001-2012 Artifex Software, Inc. -# All Rights Reserved. -# -# This software is provided AS-IS with no warranty, either express or -# implied. -# -# This software is distributed under license and may not be copied, -# modified or distributed except as expressly authorized under the terms -# of the license contained in the file LICENSE in this distribution. -# -# Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. -# - -################################################################################################# -# Functions - -##### -# WriteXMLHeader writes the beginning of the XML project file -##### -WriteXMLHeader() -{ -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "" -echo "]>" -echo "" -} - -##### -# WriteFILE generates a complete ... entry -##### -WriteFILE() -{ - echo "" - echo " Name" - echo " $1" - echo " MacOS" - echo " Text" - echo " Debug" - echo "" -} - -##### -# WriteFILEREF generates a complete ... entry -##### -WriteFILEREF() -{ - echo "" - if [ $# -ge 2 ]; then - echo " $2" - fi - echo " Name" - echo " $1" - echo " MacOS" - echo "" -} - - -##### -# WriteValueSetting generates a complete value entry -##### -WriteValueSetting() -{ - SETTINGNAME=$1 - VALUE=$2 - - echo "$SETTINGNAME$VALUE" -} - - - -##### -# WritePathSetting generates a complete path entry -##### -WritePathSetting() -{ - SETTINGNAME=$1 - PATH=$2 - PATHFORMAT=$3 - PATHROOT=$4 - - echo "" - echo "$SETTINGNAME" - echo "Path$PATH" - echo "PathFormat$PATHFORMAT" - echo "PathRoot$PATHROOT" - echo "" - echo "Recursivetrue" - echo "HostFlagsAll" - echo "" -} - -##### -# WriteSETTINGLIST generates a complete ... entry -##### -WriteSETTINGLIST() -{ - TARGETNAME=$1 - OUTPUTNAME=$2 - - echo "" - - echo "" - WriteValueSetting Linker "MacOS PPC Linker" - WriteValueSetting PreLinker "" - WriteValueSetting PostLinker "" - WriteValueSetting Targetname "$TARGETNAME" - echo "OutputDirectory" - echo "Path:Output:" - echo "PathFormatMacOS" - echo "PathRootProject" - echo "" - WriteValueSetting SaveEntriesUsingRelativePaths false - - echo "" - WriteValueSetting AlwaysSearchUserPaths false - WriteValueSetting InterpretDOSAndUnixPaths true - echo "UserSearchPaths" - WritePathSetting SearchPath ":src:" MacOS Project - WritePathSetting SearchPath ":obj:" MacOS Project - WritePathSetting SearchPath ":" MacOS Project - echo "" - echo "SystemSearchPaths" - WritePathSetting SearchPath ":jbig2dec:" MacOS Project - WritePathSetting SearchPath ":obj:" MacOS Project - WritePathSetting SearchPath ":MacOS Support:" MacOS CodeWarrior - WritePathSetting SearchPath ":MSL:MSL_C" MacOS CodeWarrior - WritePathSetting SearchPath ":" MacOS CodeWarrior - WritePathSetting SearchPath ":" MacOS Project - echo "" - - echo "" - WriteValueSetting CacheModDates true - WriteValueSetting ActivateBrowser true - WriteValueSetting DumpBrowserInfo false - WriteValueSetting CacheSubprojects true - - echo "" - WriteValueSetting MWProject_PPC_type SharedLibrary - WriteValueSetting MWProject_PPC_outfile "$OUTPUTNAME" - WriteValueSetting MWProject_PPC_filecreator 1061109567 - WriteValueSetting MWProject_PPC_filetype 1936223330 - WriteValueSetting MWProject_PPC_size 0 - WriteValueSetting MWProject_PPC_minsize 0 - WriteValueSetting MWProject_PPC_stacksize 0 - WriteValueSetting MWProject_PPC_flags 0 - WriteValueSetting MWProject_PPC_symfilename "" - WriteValueSetting MWProject_PPC_rsrcname "" - WriteValueSetting MWProject_PPC_rsrcheader Native - WriteValueSetting MWProject_PPC_rsrctype 1061109567 - WriteValueSetting MWProject_PPC_rsrcid 0 - WriteValueSetting MWProject_PPC_rsrcflags 0 - WriteValueSetting MWProject_PPC_rsrcstore 0 - WriteValueSetting MWProject_PPC_rsrcmerge 0 - - echo "" - WriteValueSetting MWFrontEnd_C_cplusplus 0 - WriteValueSetting MWFrontEnd_C_checkprotos 0 - WriteValueSetting MWFrontEnd_C_arm 0 - WriteValueSetting MWFrontEnd_C_trigraphs 0 - WriteValueSetting MWFrontEnd_C_onlystdkeywords 0 - WriteValueSetting MWFrontEnd_C_enumsalwaysint 0 - WriteValueSetting MWFrontEnd_C_mpwpointerstyle 1 - - # install the carbon prefix file for carbon targets - if test "$OUTPUTNAME" = "GhostscriptLib Carbon"; then - if test "$TARGETNAME" = "GhostscriptLib Carbon (Debug)"; then - WriteValueSetting MWFrontEnd_C_prefixname macos_carbon_d_pre.h - else - WriteValueSetting MWFrontEnd_C_prefixname macos_carbon_pre.h - fi - else - if test "$TARGETNAME" = "GhostscriptLib PPC (Debug)"; then - WriteValueSetting MWFrontEnd_C_prefixname macos_classic_d_pre.h - else - WriteValueSetting MWFrontEnd_C_prefixname - fi - fi - - WriteValueSetting MWFrontEnd_C_ansistrict 0 - WriteValueSetting MWFrontEnd_C_mpwcnewline 0 - WriteValueSetting MWFrontEnd_C_wchar_type 1 - WriteValueSetting MWFrontEnd_C_enableexceptions 0 - WriteValueSetting MWFrontEnd_C_dontreusestrings 0 - WriteValueSetting MWFrontEnd_C_poolstrings 0 - WriteValueSetting MWFrontEnd_C_dontinline 1 - WriteValueSetting MWFrontEnd_C_useRTTI 0 - WriteValueSetting MWFrontEnd_C_multibyteaware 0 - WriteValueSetting MWFrontEnd_C_unsignedchars 0 - WriteValueSetting MWFrontEnd_C_autoinline 0 - WriteValueSetting MWFrontEnd_C_booltruefalse 0 - WriteValueSetting MWFrontEnd_C_direct_to_som 0 - WriteValueSetting MWFrontEnd_C_som_env_check 0 - WriteValueSetting MWFrontEnd_C_alwaysinline 0 - WriteValueSetting MWFrontEnd_C_inlinelevel 0 - WriteValueSetting MWFrontEnd_C_ecplusplus 0 - WriteValueSetting MWFrontEnd_C_objective_c 0 - WriteValueSetting MWFrontEnd_C_defer_codegen 0 - - echo "" - WriteValueSetting MWWarning_C_warn_illpragma 1 - WriteValueSetting MWWarning_C_warn_emptydecl 0 - WriteValueSetting MWWarning_C_warn_possunwant 0 - WriteValueSetting MWWarning_C_warn_unusedvar 1 - WriteValueSetting MWWarning_C_warn_unusedarg 0 - WriteValueSetting MWWarning_C_warn_extracomma 1 - WriteValueSetting MWWarning_C_pedantic 1 - WriteValueSetting MWWarning_C_warningerrors 0 - WriteValueSetting MWWarning_C_warn_hidevirtual 1 - WriteValueSetting MWWarning_C_warn_implicitconv 0 - WriteValueSetting MWWarning_C_warn_notinlined 0 - WriteValueSetting MWWarning_C_warn_structclass 0 - - echo "" - WriteValueSetting MWCodeGen_PPC_structalignment PPC - WriteValueSetting MWCodeGen_PPC_tracebacktables Inline - WriteValueSetting MWCodeGen_PPC_processor Generic - WriteValueSetting MWCodeGen_PPC_readonlystrings 0 - WriteValueSetting MWCodeGen_PPC_tocdata 1 - WriteValueSetting MWCodeGen_PPC_profiler 0 - WriteValueSetting MWCodeGen_PPC_fpcontract 0 - WriteValueSetting MWCodeGen_PPC_schedule 1 - WriteValueSetting MWCodeGen_PPC_peephole 1 - WriteValueSetting MWCodeGen_PPC_processorspecific 0 - WriteValueSetting MWCodeGen_PPC_altivec 0 - WriteValueSetting MWCodeGen_PPC_vectortocdata 0 - WriteValueSetting MWCodeGen_PPC_vrsave 0 - - echo "" - WriteValueSetting GlobalOptimizer_PPC_optimizationlevel Level0 - WriteValueSetting GlobalOptimizer_PPC_optfor Speed - - echo "" - WriteValueSetting MWLinker_PPC_linksym 1 - WriteValueSetting MWLinker_PPC_symfullpath 1 - WriteValueSetting MWLinker_PPC_linkmap 0 - WriteValueSetting MWLinker_PPC_nolinkwarnings 0 - WriteValueSetting MWLinker_PPC_dontdeadstripinitcode 0 - WriteValueSetting MWLinker_PPC_permitmultdefs 0 - WriteValueSetting MWLinker_PPC_linkmode Fast - WriteValueSetting MWLinker_PPC_initname "__initialize" - WriteValueSetting MWLinker_PPC_mainname "" - WriteValueSetting MWLinker_PPC_termname "__terminate" - - echo "" - WriteValueSetting MWPEF_exports Pragma - WriteValueSetting MWPEF_libfolder 0 - WriteValueSetting MWPEF_sortcode None - WriteValueSetting MWPEF_expandbss 0 - WriteValueSetting MWPEF_sharedata 0 - WriteValueSetting MWPEF_olddefversion 0 - WriteValueSetting MWPEF_oldimpversion 0 - WriteValueSetting MWPEF_currentversion 0 - WriteValueSetting MWPEF_fragmentname "" - WriteValueSetting MWPEF_collapsereloads 0 - - echo "" -} - - -##### -# WriteTARGET generates a complete ... entry -##### -WriteTARGET() -{ - TARGETNAME=$1 - OUTPUTNAME=$2 - shift 2 - - echo "" - - echo "$TARGETNAME" - - WriteSETTINGLIST "$TARGETNAME" "$OUTPUTNAME" - - echo "" - for file in "$@"; do - WriteFILE "$file" - done - echo "" - - echo "" - for file in "$@"; do - WriteFILEREF "$file" - done - echo "" - - echo "" -} - - -##### -# WriteGROUP generates a complete ... entry -##### -WriteGROUP() -{ - GROUPNAME=$1 - TARGETNAME=$2 - shift 2 - - echo "$GROUPNAME" - - for file in "$@"; do - WriteFILEREF "$file" "$TARGETNAME" - done - - echo "" -} - - -################################################################################################# -# the start of the script - -##### -# first create a list of .c files that will be part of the project, we need it several times -##### - -CFILES= -while [ $# -ge 1 ]; do - case $1 in - \\);; - *.o) - # strip path before file name and convert .o to .c, then append file name to CFILES - CFILES=$CFILES\ `echo $1 | sed -e 's/\.\/.*\///' -e 's/\.\///' -e 's/\.o/\.c/'` - ;; - esac - shift -done - -# libs for codewarrior 6 -#LIBS="console.stubs.c MSL\ ShLibRuntime.Lib MSL\ RuntimePPC.Lib" -#CLASSICLIBS="MSL\ C.PPC.Lib InterfaceLib FontManager MathLib" - -# libs for codewarrior 7 & 8 -LIBS="" -CARBONLIBS="MSL_All_Carbon.Lib CarbonLib" -CLASSICLIBS="MSL_All_PPC.Lib InterfaceLib FontManager MathLib" -CLASSICLIBS="$CLASSICLIBS TextCommon UnicodeConverter UTCUtils" - -##### -# -##### - -GSNAME="GhostscriptLib" -CLASSICGSNAME="$GSNAME PPC" -CARBONGSNAME="$GSNAME Carbon" -CLASSICDEBUGTARGETNAME="$CLASSICGSNAME (Debug)" -CLASSICFINALTARGETNAME="$CLASSICGSNAME (Final)" -CARBONDEBUGTARGETNAME="$CARBONGSNAME (Debug)" -CARBONFINALTARGETNAME="$CARBONGSNAME (Final)" - -WriteXMLHeader - -echo "" - - echo "" - WriteTARGET "$CARBONDEBUGTARGETNAME" "$CARBONGSNAME" $CFILES $LIBS $CARBONLIBS - WriteTARGET "$CLASSICDEBUGTARGETNAME" "$CLASSICGSNAME" $CFILES $LIBS $CLASSICLIBS - echo "" - - echo "" - echo "$CARBONDEBUGTARGETNAME" - echo "$CLASSICDEBUGTARGETNAME" - echo "" - - echo "" - WriteGROUP "Ghostscript Sources" "$CARBONDEBUGTARGETNAME" $CFILES -# WriteGROUP "Libraries" "$CARBONDEBUGTARGETNAME" $LIBS $CARBONLIBS $CLASSICLIBS -# WriteGROUP "Libraries" "$CARBONDEBUGTARGETNAME" "console.stubs.c" "MSL ShLibRuntime.Lib" "MSL RuntimePPC.Lib" "MSL C.Carbon.Lib" "CarbonLib" "MSL C.PPC.Lib" "InterfaceLib" "FontManager" "MathLib" - -# nb: this code doesn't work if there are spaces in the library filenames - echo "Libraries" - for lib in $LIBS; do - WriteFILEREF "$lib" "$CARBONDEBUGTARGETNAME" - WriteFILEREF "$lib" "$CLASSICDEBUGTARGETNAME" - done - for lib in $CARBONLIBS; do - WriteFILEREF "$lib" "$CARBONDEBUGTARGETNAME" - done - for lib in $CLASSICLIBS; do - WriteFILEREF "$lib" "$CLASSICDEBUGTARGETNAME" - done - echo "" - - echo "" - -echo "" - -exit 0 diff -Nru ghostscript-9.10~dfsg/base/macos_carbon_d_pre.h ghostscript-9.25~dfsg+1/base/macos_carbon_d_pre.h --- ghostscript-9.10~dfsg/base/macos_carbon_d_pre.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/macos_carbon_d_pre.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* prefix include for MacOS CodeWarrior build, debug carbon target */ - -#ifndef macos_carbon_d_pre_INCLUDED -#define macos_carbon_d_pre_INCLUDED - -#define __CARBON__ - -/* turn on (verbose) debugging output */ -#define DEBUG 1 - -#endif /* macos_carbon_d_pre_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/macos_carbon_pre.h ghostscript-9.25~dfsg+1/base/macos_carbon_pre.h --- ghostscript-9.10~dfsg/base/macos_carbon_pre.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/macos_carbon_pre.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* prefix include for MacOS CodeWarrior build, carbon target */ - -#ifndef macos_carbon_pre_INCLUDED -#define macos_carbon_pre_INCLUDED - -#define __CARBON__ - -#endif /* macos_carbon_pre_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/macos_classic_d_pre.h ghostscript-9.25~dfsg+1/base/macos_classic_d_pre.h --- ghostscript-9.10~dfsg/base/macos_classic_d_pre.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/macos_classic_d_pre.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* prefix include for MacOS CodeWarrior build, debug classic target */ - -#ifndef macos_classic_d_pre_INCLUDED -#define macos_classic_d_pre_INCLUDED - -/* turn on (verbose) debugging output */ -#define DEBUG - -#endif /* macos_classic_d_pre_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/macos-mcp.mak ghostscript-9.25~dfsg+1/base/macos-mcp.mak --- ghostscript-9.10~dfsg/base/macos-mcp.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/macos-mcp.mak 1970-01-01 00:00:00.000000000 +0000 @@ -1,400 +0,0 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. -# All Rights Reserved. -# -# This software is provided AS-IS with no warranty, either express or -# implied. -# -# This software is distributed under license and may not be copied, -# modified or distributed except as expressly authorized under the terms -# of the license contained in the file LICENSE in this distribution. -# -# Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. -# -# Makefile for CodeWarrior XML project file creation from Darwin/MacOSX. - -# Run this file through make on MacOS X (or any other system with shell -# scripting) to produce an xml project file. Import that file into -# Metrowerks Codewarrior to perform the actual build targeting MacOS. - -# ------------------------------- Options ------------------------------- # - -####### The following are the only parts of the file you should need to edit. - -# Define the directory for the final executable, and the -# source, generated intermediate file, and object directories -# for the graphics library (GL) and the PostScript/PDF interpreter (PS). - -BINDIR=./bin -GLSRCDIR=./base -DEVSRCDIR=./devices -GLGENDIR=./obj -GLOBJDIR=./obj -DEVGENDIR=./obj -DEVOBJDIR=./obj -PSSRCDIR=./psi -PSLIBDIR=./lib -PSRESDIR=./Resource -PSGENDIR=./obj -PSOBJDIR=./obj - -# Do not edit the next group of lines. - -include $(GLSRCDIR)/version.mak -DD=$(GLGENDIR)/ -GLD=$(GLGENDIR)/ -PSD=$(PSGENDIR)/ - -# ------ Generic options ------ # - -# Define the default directory/ies for the runtime -# initialization, resource and font files. Separate multiple directories with a :. - -GS_LIB_DEFAULT=:Resource/Init:lib,:Resource/Font,:fonts,:examples - -GS_DOCDIR=:doc - -# Define whether or not searching for initialization files should always -# look in the current directory first. This leads to well-known security -# and confusion problems, but may be convenient sometimes. - -SEARCH_HERE_FIRST=0 - -# Define the name of the interpreter initialization file. -# (There is no reason to change this.) - -GS_INIT=gs_init.ps - -# Choose generic configuration options. - -GENOPT= - -# Define the name of the executable file. Not used for the CW project, don't change it - -GS=macgs - -# Define the platform name. - -GSPLATFORM=macos_ - - -# don't use any shared libraries, they are compiled into the Ghostscript Lib - -SHARE_LIBPNG=0 -SHARE_JPEG=0 -SHARE_ZLIB=0 -SHARE_JBIG2=0 -SHARE_JPX=0 - -# Define the directory where the IJG JPEG library sources are stored, -# and the major version of the library that is stored there. -# You may need to change this if the IJG library version changes. -# See jpeg.mak for more information. - -JSRCDIR=jpeg - -# Define the directory where the PNG library sources are stored, -# and the version of the library that is stored there. -# You may need to change this if the libpng version changes. -# See png.mak for more information. - -PNGSRCDIR=libpng - -# Define the directory where the zlib sources are stored. -# See zlib.mak for more information. - -ZSRCDIR=zlib - -# Define the jbig2dec library source location. -# See jbig2.mak for more information. - -JBIG2_LIB=jbig2dec -JBIG2SRCDIR=jbig2dec - -# Define the directory where the lcms source is stored. -# See lcms.mak for more information - -LCMSSRCDIR=lcms - -# Define the directory where the lcms2 source is stored. -# See lcms2.mak for more information - -LCMS2SRCDIR=lcms2 - -# Which CMS are we using? -# Options are currently lcms or lcms2 - -WHICH_CMS=lcms2 - -# IJS has not been ported to MacOS Classic. If you do the port, -# you'll need to set these values. You'll also need to -# include the ijs.mak makefile -# -# Define the directory where the ijs source is stored, -# and the process forking method to use for the server. -# See ijs.mak for more information. - -#IJSSRCDIR=ijs -#IJSEXECTYPE=unix - -# ------ Platform-specific options ------ # - -# Define the name of the C compiler. - -# we don't want to build, so CC and LD don't have to do anything, just echo the arguments -CC=echo -CFLAGS= -CCLD= -LDFLAGS= -EXTRALIBS= -STDLIBS= -# Define the .dev module that implements thread and synchronization -# primitives for this platform. -# No real sync in MacOS 8/9, so leave it at nosync - -SYNC=nosync - -# define the file name extension for a shared lib -DYNANIC_LIB_EXT=dylib - -# ------ Devices and features ------ # - -# Choose the language feature(s) to include. See gs.mak for details. - -FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)epsf.dev $(GLD)pipe.dev $(PSD)macres.dev $(PSD)macpoll.dev $(PSD)jbig2.dev -#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev -#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(GLD)pipe.dev -# The following is strictly for testing. -FEATURE_DEVS_ALL=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(PSD)double.dev $(PSD)trapping.dev $(PSD)stocht.dev $(GLD)pipe.dev $(GLD)macres.dev $(PSD)jbig2.dev $(PSD)jpx.dev $(PSD)macpoll.dev -#FEATURE_DEVS=$(FEATURE_DEVS_ALL) - -# Choose whether to compile the .ps initialization files into the executable. -# See gs.mak for details. - -COMPILE_INITS=0 - -# Choose whether to store band lists on files or in memory. -# The choices are 'file' or 'memory'. - -BAND_LIST_STORAGE=file - -# Choose which compression method to use when storing band lists in memory. -# The choices are 'lzw' or 'zlib'. - -BAND_LIST_COMPRESSOR=zlib - -# Choose the implementation of file I/O: 'stdio', 'fd', or 'both'. -# See gs.mak and sfxfd.c for more details. - -FILE_IMPLEMENTATION=stdio - -# Choose the implementation of stdio: '' for file I/O and 'c' for callouts -# See gs.mak and ziodevs.c/ziodevsc.c for more details. - -STDIO_IMPLEMENTATION=c - -# Choose the device(s) to include. See devs.mak for details, -# devs.mak and contrib.mak for the list of available devices. - -DEVICE_DEVS=$(DD)macos.dev $(DD)macos_.dev $(DD)display.dev - -#DEVICE_DEVS1= -#DEVICE_DEVS2= -#DEVICE_DEVS3= -#DEVICE_DEVS4= -#DEVICE_DEVS5= -#DEVICE_DEVS6= -#DEVICE_DEVS7= -#DEVICE_DEVS8= -#DEVICE_DEVS9= -#DEVICE_DEVS10= -#DEVICE_DEVS11= -#DEVICE_DEVS12= -#DEVICE_DEVS13= -#DEVICE_DEVS14= -#DEVICE_DEVS15= -#DEVICE_DEVS16= -#DEVICE_DEVS17= -#DEVICE_DEVS18= -#DEVICE_DEVS19= -#DEVICE_DEVS20= - -DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpgray.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)bmp32b.dev -DEVICE_DEVS2= -DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev $(DD)lj5mono.dev $(DD)lj5gray.dev -DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev -DEVICE_DEVS5=$(DD)uniprint.dev -DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev -DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev -DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev -DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev $(DD)pamcmyk32.dev -DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev -DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev $(DD)tiffscaled.dev $(DD)tiffscaled8.dev $(DD)tiffscaled24.dev $(DD)tiffscaled32.dev -DEVICE_DEVS12=$(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev -DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pngmonod.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev -DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev -DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)ps2write.dev $(DD)epswrite.dev $(DD)txtwrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev - -DEVICE_DEVS16=$(DD)bbox.dev $(DD)inkcov.dev -DEVICE_DEVS17= -DEVICE_DEVS18= -DEVICE_DEVS19= -DEVICE_DEVS20=$(DD)cljet5.dev $(DD)cljet5c.dev - -# ---------------------------- End of options --------------------------- # - -# Define the name of the partial makefile that specifies options -- -# used in dependencies. - -MAKEFILE=$(GLSRCDIR)/macos-mcp.mak -TOP_MAKEFILES= - - -# Define the auxilary program dependency. (we don't have any) - -AK= - -# Define the compilation rules and flags. - -CCFLAGS=$(GENOPT) $(CFLAGS) -CC_=$(CC) $(CCFLAGS) -# define CCAUX as the real cc compiler, we use this to build the code generation tools -CCAUX=cc -# These are the specific warnings we have to turn off to compile those -# specific few files that need this. We may turn off others in the future. -CC_NO_WARN=$(CC_) -Wno-cast-qual -Wno-traditional - -LD_SET_DT_SONAME=-soname= - -# ---------------- End of platform-specific section ---------------- # - -include $(GLSRCDIR)/unixhead.mak - -# Redefine the platform name before going on -GSPLATFORM=macos_ - -include $(GLSRCDIR)/gs.mak -# psromfs.mak must precede lib.mak -include $(PSSRCDIR)/psromfs.mak -include $(GLSRCDIR)/lib.mak -include $(PSSRCDIR)/int.mak -include $(GLSRCDIR)/jpeg.mak -# zlib.mak must precede png.mak -include $(GLSRCDIR)/zlib.mak -include $(GLSRCDIR)/png.mak -include $(GLSRCDIR)/jbig2.mak -include $(GLSRCDIR)/ldf_jb2.mak -include $(GLSRCDIR)/lwf_jp2.mak -include $(GLSRCDIR)/openjpeg.mak -include $(GLSRCDIR)/devs.mak -include $(GLSRCDIR)/contrib.mak -#include $(GLSRCDIR)/unix-aux.mak -#include $(GLSRCDIR)/unixlink.mak -#include $(GLSRCDIR)/unix-dll.mak -include $(GLSRCDIR)/unix-end.mak -#include $(GLSRCDIR)/unixinst.mak - - - -# ------------------------------------------------------------------- # -# ------------------------------------------------------------------- # - - - -# --------------- mac device sources (move to devs.mak??) ----------- # - -gdevmac_h=$(GLSRC)gdevmac.h -gdevmacttf_h=$(GLSRC)gdevmacttf.h - -macos_=$(GLOBJ)gdevmac.$(OBJ) - -$(GLD)macos.dev: $(macos_) $(GLOBJ)gdevemap.$(OBJ) - $(SETDEV) $(PSD)macos $(macos_) - -$(GLOBJ)gdevmac.$(OBJ): $(GLSRC)gdevmac.c $(gp_mac_h) $(gdevmac_h) -$(GLOBJ)gdevemap.$(OBJ): $(GLSRC)gdevemap.c - -# -------------------- Platform specific sources -------------------- # - -gp_mac_h=$(GLSRC)gp_mac.h -gconfig_h=$(GLOBJ)gconfig.h - -macsystypes_h=$(GLSRC)macsystypes.h -systypes_h=$(GLOBJ)sys/types.h - -$(GLOBJ)gp_mac.$(OBJ): $(GLSRC)gp_mac.c -$(GLOBJ)gp_macio.$(OBJ): $(GLSRC)gp_macio.c $(gx_h) $(gp_h) $(gpmisc_h) -$(GLOBJ)gp_stdin.$(OBJ): $(GLSRC)gp_stdin.c $(AK) $(stdio__h) $(gx_h) $(gp_h) - -# ------------------------------------------------------------------- # - -MAC1=$(GLOBJ)gp_macio.$(OBJ) $(GLOBJ)gp_mac.$(OBJ) $(GLOBJ)gp_stdin.$(OBJ) -MAC2=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_paper.$(OBJ) $(GLOBJ)gp_nsync.$(OBJ) $(GLOBJ)gdevemap.$(OBJ) $(GLOBJ)gsdll.$(OBJ) - -$(GLD)macos_.dev: $(MAC1) - $(SETMOD) $(DD)macos_ $(MAC1) $(MAC) - $(ADDMOD) $(DD)macos_ -obj $(MAC2) - # uncomment the line below if you need the legacy macstdio device - #$(ADDMOD) $(DD)macos_ -iodev macstdio # macstdio does not work with MSL!!! - -# Define polling as a separable feature because it is not needed by the gslib. -macpoll_=$(GLOBJ)gp_macpoll.$(OBJ) -$(GLD)macpoll.dev: $(ECHOGS_XE) $(macpoll_) - $(SETMOD) $(GLD)macpoll $(macpoll_) - -$(GLOBJ)gp_macpoll.$(OBJ): $(GLSRC)gp_macpoll.c $(AK)\ - $(gx_h) $(gp_h) $(gpcheck_h) $(iapi_h) $(iref_h) $(iminst_h) $(imain_h) - - -# ------------------------------------------------------------------- # - -# -------------------------- Auxiliary files ------------------------ # - -# No special gconfig_.h is needed. -$(gconfig__h): - echo "/* This file deliberately left blank. */" > $(gconfig__h) - -$(ECHOGS_XE): $(GLSRC)echogs.c $(AK) $(ECHOGS_DEPS) - $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(ECHOGS_XE) $(GLSRC)echogs.c - -$(GENARCH_XE): $(GLSRC)genarch.c $(AK) $(GENARCH_DEPS) - $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENARCH_XE) $(GLSRC)genarch.c - -$(GENCONF_XE): $(GLSRC)genconf.c $(AK) $(GENCONF_DEPS) - $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENCONF_XE) $(GLSRC)genconf.c - -$(GENDEV_XE): $(GLSRC)gendev.c $(AK) $(GENDEV_DEPS) - $(CCAUX) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENDEV_XE) $(GLSRC)gendev.c - -$(GENHT_XE): $(GLSRC)genht.c $(AK) $(GENHT_DEPS) - $(CCAUX) $(GENHT_CFLAGS) $(O_)$(GENHT_XE) $(GLSRC)genht.c - - -MKROMFS_OBJS=$(MKROMFS_ZLIB_OBJS) \ - (GLOBJ)gscdefs.$(OBJ) $(GLOBJ)gpmisc.$(OBJ) $(GLOBJ)gp_macio.$(OBJ) $(GLOBJ)gp_mac.$(OBJ) -$(MKROMFS_XE): $(GLSRC)mkromfs.c $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS) - $(CCAUX) $(GENOPT) $(CFLAGS_DEBUG) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLOBJ)$(_I) $(I_)$(ZSRCDIR)$(_I) $(GLSRC)mkromfs.c $(O_)$(MKROMFS_XE) $(MKROMFS_OBJS) -lm - -# ---------------------- CW XML Project file ------------------------ # - -ldt_tr=$(PSOBJ)ldt.tr -CWPROJ_XML=./ghostscript.mcp.xml - -$(CWPROJ_XML): $(gconfigd_h) - -mkdir -p obj/sys - $(CP_) $(macsystypes_h) $(systypes_h) - $(SH) $(GLSRC)macgenmcpxml.sh `$(CAT) $(ld_tr)` > $(CWPROJ_XML) - $(CP_) $(GLSRC)gconf.c $(GLOBJ)gconfig.c - $(CP_) $(GLSRC)iconf.c $(GLOBJ)iconfig.c - $(CP_) $(GLSRC)gscdef.c $(GLOBJ)gscdefs.c - /Developer/Tools/SetFile -c CWIE -t TEXT $(CWPROJ_XML) - -$(GS_XE): $(ld_tr) $(ECHOGS_XE) $(XE_ALL) $(CWPROJ_XML) $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) - -# ------------------------------------------------------------------- # - -# This has to come last so it won't be taken as the default target. -$(AK): - if ( $(CCAUX) --version | egrep "^2\.7\.([01]|2(\.[^1-9]|$$))" >/dev/null ); then echo -Dconst= >$(AK); else echo -Wcast-qual -Wwrite-strings >$(AK); fi - diff -Nru ghostscript-9.10~dfsg/base/macosx.mak ghostscript-9.25~dfsg+1/base/macosx.mak --- ghostscript-9.10~dfsg/base/macosx.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/macosx.mak 1970-01-01 00:00:00.000000000 +0000 @@ -1,433 +0,0 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. -# All Rights Reserved. -# -# This software is provided AS-IS with no warranty, either express or -# implied. -# -# This software is distributed under license and may not be copied, -# modified or distributed except as expressly authorized under the terms -# of the license contained in the file LICENSE in this distribution. -# -# Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. -# -# makefile for MacOS X/darwin/gcc/framework configuration. - -# ------------------------------- Options ------------------------------- # - -####### The following are the only parts of the file you should need to edit. - -# Define the directory for the final executable, and the -# source, generated intermediate file, and object directories -# for the graphics library (GL) and the PostScript/PDF interpreter (PS). - -BINDIR=./$(BUILDDIRPREFIX)bin -GLSRCDIR=./base -DEVSRCDIR=./devices -GLGENDIR=./$(BUILDDIRPREFIX)obj -GLOBJDIR=./$(BUILDDIRPREFIX)obj -DEVGENDIR=./$(BUILDDIRPREFIX)obj -DEVOBJDIR=./$(BUILDDIRPREFIX)obj -AUXDIR=$(GLGENDIR)/aux -PSSRCDIR=./psi -PSLIBDIR=./lib -PSRESDIR=./Resource -PSGENDIR=./$(BUILDDIRPREFIX)obj -PSOBJDIR=./$(BUILDDIRPREFIX)obj - -# Do not edit the next group of lines. - -#include $(COMMONDIR)/gccdefs.mak -#include $(COMMONDIR)/unixdefs.mak -#include $(COMMONDIR)/generic.mak -include $(GLSRCDIR)/version.mak -DD=$(GLGENDIR)/ -GLD=$(GLGENDIR)/ -PSD=$(PSGENDIR)/ - -# ------ Generic options ------ # - -# Define the installation commands and target directories for -# executables and files. The commands are only relevant to `make install'; -# the directories also define the default search path for the -# initialization files (gs_*.ps) and the fonts. - -INSTALL = $(GLSRCDIR)/instcopy -c -INSTALL_PROGRAM = $(INSTALL) -m 755 -INSTALL_DATA = $(INSTALL) -m 644 - -FRAMEWORK_NAME=Ghostscript -FRAMEWORK_EXT=.framework -prefix = /Library/Frameworks/$(FRAMEWORK_NAME)$(FRAMEWORK_EXT) -exec_prefix = $(prefix) -bindir = $(exec_prefix)/bin -scriptdir = $(bindir) -includedir = $(prefix)/include -libdir = $(exec_prefix)/lib -mandir = $(prefix)/man -man1ext = 1 -datadir = $(prefix)/Resources -gsdatadir = $(prefix)/Versions/$(GS_DOT_VERSION)/Resources -gssharedir = $(libdir)/ghostscript/$(GS_DOT_VERSION) -gsincludedir = $(includedir)/ghostscript/ - -docdir=$(gsdatadir)/doc -exdir=$(gsdatadir)/examples -GS_DOCDIR=$(docdir) - -# Define the default directory/ies for the runtime -# initialization, resource and font files. Separate multiple directories with a :. - -GS_LIB_DEFAULT=$(gsdatadir)/Resource/Init:$(gsdatadir)/lib:$(gsdatadir)/Resource/Font:$(datadir)/fonts:/Library/Fonts:/System/Library/Fonts - -# Define whether or not searching for initialization files should always -# look in the current directory first. This leads to well-known security -# and confusion problems, but may be convenient sometimes. - -SEARCH_HERE_FIRST=0 - -# Define the name of the interpreter initialization file. -# (There is no reason to change this.) - -GS_INIT=gs_init.ps - -# Choose generic configuration options. - -# -DDEBUG -# includes debugging features (-Z switch) in the code. -# Code runs substantially slower even if no debugging switches -# are set. - -GENOPT= - -# Choose capability options. - -# -DHAVE_MKSTEMP -# uses mkstemp instead of mktemp -# This uses the more secure temporary file creation call -# Enable this if it is available on your platform. - -CAPOPT= -DHAVE_MKSTEMP - -# Define the name of the executable file. - -GS=gs - -# Define the directories for debugging and profiling binaries, relative to -# the standard binaries. - -DEBUGDIRPREFIX=debug -MEMENTODIRPREFIX=debug -PGDIRPREFIX=pg -SODIRPREFIX=so - -# Define the directory where the IJG JPEG library sources are stored, -# and the major version of the library that is stored there. -# You may need to change this if the IJG library version changes. -# See jpeg.mak for more information. - -JSRCDIR=jpeg - -# Note: if a shared library is used, it may not contain the -# D_MAX_BLOCKS_IN_MCU patch, and thus may not be able to read -# some older JPEG streams that violate the standard. If the JPEG -# library built from local sources, the patch will be applied. - -SHARE_JPEG=0 -JPEG_NAME=jpeg - -# Define the directory where the PNG library sources are stored, -# and the version of the library that is stored there. -# You may need to change this if the libpng version changes. -# See png.mak for more information. - -PNGSRCDIR=libpng - -# Choose whether to use a shared version of the PNG library, and if so, -# what its name is. -# See gs.mak and Make.htm for more information. - -SHARE_LIBPNG=0 -LIBPNG_NAME=png - -# Define the directory where the zlib sources are stored. -# See zlib.mak for more information. - -ZSRCDIR=zlib - -# Choose whether to use a shared version of the zlib library, and if so, -# what its name is (usually libz, but sometimes libgz). -# See gs.mak and Make.htm for more information. - -SHARE_ZLIB=1 -#ZLIB_NAME=gz -ZLIB_NAME=z - -# Choose shared or compiled in libjbig2dec and source location - -JBIG2_LIB=jbig2dec -SHARE_JBIG2=0 -JBIG2SRCDIR=jbig2dec - -# Define the directory where the lcms source is stored. -# See lcms.mak for more information - -LCMSSRCDIR=lcms - -# Define the directory where the lcms2 source is stored. -# See lcms2.mak for more information - -LCMS2SRCDIR=lcms2 - -# Which CMS are we using? -# Options are currently lcms or lcms2 - -WHICH_CMS=lcms2 - -# Define the directory where the ijs source is stored, -# and the process forking method to use for the server. -# See ijs.mak for more information. - -SHARE_IJS=0 -IJS_NAME= -IJSSRCDIR=ijs -IJSEXECTYPE=unix - -# Define how to build the library archives. (These are not used in any -# standard configuration.) - -AR=ar -ARFLAGS=qc -RANLIB=ranlib - -# ------ Platform-specific options ------ # - -# Define the name of the C compiler. - -CC=cc - -# Define the name of the linker for the final link step. -# Normally this is the same as the C compiler. - -CCLD=$(CC) - -# Define the default gcc flags. -# Note that depending whether or not we are running a version of gcc with -# the 2.7.0-2.7.2 optimizer bug, either "-Dconst=" or -# "-Wcast-qual -Wwrite-strings" is automatically included. - -GCFLAGS=-Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes \ - -fno-builtin -fno-common -DHAVE_STDINT_H - -# Define the added flags for standard, debugging, profiling -# and shared object builds. - -CFLAGS_STANDARD= -CFLAGS_DEBUG=-g -O -CFLAGS_PROFILE=-pg -O2 -CFLAGS_SO=-dynamic - -# Define the other compilation flags. Add at most one of the following: -# -DBSD4_2 for 4.2bsd systems. -# -DSYSV for System V or DG/UX. -# -DSYSV -D__SVR3 for SCO ODT, ISC Unix 2.2 or before, -# or any System III Unix, or System V release 3-or-older Unix. -# -DSVR4 -DSVR4_0 (not -DSYSV) for System V release 4.0. -# -DSVR4 (not -DSYSV) for System V release 4.2 (or later) and Solaris 2. -# XCFLAGS can be set from the command line. -# We don't include -ansi, because this gets in the way of the platform- -# specific stuff that typically needs; nevertheless, we expect -# gcc to accept ANSI-style function prototypes and function definitions. -XCFLAGS= - -CFLAGS=$(CFLAGS_STANDARD) $(GCFLAGS) $(XCFLAGS) - -# Define platform flags for ld. -# SunOS 4.n may need -Bstatic. -# Solaris 2.6 (and possibly some other versions) with any of the SHARE_ -# parameters set to 1 may need -# -R /usr/local/xxx/lib:/usr/local/lib -# giving the full path names of the shared library directories. -# XLDFLAGS can be set from the command line. -XLDFLAGS= - -LDFLAGS=$(XLDFLAGS) - -# Define any extra libraries to link into the executable. -# ISC Unix 2.2 wants -linet. -# SCO Unix needs -lsocket if you aren't including the X11 driver. -# SVR4 may need -lnsl. -# Solaris may need -lnsl -lsocket -lposix4. -# (Libraries required by individual drivers are handled automatically.) - -EXTRALIBS= - -# Define the standard libraries to search at the end of linking. -# Most platforms require -lpthread for the POSIX threads library; -# on FreeBSD, change -lpthread to -lc_r; BSDI and perhaps some others -# include pthreads in libc and don't require any additional library. -# All reasonable platforms require -lm, but Rhapsody and perhaps one or -# two others fold libm into libc and don't require any additional library. - -# both of these are included in the stdlib on darwin/osx -#STDLIBS=-lpthread -lm - -# Define the include switch(es) for the X11 header files. -# This can be null if handled in some other way (e.g., the files are -# in /usr/include, or the directory is supplied by an environment variable); -# in particular, SCO Xenix, Unix, and ODT just want -XINCLUDE= -# Note that x_.h expects to find the header files in $(XINCLUDE)/X11, -# not in $(XINCLUDE). - -#XINCLUDE=-I/usr/X11R6/include - -# Define the directory/ies and library names for the X11 library files. -# XLIBDIRS is for ld and should include -L; XLIBDIR is for LD_RUN_PATH -# (dynamic libraries on SVR4) and should not include -L. -# Newer SVR4 systems can use -R in XLIBDIRS rather than setting XLIBDIR. -# Both can be null if these files are in the default linker search path; -# in particular, SCO Xenix, Unix, and ODT just want -XLIBDIRS= -# Solaris and other SVR4 systems with dynamic linking probably want -#XLIBDIRS=-L/usr/openwin/lib -R/usr/openwin/lib -# X11R6 (on any platform) may need -#XLIBS=Xt SM ICE Xext X11 - -#XLIBDIRS=-L/usr/local/X/lib -#XLIBDIRS=-L/usr/X11R6/lib -XLIBDIR= -#XLIBS=Xt Xext X11 -XLIBS= - -# Define the .dev module that implements thread and synchronization -# primitives for this platform. - -# If POSIX sync primitives are used, also change the STDLIBS to include -# the pthread library. -#SYNC=posync - -# Default is No sync primitives since some platforms don't have it (HP-UX) -SYNC=nosync - -# define the file name extension for a shared lib -DYNANIC_LIB_EXT=dylib - -# ------ Devices and features ------ # - -# Choose the language feature(s) to include. See gs.mak for details. - -FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)epsf.dev $(GLD)pipe.dev -#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev -#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(GLD)pipe.dev -# The following is strictly for testing. -FEATURE_DEVS_ALL=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(PSD)double.dev $(PSD)trapping.dev $(PSD)stocht.dev $(GLD)pipe.dev -#FEATURE_DEVS=$(FEATURE_DEVS_ALL) - -# Choose whether to compile the .ps initialization files into the executable. -# See gs.mak for details. - -COMPILE_INITS=1 - -# Choose whether to store band lists on files or in memory. -# The choices are 'file' or 'memory'. - -BAND_LIST_STORAGE=file - -# Choose which compression method to use when storing band lists in memory. -# The choices are 'lzw' or 'zlib'. - -BAND_LIST_COMPRESSOR=zlib - -# Choose the implementation of file I/O: 'stdio', 'fd', or 'both'. -# See gs.mak and sfxfd.c for more details. - -FILE_IMPLEMENTATION=stdio - -# Choose the implementation of stdio: '' for file I/O and 'c' for callouts -# See gs.mak and ziodevs.c/ziodevsc.c for more details. - -STDIO_IMPLEMENTATION=c - -# Override the default device. This is set to 'display' by -# unix-dll.mak when building a shared object. -DISPLAY_DEV= - -# Choose the device(s) to include. See devs.mak for details, -# devs.mak and contrib.mak for the list of available devices. - -# use png output by default -DEVICE_DEVS=$(DD)png16m.dev $(DD)pnggray.dev $(DD)pngmono.dev $(DD)pngmonod.dev -#DEVICE_DEVS=$(DISPLAY_DEV) - -# most devices are disabled by default since file conversion is the -# the major demand on macos -DEVICE_DEVS1= -DEVICE_DEVS2= -DEVICE_DEVS3= -DEVICE_DEVS4= -DEVICE_DEVS5= -DEVICE_DEVS6= -DEVICE_DEVS7= -DEVICE_DEVS8= -DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev $(DD)pamcmyk32.dev -DEVICE_DEVS10= -DEVICE_DEVS11= -DEVICE_DEVS12= -#DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pngmonod.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev -DEVICE_DEVS13=$(DD)png16.dev $(DD)png256.dev $(DD)pngalpha.dev -DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev -DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)ps2write.dev $(DD)epswrite.dev $(DD)txtwrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev -DEVICE_DEVS16=$(DD)bbox.dev $(DD)inkcov.dev -DEVICE_DEVS17= -DEVICE_DEVS18= -DEVICE_DEVS19= -DEVICE_DEVS20= - -# ---------------------------- End of options --------------------------- # - -# Define the name of the partial makefile that specifies options -- -# used in dependencies. - -MAKEFILE=$(GLSRCDIR)/macosx.mak -TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)/unixhead.mak - -# Define the auxiliary programs dependency. We don't use this. - -AK= - -# Define the compilation rules and flags. - -CCFLAGS=$(GENOPT) $(CAPOPT) $(CFLAGS) -CC_=$(CC) $(CCFLAGS) -CCAUX=$(CC) -# These are the specific warnings we have to turn off to compile those -# specific few files that need this. We may turn off others in the future. -CC_NO_WARN=$(CC_) -Wno-cast-qual -Wno-traditional - -LD_SET_DT_SONAME=-soname= - -# ---------------- End of platform-specific section ---------------- # - -include $(GLSRCDIR)/unixhead.mak -include $(GLSRCDIR)/gs.mak -# psromfs.mak must precede lib.mak -include $(PSSRCDIR)/psromfs.mak -include $(GLSRCDIR)/lib.mak -include $(PSSRCDIR)/int.mak -include $(GLSRCDIR)/jpeg.mak -# zlib.mak must precede png.mak -include $(GLSRCDIR)/zlib.mak -include $(GLSRCDIR)/png.mak -include $(GLSRCDIR)/jbig2.mak -include $(GLSRCDIR)/ijs.mak -include $(GLSRCDIR)/devs.mak -include $(GLSRCDIR)/contrib.mak -include $(GLSRCDIR)/unix-aux.mak -include $(GLSRCDIR)/unixlink.mak -#include $(GLSRCDIR)/unix-dll.mak -include $(GLSRCDIR)/macos-fw.mak -include $(GLSRCDIR)/unix-end.mak -include $(GLSRCDIR)/unixinst.mak - diff -Nru ghostscript-9.10~dfsg/base/macsystypes.h ghostscript-9.25~dfsg+1/base/macsystypes.h --- ghostscript-9.10~dfsg/base/macsystypes.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/macsystypes.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - - -#ifndef __sys_types_h__ -#define __sys_types_h__ - -#include -#include -#define CHECK_INTERRUPTS - -/* use a 64 bit type for color vectors. (from MacTypes.h) - this is important for devicen support, but can be safely - undef'd to fallback to a 32 bit representation */ -#define GX_COLOR_INDEX_TYPE UInt64 - -#define main gs_main - -#if (0) -#define fprintf myfprintf -#define fputs myfputs -#define getenv mygetenv -int myfprintf(FILE *file, const char *fmt, ...); -int myfputs(const char *string, FILE *file); -#endif - -/* Metrowerks CodeWarrior should define this */ -#ifndef __MACOS__ -#define __MACOS__ -#endif - -#endif /* __sys_types_h__ */ diff -Nru ghostscript-9.10~dfsg/base/malloc_.h ghostscript-9.25~dfsg+1/base/malloc_.h --- ghostscript-9.10~dfsg/base/malloc_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/malloc_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,6 +24,7 @@ /* This is a good place to #define MEMENTO, if you're using it. */ +#include "bobbin.h" #include "memento.h" #ifdef __TURBOC__ diff -Nru ghostscript-9.10~dfsg/base/math_.h ghostscript-9.25~dfsg+1/base/math_.h --- ghostscript-9.10~dfsg/base/math_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/math_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -58,6 +58,11 @@ ((0x1000000 - 1.0) * 0x1000000 * 0x1000000 * 0x10000000 * 0x10000000) #endif +/* IEEE, FLT_EPSILON */ +#ifndef FLT_EPSILON +#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */ +#endif + /* we use our own hypot() since the system one is not consistent between Linux and Mac OS X, also ours is faster */ #undef hypot #define hypot(x,y) sqrt((double)(x)*(x)+(double)(y)*(y)) @@ -74,4 +79,14 @@ #define sqrt(x) gs_sqrt(x, __FILE__, __LINE__) #endif /* DEBUG */ +#if defined(_MSC_VER) +#if _MSC_VER < 1800 +#define isnan(x) _isnan(x) +#define isfinite(x) _finite(x) +#define isinf(x) (!_finite(x)) +#endif +#define HAVE_ISNAN +#define HAVE_ISINF +#endif + #endif /* math__INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/md5.c ghostscript-9.25~dfsg+1/base/md5.c --- ghostscript-9.10~dfsg/base/md5.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/md5.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,382 +0,0 @@ -/* - Copyright (C) 1999-2012 Artifex Software, Inc. - All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2007-06-08 RG Namespaced the api calls to avoid conflict with other - implementations when linking gs as a library. - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -#include "md5.h" -#include - -#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ -#ifdef ARCH_IS_BIG_ENDIAN -# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) -#else -# define BYTE_ORDER 0 -#endif - -#define T_MASK ((gs_md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - -static void -gs_md5_process(gs_md5_state_t *pms, const gs_md5_byte_t *data /*[64]*/) -{ - gs_md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - gs_md5_word_t t; -#if BYTE_ORDER > 0 - /* Define storage only for big-endian CPUs. */ - gs_md5_word_t X[16]; -#else - /* Define storage for little-endian or both types of CPUs. */ - gs_md5_word_t xbuf[16]; - const gs_md5_word_t *X; -#endif - - { -#if BYTE_ORDER == 0 - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const gs_md5_byte_t *)&w)) /* dynamic little-endian */ -#endif -#if BYTE_ORDER <= 0 /* little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - (const gs_md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const gs_md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } -#endif -#if BYTE_ORDER == 0 - else /* dynamic big-endian */ -#endif -#if BYTE_ORDER >= 0 /* big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const gs_md5_byte_t *xp = data; - int i; - -# if BYTE_ORDER == 0 - X = xbuf; /* (dynamic only) */ -# else -# define xbuf X /* (static only) */ -# endif - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } -#endif - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); -#undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); -#undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); -#undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); -#undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -void -gs_md5_init(gs_md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -void -gs_md5_append(gs_md5_state_t *pms, const gs_md5_byte_t *data, int nbytes) -{ - const gs_md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - gs_md5_word_t nbits = (gs_md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - gs_md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - gs_md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -void -gs_md5_finish(gs_md5_state_t *pms, gs_md5_byte_t digest[16]) -{ - static const gs_md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - gs_md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (gs_md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - gs_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - gs_md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (gs_md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} diff -Nru ghostscript-9.10~dfsg/base/md5.h ghostscript-9.25~dfsg+1/base/md5.h --- ghostscript-9.10~dfsg/base/md5.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/md5.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ -/* - Copyright (C) 1999-2012 Artifex Software, Inc. - All rights reserved. - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.h is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Removed support for non-ANSI compilers; removed - references to Ghostscript; clarified derivation from RFC 1321; - now handles byte order either statically or dynamically. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); - added conditionalization for C++ compilation from Martin - Purschke . - 1999-05-03 lpd Original version. - */ - -#ifndef md5_INCLUDED -# define md5_INCLUDED - -/* - * This package supports both compile-time and run-time determination of CPU - * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be - * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is - * defined as non-zero, the code will be compiled to run only on big-endian - * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to - * run on either big- or little-endian CPUs, but will run slightly less - * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. - */ - -typedef unsigned char gs_md5_byte_t; /* 8-bit byte */ -typedef unsigned int gs_md5_word_t; /* 32-bit word */ - -/* Define the state of the MD5 Algorithm. */ -typedef struct gs_md5_state_s { - gs_md5_word_t count[2]; /* message length in bits, lsw first */ - gs_md5_word_t abcd[4]; /* digest buffer */ - gs_md5_byte_t buf[64]; /* accumulate block */ -} gs_md5_state_t; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Initialize the algorithm. */ -void gs_md5_init(gs_md5_state_t *pms); - -/* Append a string to the message. */ -void gs_md5_append(gs_md5_state_t *pms, const gs_md5_byte_t *data, int nbytes); - -/* Finish the message and return the digest. */ -void gs_md5_finish(gs_md5_state_t *pms, gs_md5_byte_t digest[16]); - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* md5_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/md5main.c ghostscript-9.25~dfsg+1/base/md5main.c --- ghostscript-9.10~dfsg/base/md5main.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/md5main.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2012 Artifex Software, Inc. + Copyright (C) 2002-2018 Artifex Software, Inc. All rights reserved. This software is provided 'as-is', without any express or implied @@ -42,7 +42,7 @@ 2002-04-13 lpd Splits off main program into a separate file, md5main.c. */ -#include "md5.h" +#include "gsmd5.h" #include #include #include diff -Nru ghostscript-9.10~dfsg/base/memento.c ghostscript-9.25~dfsg+1/base/memento.c --- ghostscript-9.10~dfsg/base/memento.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/memento.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,31 +1,24 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2009-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or implied. - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. */ - /* Inspired by Fortify by Simon P Bullen. */ - /* Set the following if you're only looking for leaks, not memory overwrites * to speed the operation */ /* #define MEMENTO_LEAKONLY */ -#ifndef MEMENTO_STACKTRACE_METHOD -#ifdef __GNUC__ -#define MEMENTO_STACKTRACE_METHOD 1 -#endif -#endif +/* Set the following to keep extra details about the history of blocks */ +#define MEMENTO_DETAILS /* Don't keep blocks around if they'd mean losing more than a quarter of * the freelist. */ @@ -40,19 +33,117 @@ #ifdef MEMENTO_GS_HACKS /* For GS we include malloc_.h. Anyone else would just include memento.h */ #include "malloc_.h" -#ifdef __MACH__ -#include -#else -#ifndef memset -void *memset(void *,int,size_t); -#endif -#endif +#include "memory_.h" int atexit(void (*)(void)); #else #include "memento.h" #include #include #endif +#ifndef _MSC_VER +#include +#include +#endif + +#ifdef MEMENTO + +#ifndef MEMENTO_CPP_EXTRAS_ONLY + +#ifdef MEMENTO_ANDROID +#include + +static char log_buffer[4096]; +static int log_fill = 0; + +static char log_buffer2[4096]; + +static int +android_fprintf(FILE *file, const char *fmt, ...) +{ + va_list args; + char *p, *q; + + va_start(args, fmt); + vsnprintf(log_buffer2, sizeof(log_buffer2)-1, fmt, args); + va_end(args); + + /* Ensure we are always null terminated */ + log_buffer2[sizeof(log_buffer2)-1] = 0; + + p = log_buffer2; + q = p; + do + { + /* Find the end of the string, or the next \n */ + while (*p && *p != '\n') + p++; + + /* We need to output from q to p. Limit ourselves to what + * will fit in the existing */ + if (p - q >= sizeof(log_buffer)-1 - log_fill) + p = q + sizeof(log_buffer)-1 - log_fill; + + memcpy(&log_buffer[log_fill], q, p-q); + log_fill += p-q; + if (*p == '\n') + { + log_buffer[log_fill] = 0; + __android_log_print(ANDROID_LOG_ERROR, "memento", "%s", log_buffer); + usleep(1); + log_fill = 0; + p++; /* Skip over the \n */ + } + else if (log_fill >= sizeof(log_buffer)-1) + { + log_buffer[sizeof(log_buffer2)-1] = 0; + __android_log_print(ANDROID_LOG_ERROR, "memento", "%s", log_buffer); + usleep(1); + log_fill = 0; + } + q = p; + } + while (*p); + + return 0; +} + +#define fprintf android_fprintf +#define MEMENTO_STACKTRACE_METHOD 3 +#endif + +#if defined(_WIN32) || defined(_WIN64) +#include + +static int +windows_fprintf(FILE *file, const char *fmt, ...) +{ + va_list args; + char text[4096]; + int ret; + + va_start(args, fmt); + ret = vfprintf(file, fmt, args); + va_end(args); + + va_start(args, fmt); + vsnprintf(text, 4096, fmt, args); + OutputDebugStringA(text); + va_end(args); + + return ret; +} + +#define fprintf windows_fprintf +#endif + +#ifndef MEMENTO_STACKTRACE_METHOD +#ifdef __GNUC__ +#define MEMENTO_STACKTRACE_METHOD 1 +#endif +#ifdef _WIN32 +#define MEMENTO_STACKTRACE_METHOD 2 +#endif +#endif #if defined(__linux__) #define MEMENTO_HAS_FORK @@ -79,8 +170,6 @@ #define MEMENTO_MAXPATTERN 0 #endif -#ifdef MEMENTO - #ifdef MEMENTO_GS_HACKS #include "valgrind.h" #else @@ -98,24 +187,73 @@ Memento_PostSize = 16 }; +/* Some compile time checks */ +typedef struct +{ + char MEMENTO_PRESIZE_MUST_BE_A_MULTIPLE_OF_4[Memento_PreSize & 3 ? -1 : 1]; + char MEMENTO_POSTSIZE_MUST_BE_A_MULTIPLE_OF_4[Memento_PostSize & 3 ? -1 : 1]; + char MEMENTO_POSTSIZE_MUST_BE_AT_LEAST_4[Memento_PostSize >= 4 ? 1 : -1]; + char MEMENTO_PRESIZE_MUST_BE_AT_LEAST_4[Memento_PreSize >= 4 ? 1 : -1]; +} MEMENTO_SANITY_CHECK_STRUCT; + +#define MEMENTO_UINT32 unsigned int +#define MEMENTO_UINT16 unsigned short + +#define MEMENTO_PREFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_PREFILL | (MEMENTO_PREFILL <<8) | (MEMENTO_PREFILL <<16) |(MEMENTO_PREFILL <<24))) +#define MEMENTO_POSTFILL_UINT16 ((MEMENTO_UINT16)(MEMENTO_POSTFILL | (MEMENTO_POSTFILL<<8))) +#define MEMENTO_POSTFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_POSTFILL | (MEMENTO_POSTFILL<<8) | (MEMENTO_POSTFILL<<16) |(MEMENTO_POSTFILL<<24))) +#define MEMENTO_FREEFILL_UINT16 ((MEMENTO_UINT16)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8))) +#define MEMENTO_FREEFILL_UINT32 ((MEMENTO_UINT32)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8) | (MEMENTO_FREEFILL<<16) |(MEMENTO_FREEFILL<<24))) + enum { Memento_Flag_OldBlock = 1, Memento_Flag_HasParent = 2, Memento_Flag_BreakOnFree = 4, - Memento_Flag_BreakOnRealloc = 8 + Memento_Flag_BreakOnRealloc = 8, + Memento_Flag_Freed = 16, + Memento_Flag_KnownLeak = 32 +}; + +enum { + Memento_EventType_malloc = 0, + Memento_EventType_calloc = 1, + Memento_EventType_realloc = 2, + Memento_EventType_free = 3, + Memento_EventType_new = 4, + Memento_EventType_delete = 5, + Memento_EventType_newArray = 6, + Memento_EventType_deleteArray = 7, + Memento_EventType_takeRef = 8, + Memento_EventType_dropRef = 9, + Memento_EventType_reference = 10 +}; + +static const char *eventType[] = +{ + "malloc", + "calloc", + "realloc", + "free", + "new", + "delete", + "new[]", + "delete[]", + "takeRef", + "dropRef", + "reference" }; /* When we list leaked blocks at the end of execution, we search for pointers * between blocks in order to be able to give a nice nested view. * Unfortunately, if you have are running your own allocator (such as - * ghostscripts chunk allocator) you can often find that the header of the + * postscript's chunk allocator) you can often find that the header of the * block always contains pointers to next or previous blocks. This tends to * mean the nesting displayed is "uninteresting" at best :) * * As a hack to get around this, we have a define MEMENTO_SKIP_SEARCH that * indicates how many bytes to skip over at the start of the chunk. * This may cause us to miss true nestings, but such is life... - */ + */ #ifndef MEMENTO_SEARCH_SKIP #ifdef MEMENTO_GS_HACKS #define MEMENTO_SEARCH_SKIP (2*sizeof(void *)) @@ -124,24 +262,46 @@ #endif #endif -typedef struct Memento_BlkHeader Memento_BlkHeader; +#define MEMENTO_CHILD_MAGIC ((Memento_BlkHeader *)('M' | ('3' << 8) | ('m' << 16) | ('3' << 24))) +#define MEMENTO_SIBLING_MAGIC ((Memento_BlkHeader *)('n' | ('t' << 8) | ('0' << 16) | ('!' << 24))) -struct Memento_BlkHeader +#ifdef MEMENTO_DETAILS +typedef struct Memento_BlkDetails Memento_BlkDetails; + +struct Memento_BlkDetails { - size_t rawsize; - int sequence; - int lastCheckedOK; - int flags; - Memento_BlkHeader *next; - Memento_BlkHeader *parent; /* Only used while printing out nested list */ + Memento_BlkDetails *next; + char type; + char count; + int sequence; + void *stack[1]; +}; +#endif /* MEMENTO_DETAILS */ - const char *label; +typedef struct Memento_BlkHeader Memento_BlkHeader; - /* Entries for nesting display calculations */ - Memento_BlkHeader *child; - Memento_BlkHeader *sibling; +struct Memento_BlkHeader +{ + size_t rawsize; + int sequence; + int lastCheckedOK; + int flags; + Memento_BlkHeader *next; + Memento_BlkHeader *prev; /* Reused as 'parent' when printing nested list */ + + const char *label; + + /* Entries for nesting display calculations. Set to magic + * values at all other time. */ + Memento_BlkHeader *child; + Memento_BlkHeader *sibling; + +#ifdef MEMENTO_DETAILS + Memento_BlkDetails *details; + Memento_BlkDetails **details_tail; +#endif - char preblk[Memento_PreSize]; + char preblk[Memento_PreSize]; }; /* In future this could (should) be a smarter data structure, like, say, @@ -149,10 +309,54 @@ */ typedef struct Memento_Blocks { - Memento_BlkHeader *head; - Memento_BlkHeader **tail; + Memento_BlkHeader *head; + Memento_BlkHeader *tail; } Memento_Blocks; +/* What sort of Mutex should we use? */ +#ifdef MEMENTO_LOCKLESS +typedef int Memento_mutex; + +static void Memento_initMutex(Memento_mutex *m) +{ + (void)m; +} + +#define MEMENTO_DO_LOCK() do { } while (0) +#define MEMENTO_DO_UNLOCK() do { } while (0) + +#else +#if defined(_WIN32) || defined(_WIN64) +/* Windows */ +typedef CRITICAL_SECTION Memento_mutex; + +static void Memento_initMutex(Memento_mutex *m) +{ + InitializeCriticalSection(m); +} + +#define MEMENTO_DO_LOCK() \ + EnterCriticalSection(&memento.mutex) +#define MEMENTO_DO_UNLOCK() \ + LeaveCriticalSection(&memento.mutex) + +#else +#include +typedef pthread_mutex_t Memento_mutex; + +static void Memento_initMutex(Memento_mutex *m) +{ + pthread_mutex_init(m, NULL); +} + +#define MEMENTO_DO_LOCK() \ + pthread_mutex_lock(&memento.mutex) +#define MEMENTO_DO_UNLOCK() \ + pthread_mutex_unlock(&memento.mutex) + +#endif +#endif + /* And our global structure */ static struct { int inited; @@ -174,6 +378,7 @@ int pattern; int nextPattern; int patternBit; + int leaking; size_t maxMemory; size_t alloc; size_t peakAlloc; @@ -181,7 +386,8 @@ size_t numMallocs; size_t numFrees; size_t numReallocs; -} globals; + Memento_mutex mutex; +} memento; #define MEMENTO_EXTRASIZE (sizeof(Memento_BlkHeader) + Memento_PostSize) @@ -193,7 +399,500 @@ #define MEMBLK_FROMBLK(B) (&((Memento_BlkHeader*)(void *)(B))[-1]) #define MEMBLK_TOBLK(B) ((void*)(&((Memento_BlkHeader*)(void*)(B))[1])) #define MEMBLK_POSTPTR(B) \ - (&((char *)(void *)(B))[(B)->rawsize + sizeof(Memento_BlkHeader)]) + (&((unsigned char *)(void *)(B))[(B)->rawsize + sizeof(Memento_BlkHeader)]) + +enum +{ + SkipStackBackTraceLevels = 4 +}; + +#if defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 1 +extern size_t backtrace(void **, int); +extern void backtrace_symbols_fd(void **, size_t, int); +extern char **backtrace_symbols(void **, size_t); + +#define MEMENTO_BACKTRACE_MAX 256 + +/* Libbacktrace gubbins - relies on us having libdl to load the .so */ +#ifdef HAVE_LIBDL +#include + +typedef void (*backtrace_error_callback) (void *data, const char *msg, int errnum); + +typedef struct backtrace_state *(*backtrace_create_state_type)( + const char *filename, int threaded, + backtrace_error_callback error_callback, void *data); + +typedef int (*backtrace_full_callback) (void *data, uintptr_t pc, + const char *filename, int lineno, + const char *function); + +typedef int (*backtrace_pcinfo_type)(struct backtrace_state *state, + uintptr_t pc, + backtrace_full_callback callback, + backtrace_error_callback error_callback, + void *data); + +typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc, + const char *symname, + uintptr_t symval, + uintptr_t symsize); + +typedef int (*backtrace_syminfo_type)(struct backtrace_state *state, + uintptr_t addr, + backtrace_syminfo_callback callback, + backtrace_error_callback error_callback, + void *data); + +static backtrace_syminfo_type backtrace_syminfo; +static backtrace_create_state_type backtrace_create_state; +static backtrace_pcinfo_type backtrace_pcinfo; +static struct backtrace_state *my_backtrace_state; +static void *libbt; +static void (*print_stack_value)(void *address); +static char backtrace_exe[4096]; +static void *current_addr; + +static void error2_cb(void *data, const char *msg, int errnum) +{ +} + +static void syminfo_cb(void *data, uintptr_t pc, const char *symname, uintptr_t symval, uintptr_t symsize) +{ + if (sizeof(void *) == 4) + fprintf(stderr, " 0x%08lx %s\n", pc, symname?symname:"?"); + else + fprintf(stderr, " 0x%016lx %s\n", pc, symname?symname:"?"); +} + +static void error_cb(void *data, const char *msg, int errnum) +{ + backtrace_syminfo(my_backtrace_state, + (uintptr_t)current_addr, + syminfo_cb, + error2_cb, + NULL); +} + +static int full_cb(void *data, uintptr_t pc, const char *fname, int line, const char *fn) +{ + if (sizeof(void *) == 4) + fprintf(stderr, " 0x%08lx %s(%s:%d)\n", pc, fn?fn:"?", fname?fname:"?", line); + else + fprintf(stderr, " 0x%016lx %s(%s:%d)\n", pc, fn?fn:"?", fname?fname:"?", line); + return 0; +} + +static void print_stack_libbt(void *addr) +{ + current_addr = addr; + backtrace_pcinfo(my_backtrace_state, + (uintptr_t)addr, + full_cb, + error_cb, + NULL); +} + +static void print_stack_libbt_failed(void *addr) +{ + char **strings = backtrace_symbols(&addr, 1); + + if (strings == NULL || strings[0] == NULL) + { + if (sizeof(void *) == 4) + fprintf(stderr, " [0x%08lx]\n", (uintptr_t)addr); + else + fprintf(stderr, " [0x%016lx]\n", (uintptr_t)addr); + } + else + { + fprintf(stderr, " %s\n", strings[0]); + } + (free)(strings); +} + +static int init_libbt(void) +{ + libbt = dlopen("libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/opt/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/usr/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + libbt = dlopen("/usr/local/lib/libbacktrace.so", RTLD_LAZY); + if (libbt == NULL) + goto fail; + + backtrace_create_state = dlsym(libbt, "backtrace_create_state"); + backtrace_syminfo = dlsym(libbt, "backtrace_syminfo"); + backtrace_pcinfo = dlsym(libbt, "backtrace_pcinfo"); + + if (backtrace_create_state == NULL || + backtrace_syminfo == NULL || + backtrace_pcinfo == NULL) + { + goto fail; + } + + my_backtrace_state = backtrace_create_state(backtrace_exe, + 1 /*BACKTRACE_SUPPORTS_THREADS*/, + error_cb, + NULL); + if (my_backtrace_state == NULL) + goto fail; + + print_stack_value = print_stack_libbt; + + return 1; + + fail: + libbt = NULL; + backtrace_create_state = NULL; + backtrace_syminfo = NULL; + print_stack_value = print_stack_libbt_failed; + return 0; +} +#endif + +static void print_stack_default(void *addr) +{ + char **strings = backtrace_symbols(&addr, 1); + + if (strings == NULL || strings[0] == NULL) + { + fprintf(stderr, " [0x%p]\n", addr); + } +#ifdef HAVE_LIBDL + else if (strchr(strings[0], ':') == NULL) + { + /* Probably a "path [address]" format string */ + char *s = strchr(strings[0], ' '); + + if (s != strings[0]) + { + memcpy(backtrace_exe, strings[0], s - strings[0]); + backtrace_exe[s-strings[0]] = 0; + if (init_libbt()) + print_stack_value(addr); + } + } +#endif + else + { + fprintf(stderr, " %s\n", strings[0]); + } + free(strings); +} + +static void Memento_initStacktracer(void) +{ + print_stack_value = print_stack_default; +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + size_t num; + + num = backtrace(&stack[0], MEMENTO_BACKTRACE_MAX); + + *skip = SkipStackBackTraceLevels; + if (num <= SkipStackBackTraceLevels) + return 0; + return (int)(num-SkipStackBackTraceLevels); +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ + int i; + + for (i = 0; i < numberOfFrames; i++) + { + print_stack_value(stack[i]); + } +} +#elif defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 2 +#include + +/* We use DbgHelp.dll rather than DbgHelp.lib. This avoids us needing + * extra link time complications, and enables us to fall back gracefully + * if the DLL cannot be found. + * + * To achieve this we have our own potted versions of the required types + * inline here. + */ +#ifdef _WIN64 +typedef DWORD64 DWORD_NATIVESIZED; +#else +typedef DWORD DWORD_NATIVESIZED; +#endif + +#define MEMENTO_BACKTRACE_MAX 64 + +typedef USHORT (__stdcall *My_CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID*, __out_opt PULONG); + +typedef struct MY_IMAGEHLP_LINE { + DWORD SizeOfStruct; + PVOID Key; + DWORD LineNumber; + PCHAR FileName; + DWORD_NATIVESIZED Address; +} MY_IMAGEHLP_LINE, *MY_PIMAGEHLP_LINE; + +typedef BOOL (__stdcall *My_SymGetLineFromAddrType)(HANDLE hProcess, DWORD_NATIVESIZED dwAddr, PDWORD pdwDisplacement, MY_PIMAGEHLP_LINE Line); + +typedef struct MY_SYMBOL_INFO { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG info; + ULONG Size; + ULONG64 ModBase; // Base Address of module containing this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + CHAR Name[1]; // Name of symbol +} MY_SYMBOL_INFO, *MY_PSYMBOL_INFO; + +typedef BOOL (__stdcall *My_SymFromAddrType)(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, MY_PSYMBOL_INFO Symbol); +typedef BOOL (__stdcall *My_SymInitializeType)(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess); + +static My_CaptureStackBackTraceType Memento_CaptureStackBackTrace; +static My_SymGetLineFromAddrType Memento_SymGetLineFromAddr; +static My_SymFromAddrType Memento_SymFromAddr; +static My_SymInitializeType Memento_SymInitialize; +static HANDLE Memento_process; + +static void Memento_initStacktracer(void) +{ + HMODULE mod = LoadLibrary("kernel32.dll"); + + if (mod == NULL) + return; + Memento_CaptureStackBackTrace = (My_CaptureStackBackTraceType)(GetProcAddress(mod, "RtlCaptureStackBackTrace")); + if (Memento_CaptureStackBackTrace == NULL) + return; + mod = LoadLibrary("Dbghelp.dll"); + if (mod == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_SymGetLineFromAddr = + (My_SymGetLineFromAddrType)(GetProcAddress(mod, +#ifdef _WIN64 + "SymGetLineFromAddr64" +#else + "SymGetLineFromAddr" +#endif + )); + if (Memento_SymGetLineFromAddr == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_SymFromAddr = (My_SymFromAddrType)(GetProcAddress(mod, "SymFromAddr")); + if (Memento_SymFromAddr == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_SymInitialize = (My_SymInitializeType)(GetProcAddress(mod, "SymInitialize")); + if (Memento_SymInitialize == NULL) { + Memento_CaptureStackBackTrace = NULL; + return; + } + Memento_process = GetCurrentProcess(); + Memento_SymInitialize(Memento_process, NULL, TRUE); +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + if (Memento_CaptureStackBackTrace == NULL) + return 0; + + *skip = 0; + /* Limit us to 63 levels due to windows bug */ + return Memento_CaptureStackBackTrace(SkipStackBackTraceLevels, 63-SkipStackBackTraceLevels, stack, NULL); +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ + MY_IMAGEHLP_LINE line; + int i; + char symbol_buffer[sizeof(MY_SYMBOL_INFO) + 1024 + 1]; + MY_SYMBOL_INFO *symbol = (MY_SYMBOL_INFO *)symbol_buffer; + + symbol->MaxNameLen = 1024; + symbol->SizeOfStruct = sizeof(MY_SYMBOL_INFO); + line.SizeOfStruct = sizeof(MY_IMAGEHLP_LINE); + for (i = 0; i < numberOfFrames; i++) + { + DWORD64 dwDisplacement64; + DWORD dwDisplacement; + Memento_SymFromAddr(Memento_process, (DWORD64)(stack[i]), &dwDisplacement64, symbol); + Memento_SymGetLineFromAddr(Memento_process, (DWORD_NATIVESIZED)(stack[i]), &dwDisplacement, &line); + fprintf(stderr, " %s in %s:%d\n", symbol->Name, line.FileName, line.LineNumber); + } +} +#elif defined(MEMENTO_STACKTRACE_METHOD) && MEMENTO_STACKTRACE_METHOD == 3 + +#include +#include + +/* From cxxabi.h */ +extern char* __cxa_demangle(const char* mangled_name, + char* output_buffer, + size_t* length, + int* status); + +static void Memento_initStacktracer(void) +{ +} + +#define MEMENTO_BACKTRACE_MAX 256 + +typedef struct +{ + int count; + void **addr; +} my_unwind_details; + +static _Unwind_Reason_Code unwind_populate_callback(struct _Unwind_Context *context, + void *arg) +{ + my_unwind_details *uw = (my_unwind_details *)arg; + int count = uw->count; + + if (count >= MEMENTO_BACKTRACE_MAX) + return _URC_END_OF_STACK; + + uw->addr[count] = (void *)_Unwind_GetIP(context); + uw->count++; + + return _URC_NO_REASON; +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + my_unwind_details uw = { 0, stack }; + + *skip = 0; + + /* Collect the backtrace. Deliberately only unwind once, + * and avoid using malloc etc until this completes just + * in case. */ + _Unwind_Backtrace(unwind_populate_callback, &uw); + if (uw.count <= SkipStackBackTraceLevels) + return 0; + + *skip = SkipStackBackTraceLevels; + return uw.count-SkipStackBackTraceLevels; +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ + int i; + + for (i = 0; i < numberOfFrames; i++) + { + Dl_info info; + if (dladdr(stack[i], &info)) + { + int status = 0; + const char *sym = info.dli_sname ? info.dli_sname : ""; + char *demangled = __cxa_demangle(sym, NULL, 0, &status); + int offset = stack[i] - info.dli_saddr; + fprintf(stderr, " [%p]%s(+0x%x)\n", stack[i], demangled && status == 0 ? demangled : sym, offset); + free(demangled); + } + else + { + fprintf(stderr, " [%p]\n", stack[i]); + } + } +} + +#else +static void Memento_initStacktracer(void) +{ +} + +static int Memento_getStacktrace(void **stack, int *skip) +{ + *skip = 0; + return 0; +} + +static void Memento_showStacktrace(void **stack, int numberOfFrames) +{ +} +#endif /* MEMENTO_STACKTRACE_METHOD */ + +#ifdef MEMENTO_DETAILS +static void Memento_storeDetails(Memento_BlkHeader *head, int type) +{ + void *stack[MEMENTO_BACKTRACE_MAX]; + Memento_BlkDetails *details; + int count; + int skip; + + if (head == NULL) + return; + +#ifdef MEMENTO_STACKTRACE_METHOD + count = Memento_getStacktrace(stack, &skip); +#else + skip = 0; + count = 0; +#endif + + details = MEMENTO_UNDERLYING_MALLOC(sizeof(*details) + (count-1) * sizeof(void *)); + if (details == NULL) + return; + + if (count) + memcpy(&details->stack, &stack[skip], count * sizeof(void *)); + + details->type = type; + details->count = count; + details->sequence = memento.sequence; + details->next = NULL; + VALGRIND_MAKE_MEM_DEFINED(&head->details_tail, sizeof(head->details_tail)); + *head->details_tail = details; + head->details_tail = &details->next; + VALGRIND_MAKE_MEM_NOACCESS(&head->details_tail, sizeof(head->details_tail)); +} +#endif + +void (Memento_bt)(void) +{ +#ifdef MEMENTO_STACKTRACE_METHOD + void *stack[MEMENTO_BACKTRACE_MAX]; + int count; + int skip; + + count = Memento_getStacktrace(stack, &skip); + Memento_showStacktrace(&stack[skip-2], count-skip+2); +#endif +} + +static void Memento_bt_internal(int skip2) +{ +#ifdef MEMENTO_STACKTRACE_METHOD + void *stack[MEMENTO_BACKTRACE_MAX]; + int count; + int skip; + + count = Memento_getStacktrace(stack, &skip); + Memento_showStacktrace(&stack[skip+skip2], count-skip-skip2); +#endif +} + +static int Memento_checkAllMemoryLocked(void); void Memento_breakpoint(void) { @@ -207,15 +906,33 @@ #endif } +static void Memento_init(void); + +#define MEMENTO_LOCK() \ +do { if (!memento.inited) Memento_init(); MEMENTO_DO_LOCK(); } while (0) + +#define MEMENTO_UNLOCK() \ +do { MEMENTO_DO_UNLOCK(); } while (0) + +/* Do this as a macro to prevent another level in the callstack, + * which is annoying while stepping. */ +#define Memento_breakpointLocked() \ +do { MEMENTO_UNLOCK(); Memento_breakpoint(); MEMENTO_LOCK(); } while (0) + static void Memento_addBlockHead(Memento_Blocks *blks, Memento_BlkHeader *b, int type) { - if (blks->tail == &blks->head) { - /* Adding into an empty list, means the tail changes too */ - blks->tail = &b->next; - } + if (blks->tail == NULL) + blks->tail = b; b->next = blks->head; + b->prev = NULL; + if (blks->head) + { + VALGRIND_MAKE_MEM_DEFINED(&blks->head->prev, sizeof(blks->head->prev)); + blks->head->prev = b; + VALGRIND_MAKE_MEM_NOACCESS(&blks->head->prev, sizeof(blks->head->prev)); + } blks->head = b; #ifndef MEMENTO_LEAKONLY memset(b->preblk, MEMENTO_PREFILL, Memento_PreSize); @@ -234,11 +951,17 @@ Memento_BlkHeader *b, int type) { - VALGRIND_MAKE_MEM_DEFINED(blks->tail, sizeof(Memento_BlkHeader *)); - *blks->tail = b; - blks->tail = &b->next; + VALGRIND_MAKE_MEM_DEFINED(&blks->tail, sizeof(Memento_BlkHeader *)); + if (blks->head == NULL) + blks->head = b; + b->prev = blks->tail; b->next = NULL; - VALGRIND_MAKE_MEM_NOACCESS(blks->tail, sizeof(Memento_BlkHeader *)); + if (blks->tail) { + VALGRIND_MAKE_MEM_DEFINED(&blks->tail->next, sizeof(blks->tail->next)); + blks->tail->next = b; + VALGRIND_MAKE_MEM_NOACCESS(&blks->tail->next, sizeof(blks->tail->next)); + } + blks->tail = b; #ifndef MEMENTO_LEAKONLY memset(b->preblk, MEMENTO_PREFILL, Memento_PreSize); memset(MEMBLK_POSTPTR(b), MEMENTO_POSTFILL, Memento_PostSize); @@ -250,6 +973,7 @@ VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_TOBLK(b), b->rawsize); } VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); + VALGRIND_MAKE_MEM_NOACCESS(&blks->tail, sizeof(Memento_BlkHeader *)); } typedef struct BlkCheckData { @@ -260,137 +984,137 @@ int index; } BlkCheckData; +#ifndef MEMENTO_LEAKONLY static int Memento_Internal_checkAllocedBlock(Memento_BlkHeader *b, void *arg) { -#ifndef MEMENTO_LEAKONLY - int i; - char *p; - int corrupt = 0; - BlkCheckData *data = (BlkCheckData *)arg; + int i; + MEMENTO_UINT32 *ip; + unsigned char *p; + BlkCheckData *data = (BlkCheckData *)arg; - p = b->preblk; - i = Memento_PreSize; + ip = (MEMENTO_UINT32 *)(void *)(b->preblk); + i = Memento_PreSize>>2; do { - corrupt |= (*p++ ^ (char)MEMENTO_PREFILL); + if (*ip++ != MEMENTO_PREFILL_UINT32) + goto pre_corrupt; } while (--i); - if (corrupt) { + if (0) { +pre_corrupt: data->preCorrupt = 1; } + /* Postfill may not be aligned, so have to be slower */ p = MEMBLK_POSTPTR(b); - i = Memento_PreSize; + i = Memento_PostSize-4; + if ((intptr_t)p & 1) + { + if (*p++ != MEMENTO_POSTFILL) + goto post_corrupt; + i--; + } + if ((intptr_t)p & 2) + { + if (*(MEMENTO_UINT16 *)p != MEMENTO_POSTFILL_UINT16) + goto post_corrupt; + p += 2; + i -= 2; + } do { - corrupt |= (*p++ ^ (char)MEMENTO_POSTFILL); - } while (--i); - if (corrupt) { + if (*(MEMENTO_UINT32 *)p != MEMENTO_POSTFILL_UINT32) + goto post_corrupt; + p += 4; + i -= 4; + } while (i >= 0); + if (i & 2) + { + if (*(MEMENTO_UINT16 *)p != MEMENTO_POSTFILL_UINT16) + goto post_corrupt; + p += 2; + } + if (i & 1) + { + if (*p != MEMENTO_POSTFILL) + goto post_corrupt; + } + if (0) { +post_corrupt: data->postCorrupt = 1; } if ((data->freeCorrupt | data->preCorrupt | data->postCorrupt) == 0) { - b->lastCheckedOK = globals.sequence; + b->lastCheckedOK = memento.sequence; } data->found |= 1; -#endif return 0; } static int Memento_Internal_checkFreedBlock(Memento_BlkHeader *b, void *arg) { -#ifndef MEMENTO_LEAKONLY - int i; - char *p; - BlkCheckData *data = (BlkCheckData *)arg; + int i; + unsigned char *p; + BlkCheckData *data = (BlkCheckData *)arg; - p = MEMBLK_TOBLK(b); - i = b->rawsize; + p = MEMBLK_TOBLK(b); /* p will always be aligned */ + i = b->rawsize - 4; /* Attempt to speed this up by checking an (aligned) int at a time */ - do { - if (((size_t)p) & 1) { - if (*p++ != (char)MEMENTO_FREEFILL) - break; - i--; - if (i == 0) - break; - } - if ((i >= 2) && (((size_t)p) & 2)) { - if (*(short *)p != (short)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8))) - goto mismatch; - p += 2; - i -= 2; - if (i == 0) - break; - } + while (i >= 0) { + if (*(MEMENTO_UINT32 *)p != MEMENTO_FREEFILL_UINT32) + goto mismatch; + p += 4; i -= 4; - while (i >= 0) { - if (*(int *)p != (MEMENTO_FREEFILL | - (MEMENTO_FREEFILL<<8) | - (MEMENTO_FREEFILL<<16) | - (MEMENTO_FREEFILL<<24))) - goto mismatch; - p += 4; - i -= 4; - } - i += 4; - if ((i >= 2) && (((size_t)p) & 2)) { - if (*(short *)p != (short)(MEMENTO_FREEFILL | (MEMENTO_FREEFILL<<8))) - goto mismatch; - p += 2; - i -= 2; - } + } + i += 4; + if (i & 2) { + if (*(MEMENTO_UINT16 *)p != MEMENTO_FREEFILL_UINT16) + goto mismatch; + p += 2; + i -= 2; + } mismatch: - while (i) { - if (*p++ != (char)MEMENTO_FREEFILL) - break; - i--; - } - } while (0); + while (i) { + if (*p++ != (unsigned char)MEMENTO_FREEFILL) + break; + i--; + } if (i) { data->freeCorrupt = 1; data->index = b->rawsize-i; } return Memento_Internal_checkAllocedBlock(b, arg); -#else - return 0; -#endif } +#endif /* MEMENTO_LEAKONLY */ static void Memento_removeBlock(Memento_Blocks *blks, Memento_BlkHeader *b) { - Memento_BlkHeader *head = blks->head; - Memento_BlkHeader *prev = NULL; - while ((head) && (head != b)) { - VALGRIND_MAKE_MEM_DEFINED(head, sizeof(*head)); - prev = head; - head = head->next; - VALGRIND_MAKE_MEM_NOACCESS(prev, sizeof(*prev)); + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b)); + if (b->next) { + VALGRIND_MAKE_MEM_DEFINED(&b->next->prev, sizeof(b->next->prev)); + b->next->prev = b->prev; + VALGRIND_MAKE_MEM_NOACCESS(&b->next->prev, sizeof(b->next->prev)); } - if (head == NULL) { - /* FAIL! Will have been reported to user earlier, so just exit. */ - return; - } - VALGRIND_MAKE_MEM_DEFINED(blks->tail, sizeof(*blks->tail)); - if (*blks->tail == head) { - /* Removing the tail of the list */ - if (prev == NULL) { - /* Which is also the head */ - blks->tail = &blks->head; - } else { - /* Which isn't the head */ - blks->tail = &prev->next; - } + if (b->prev) { + VALGRIND_MAKE_MEM_DEFINED(&b->prev->next, sizeof(b->prev->next)); + b->prev->next = b->next; + VALGRIND_MAKE_MEM_NOACCESS(&b->prev->next, sizeof(b->prev->next)); } - if (prev == NULL) { - /* Removing from the head of the list */ - VALGRIND_MAKE_MEM_DEFINED(head, sizeof(*head)); - blks->head = head->next; - VALGRIND_MAKE_MEM_NOACCESS(head, sizeof(*head)); - } else { - /* Removing from not-the-head */ - VALGRIND_MAKE_MEM_DEFINED(head, sizeof(*head)); - VALGRIND_MAKE_MEM_DEFINED(prev, sizeof(*prev)); - prev->next = head->next; - VALGRIND_MAKE_MEM_NOACCESS(head, sizeof(*head)); - VALGRIND_MAKE_MEM_NOACCESS(prev, sizeof(*prev)); + if (blks->tail == b) + blks->tail = b->prev; + if (blks->head == b) + blks->head = b->next; +} + +static void free_block(Memento_BlkHeader *head) +{ +#ifdef MEMENTO_DETAILS + Memento_BlkDetails *details = head->details; + + while (details) + { + Memento_BlkDetails *next = details->next; + MEMENTO_UNDERLYING_FREE(details); + details = next; } +#endif + MEMENTO_UNDERLYING_FREE(head); } static int Memento_Internal_makeSpace(size_t space) @@ -399,19 +1123,19 @@ if (space > MEMENTO_FREELIST_MAX_SINGLE_BLOCK) return 0; /* Pretend we added it on. */ - globals.freeListSize += space; + memento.freeListSize += space; /* Ditch blocks until it fits within our limit */ - while (globals.freeListSize > MEMENTO_FREELIST_MAX) { - Memento_BlkHeader *head = globals.free.head; + while (memento.freeListSize > MEMENTO_FREELIST_MAX) { + Memento_BlkHeader *head = memento.free.head; VALGRIND_MAKE_MEM_DEFINED(head, sizeof(*head)); - globals.free.head = head->next; - globals.freeListSize -= MEMBLK_SIZE(head->rawsize); - MEMENTO_UNDERLYING_FREE(head); + memento.free.head = head->next; + memento.freeListSize -= MEMBLK_SIZE(head->rawsize); + free_block(head); } /* Make sure we haven't just completely emptied the free list */ /* (This should never happen, but belt and braces... */ - if (globals.free.head == NULL) - globals.free.tail = &globals.free.head; + if (memento.free.head == NULL) + memento.free.tail = NULL; return 1; } @@ -438,11 +1162,13 @@ return 0; } -static int Memento_appBlock(Memento_Blocks *blks, - int (*app)(Memento_BlkHeader *, - void *), - void *arg, - Memento_BlkHeader *b) +#ifndef MEMENTO_LEAKONLY +/* Distrustful - check the block is a real one */ +static int Memento_appBlockUser(Memento_Blocks *blks, + int (*app)(Memento_BlkHeader *, + void *), + void *arg, + Memento_BlkHeader *b) { Memento_BlkHeader *head = blks->head; Memento_BlkHeader *next; @@ -450,7 +1176,7 @@ while (head && head != b) { VALGRIND_MAKE_MEM_DEFINED(head, sizeof(Memento_BlkHeader)); next = head->next; - VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize); + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(head), Memento_PostSize); head = next; } if (head == b) { @@ -465,17 +1191,41 @@ return 0; } +static int Memento_appBlock(Memento_Blocks *blks, + int (*app)(Memento_BlkHeader *, + void *), + void *arg, + Memento_BlkHeader *b) +{ + int result; + VALGRIND_MAKE_MEM_DEFINED(b, sizeof(Memento_BlkHeader)); + VALGRIND_MAKE_MEM_DEFINED(MEMBLK_TOBLK(b), + b->rawsize + Memento_PostSize); + result = app(b, arg); + VALGRIND_MAKE_MEM_NOACCESS(MEMBLK_POSTPTR(b), Memento_PostSize); + VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(Memento_BlkHeader)); + return result; +} +#endif /* MEMENTO_LEAKONLY */ + static void showBlock(Memento_BlkHeader *b, int space) { fprintf(stderr, "0x%p:(size=%d,num=%d)", MEMBLK_TOBLK(b), (int)b->rawsize, b->sequence); if (b->label) fprintf(stderr, "%c(%s)", space, b->label); + if (b->flags & Memento_Flag_KnownLeak) + fprintf(stderr, "(Known Leak)"); } static void blockDisplay(Memento_BlkHeader *b, int n) { n++; + while (n > 40) + { + fprintf(stderr, "*"); + n -= 40; + } while(n > 0) { int i = n; @@ -501,9 +1251,18 @@ static void doNestedDisplay(Memento_BlkHeader *b, int depth) { - blockDisplay(b, depth); - for (b = b->child; b; b = b->sibling) - doNestedDisplay(b, depth+1); + /* Try and avoid recursion if we can help it */ + do { + blockDisplay(b, depth); + if (b->sibling) { + if (b->child) + doNestedDisplay(b->child, depth+1); + b = b->sibling; + } else { + b = b->child; + depth++; + } + } while (b); } static int ptrcmp(const void *a_, const void *b_) @@ -517,14 +1276,14 @@ int Memento_listBlocksNested(void) { int count, size, i; - Memento_BlkHeader *b; + Memento_BlkHeader *b, *prev; void **blocks, *minptr, *maxptr; - long mask; + intptr_t mask; /* Count the blocks */ count = 0; size = 0; - for (b = globals.used.head; b; b = b->next) { + for (b = memento.used.head; b; b = b->next) { VALGRIND_MAKE_MEM_DEFINED(b, sizeof(*b)); size += b->rawsize; count++; @@ -536,12 +1295,12 @@ return 1; /* Populate our block list */ - b = globals.used.head; + b = memento.used.head; minptr = maxptr = MEMBLK_TOBLK(b); - mask = (long)minptr; + mask = (intptr_t)minptr; for (i = 0; b; b = b->next, i++) { void *p = MEMBLK_TOBLK(b); - mask &= (long)p; + mask &= (intptr_t)p; if (p < minptr) minptr = p; if (p > maxptr) @@ -550,12 +1309,12 @@ b->flags &= ~Memento_Flag_HasParent; b->child = NULL; b->sibling = NULL; - b->parent = NULL; + b->prev = NULL; /* parent */ } qsort(blocks, count, sizeof(void *), ptrcmp); /* Now, calculate tree */ - for (b = globals.used.head; b; b = b->next) { + for (b = memento.used.head; b; b = b->next) { char *p = MEMBLK_TOBLK(b); int end = (b->rawsize < MEMENTO_PTRSEARCH ? b->rawsize : MEMENTO_PTRSEARCH); for (i = MEMENTO_SEARCH_SKIP; i < end; i += sizeof(void *)) { @@ -563,7 +1322,7 @@ void **r; /* Do trivial checks on pointer */ - if ((mask & (int)q) != mask || q < minptr || q > maxptr) + if ((mask & (intptr_t)q) != mask || q < minptr || q > maxptr) continue; /* Search for pointer */ @@ -575,29 +1334,33 @@ /* We're assuming tree structure, not graph - ignore second * and subsequent pointers. */ - if (child->parent != NULL) + if (child->prev != NULL) /* parent */ continue; if (child->flags & Memento_Flag_HasParent) continue; + /* Not interested in pointers to ourself! */ + if (child == b) + continue; + /* We're also assuming acyclicness here. If this is one of * our parents, ignore it. */ - parent = b->parent; + parent = b->prev; /* parent */ while (parent != NULL && parent != child) - parent = parent->parent; + parent = parent->prev; /* parent */ if (parent == child) continue; child->sibling = b->child; b->child = child; - child->parent = b; + child->prev = b; /* parent */ child->flags |= Memento_Flag_HasParent; } } } /* Now display with nesting */ - for (b = globals.used.head; b; b = b->next) { + for (b = memento.used.head; b; b = b->next) { if ((b->flags & Memento_Flag_HasParent) == 0) doNestedDisplay(b, 0); } @@ -606,9 +1369,15 @@ MEMENTO_UNDERLYING_FREE(blocks); - /* Now put the blocks back for valgrind */ - for (b = globals.used.head; b;) { + /* Now put the blocks back for valgrind, and restore the prev + * and magic values. */ + prev = NULL; + for (b = memento.used.head; b;) { Memento_BlkHeader *next = b->next; + b->prev = prev; + b->child = MEMENTO_CHILD_MAGIC; + b->sibling = MEMENTO_SIBLING_MAGIC; + prev = b; VALGRIND_MAKE_MEM_NOACCESS(b, sizeof(*b)); b = next; } @@ -618,16 +1387,18 @@ void Memento_listBlocks(void) { + MEMENTO_LOCK(); fprintf(stderr, "Allocated blocks:\n"); if (Memento_listBlocksNested()) { int counts[2]; counts[0] = 0; counts[1] = 0; - Memento_appBlocks(&globals.used, Memento_listBlock, &counts[0]); + Memento_appBlocks(&memento.used, Memento_listBlock, &counts[0]); fprintf(stderr, " Total number of blocks = %d\n", counts[0]); fprintf(stderr, " Total size of blocks = %d\n", counts[1]); } + MEMENTO_UNLOCK(); } static int Memento_listNewBlock(Memento_BlkHeader *b, @@ -639,105 +1410,216 @@ return Memento_listBlock(b, arg); } -void Memento_listNewBlocks(void) { +void Memento_listNewBlocks(void) +{ int counts[2]; + MEMENTO_LOCK(); counts[0] = 0; counts[1] = 0; fprintf(stderr, "Blocks allocated and still extant since last list:\n"); - Memento_appBlocks(&globals.used, Memento_listNewBlock, &counts[0]); + Memento_appBlocks(&memento.used, Memento_listNewBlock, &counts[0]); fprintf(stderr, " Total number of blocks = %d\n", counts[0]); fprintf(stderr, " Total size of blocks = %d\n", counts[1]); + MEMENTO_UNLOCK(); } static void Memento_endStats(void) { - fprintf(stderr, "Total memory malloced = %u bytes\n", (unsigned int)globals.totalAlloc); - fprintf(stderr, "Peak memory malloced = %u bytes\n", (unsigned int)globals.peakAlloc); - fprintf(stderr, "%u mallocs, %u frees, %u reallocs\n", (unsigned int)globals.numMallocs, - (unsigned int)globals.numFrees, (unsigned int)globals.numReallocs); + fprintf(stderr, "Total memory malloced = %u bytes\n", (unsigned int)memento.totalAlloc); + fprintf(stderr, "Peak memory malloced = %u bytes\n", (unsigned int)memento.peakAlloc); + fprintf(stderr, "%u mallocs, %u frees, %u reallocs\n", (unsigned int)memento.numMallocs, + (unsigned int)memento.numFrees, (unsigned int)memento.numReallocs); fprintf(stderr, "Average allocation size %u bytes\n", (unsigned int) - (globals.numMallocs != 0 ? globals.totalAlloc/globals.numMallocs: 0)); + (memento.numMallocs != 0 ? memento.totalAlloc/memento.numMallocs: 0)); } void Memento_stats(void) { - fprintf(stderr, "Current memory malloced = %u bytes\n", (unsigned int)globals.alloc); + MEMENTO_LOCK(); + fprintf(stderr, "Current memory malloced = %u bytes\n", (unsigned int)memento.alloc); Memento_endStats(); + MEMENTO_UNLOCK(); } -static void Memento_fin(void) +#ifdef MEMENTO_DETAILS +static int showInfo(Memento_BlkHeader *b, void *arg) { - Memento_checkAllMemory(); - Memento_endStats(); - if (globals.used.head != NULL) { - Memento_listBlocks(); - Memento_breakpoint(); - } - if (globals.segv) { - fprintf(stderr, "Memory dumped on SEGV while squeezing @ %d\n", globals.failAt); - } else if (globals.squeezing) { - if (globals.pattern == 0) - fprintf(stderr, "Memory squeezing @ %d complete\n", globals.squeezeAt); - else - fprintf(stderr, "Memory squeezing @ %d (%d) complete\n", globals.squeezeAt, globals.pattern); - } - if (globals.failing) + Memento_BlkDetails *details; + + fprintf(stderr, "0x%p:(size=%d,num=%d)", + MEMBLK_TOBLK(b), (int)b->rawsize, b->sequence); + if (b->label) + fprintf(stderr, " (%s)", b->label); + fprintf(stderr, "\nEvents:\n"); + + details = b->details; + while (details) { - fprintf(stderr, "MEMENTO_FAILAT=%d\n", globals.failAt); - fprintf(stderr, "MEMENTO_PATTERN=%d\n", globals.pattern); + fprintf(stderr, " Event %d (%s)\n", details->sequence, eventType[(int)details->type]); + Memento_showStacktrace(details->stack, details->count); + details = details->next; } - if (globals.nextFailAt != 0) + return 0; +} +#endif + +void Memento_listBlockInfo(void) +{ +#ifdef MEMENTO_DETAILS + MEMENTO_LOCK(); + fprintf(stderr, "Details of allocated blocks:\n"); + Memento_appBlocks(&memento.used, showInfo, NULL); + MEMENTO_UNLOCK(); +#endif +} + +static int Memento_nonLeakBlocksLeaked(void) +{ + Memento_BlkHeader *blk = memento.used.head; + while (blk) { - fprintf(stderr, "MEMENTO_NEXTFAILAT=%d\n", globals.nextFailAt); - fprintf(stderr, "MEMENTO_NEXTPATTERN=%d\n", globals.nextPattern); + if ((blk->flags & Memento_Flag_KnownLeak) == 0) + return 1; + blk = blk->next; } + return 0; } -static void Memento_inited(void) +void Memento_fin(void) { - /* A good place for a breakpoint */ + Memento_checkAllMemory(); + if (!memento.segv) + { + Memento_endStats(); + if (Memento_nonLeakBlocksLeaked()) { + Memento_listBlocks(); +#ifdef MEMENTO_DETAILS + fprintf(stderr, "\n"); + Memento_listBlockInfo(); +#endif + Memento_breakpoint(); + } + } + if (memento.squeezing) { + if (memento.pattern == 0) + fprintf(stderr, "Memory squeezing @ %d complete%s\n", memento.squeezeAt, memento.segv ? " (with SEGV)" : ""); + else + fprintf(stderr, "Memory squeezing @ %d (%d) complete%s\n", memento.squeezeAt, memento.pattern, memento.segv ? " (with SEGV)" : ""); + } else if (memento.segv) { + fprintf(stderr, "Memory squeezing complete (with SEGV)\n", memento.failAt); + } + if (memento.failing) + { + fprintf(stderr, "MEMENTO_FAILAT=%d\n", memento.failAt); + fprintf(stderr, "MEMENTO_PATTERN=%d\n", memento.pattern); + } + if (memento.nextFailAt != 0) + { + fprintf(stderr, "MEMENTO_NEXTFAILAT=%d\n", memento.nextFailAt); + fprintf(stderr, "MEMENTO_NEXTPATTERN=%d\n", memento.nextPattern); + } } static void Memento_init(void) { char *env; - memset(&globals, 0, sizeof(globals)); - globals.inited = 1; - globals.used.head = NULL; - globals.used.tail = &globals.used.head; - globals.free.head = NULL; - globals.free.tail = &globals.free.head; - globals.sequence = 0; - globals.countdown = 1024; + memset(&memento, 0, sizeof(memento)); + memento.inited = 1; + memento.used.head = NULL; + memento.used.tail = NULL; + memento.free.head = NULL; + memento.free.tail = NULL; + memento.sequence = 0; + memento.countdown = 1024; env = getenv("MEMENTO_FAILAT"); - globals.failAt = (env ? atoi(env) : 0); + memento.failAt = (env ? atoi(env) : 0); env = getenv("MEMENTO_PARANOIA"); - globals.paranoia = (env ? atoi(env) : 0); - if (globals.paranoia == 0) - globals.paranoia = 1024; + memento.paranoia = (env ? atoi(env) : 0); + if (memento.paranoia == 0) + memento.paranoia = -1024; env = getenv("MEMENTO_PARANOIDAT"); - globals.paranoidAt = (env ? atoi(env) : 0); + memento.paranoidAt = (env ? atoi(env) : 0); env = getenv("MEMENTO_SQUEEZEAT"); - globals.squeezeAt = (env ? atoi(env) : 0); + memento.squeezeAt = (env ? atoi(env) : 0); env = getenv("MEMENTO_PATTERN"); - globals.pattern = (env ? atoi(env) : 0); + memento.pattern = (env ? atoi(env) : 0); env = getenv("MEMENTO_MAXMEMORY"); - globals.maxMemory = (env ? atoi(env) : 0); + memento.maxMemory = (env ? atoi(env) : 0); atexit(Memento_fin); - Memento_inited(); + Memento_initMutex(&memento.mutex); + + Memento_initStacktracer(); + + Memento_breakpoint(); +} + +typedef struct findBlkData { + void *addr; + Memento_BlkHeader *blk; + int flags; +} findBlkData; + +static int Memento_containsAddr(Memento_BlkHeader *b, + void *arg) +{ + findBlkData *data = (findBlkData *)arg; + char *blkend = &((char *)MEMBLK_TOBLK(b))[b->rawsize]; + if ((MEMBLK_TOBLK(b) <= data->addr) && + ((void *)blkend > data->addr)) { + data->blk = b; + data->flags = 1; + return 1; + } + if (((void *)b <= data->addr) && + (MEMBLK_TOBLK(b) > data->addr)) { + data->blk = b; + data->flags = 2; + return 1; + } + if (((void *)blkend <= data->addr) && + ((void *)(blkend + Memento_PostSize) > data->addr)) { + data->blk = b; + data->flags = 3; + return 1; + } + return 0; +} + +void Memento_info(void *addr) +{ +#ifdef MEMENTO_DETAILS + findBlkData data; + + MEMENTO_LOCK(); + data.addr = addr; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk != NULL) + showInfo(data.blk, NULL); + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); + if (data.blk != NULL) + showInfo(data.blk, NULL); + MEMENTO_UNLOCK(); +#else + printf("Memento not compiled with details support\n"); +#endif } #ifdef MEMENTO_HAS_FORK #include #include +#include #ifdef MEMENTO_STACKTRACE_METHOD #if MEMENTO_STACKTRACE_METHOD == 1 #include @@ -746,32 +1628,19 @@ /* FIXME: Find some portable way of getting this */ /* MacOSX has 10240, Ubuntu seems to have 256 */ +#ifndef OPEN_MAX #define OPEN_MAX 10240 +#endif -/* stashed_map[j] = i means that filedescriptor i-1 was duplicated to j */ +/* stashed_map[j] = i means that file descriptor i-1 was duplicated to j */ int stashed_map[OPEN_MAX]; -extern size_t backtrace(void **, int); -extern void backtrace_symbols_fd(void **, size_t, int); - -static void Memento_signal(void) -{ - fprintf(stderr, "SEGV after Memory squeezing @ %d\n", globals.squeezeAt); - -#ifdef MEMENTO_STACKTRACE_METHOD -#if MEMENTO_STACKTRACE_METHOD == 1 - { - void *array[100]; - size_t size; - - size = backtrace(array, 100); - fprintf(stderr, "------------------------------------------------------------------------\n"); - fprintf(stderr, "Backtrace:\n"); - backtrace_symbols_fd(array, size, 2); - fprintf(stderr, "------------------------------------------------------------------------\n"); - } -#endif -#endif +static void Memento_signal(int sig) +{ + (void)sig; + fprintf(stderr, "SEGV at:\n"); + memento.segv = 1; + Memento_bt_internal(0); exit(1); } @@ -781,18 +1650,18 @@ pid_t pid; int i, status; - if (globals.patternBit < 0) + if (memento.patternBit < 0) return 1; - if (globals.squeezing && globals.patternBit >= MEMENTO_MAXPATTERN) + if (memento.squeezing && memento.patternBit >= MEMENTO_MAXPATTERN) return 1; - if (globals.patternBit == 0) - globals.squeezeAt = globals.sequence; + if (memento.patternBit == 0) + memento.squeezeAt = memento.sequence; - if (!globals.squeezing) { - fprintf(stderr, "Memory squeezing @ %d\n", globals.squeezeAt); + if (!memento.squeezing) { + fprintf(stderr, "Memory squeezing @ %d\n", memento.squeezeAt); } else - fprintf(stderr, "Memory squeezing @ %d (%x,%x)\n", globals.squeezeAt, globals.pattern, globals.patternBit); + fprintf(stderr, "Memory squeezing @ %d (%x,%x)\n", memento.squeezeAt, memento.pattern, memento.patternBit); /* When we fork below, the child is going to snaffle all our file pointers * and potentially corrupt them. Let's make copies of all of them before @@ -804,26 +1673,45 @@ } } + fprintf(stderr, "Failing at:\n"); + Memento_bt_internal(2); pid = fork(); if (pid == 0) { /* Child */ signal(SIGSEGV, Memento_signal); /* In the child, we always fail the next allocation. */ - if (globals.patternBit == 0) { - globals.patternBit = 1; + if (memento.patternBit == 0) { + memento.patternBit = 1; } else - globals.patternBit <<= 1; - globals.squeezing = 1; + memento.patternBit <<= 1; + memento.squeezing = 1; return 1; } /* In the parent if we hit another allocation, pass it (and record the * fact we passed it in the pattern. */ - globals.pattern |= globals.patternBit; - globals.patternBit <<= 1; + memento.pattern |= memento.patternBit; + memento.patternBit <<= 1; - /* Wait for pid to finish */ - waitpid(pid, &status, 0); + /* Wait for pid to finish, with a timeout. */ + { + struct timespec tm = { 0, 10 * 1000 * 1000 }; /* 10ms = 100th sec */ + int timeout = 30 * 1000 * 1000; /* time out in microseconds! */ + while (waitpid(pid, &status, WNOHANG) == 0) { + nanosleep(&tm, NULL); + timeout -= (tm.tv_nsec/1000); + tm.tv_nsec *= 2; + if (tm.tv_nsec > 999999999) + tm.tv_nsec = 999999999; + if (timeout <= 0) { + char text[32]; + fprintf(stderr, "Child is taking a long time to die. Killing it.\n"); + sprintf(text, "kill %d", pid); + system(text); + break; + } + } + } if (status != 0) { fprintf(stderr, "Child status=%d\n", status); @@ -843,12 +1731,13 @@ #else #include -static void Memento_signal(void) +static void Memento_signal(int sig) { - globals.segv = 1; + (void)sig; + memento.segv = 1; /* If we just return from this function the SEGV will be unhandled, and * we'll launch into whatever JIT debugging system the OS provides. At - * least output something useful first. If MEMENTO_NOJIT is set, then + * least fprintf(stderr, something useful first. If MEMENTO_NOJIT is set, then * just exit to avoid the JIT (and get the usual atexit handling). */ if (getenv("MEMENTO_NOJIT")) exit(1); @@ -856,7 +1745,7 @@ Memento_fin(); } -int squeeze(void) +static int squeeze(void) { fprintf(stderr, "Memento memory squeezing disabled as no fork!\n"); return 0; @@ -865,152 +1754,350 @@ static void Memento_startFailing(void) { - if (!globals.failing) { + if (!memento.failing) { fprintf(stderr, "Starting to fail...\n"); fflush(stderr); - globals.failing = 1; - globals.failAt = globals.sequence; - globals.nextFailAt = globals.sequence+1; - globals.pattern = 0; - globals.patternBit = 0; + memento.failing = 1; + memento.failAt = memento.sequence; + memento.nextFailAt = memento.sequence+1; + memento.pattern = 0; + memento.patternBit = 0; signal(SIGSEGV, Memento_signal); signal(SIGABRT, Memento_signal); - Memento_breakpoint(); + Memento_breakpointLocked(); } } -static void Memento_event(void) +static int Memento_event(void) { - globals.sequence++; - if ((globals.sequence >= globals.paranoidAt) && (globals.paranoidAt != 0)) { - globals.paranoia = 1; - globals.countdown = 1; + memento.sequence++; + if ((memento.sequence >= memento.paranoidAt) && (memento.paranoidAt != 0)) { + memento.paranoia = 1; + memento.countdown = 1; } - if (--globals.countdown == 0) { - Memento_checkAllMemory(); - globals.countdown = globals.paranoia; + if (--memento.countdown == 0) { + Memento_checkAllMemoryLocked(); + if (memento.paranoia > 0) + memento.countdown = memento.paranoia; + else + { + memento.countdown = -memento.paranoia; + if (memento.paranoia > INT_MIN/2) + memento.paranoia *= 2; + } } - if (globals.sequence == globals.breakAt) { - fprintf(stderr, "Breaking at event %d\n", globals.breakAt); - Memento_breakpoint(); + if (memento.sequence == memento.breakAt) { + fprintf(stderr, "Breaking at event %d\n", memento.breakAt); + return 1; } + return 0; +} + +int Memento_sequence(void) +{ + return memento.sequence; } int Memento_breakAt(int event) { - globals.breakAt = event; + MEMENTO_LOCK(); + memento.breakAt = event; + MEMENTO_UNLOCK(); return event; } -void *Memento_label(void *ptr, const char *label) +static void *safe_find_block(void *ptr) { Memento_BlkHeader *block; + int valid; if (ptr == NULL) return NULL; + block = MEMBLK_FROMBLK(ptr); - VALGRIND_MAKE_MEM_DEFINED(&block->label, sizeof(block->label)); - block->label = label; - VALGRIND_MAKE_MEM_NOACCESS(&block->label, sizeof(block->label)); + /* Sometimes wrapping allocators can mean Memento_label + * is called with a value within the block, rather than + * at the start of the block. If we detect this, find it + * the slow way. */ + VALGRIND_MAKE_MEM_DEFINED(&block->child, sizeof(block->child)); + VALGRIND_MAKE_MEM_DEFINED(&block->sibling, sizeof(block->sibling)); + valid = (block->child == MEMENTO_CHILD_MAGIC && + block->sibling == MEMENTO_SIBLING_MAGIC); + VALGRIND_MAKE_MEM_NOACCESS(&block->child, sizeof(block->child)); + VALGRIND_MAKE_MEM_NOACCESS(&block->sibling, sizeof(block->sibling)); + if (!valid) + { + findBlkData data; + + data.addr = ptr; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk == NULL) + return NULL; + block = data.blk; + } + return block; +} + +void *Memento_label(void *ptr, const char *label) +{ + Memento_BlkHeader *block; + + if (ptr == NULL) + return NULL; + MEMENTO_LOCK(); + block = safe_find_block(ptr); + if (block != NULL) + { + VALGRIND_MAKE_MEM_DEFINED(&block->label, sizeof(block->label)); + block->label = label; + VALGRIND_MAKE_MEM_NOACCESS(&block->label, sizeof(block->label)); + } + MEMENTO_UNLOCK(); return ptr; } -int Memento_failThisEvent(void) +void Memento_tick(void) { - int failThisOne; + MEMENTO_LOCK(); + if (Memento_event()) Memento_breakpointLocked(); + MEMENTO_UNLOCK(); +} - if (!globals.inited) - Memento_init(); +static int Memento_failThisEventLocked(void) +{ + int failThisOne; - Memento_event(); + if (Memento_event()) Memento_breakpointLocked(); - if ((globals.sequence >= globals.failAt) && (globals.failAt != 0)) + if ((memento.sequence >= memento.failAt) && (memento.failAt != 0)) Memento_startFailing(); - if ((globals.sequence >= globals.squeezeAt) && (globals.squeezeAt != 0)) { + if ((memento.sequence >= memento.squeezeAt) && (memento.squeezeAt != 0)) { return squeeze(); } - if (!globals.failing) + if (!memento.failing) return 0; - failThisOne = ((globals.patternBit & globals.pattern) == 0); + failThisOne = ((memento.patternBit & memento.pattern) == 0); /* If we are failing, and we've reached the end of the pattern and we've * still got bits available in the pattern word, and we haven't already * set a nextPattern, then extend the pattern. */ - if (globals.failing && - ((~(globals.patternBit-1) & globals.pattern) == 0) && - (globals.patternBit != 0) && - globals.nextPattern == 0) + if (memento.failing && + ((~(memento.patternBit-1) & memento.pattern) == 0) && + (memento.patternBit != 0) && + memento.nextPattern == 0) { /* We'll fail this one, and set the 'next' one to pass it. */ - globals.nextFailAt = globals.failAt; - globals.nextPattern = globals.pattern | globals.patternBit; + memento.nextFailAt = memento.failAt; + memento.nextPattern = memento.pattern | memento.patternBit; } - globals.patternBit = (globals.patternBit ? globals.patternBit << 1 : 1); + memento.patternBit = (memento.patternBit ? memento.patternBit << 1 : 1); return failThisOne; } -void *Memento_malloc(size_t s) +int Memento_failThisEvent(void) +{ + int ret; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + ret = Memento_failThisEventLocked(); + MEMENTO_UNLOCK(); + return ret; +} + +static void *do_malloc(size_t s, int eventType) { Memento_BlkHeader *memblk; size_t smem = MEMBLK_SIZE(s); - if (Memento_failThisEvent()) + if (Memento_failThisEventLocked()) return NULL; if (s == 0) return NULL; - globals.numMallocs++; + memento.numMallocs++; - if (globals.maxMemory != 0 && globals.alloc + s > globals.maxMemory) + if (memento.maxMemory != 0 && memento.alloc + s > memento.maxMemory) return NULL; memblk = MEMENTO_UNDERLYING_MALLOC(smem); if (memblk == NULL) return NULL; - globals.alloc += s; - globals.totalAlloc += s; - if (globals.peakAlloc < globals.alloc) - globals.peakAlloc = globals.alloc; + memento.alloc += s; + memento.totalAlloc += s; + if (memento.peakAlloc < memento.alloc) + memento.peakAlloc = memento.alloc; #ifndef MEMENTO_LEAKONLY memset(MEMBLK_TOBLK(memblk), MEMENTO_ALLOCFILL, s); #endif memblk->rawsize = s; - memblk->sequence = globals.sequence; + memblk->sequence = memento.sequence; memblk->lastCheckedOK = memblk->sequence; memblk->flags = 0; memblk->label = 0; - memblk->child = NULL; - memblk->sibling = NULL; - Memento_addBlockHead(&globals.used, memblk, 0); + memblk->child = MEMENTO_CHILD_MAGIC; + memblk->sibling = MEMENTO_SIBLING_MAGIC; +#ifdef MEMENTO_DETAILS + memblk->details = NULL; + memblk->details_tail = &memblk->details; + Memento_storeDetails(memblk, Memento_EventType_malloc); +#endif /* MEMENTO_DETAILS */ + Memento_addBlockHead(&memento.used, memblk, 0); + + if (memento.leaking > 0) + memblk->flags |= Memento_Flag_KnownLeak; + return MEMBLK_TOBLK(memblk); } +void *Memento_malloc(size_t s) +{ + void *ret; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + ret = do_malloc(s, Memento_EventType_malloc); + MEMENTO_UNLOCK(); + return ret; +} + void *Memento_calloc(size_t n, size_t s) { - void *block = Memento_malloc(n*s); + void *block; + + if (!memento.inited) + Memento_init(); + MEMENTO_LOCK(); + block = do_malloc(n*s, Memento_EventType_calloc); if (block) memset(block, 0, n*s); + MEMENTO_UNLOCK(); return block; } +static void do_reference(Memento_BlkHeader *blk, int event) +{ +#ifdef MEMENTO_DETAILS + Memento_storeDetails(blk, event); +#endif /* MEMENTO_DETAILS */ +} + +void *Memento_takeRef(void *blk) +{ + if (!blk) + return NULL; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + do_reference(safe_find_block(blk), Memento_EventType_takeRef); + MEMENTO_UNLOCK(); + return blk; +} + +void *Memento_dropRef(void *blk) +{ + if (!blk) + return NULL; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + do_reference(safe_find_block(blk), Memento_EventType_dropRef); + MEMENTO_UNLOCK(); + return blk; +} + +void *Memento_reference(void *blk) +{ + if (!blk) + return NULL; + + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + do_reference(safe_find_block(blk), Memento_EventType_reference); + MEMENTO_UNLOCK(); + return blk; +} + +/* Treat blocks from the user with suspicion, and check them the slow + * but safe way. */ +static int checkBlockUser(Memento_BlkHeader *memblk, const char *action) +{ +#ifndef MEMENTO_LEAKONLY + BlkCheckData data; + + memset(&data, 0, sizeof(data)); + Memento_appBlockUser(&memento.used, Memento_Internal_checkAllocedBlock, + &data, memblk); + if (!data.found) { + /* Failure! */ + fprintf(stderr, "Attempt to %s block ", action); + showBlock(memblk, 32); + fprintf(stderr, "\n"); + Memento_breakpointLocked(); + return 1; + } else if (data.preCorrupt || data.postCorrupt) { + fprintf(stderr, "Block "); + showBlock(memblk, ' '); + fprintf(stderr, " found to be corrupted on %s!\n", action); + if (data.preCorrupt) { + fprintf(stderr, "Preguard corrupted\n"); + } + if (data.postCorrupt) { + fprintf(stderr, "Postguard corrupted\n"); + } + fprintf(stderr, "Block last checked OK at allocation %d. Now %d.\n", + memblk->lastCheckedOK, memento.sequence); + Memento_breakpointLocked(); + return 1; + } +#endif + return 0; +} + static int checkBlock(Memento_BlkHeader *memblk, const char *action) { #ifndef MEMENTO_LEAKONLY BlkCheckData data; +#endif + + if (memblk->child != MEMENTO_CHILD_MAGIC || + memblk->sibling != MEMENTO_SIBLING_MAGIC) + { + /* Failure! */ + fprintf(stderr, "Attempt to %s invalid block ", action); + showBlock(memblk, 32); + fprintf(stderr, "\n"); + Memento_breakpointLocked(); + return 1; + } +#ifndef MEMENTO_LEAKONLY memset(&data, 0, sizeof(data)); - Memento_appBlock(&globals.used, Memento_Internal_checkAllocedBlock, + Memento_appBlock(&memento.used, Memento_Internal_checkAllocedBlock, &data, memblk); if (!data.found) { /* Failure! */ fprintf(stderr, "Attempt to %s block ", action); showBlock(memblk, 32); - Memento_breakpoint(); + fprintf(stderr, "\n"); + Memento_breakpointLocked(); return 1; } else if (data.preCorrupt || data.postCorrupt) { fprintf(stderr, "Block "); @@ -1023,22 +2110,19 @@ fprintf(stderr, "Postguard corrupted\n"); } fprintf(stderr, "Block last checked OK at allocation %d. Now %d.\n", - memblk->lastCheckedOK, globals.sequence); - Memento_breakpoint(); + memblk->lastCheckedOK, memento.sequence); + Memento_breakpointLocked(); return 1; } #endif return 0; } -void Memento_free(void *blk) +static void do_free(void *blk, int eventType) { Memento_BlkHeader *memblk; - if (!globals.inited) - Memento_init(); - - Memento_event(); + if (Memento_event()) Memento_breakpointLocked(); if (blk == NULL) return; @@ -1048,14 +2132,18 @@ if (checkBlock(memblk, "free")) return; +#ifdef MEMENTO_DETAILS + Memento_storeDetails(memblk, Memento_EventType_free); +#endif + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); if (memblk->flags & Memento_Flag_BreakOnFree) - Memento_breakpoint(); + Memento_breakpointLocked(); - globals.alloc -= memblk->rawsize; - globals.numFrees++; + memento.alloc -= memblk->rawsize; + memento.numFrees++; - Memento_removeBlock(&globals.used, memblk); + Memento_removeBlock(&memento.used, memblk); VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); if (Memento_Internal_makeSpace(MEMBLK_SIZE(memblk->rawsize))) { @@ -1065,80 +2153,130 @@ #ifndef MEMENTO_LEAKONLY memset(MEMBLK_TOBLK(memblk), MEMENTO_FREEFILL, memblk->rawsize); #endif - Memento_addBlockTail(&globals.free, memblk, 1); + memblk->flags |= Memento_Flag_Freed; + Memento_addBlockTail(&memento.free, memblk, 1); } else { - MEMENTO_UNDERLYING_FREE(memblk); + free_block(memblk); } } -void *Memento_realloc(void *blk, size_t newsize) +void Memento_free(void *blk) +{ + if (!memento.inited) + Memento_init(); + + MEMENTO_LOCK(); + do_free(blk, Memento_EventType_free); + MEMENTO_UNLOCK(); +} + +static void *do_realloc(void *blk, size_t newsize, int type) { Memento_BlkHeader *memblk, *newmemblk; size_t newsizemem; int flags; - if (blk == NULL) - return Memento_malloc(newsize); - if (newsize == 0) { - Memento_free(blk); - return NULL; - } - - if (Memento_failThisEvent()) + if (Memento_failThisEventLocked()) return NULL; memblk = MEMBLK_FROMBLK(blk); + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); if (checkBlock(memblk, "realloc")) return NULL; +#ifdef MEMENTO_DETAILS + Memento_storeDetails(memblk, type); +#endif + + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); if (memblk->flags & Memento_Flag_BreakOnRealloc) - Memento_breakpoint(); + Memento_breakpointLocked(); - if (globals.maxMemory != 0 && globals.alloc - memblk->rawsize + newsize > globals.maxMemory) + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); + if (memento.maxMemory != 0 && memento.alloc - memblk->rawsize + newsize > memento.maxMemory) return NULL; newsizemem = MEMBLK_SIZE(newsize); - Memento_removeBlock(&globals.used, memblk); + Memento_removeBlock(&memento.used, memblk); + VALGRIND_MAKE_MEM_DEFINED(memblk, sizeof(*memblk)); flags = memblk->flags; newmemblk = MEMENTO_UNDERLYING_REALLOC(memblk, newsizemem); if (newmemblk == NULL) { - Memento_addBlockHead(&globals.used, memblk, 2); + Memento_addBlockHead(&memento.used, memblk, 2); return NULL; } - globals.numReallocs++; - globals.totalAlloc += newsize; - globals.alloc -= newmemblk->rawsize; - globals.alloc += newsize; - if (globals.peakAlloc < globals.alloc) - globals.peakAlloc = globals.alloc; + memento.numReallocs++; + memento.totalAlloc += newsize; + memento.alloc -= newmemblk->rawsize; + memento.alloc += newsize; + if (memento.peakAlloc < memento.alloc) + memento.peakAlloc = memento.alloc; newmemblk->flags = flags; +#ifndef MEMENTO_LEAKONLY if (newmemblk->rawsize < newsize) { char *newbytes = ((char *)MEMBLK_TOBLK(newmemblk))+newmemblk->rawsize; -#ifndef MEMENTO_LEAKONLY + VALGRIND_MAKE_MEM_DEFINED(newbytes, newsize - newmemblk->rawsize); memset(newbytes, MEMENTO_ALLOCFILL, newsize - newmemblk->rawsize); -#endif VALGRIND_MAKE_MEM_UNDEFINED(newbytes, newsize - newmemblk->rawsize); } +#endif newmemblk->rawsize = newsize; #ifndef MEMENTO_LEAKONLY + VALGRIND_MAKE_MEM_DEFINED(newmemblk->preblk, Memento_PreSize); memset(newmemblk->preblk, MEMENTO_PREFILL, Memento_PreSize); + VALGRIND_MAKE_MEM_UNDEFINED(newmemblk->preblk, Memento_PreSize); + VALGRIND_MAKE_MEM_DEFINED(MEMBLK_POSTPTR(newmemblk), Memento_PostSize); memset(MEMBLK_POSTPTR(newmemblk), MEMENTO_POSTFILL, Memento_PostSize); + VALGRIND_MAKE_MEM_UNDEFINED(MEMBLK_POSTPTR(newmemblk), Memento_PostSize); #endif - Memento_addBlockHead(&globals.used, newmemblk, 2); + Memento_addBlockHead(&memento.used, newmemblk, 2); return MEMBLK_TOBLK(newmemblk); } +void *Memento_realloc(void *blk, size_t newsize) +{ + void *ret; + + if (!memento.inited) + Memento_init(); + + if (blk == NULL) + { + MEMENTO_LOCK(); + ret = do_malloc(newsize, Memento_EventType_realloc); + MEMENTO_UNLOCK(); + return ret; + } + if (newsize == 0) { + MEMENTO_LOCK(); + do_free(blk, Memento_EventType_realloc); + MEMENTO_UNLOCK(); + return NULL; + } + + MEMENTO_LOCK(); + ret = do_realloc(blk, newsize, Memento_EventType_realloc); + MEMENTO_UNLOCK(); + return ret; +} + int Memento_checkBlock(void *blk) { Memento_BlkHeader *memblk; + int ret; if (blk == NULL) return 0; + + MEMENTO_LOCK(); memblk = MEMBLK_FROMBLK(blk); - return checkBlock(memblk, "check"); + ret = checkBlockUser(memblk, "check"); + MEMENTO_UNLOCK(); + return ret; } +#ifndef MEMENTO_LEAKONLY static int Memento_Internal_checkAllAlloced(Memento_BlkHeader *memblk, void *arg) { BlkCheckData *data = (BlkCheckData *)arg; @@ -1160,13 +2298,13 @@ } fprintf(stderr, "corrupted.\n " "Block last checked OK at allocation %d. Now %d.\n", - memblk->lastCheckedOK, globals.sequence); + memblk->lastCheckedOK, memento.sequence); data->preCorrupt = 0; data->postCorrupt = 0; data->freeCorrupt = 0; } else - memblk->lastCheckedOK = globals.sequence; + memblk->lastCheckedOK = memento.sequence; return 0; } @@ -1202,42 +2340,60 @@ } fprintf(stderr, " corrupted.\n" " Block last checked OK at allocation %d. Now %d.\n", - memblk->lastCheckedOK, globals.sequence); + memblk->lastCheckedOK, memento.sequence); data->preCorrupt = 0; data->postCorrupt = 0; data->freeCorrupt = 0; } else - memblk->lastCheckedOK = globals.sequence; + memblk->lastCheckedOK = memento.sequence; return 0; } +#endif /* MEMENTO_LEAKONLY */ -int Memento_checkAllMemory(void) +static int Memento_checkAllMemoryLocked(void) { #ifndef MEMENTO_LEAKONLY BlkCheckData data; memset(&data, 0, sizeof(data)); - Memento_appBlocks(&globals.used, Memento_Internal_checkAllAlloced, &data); - Memento_appBlocks(&globals.free, Memento_Internal_checkAllFreed, &data); - if (data.found & 6) { + Memento_appBlocks(&memento.used, Memento_Internal_checkAllAlloced, &data); + Memento_appBlocks(&memento.free, Memento_Internal_checkAllFreed, &data); + return data.found; +#else + return 0; +#endif +} + +int Memento_checkAllMemory(void) +{ +#ifndef MEMENTO_LEAKONLY + int ret; + + MEMENTO_LOCK(); + ret = Memento_checkAllMemoryLocked(); + MEMENTO_UNLOCK(); + if (ret & 6) { Memento_breakpoint(); return 1; } -#endif return 0; +#endif } int Memento_setParanoia(int i) { - globals.paranoia = i; - globals.countdown = globals.paranoia; + memento.paranoia = i; + if (memento.paranoia > 0) + memento.countdown = memento.paranoia; + else + memento.countdown = -memento.paranoia; return i; } int Memento_paranoidAt(int i) { - globals.paranoidAt = i; + memento.paranoidAt = i; return i; } @@ -1260,46 +2416,15 @@ return result; } -typedef struct findBlkData { - void *addr; - Memento_BlkHeader *blk; - int flags; -} findBlkData; - -static int Memento_containsAddr(Memento_BlkHeader *b, - void *arg) -{ - findBlkData *data = (findBlkData *)arg; - char *blkend = &((char *)MEMBLK_TOBLK(b))[b->rawsize]; - if ((MEMBLK_TOBLK(b) <= data->addr) && - ((void *)blkend > data->addr)) { - data->blk = b; - data->flags = 1; - return 1; - } - if (((void *)b <= data->addr) && - (MEMBLK_TOBLK(b) > data->addr)) { - data->blk = b; - data->flags = 2; - return 1; - } - if (((void *)blkend <= data->addr) && - ((void *)(blkend + Memento_PostSize) > data->addr)) { - data->blk = b; - data->flags = 3; - return 1; - } - return 0; -} - int Memento_find(void *a) { findBlkData data; + MEMENTO_LOCK(); data.addr = a; data.blk = NULL; data.flags = 0; - Memento_appBlocks(&globals.used, Memento_containsAddr, &data); + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); if (data.blk != NULL) { fprintf(stderr, "Address 0x%p is in %sallocated block ", data.addr, @@ -1307,11 +2432,12 @@ "preguard of " : "postguard of "))); showBlock(data.blk, ' '); fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); return data.blk->sequence; } data.blk = NULL; data.flags = 0; - Memento_appBlocks(&globals.free, Memento_containsAddr, &data); + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); if (data.blk != NULL) { fprintf(stderr, "Address 0x%p is in %sfreed block ", data.addr, @@ -1319,8 +2445,10 @@ "preguard of " : "postguard of "))); showBlock(data.blk, ' '); fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); return data.blk->sequence; } + MEMENTO_UNLOCK(); return 0; } @@ -1328,10 +2456,11 @@ { findBlkData data; + MEMENTO_LOCK(); data.addr = a; data.blk = NULL; data.flags = 0; - Memento_appBlocks(&globals.used, Memento_containsAddr, &data); + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); if (data.blk != NULL) { fprintf(stderr, "Will stop when address 0x%p (in %sallocated block ", data.addr, @@ -1340,11 +2469,12 @@ showBlock(data.blk, ' '); fprintf(stderr, ") is freed\n"); data.blk->flags |= Memento_Flag_BreakOnFree; + MEMENTO_UNLOCK(); return; } data.blk = NULL; data.flags = 0; - Memento_appBlocks(&globals.free, Memento_containsAddr, &data); + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); if (data.blk != NULL) { fprintf(stderr, "Can't stop on free; address 0x%p is in %sfreed block ", data.addr, @@ -1352,19 +2482,22 @@ "preguard of " : "postguard of "))); showBlock(data.blk, ' '); fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); return; } fprintf(stderr, "Can't stop on free; address 0x%p is not in a known block.\n", a); + MEMENTO_UNLOCK(); } void Memento_breakOnRealloc(void *a) { findBlkData data; + MEMENTO_LOCK(); data.addr = a; data.blk = NULL; data.flags = 0; - Memento_appBlocks(&globals.used, Memento_containsAddr, &data); + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); if (data.blk != NULL) { fprintf(stderr, "Will stop when address 0x%p (in %sallocated block ", data.addr, @@ -1373,11 +2506,12 @@ showBlock(data.blk, ' '); fprintf(stderr, ") is freed (or realloced)\n"); data.blk->flags |= Memento_Flag_BreakOnFree | Memento_Flag_BreakOnRealloc; + MEMENTO_UNLOCK(); return; } data.blk = NULL; data.flags = 0; - Memento_appBlocks(&globals.free, Memento_containsAddr, &data); + Memento_appBlocks(&memento.free, Memento_containsAddr, &data); if (data.blk != NULL) { fprintf(stderr, "Can't stop on free/realloc; address 0x%p is in %sfreed block ", data.addr, @@ -1385,26 +2519,94 @@ "preguard of " : "postguard of "))); showBlock(data.blk, ' '); fprintf(stderr, "\n"); + MEMENTO_UNLOCK(); return; } fprintf(stderr, "Can't stop on free/realloc; address 0x%p is not in a known block.\n", a); + MEMENTO_UNLOCK(); } int Memento_failAt(int i) { - globals.failAt = i; - if ((globals.sequence > globals.failAt) && - (globals.failing != 0)) + memento.failAt = i; + if ((memento.sequence > memento.failAt) && + (memento.failing != 0)) Memento_startFailing(); return i; } size_t Memento_setMax(size_t max) { - globals.maxMemory = max; + memento.maxMemory = max; return max; } +void Memento_startLeaking(void) +{ + memento.leaking++; +} + +void Memento_stopLeaking(void) +{ + memento.leaking--; +} + +#endif /* MEMENTO_CPP_EXTRAS_ONLY */ + +#ifdef __cplusplus +/* Dumb overrides for the new and delete operators */ + +void *operator new(size_t size) +{ + void *ret; + + if (!memento.inited) + Memento_init(); + + if (size == 0) + size = 1; + MEMENTO_LOCK(); + ret = do_malloc(size, Memento_EventType_new); + MEMENTO_UNLOCK(); + return ret; +} + +void operator delete(void *pointer) +{ + if (!pointer) + return; + + MEMENTO_LOCK(); + do_free(pointer, Memento_EventType_delete); + MEMENTO_UNLOCK(); +} + +/* Some C++ systems (apparently) don't provide new[] or delete[] + * operators. Provide a way to cope with this */ +#ifndef MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS +void *operator new[](size_t size) +{ + void *ret; + if (!memento.inited) + Memento_init(); + + if (size == 0) + size = 1; + MEMENTO_LOCK(); + ret = do_malloc(size, Memento_EventType_newArray); + MEMENTO_UNLOCK(); + return ret; +} + +void operator delete[](void *pointer) +{ + MEMENTO_LOCK(); + do_free(pointer, Memento_EventType_deleteArray); + MEMENTO_UNLOCK(); +} +#endif /* MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS */ +#endif /* __cplusplus */ + #else /* Just in case anyone has left some debugging code in... */ @@ -1465,6 +2667,21 @@ { } +void *(Memento_takeRef)(void *a) +{ + return a; +} + +void *(Memento_dropRef)(void *a) +{ + return a; +} + +void *(Memento_reference)(void *a) +{ + return a; +} + #undef Memento_malloc #undef Memento_free #undef Memento_realloc @@ -1512,4 +2729,20 @@ return ptr; } +void (Memento_info)(void *addr) +{ +} + +void (Memento_listBlockInfo)(void) +{ +} + +void (Memento_startLeaking)(void) +{ +} + +void (Memento_stopLeaking)(void) +{ +} + #endif diff -Nru ghostscript-9.10~dfsg/base/memento.h ghostscript-9.25~dfsg+1/base/memento.h --- ghostscript-9.10~dfsg/base/memento.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/memento.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,22 +1,19 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2009-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or implied. - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com + or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, + Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. */ - /* Memento: A library to aid debugging of memory leaks/heap corruption. * - * Usage: + * Usage (with C): * First, build your project with MEMENTO defined, and include this * header file wherever you use malloc, realloc or free. * This header file will use macros to point malloc, realloc and free to @@ -32,10 +29,14 @@ * On each event Memento increments a counter. Every block is tagged with * the current counter on allocation. Every so often during program * execution, the heap is checked for consistency. By default this happens - * every 1024 events. This can be changed at runtime by using - * Memento_setParanoia(int level). 0 turns off such checking, 1 sets - * checking to happen on every event, any other number n sets checking to - * happen once every n events. + * after 1024 events, then after 2048 events, then after 4096 events, etc. + * This can be changed at runtime by using Memento_setParanoia(int level). + * 0 turns off such checking, 1 sets checking to happen on every event, + * any positive number n sets checking to happen once every n events, + * and any negative number n sets checking to happen after -n events, then + * after -2n events etc. + * + * The default paranoia level is therefore -1024. * * Memento keeps blocks around for a while after they have been freed, and * checks them as part of these heap checks to see if they have been @@ -133,11 +134,39 @@ * then more useful features can be used; firstly memory squeezing will * work, and secondly, Memento will have a "finer grained" paranoia * available to it. + * + * Usage with C++: + * + * Memento has some experimental code in it to trap new/delete (and + * new[]/delete[] if required) calls. + * + * In order for this to work, either: + * + * 1) Build memento.c with the c++ compiler. + * + * or + * + * 2) Build memento.c as normal with the C compiler, then from any + * one of your .cpp files, do: + * + * #define MEMENTO_CPP_EXTRAS_ONLY + * #include "memento.c" + * + * In the case where MEMENTO is not defined, this will not do anything. + * + * Both Windows and GCC provide separate new[] and delete[] operators + * for arrays. Apparently some systems do not. If this is the case for + * your system, define MEMENTO_CPP_NO_ARRAY_CONSTRUCTORS. */ #ifndef MEMENTO_H -#include +#include + +#ifdef __ANDROID__ +#define MEMENTO_ANDROID +#include +#endif #define MEMENTO_H @@ -184,12 +213,28 @@ size_t Memento_setMax(size_t); void Memento_stats(void); void *Memento_label(void *, const char *); +void Memento_tick(void); void *Memento_malloc(size_t s); void *Memento_realloc(void *, size_t s); void Memento_free(void *); void *Memento_calloc(size_t, size_t); +void Memento_info(void *addr); +void Memento_listBlockInfo(void); +void *Memento_takeRef(void *blk); +void *Memento_dropRef(void *blk); +void *Memento_reference(void *blk); + +void Memento_startLeaking(void); +void Memento_stopLeaking(void); + +int Memento_sequence(void); + +void Memento_fin(void); + +void Memento_bt(void); + #ifdef MEMENTO #ifndef COMPILING_MEMENTO_C @@ -224,6 +269,17 @@ #define Memento_setMax(A) 0 #define Memento_stats() do {} while (0) #define Memento_label(A,B) (A) +#define Memento_info(A) do {} while (0) +#define Memento_listBlockInfo() do {} while (0) +#define Memento_takeRef(A) (A) +#define Memento_dropRef(A) (A) +#define Memento_reference(A) (A) +#define Memento_tick() do {} while (0) +#define Memento_startLeaking() do {} while (0) +#define Memento_stopLeaking() do {} while (0) +#define Memento_fin() do {} while (0) +#define Memento_bt() do {} while (0) +#define Memento_sequence() (0) #endif /* MEMENTO */ diff -Nru ghostscript-9.10~dfsg/base/memory_.h ghostscript-9.25~dfsg+1/base/memory_.h --- ghostscript-9.10~dfsg/base/memory_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/memory_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/mkromfs.c ghostscript-9.25~dfsg+1/base/mkromfs.c --- ghostscript-9.10~dfsg/base/mkromfs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/mkromfs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -117,6 +117,26 @@ char *path; } Xlist_element; + +#define PATH_STR_LEN 1024 + +#ifndef ARCH_IS_BIG_ENDIAN +#define ARCH_IS_BIG_ENDIAN 0 +#endif +/* This gives what we're running on, + * whilst ARCH_IS_BIG_ENDIAN gives what we're + * building for. + */ +static inline int isbigendian(void) +{ + union { + int i; + char c[sizeof(int)]; + } u = {1}; + + return u.c[0] != 1; +} + /******************************************************************************* * The following are non-redirected printing functions to avoid the need for * these included from gsmisc.c (unix gp_ functions, among others, use if_debug). @@ -212,11 +232,6 @@ epf(": "); } } -void -lprintf_file_only(FILE * f, const char *file) -{ - epf("%s(?): ", file); -} #endif void @@ -329,6 +344,7 @@ 0 /* max used */ }; +int cmpstringp(const void *p1, const void *p2); void put_uint32(FILE *out, const unsigned int q); void put_bytes_padded(FILE *out, unsigned char *p, unsigned int len); void inode_clear(romfs_inode* node); @@ -372,7 +388,12 @@ w2c.c.c2 = p[j++]; w2c.c.c3 = p[j++]; w2c.c.c4 = p[j++]; - fprintf(out, "0x%08x,", w2c.w); + if (isbigendian() != ARCH_IS_BIG_ENDIAN) { + fprintf (out, "0x%02x%02x%02x%02x,", (w2c.w) & 0xff, (w2c.w>>8) & 0xff, (w2c.w>>16) & 0xff, (w2c.w >>24) & 0xff); + } + else { + fprintf(out, "0x%08x,", w2c.w); + } if ((i & 7) == 7) fprintf(out, "\n\t"); } @@ -384,7 +405,12 @@ w2c.c.c2 = p[j+1]; case 1: w2c.c.c1 = p[j]; - fprintf(out, "0x%08x,", w2c.w); + if (isbigendian() != ARCH_IS_BIG_ENDIAN) { + fprintf (out, "0x%02x%02x%02x%02x,", (w2c.w) & 0xff, (w2c.w>>8) & 0xff, (w2c.w>>16) & 0xff, (w2c.w >>24) & 0xff); + } + else { + fprintf(out, "0x%08x,", w2c.w); + } default: ; } fprintf(out, "\n\t"); @@ -444,9 +470,9 @@ fprintf(out, "\t0 };\t/* end-of-node */\n"); printf("node '%s' len=%ld", node->name, node->length); - printf(" %ld blocks", blocks); + printf(" %d blocks", blocks); if (compression) { - printf(", compressed size=%ld", clen); + printf(", compressed size=%d", clen); } printf("\n"); } @@ -958,6 +984,15 @@ } psc->bufferin[psc->inpos] = 0; *i = atoi(psc->bufferin); + + /* Check for 32bit overflow */ + if (psc->inpos > 9) { + char *end; + double d = strtod(psc->bufferin, &end); + if (d != (double)(int)*i) + return 0; + } + return 1; } @@ -1230,7 +1265,7 @@ psc->state = PSC_BufferOut; break; } - if (psc->binary && psc->names && pscompact_isname(psc, &i)) { + if (psc->names && pscompact_isname(psc, &i)) { /* Encode as a name lookup */ if (i >= 0) { /* Executable */ @@ -1381,8 +1416,9 @@ pscompact_copyinout_bin(psc); break; } else if (psc->inpos < 65536) { - pscompact_bufferatstart(psc, psc->inpos>>8); - pscompact_bufferatstart(psc, psc->inpos & 255); + int count = psc->inpos; + pscompact_bufferatstart(psc, count>>8); + pscompact_bufferatstart(psc, count & 255); pscompact_bufferatstart(psc, 144); pscompact_copyinout_bin(psc); break; @@ -1484,8 +1520,9 @@ pscompact_bufferatstart(psc, 142); pscompact_copyinout_bin(psc); } else if (psc->inpos < 65536) { - pscompact_bufferatstart(psc, psc->inpos>>8); - pscompact_bufferatstart(psc, psc->inpos & 255); + int count = psc->inpos; + pscompact_bufferatstart(psc, count>>8); + pscompact_bufferatstart(psc, count & 255); pscompact_bufferatstart(psc, 144); pscompact_copyinout_bin(psc); } else { @@ -1517,6 +1554,15 @@ return out-ubuf; } +int cmpstringp(const void *p1, const void *p2) +{ + /* The actual arguments to this function are "pointers to + pointers to char", but strcmp(3) arguments are "pointers + to char", hence the following cast plus dereference */ + + return strcmp(* (char * const *) p1, * (char * const *) p2); +} + /* This relies on the gp_enumerate_* which should not return directories, nor */ /* should it recurse into directories (unlike Adobe's implementation) */ /* paths are checked to see if they are an ordinary file or a path */ @@ -1524,7 +1570,7 @@ Xlist_element *Xlist_head, int compression, int compaction, int *inode_count, int *totlen, FILE *out) { - int namelen, excluded, save_count=*inode_count; + int i, namelen, excluded, save_count=*inode_count; Xlist_element *Xlist_scan; char *prefixed_path; char *found_path, *rom_filename; @@ -1536,10 +1582,12 @@ FILE *in; unsigned long psc_len; pscompstate psc = { 0 }; + unsigned long numfiles = 0; + char **foundfiles = NULL, *temp; - prefixed_path = malloc(1024); - found_path = malloc(1024); - rom_filename = malloc(1024); + prefixed_path = malloc(PATH_STR_LEN); + found_path = malloc(PATH_STR_LEN); + rom_filename = malloc(PATH_STR_LEN); ubuf = malloc(ROMFS_BLOCKSIZE); cbuf = malloc(ROMFS_CBUFSIZE); if (ubuf == NULL || cbuf == NULL || prefixed_path == NULL || @@ -1573,19 +1621,40 @@ if (excluded) continue; + numfiles++; + temp = realloc(foundfiles, sizeof(char *) * numfiles); + if (temp == NULL) { + free(cbuf); + free(ubuf); + free(found_path); + free(foundfiles); + free(prefixed_path); + free(rom_filename); + printf("realloc failed in process_path.\n"); + exit(1); + } + foundfiles = (char **)temp; + foundfiles[numfiles - 1] = strdup(found_path); + } + + qsort(foundfiles, numfiles, sizeof(char *), cmpstringp); + + for (i = 0; i < numfiles; i++) { + char *fpath = foundfiles[i]; + /* process a file */ node = calloc(1, sizeof(romfs_inode)); /* get info for this file */ - in = fopen(found_path, "rb"); + in = fopen(fpath, "rb"); if (in == NULL) { - printf("unable to open file for processing: %s\n", found_path); + printf("unable to open file for processing: %s\n", fpath); continue; } - /* printf("compacting %s\n", found_path); */ + /* printf("compacting %s\n", fpath); */ /* rom_filename + strlen(rom_prefix) is first char after the new prefix we want to add */ - /* found_path + strlen(os_prefix) is the file name after the -P prefix */ + /* fpath + strlen(os_prefix) is the file name after the -P prefix */ rom_filename[strlen(rom_prefix)] = 0; /* truncate afater prefix */ - strcat(rom_filename, found_path + strlen(os_prefix)); + strcat(rom_filename, fpath + strlen(os_prefix)); node->name = rom_filename; /* without -P prefix, with -d rom_prefix */ fseek(in, 0, SEEK_END); node->disc_length = node->length = ftell(in); @@ -1593,8 +1662,8 @@ node->data_lengths = calloc(blocks, sizeof(*node->data_lengths)); node->data = calloc(blocks, sizeof(*node->data)); fclose(in); - in = fopen(found_path, "rb"); - ulen = strlen(found_path); + in = fopen(fpath, "rb"); + ulen = strlen(fpath); block = 0; psc_len = 0; if (compaction) @@ -1626,7 +1695,7 @@ fclose(in); if (compaction) { /* printf("%s: Compaction saved %d bytes (before compression)\n", - * found_path, node->length - psc_len); */ + * fpath, node->length - psc_len); */ pscompact_end(&psc); node->length = psc_len; } @@ -1636,11 +1705,14 @@ inode_clear(node); free(node); (*inode_count)++; + free(fpath); } free(cbuf); free(ubuf); free(found_path); + free(foundfiles); free(prefixed_path); + free(rom_filename); if (save_count == *inode_count) { printf("warning: no files found from path '%s%s'\n", os_prefix, path); } @@ -1726,14 +1798,15 @@ int *totlen, FILE *out) { int ret, block, blocks; - romfs_inode *node; - unsigned char *ubuf, *cbuf; - char *prefixed_path, *rom_filename; + romfs_inode *node = NULL; + unsigned char *ubuf = NULL, *cbuf = NULL; + char *prefixed_path = NULL, *rom_filename = NULL; unsigned long clen; FILE *in; FILE *config; in_block_t *in_block = NULL; int compaction = 1; + int code = 0; ubuf = malloc(ROMFS_BLOCKSIZE); cbuf = malloc(ROMFS_CBUFSIZE); @@ -1743,7 +1816,8 @@ rom_filename == NULL) { printf("malloc fail in process_initfile\n"); /* should free whichever buffers got allocated, but don't bother */ - return -1; + code = -1; + goto done; } prefix_add(os_prefix, initfile, prefixed_path); @@ -1752,13 +1826,15 @@ in = fopen(prefixed_path, "r"); if (in == 0) { printf("cannot open initfile at: %s\n", prefixed_path); - return -1; + code = -1; + goto done; } config = fopen(gconfig_h, "r"); if (config == 0) { printf("Cannot open gconfig file %s\n", gconfig_h); fclose(in); - return -1; + code = -1; + goto done; } memset(linebuf, 0, sizeof(linebuf)); node = calloc(1, sizeof(romfs_inode)); @@ -1769,12 +1845,11 @@ fclose(in); fclose(config); -/**********/ if (compaction) { in_block_t *comp_block_head; in_block_t *comp_block; - pscompstate psc; + pscompstate psc = {0}; in_block_file ibf; int ulen; @@ -1829,7 +1904,8 @@ ret = compress(cbuf, &clen, in_block->data, block_len); if (ret != Z_OK) { printf("error compressing data block!\n"); - exit(1); + code = -1; + goto done; } } else { memcpy(cbuf, in_block->data, block_len); @@ -1846,14 +1922,14 @@ inode_write(out, node, compression, *inode_count, totlen); /* clean up */ inode_clear(node); - free(node); (*inode_count)++; - +done: + free(node); free(cbuf); free(ubuf); free(prefixed_path); free(rom_filename); - return 0; + return code; } void @@ -2165,6 +2241,8 @@ if (!strncmp(psname, "psfile_(\"", 9)) { FILE *ps; char *quote = strchr(psname + 9, '"'); + if (quote == NULL) + exit(1); *quote = 0; ps = prefix_open(os_prefix, psname + 9); @@ -2243,11 +2321,15 @@ const char *outfilename = "obj/gsromfs.c"; const char *os_prefix = ""; const char *rom_prefix = ""; - char *initfile, *gconfig_h; int atarg = 1; int compression = 1; /* default to doing compression */ int compaction = 0; - Xlist_element *Xlist_scan, *Xlist_head = NULL; + Xlist_element *Xlist_scan = NULL, *Xlist_head = NULL; + char pa[PATH_STR_LEN]; + time_t buildtime = 0; + char* env_source_date_epoch; + + memset(pa, 0x00, PATH_STR_LEN); if (argc < 2) { printf("\n" @@ -2302,7 +2384,13 @@ #endif fprintf(out,"\n#include \"stdint_.h\"\n"); fprintf(out,"\n#include \"time_.h\"\n\n"); - fprintf(out," time_t gs_romfs_buildtime = %ld;\n\n", time(NULL)); + + if ((env_source_date_epoch = getenv("SOURCE_DATE_EPOCH"))) { + buildtime = strtoul(env_source_date_epoch, NULL, 10); + } + if (!buildtime) + buildtime = time(NULL); + fprintf(out," time_t gs_romfs_buildtime = %ld;\n\n", buildtime); /* process the remaining arguments (options interspersed with paths) */ for (; atarg < argc; atarg++) { @@ -2329,14 +2417,19 @@ rom_prefix = argv[atarg]; break; case 'g': - if ((++atarg) + 1 == argc) { - printf(" option %s missing required arguments\n", argv[atarg-1]); - exit(1); + { + char initfile[PATH_STR_LEN] = {0}; + char gconfig_h[PATH_STR_LEN] = {0}; + if ((++atarg) + 1 == argc) { + printf(" option %s missing required arguments\n", argv[atarg-1]); + exit(1); + } + strncpy(initfile, argv[atarg], PATH_STR_LEN - 1); + atarg++; + strncpy(gconfig_h, argv[atarg], PATH_STR_LEN - 1); + process_initfile(initfile, gconfig_h, os_prefix, rom_prefix, compression, + &inode_count, &totlen, out); } - initfile = argv[atarg++]; - gconfig_h = argv[atarg]; - process_initfile(initfile, gconfig_h, os_prefix, rom_prefix, compression, - &inode_count, &totlen, out); break; case 'P': if (++atarg == argc) { @@ -2364,18 +2457,21 @@ continue; } /* process a path or file */ - process_path(argv[atarg], os_prefix, rom_prefix, Xlist_head, + strncpy(pa, argv[atarg], PATH_STR_LEN - (strlen(os_prefix) < strlen(rom_prefix) ? strlen(rom_prefix) : strlen(os_prefix))); + process_path(pa, os_prefix, rom_prefix, Xlist_head, compression, compaction, &inode_count, &totlen, out); - } /* now write out the array of nodes */ fprintf(out, " uint32_t *gs_romfs[] = {\n"); for (i=0; inext; + free(Xlist_head); + Xlist_head = Xlist_scan; + } printf("Total %%rom%% structure size is %d bytes.\n", totlen); return 0; diff -Nru ghostscript-9.10~dfsg/base/msvccmd.mak ghostscript-9.25~dfsg+1/base/msvccmd.mak --- ghostscript-9.10~dfsg/base/msvccmd.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/msvccmd.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Command definition section for Microsoft Visual C++ 4.x/5.x, # Windows NT or Windows 95 platform. @@ -165,7 +165,7 @@ !if $(TDEBUG)!=0 # /Fd designates the directory for the .pdb file. # Note that it must be followed by a space. -CT=/Od /Fd$(GLOBJDIR) $(NULL) $(CDCC) $(CPCH) +CT=/Od /Fd$(GLOBJDIR)\ $(NULL) $(CDCC) $(CPCH) LCT=/DEBUG /INCREMENTAL:YES COMPILE_FULL_OPTIMIZED= # no optimization when debugging COMPILE_WITH_FRAMES= # no optimization when debugging @@ -176,20 +176,23 @@ CT= LCT= CMT=/MT +COMPILE_WITHOUT_FRAMES=/Oy !else -CT=/Zi /Fd$(GLOBJDIR) $(NULL) -LCT=/DEBUG +# Assume that DEBUGSYM != 0 implies a PROFILE build +CT=/Zi /Fd$(GLOBJDIR)\ $(NULL) $(CDCC) $(CPCH) +LCT=/DEBUG /PROFILE /OPT:REF /OPT:ICF CMT=/MTd +# Do not disable frame pointers in profile builds. +COMPILE_WITHOUT_FRAMES=/Oy- !endif !if $(MSVC_VERSION) == 5 # NOTE: With MSVC++ 5.0, /O2 produces a non-working executable. # We believe the following list of optimizations works around this bug. -COMPILE_FULL_OPTIMIZED=/GF /Ot /Oi /Ob2 /Oy /Oa- /Ow- +COMPILE_FULL_OPTIMIZED=/GF /Ot /Oi /Ob2 /Oa- /Ow- $(COMPILE_WITHOUT_FRAMES) !else -COMPILE_FULL_OPTIMIZED=/GF /O2 /Ob2 +COMPILE_FULL_OPTIMIZED=/GF /O2 /Ob2 $(COMPILE_WITHOUT_FRAMES) !endif -COMPILE_WITH_FRAMES= -COMPILE_WITHOUT_FRAMES=/Oy +COMPILE_WITH_FRAMES=/Oy- !endif !if $(MSVC_VERSION) >= 8 diff -Nru ghostscript-9.10~dfsg/base/msvclib.mak ghostscript-9.25~dfsg+1/base/msvclib.mak --- ghostscript-9.10~dfsg/base/msvclib.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/msvclib.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,53 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for Microsoft Visual C++ 4.1 or later, Windows NT or Windows 95 LIBRARY. # # All configurable options are surrounded by !ifndef/!endif to allow # preconfiguration from within another makefile. +# If we are building MEMENTO=1, then adjust default debug flags +!if "$(MEMENTO)"=="1" +!ifndef DEBUG +DEBUG=1 +!endif +!ifndef TDEBUG +TDEBUG=1 +!endif +!ifndef DEBUGSYM +DEBUGSYM=1 +!endif +!endif + +# If we are building PROFILE=1, then adjust default debug flags +!if "$(PROFILE)"=="1" +!ifndef DEBUG +DEBUG=0 +!endif +!ifndef TDEBUG +TDEBUG=0 +!endif +!ifndef DEBUGSYM +DEBUGSYM=1 +!endif +!endif + +# Pick the target architecture file +!if "$(TARGET_ARCH_FILE)"=="" +!ifdef WIN64 +TARGET_ARCH_FILE=$(GLSRCDIR)\..\arch\windows-x64-msvc.h +!else +!ifdef ARM +TARGET_ARCH_FILE=$(GLSRCDIR)\..\arch\windows-arm-msvc.h +!else +TARGET_ARCH_FILE=$(GLSRCDIR)\..\arch\windows-x86-msvc.h +!endif +!endif +!endif + # ------------------------------- Options ------------------------------- # ###### This section is the only part of the file you should need to edit. @@ -81,10 +120,103 @@ TDEBUG=1 !endif +# Setting DEBUGSYM=1 is only useful with TDEBUG=0. +# This option is for advanced developers. It includes symbol table +# information for the debugger in an optimized (release) build. +# NOTE: The debugging information generated for the optimized code may be +# significantly misleading. For general MSVC users we recommend TDEBUG=1. + +!ifndef DEBUGSYM +DEBUGSYM=0 +!endif + + +# We can compile for a 32-bit or 64-bit target +# WIN32 and WIN64 are mutually exclusive. WIN32 is the default. +!if !defined(WIN32) && (!defined(Win64) || !defined(WIN64)) +WIN32=0 +!endif + +# We can build either 32-bit or 64-bit target on a 64-bit platform +# but the location of the binaries differs. Would be nice if the +# detection of the platform could be automatic. +!ifndef BUILD_SYSTEM +!if "$(PROCESSOR_ARCHITEW6432)"=="AMD64" || "$(PROCESSOR_ARCHITECTURE)"=="AMD64" +BUILD_SYSTEM=64 +PGMFILES=$(SYSTEMDRIVE)\Program Files +PGMFILESx86=$(SYSTEMDRIVE)\Program Files (x86) +!else +BUILD_SYSTEM=32 +PGMFILES=$(SYSTEMDRIVE)\Program Files +PGMFILESx86=$(SYSTEMDRIVE)\Program Files +!endif +!endif + +!ifndef MSWINSDKPATH +!if exist ("$(PGMFILESx86)\Microsoft SDKs\Windows") +!if exist ("$(PGMFILESx86)\Microsoft SDKs\Windows\v7.1A") +MSWINSDKPATH=$(PGMFILESx86)\Microsoft SDKs\Windows\v7.1A +!else +!if exist ("$(PGMFILESx86)\Microsoft SDKs\Windows\v7.1") +MSWINSDKPATH=$(PGMFILESx86)\Microsoft SDKs\Windows\v7.1 +!else +!if exist ("$(PGMFILESx86)\Microsoft SDKs\Windows\v7.0A") +MSWINSDKPATH=$(PGMFILESx86)\Microsoft SDKs\Windows\v7.0A +!else +!if exist ("$(PGMFILESx86)\Microsoft SDKs\Windows\v7.0") +MSWINSDKPATH=$(PGMFILESx86)\Microsoft SDKs\Windows\v7.0 +!endif +!endif +!endif +!endif +!else +!if exist ("$(PGMFILES)\Microsoft SDKs\Windows") +!if exist ("$(PGMFILES)\Microsoft SDKs\Windows\v7.1A") +MSWINSDKPATH=$(PGMFILES)\Microsoft SDKs\Windows\v7.1A +!else +!if exist ("$(PGMFILES)\Microsoft SDKs\Windows\v7.1") +MSWINSDKPATH=$(PGMFILES)\Microsoft SDKs\Windows\v7.1 +!else +!if exist ("$(PGMFILES)\Microsoft SDKs\Windows\v7.0A") +MSWINSDKPATH=$(PGMFILES)\Microsoft SDKs\Windows\v7.0A +!else +!if exist ("$(PGMFILES)\Microsoft SDKs\Windows\v7.0") +MSWINSDKPATH=$(PGMFILES)\Microsoft SDKs\Windows\v7.0 +!endif +!endif +!endif +!endif +!endif +!endif +!endif + +XPSPRINTCFLAGS= +XPSPRINT=0 + +!ifdef MSWINSDKPATH +!if exist ("$(MSWINSDKPATH)\Include\XpsPrint.h") +XPSPRINTCFLAGS=/DXPSPRINT=1 /I"$(MSWINSDKPATH)\Include" +XPSPRINT=1 +!endif +!endif + !if "$(MEMENTO)"=="1" CFLAGS=$(CFLAGS) -DMEMENTO !endif +!if "$(USE_LARGE_COLOR_INDEX)"=="1" +# Definitions to force gx_color_index to 64 bits +LARGEST_UINTEGER_TYPE=unsigned __int64 +GX_COLOR_INDEX_TYPE=$(LARGEST_UINTEGER_TYPE) + +CFLAGS=$(CFLAGS) /DGX_COLOR_INDEX_TYPE="$(GX_COLOR_INDEX_TYPE)" +!endif + +# -W3 generates too much noise. +!ifndef WARNOPT +WARNOPT=-W2 +!endif + # Define the name of the executable file. !ifndef GS @@ -95,6 +227,30 @@ # source, generated intermediate file, and object directories # for the graphics library (GL) and the PostScript/PDF interpreter (PS). +!if "$(MEMENTO)"=="1" +DEFAULT_OBJ_DIR=.\$(PRODUCT_PREFIX)memobj +!else +!if "$(PROFILE)"=="1" +DEFAULT_OBJ_DIR=.\$(PRODUCT_PREFIX)profobj +!else +!if "$(DEBUG)"=="1" +DEFAULT_OBJ_DIR=.\$(PRODUCT_PREFIX)debugobj +!else +DEFAULT_OBJ_DIR=.\$(PRODUCT_PREFIX)obj +!endif +!endif +!endif +!ifdef METRO +DEFAULT_OBJ_DIR=$(DEFAULT_OBJ_DIR)rt +!endif +!ifdef WIN64 +DEFAULT_OBJ_DIR=$(DEFAULT_OBJ_DIR)64 +!endif + +!ifndef AUXDIR +AUXDIR=$(DEFAULT_OBJ_DIR)\aux_ +!endif + !ifndef BINDIR BINDIR=.\bin !endif @@ -106,40 +262,98 @@ !ifndef PSRESDIR PSRESDIR=.\Resource !endif +!ifndef PSGENDIR +PSGENDIR=$(GLGENDIR) !endif -!ifndef GLGENDIR -!if "$(DEBUG)"="1" -GLGENDIR=.\debugobj -!else -GLGENDIR=.\obj +!ifndef PSOBJDIR +PSOBJDIR=$(GLOBJDIR) !endif !endif +!ifndef GLGENDIR +GLGENDIR=$(DEFAULT_OBJ_DIR) +!endif !ifndef GLOBJDIR -!if "$(DEBUG)"="1" -GLOBJDIR=.\debugobj -!else -GLOBJDIR=.\obj +GLOBJDIR=$(GLGENDIR) !endif +!ifndef DEVGENDIR +DEVGENDIR=$(GLGENDIR) +!endif +!ifndef DEVOBJDIR +DEVOBJDIR=$(DEVGENDIR) !endif -!ifndef DEVGENDIR -!if "$(DEBUG)"="1" -DEVGENDIR=.\debugobj -!else -DEVGENDIR=.\obj +!ifndef EXPATGENDIR +EXPATGENDIR=$(GLGENDIR) !endif + +!ifndef EXPATOBJDIR +EXPATOBJDIR=$(GLOBJDIR) !endif -!ifndef DEVOBJDIR -DEVOBJDIR=$(DEVGENDIR) +!ifndef JPEGXR_GENDIR +JPEGXR_GENDIR=$(GLGENDIR) +!endif + +!ifndef JPEGXR_OBJDIR +JPEGXR_OBJDIR=$(GLOBJDIR) +!endif + +!ifndef AUXDIR +AUXDIR=$(DEFAULT_OBJ_DIR)\aux_ !endif +!ifndef CONTRIBDIR +CONTRIBDIR=.\contrib +!endif # Do not edit the next group of lines. NUL= DD=$(GLGENDIR)\$(NUL) GLD=$(GLGENDIR)\$(NUL) +# Should we build in the cups device.... +!ifdef WITH_CUPS +!if "$(WITH_CUPS)"!="0" +WITH_CUPS=1 +!else +WITH_CUPS=0 +!endif +!else +WITH_CUPS=0 +!endif + +# We can't build cups libraries in a Metro friendly way, +# so if building for Metro, disable cups regardless of the +# request +!ifdef METRO +WITH_CUPS=0 +!endif + +# Define the directory where the FreeType2 library sources are stored. +# See freetype.mak for more information. + +!ifdef UFST_BRIDGE +!if "$(UFST_BRIDGE)"=="1" +FT_BRIDGE=0 +!endif +!endif + +!ifndef FT_BRIDGE +FT_BRIDGE=1 +!endif + +!ifndef FTSRCDIR +FTSRCDIR=freetype +!endif +!ifndef FT_CFLAGS +FT_CFLAGS=-I$(FTSRCDIR)\include +!endif + +!ifdef BITSTREAM_BRIDGE +FT_BRIDGE=0 +!endif + + # Define the directory where the IJG JPEG library sources are stored, # and the major version of the library that is stored there. # You may need to change this if the IJG library version changes. @@ -165,43 +379,193 @@ ZSRCDIR=zlib !endif -# Define the jbig2 library and source location. -# See jbig2.mak for more information. +!ifndef TIFFSRCDIR +TIFFSRCDIR=tiff$(D) +TIFFCONFDIR=$(TIFFSRCDIR) +TIFFCONFIG_SUFFIX=.vc +TIFFPLATFORM=win32 +TIFFCFLAGS="-DJPEG_LIB_MK1_OR_12BIT=0" +!endif + +# Define which jbig2 library to use +!if !defined(JBIG2_LIB) && (!defined(NO_LURATECH) || "$(NO_LURATECH)" != "1") +!if exist("luratech\ldf_jb2") +JBIG2_LIB=luratech +!endif +!endif !ifndef JBIG2_LIB JBIG2_LIB=jbig2dec !endif +!if "$(JBIG2_LIB)" == "luratech" || "$(JBIG2_LIB)" == "ldf_jb2" +# Set defaults for using the Luratech JB2 implementation !ifndef JBIG2SRCDIR +# CSDK source code location +JBIG2SRCDIR=luratech\ldf_jb2 +!endif +!ifndef JBIG2_CFLAGS +# required compiler flags +!ifdef WIN64 +JBIG2_CFLAGS=-DUSE_LDF_JB2 -DWIN64 +!else +JBIG2_CFLAGS=-DUSE_LDF_JB2 -DWIN32 +!endif +!endif +!else +# Use jbig2dec by default. See jbig2.mak for more information. +!ifndef JBIG2SRCDIR +# location of included jbig2dec library source JBIG2SRCDIR=jbig2dec !endif +!endif -# Define the directory where the lcms source is stored. -# See lcms.mak for more information +# Alternatively, you can build a separate DLL +# and define SHARE_JBIG2=1 in src/winlib.mak -!ifndef LCMSSRCDIR -LCMSSRCDIR=lcms +# Define which jpeg2k library to use +!if !defined(JPX_LIB) && (!defined(NO_LURATECH) || "$(NO_LURATECH)" != "1") +!if exist("luratech\lwf_jp2") +JPX_LIB=luratech +!endif !endif -# Define the directory where the lcms2 source is stored. -# See lcms2.mak for more information +# Alternatively, you can build a separate DLL +# and define SHARE_JPX=1 in src/winlib.mak +!ifndef JPX_LIB +JPX_LIB=openjpeg +!endif -!ifndef LCMS2SRCDIR -LCMS2SRCDIR=lcms2 +!ifndef JPEGXR_SRCDIR +JPEGXR_SRCDIR=.\jpegxr +!endif + +!ifndef SHARE_JPEGXR +SHARE_JPEGXR=0 +!endif + +!ifndef JPEGXR_CFLAGS +JPEGXR_CFLAGS=/TP /DNDEBUG +!endif + +!ifndef EXPATSRCDIR +EXPATSRCDIR=.\expat +!endif + +!ifndef SHARE_EXPAT +SHARE_EXPAT=0 +!endif + +!ifndef EXPAT_CFLAGS +EXPAT_CFLAGS=/DWIN32 !endif # Define any other compilation flags. +!ifndef XCFLAGS +XCFLAGS= +!endif + !ifndef CFLAGS CFLAGS= !endif +!ifdef DEVSTUDIO +CFLAGS=$(CFLAGS) /FC +!endif + +!ifdef CLUSTER +CFLAGS=$(CFLAGS) -DCLUSTER +!endif + +!if "$(MEMENTO)"=="1" +CFLAGS=$(CFLAGS) -DMEMENTO +!endif + +!ifdef METRO +# Ideally the TIF_PLATFORM_CONSOLE define should only be for libtiff, +# but we aren't set up to do that easily +CFLAGS=$(CFLAGS) -DMETRO -DWINAPI_FAMILY=WINAPI_PARTITION_APP -DTIF_PLATFORM_CONSOLE +# WinRT doesn't allow ExitProcess() so we have to suborn it here. +# it shouldn't matter since we actually rely on setjmp()/longjmp() for error handling in libtiff +PNG_CFLAGS=/DExitProcess=exit +!endif + +CFLAGS=$(CFLAGS) $(XCFLAGS) + # ------ Platform-specific options ------ # -# Define which major version of MSVC is being used (currently, 4, 5 & 6 supported) +# Define which major version of MSVC is being used +# (currently, 4, 5, 6, 7, and 8 are supported). +# Define the minor version of MSVC, currently only +# used for Microsoft Visual Studio .NET 2003 (7.1) + +#MSVC_VERSION=6 +#MSVC_MINOR_VERSION=0 + +# Make a guess at the version of MSVC in use +# This will not work if service packs change the version numbers. + +!if defined(_NMAKE_VER) && !defined(MSVC_VERSION) +!if "$(_NMAKE_VER)" == "162" +MSVC_VERSION=5 +!endif +!if "$(_NMAKE_VER)" == "6.00.8168.0" +MSVC_VERSION=6 +!endif +!if "$(_NMAKE_VER)" == "7.00.9466" +MSVC_VERSION=7 +!endif +!if "$(_NMAKE_VER)" == "7.00.9955" +MSVC_VERSION=7 +!endif +!if "$(_NMAKE_VER)" == "7.10.3077" +MSVC_VERSION=7 +MSVC_MINOR_VERSION=1 +!endif +!if "$(_NMAKE_VER)" == "8.00.40607.16" +MSVC_VERSION=8 +!endif +!if "$(_NMAKE_VER)" == "8.00.50727.42" +MSVC_VERSION=8 +!endif +!if "$(_NMAKE_VER)" == "8.00.50727.762" +MSVC_VERSION=8 +!endif +!if "$(_NMAKE_VER)" == "9.00.21022.08" +MSVC_VERSION=9 +!endif +!if "$(_NMAKE_VER)" == "9.00.30729.01" +MSVC_VERSION=9 +!endif +!if "$(_NMAKE_VER)" == "10.00.30319.01" +MSVC_VERSION=10 +!endif +!if "$(_NMAKE_VER)" == "11.00.50522.1" +MSVC_VERSION=11 +!endif +!if "$(_NMAKE_VER)" == "11.00.50727.1" +MSVC_VERSION=11 +!endif +!if "$(_NMAKE_VER)" == "11.00.60315.1" +MSVC_VERSION=11 +!endif +!if "$(_NMAKE_VER)" == "11.00.60610.1" +MSVC_VERSION=11 +!endif +!if "$(_NMAKE_VER)" == "12.00.21005.1" +MSVC_VERSION=12 +!endif +!if "$(_NMAKE_VER)" == "14.00.23506.0" +MSVC_VERSION=14 +!endif +!endif !ifndef MSVC_VERSION -MSVC_VERSION = 6 +MSVC_VERSION=6 +!endif +!ifndef MSVC_MINOR_VERSION +MSVC_MINOR_VERSION=0 !endif # Define the drive, directory, and compiler name for the Microsoft C files. @@ -250,6 +614,269 @@ !endif !endif +!if $(MSVC_VERSION) == 7 +! ifndef DEVSTUDIO +!if $(MSVC_MINOR_VERSION) == 0 +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio .NET +!else +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio .NET 2003 +!endif +! endif +!if "$(DEVSTUDIO)"=="" +COMPBASE= +SHAREDBASE= +!else +COMPBASE=$(DEVSTUDIO)\Vc7 +SHAREDBASE=$(DEVSTUDIO)\Vc7 +!endif +!endif + +!if $(MSVC_VERSION) == 8 +! ifndef DEVSTUDIO +!if $(BUILD_SYSTEM) == 64 +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio 8 +!else +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio 8 +!endif +! endif +!if "$(DEVSTUDIO)"=="" +COMPBASE= +SHAREDBASE= +!else +COMPBASE=$(DEVSTUDIO)\VC +SHAREDBASE=$(DEVSTUDIO)\VC +!ifdef WIN64 +COMPDIR64=$(COMPBASE)\bin\amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" /LIBPATH:"$(COMPBASE)\PlatformSDK\Lib\AMD64" +!endif +!endif +!endif + +!if $(MSVC_VERSION) == 9 +! ifndef DEVSTUDIO +!if $(BUILD_SYSTEM) == 64 +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio 9.0 +!else +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio 9.0 +!endif +! endif +!if "$(DEVSTUDIO)"=="" +COMPBASE= +SHAREDBASE= +!else +# There are at least 4 different values: +# "v6.0"=Vista, "v6.0A"=Visual Studio 2008, +# "v6.1"=Windows Server 2008, "v7.0"=Windows 7 +! ifdef MSSDK +RCDIR=$(MSSDK)\bin +! else +RCDIR=C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin +! endif +COMPBASE=$(DEVSTUDIO)\VC +SHAREDBASE=$(DEVSTUDIO)\VC +!ifdef WIN64 +COMPDIR64=$(COMPBASE)\bin\amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" /LIBPATH:"$(COMPBASE)\PlatformSDK\Lib\AMD64" +!endif +!endif +!endif + +!if $(MSVC_VERSION) == 10 +! ifndef DEVSTUDIO +!if $(BUILD_SYSTEM) == 64 +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio 10.0 +!else +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio 10.0 +!endif +! endif +!if "$(DEVSTUDIO)"=="" +COMPBASE= +SHAREDBASE= +!else +# There are at least 4 different values: +# "v6.0"=Vista, "v6.0A"=Visual Studio 2008, +# "v6.1"=Windows Server 2008, "v7.0"=Windows 7 +! ifdef MSSDK +! ifdef WIN64 +RCDIR=$(MSSDK)\bin\x64 +! else +RCDIR=$(MSSDK)\bin +! endif +! else +!ifdef WIN64 +RCDIR=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0\bin +!else +RCDIR=C:\Program Files\Microsoft SDKs\Windows\v7.0\bin +!endif +! endif +COMPBASE=$(DEVSTUDIO)\VC +SHAREDBASE=$(DEVSTUDIO)\VC +!ifdef WIN64 +!if $(BUILD_SYSTEM) == 64 +COMPDIR64=$(COMPBASE)\bin\amd64 +LINKLIBPATH=/LIBPATH:"$(MSSDK)\lib\x64" /LIBPATH:"$(COMPBASE)\lib\amd64" +!else +COMPDIR64=$(COMPBASE)\bin\x86_amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" /LIBPATH:"$(COMPBASE)\PlatformSDK\Lib\x64" +!endif +!endif +!endif +!endif + +!if $(MSVC_VERSION) == 11 +! ifndef DEVSTUDIO +!if $(BUILD_SYSTEM) == 64 +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio 11.0 +!else +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio 11.0 +!endif +! endif +!if "$(DEVSTUDIO)"=="" +COMPBASE= +SHAREDBASE= +!else +# There are at least 4 different values: +# "v6.0"=Vista, "v6.0A"=Visual Studio 2008, +# "v6.1"=Windows Server 2008, "v7.0"=Windows 7 +! ifdef MSSDK +! ifdef WIN64 +RCDIR=$(MSSDK)\bin\x64 +! else +RCDIR=$(MSSDK)\bin +! endif +! else +!if $(BUILD_SYSTEM) == 64 +RCDIR=C:\Program Files (x86)\Windows Kits\8.0\bin\x64 +!else +RCDIR=C:\Program Files\Windows Kits\8.0\bin\x86 +!endif +! endif +COMPBASE=$(DEVSTUDIO)\VC +SHAREDBASE=$(DEVSTUDIO)\VC +!ifdef WIN64 +!if $(BUILD_SYSTEM) == 64 +COMPDIR64=$(COMPBASE)\bin\x86_amd64 +LINKLIBPATH=/LIBPATH:"$(MSSDK)\lib\x64" /LIBPATH:"$(COMPBASE)\lib\amd64" +!else +COMPDIR64=$(COMPBASE)\bin\x86_amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" /LIBPATH:"$(COMPBASE)\PlatformSDK\Lib\x64" +!endif +!endif +!endif +!endif + +!if $(MSVC_VERSION) == 12 +! ifndef DEVSTUDIO +! if $(BUILD_SYSTEM) == 64 +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio 12.0 +! else +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio 12.0 +! endif +! endif +! if "$(DEVSTUDIO)"=="" +COMPBASE= +SHAREDBASE= +! else +# There are at least 4 different values: +# "v6.0"=Vista, "v6.0A"=Visual Studio 2008, +# "v6.1"=Windows Server 2008, "v7.0"=Windows 7 +! ifdef MSSDK +! ifdef WIN64 +RCDIR=$(MSSDK)\bin\x64 +! else +RCDIR=$(MSSDK)\bin +! endif +! else +! if $(BUILD_SYSTEM) == 64 +RCDIR=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin +! else +RCDIR=C:\Program Files\Microsoft SDKs\Windows\v7.1A\Bin +! endif +! endif +COMPBASE=$(DEVSTUDIO)\VC +SHAREDBASE=$(DEVSTUDIO)\VC +! ifdef WIN64 +! if $(BUILD_SYSTEM) == 64 +COMPDIR64=$(COMPBASE)\bin\x86_amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" +! else +COMPDIR64=$(COMPBASE)\bin\x86_amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" /LIBPATH:"$(COMPBASE)\PlatformSDK\Lib\x64" +! endif +! endif +! endif +!endif + +!if $(MSVC_VERSION) == 14 +! ifndef DEVSTUDIO +! if $(BUILD_SYSTEM) == 64 +DEVSTUDIO=C:\Program Files (x86)\Microsoft Visual Studio 14.0 +! else +DEVSTUDIO=C:\Program Files\Microsoft Visual Studio 14.0 +! endif +! endif +! if "$(DEVSTUDIO)"=="" +COMPBASE= +SHAREDBASE= +! else +# There are at least 4 different values: +# "v6.0"=Vista, "v6.0A"=Visual Studio 2008, +# "v6.1"=Windows Server 2008, "v7.0"=Windows 7 +! ifdef MSSDK +! ifdef WIN64 +RCDIR=$(MSSDK)\bin\x64 +! else +RCDIR=$(MSSDK)\bin +! endif +! else +! if $(BUILD_SYSTEM) == 64 +RCDIR=C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\Bin +! else +RCDIR=C:\Program Files\Microsoft SDKs\Windows\v10.0A\Bin +! endif +! endif +COMPBASE=$(DEVSTUDIO)\VC +SHAREDBASE=$(DEVSTUDIO)\VC +! ifdef WIN64 +! if $(BUILD_SYSTEM) == 64 +COMPDIR64=$(COMPBASE)\bin\x86_amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" +! else +COMPDIR64=$(COMPBASE)\bin\x86_amd64 +LINKLIBPATH=/LIBPATH:"$(COMPBASE)\lib\amd64" /LIBPATH:"$(COMPBASE)\PlatformSDK\Lib\x64" +! endif +! endif +! endif +!endif + +!if "$(ARM)"=="1" +VCINSTDIR=$(VS110COMNTOOLS)..\..\VC\ + +!ifndef WINSDKVER +WINSDKVER=8.0 +!endif + +!ifndef WINSDKDIR +WINSDKDIR=$(VS110COMNTOOLS)..\..\..\Windows Kits\$(WINSDKVER)\ +!endif + +COMPAUX__="$(VCINSTDIR)\bin\cl.exe" +COMPAUXCFLAGS=/I"$(VCINSTDIR)\INCLUDE" /I"$(VCINSTDIR)\ATLMFC\INCLUDE" \ +/I"$(WINSDKDIR)\include\shared" /I"$(WINSDKDIR)\include\um" \ +/I"$(WINDSKDIR)include\winrt" + +COMPAUXLDFLAGS=/LIBPATH:"$(VCINSTDIR)\LIB" \ +/LIBPATH:"$(VCINSTDIR)\ATLMFC\LIB" \ +/LIBPATH:"$(WINSDKDIR)\lib\win8\um\x86" + +COMPAUX=$(COMPAUX__) $(COMPAUXCFLAGS) + +!else + +COMPAUXLDFLAGS="" + +!endif + # Some environments don't want to specify the path names for the tools at all. # Typical definitions for such an environment would be: # MSINCDIR= LIBDIR= COMP=cl COMPAUX=cl RCOMP=rc LINK=link @@ -260,17 +887,25 @@ !if "$(COMPBASE)"=="" COMPDIR= !else +!ifdef WIN64 +COMPDIR=$(COMPDIR64) +!else COMPDIR=$(COMPBASE)\bin !endif !endif +!endif !ifndef LINKDIR !if "$(COMPBASE)"=="" LINKDIR= !else +!ifdef WIN64 +LINKDIR=$(COMPDIR64) +!else LINKDIR=$(COMPBASE)\bin !endif !endif +!endif !ifndef RCDIR !if "$(SHAREDBASE)"=="" @@ -292,9 +927,13 @@ !if "$(COMPBASE)"=="" LIBDIR= !else +!ifdef WIN64 +LIBDIR=$(COMPBASE)\lib\amd64 +!else LIBDIR=$(COMPBASE)\lib !endif !endif +!endif !ifndef COMP !if "$(COMPDIR)"=="" @@ -307,7 +946,11 @@ COMPCPP=$(COMP) !endif !ifndef COMPAUX +!ifdef WIN64 COMPAUX=$(COMP) +!else +COMPAUX=$(COMP) +!endif !endif !ifndef RCOMP @@ -346,6 +989,10 @@ !endif !endif +!ifndef LINKLIBPATH +LINKLIBPATH= +!endif + # Define the processor architecture. (i386, ppc, alpha) !ifndef CPU_FAMILY @@ -364,6 +1011,28 @@ #CPU_TYPE=601 !endif +# Define special features of CPUs + +# We'll assume that if you have an x86 machine, you've got a modern +# enough one to have SSE2 instructions. If you don't, then predefine +# DONT_HAVE_SSE2 when calling this makefile +!ifndef ARM +!if "$(CPU_FAMILY)" == "i386" +!ifndef DONT_HAVE_SSE2 +!ifndef HAVE_SSE2 +!message ************************************************************** +!message * Assuming that target has SSE2 instructions available. If * +!message * this is NOT the case, define DONT_HAVE_SSE2 when building. * +!message ************************************************************** +!endif +HAVE_SSE2=1 +CFLAGS=$(CFLAGS) /DHAVE_SSE2 +# add "/D__SSE__" here, but causes crashes just now +JPX_SSE_CFLAGS= +!endif +!endif +!endif + # Define the .dev module that implements thread and synchronization # primitives for this platform. Don't change this unless you really know # what you're doing. @@ -372,12 +1041,65 @@ SYNC=winsync !endif +# Luratech jp2 flags depend on the compiler version +# +!if "$(JPX_LIB)" == "luratech" || "$(JPX_LIB)" == "lwf_jp2" +# Set defaults for using the Luratech JP2 implementation +!ifndef JPXSRCDIR +# CSDK source code location +JPXSRCDIR=luratech\lwf_jp2 +!endif +!ifndef JPX_CFLAGS +# required compiler flags +!ifdef WIN64 +JPX_CFLAGS=-DUSE_LWF_JP2 -DWIN64 -DNO_ASSEMBLY +!else +JPX_CFLAGS=-DUSE_LWF_JP2 -DWIN32 -DNO_ASSEMBLY +!endif +!endif +!endif + +# OpenJPEG compiler flags +# +!if "$(JPX_LIB)" == "openjpeg" +!ifndef JPXSRCDIR +JPXSRCDIR=openjpeg +!endif +!ifndef JPX_CFLAGS +!ifdef WIN64 +JPX_CFLAGS=-DMUTEX_pthread=0 -DUSE_OPENJPEG_JP2 -DUSE_JPIP $(JPX_SSE_CFLAGS) -DOPJ_STATIC -DWIN64 +!else +JPX_CFLAGS=-DMUTEX_pthread=0 -DUSE_OPENJPEG_JP2 -DUSE_JPIP $(JPX_SSE_CFLAGS) -DOPJ_STATIC -DWIN32 +!endif +!else +JPX_CFLAGS = $JPX_CFLAGS -DUSE_JPIP -DUSE_OPENJPEG_JP2 -DOPJ_STATIC +!endif +!endif + +# Define the directory where the lcms2mt source is stored. +# See lcms2mt.mak for more information +SHARE_LCMS=0 +!ifndef LCMS2MTSRCDIR +LCMS2MTSRCDIR=lcms2mt +!endif + +# Define the directory where the lcms2 source is stored. +# See lcms2.mak for more information +!ifndef LCMS2SRCDIR +LCMS2SRCDIR=lcms2 +!endif + # ------ Devices and features ------ # # Choose the language feature(s) to include. See gs.mak for details. !ifndef FEATURE_DEVS -FEATURE_DEVS=$(GLD)psl3lib.dev $(GLD)path1lib.dev $(GLD)dps2lib.dev $(GLD)psl2cs.dev $(GLD)cielib.dev $(GLD)imasklib.dev $(GLD)patlib.dev $(GLD)htxlib.dev $(GLD)devcmap.dev $(GLD)bbox.dev $(GLD)pipe.dev +FEATURE_DEVS=$(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(GLD)psl3lib.dev $(GLD)psl2lib.dev \ + $(GLD)dps2lib.dev $(GLD)path1lib.dev $(GLD)patlib.dev $(GLD)psl2cs.dev $(GLD)rld.dev $(GLD)gxfapiu$(UFST_BRIDGE).dev\ + $(GLD)ttflib.dev $(GLD)cielib.dev $(GLD)pipe.dev $(GLD)htxlib.dev $(GLD)sdct.dev $(GLD)libpng.dev\ + $(GLD)seprlib.dev $(GLD)translib.dev $(GLD)cidlib.dev $(GLD)psf0lib.dev $(GLD)psf1lib.dev\ + $(GLD)psf2lib.dev $(GLD)lzwd.dev $(GLD)sicclib.dev $(GLD)mshandle.dev \ + $(GLD)ramfs.dev $(GLD)sjpx.dev $(GLD)sjbig2.dev $(GLD)pwgd.dev !endif # Choose whether to compile the .ps initialization files into the executable. @@ -416,7 +1138,7 @@ # Choose the device(s) to include. See devs.mak for details, # devs.mak and contrib.mak for the list of available devices. !ifndef DEVICE_DEVS -DEVICE_DEVS=$(DD)ljet2p.dev $(DD)bbox.dev +DEVICE_DEVS=$(DD)ppmraw.dev $(DD)bbox.dev DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= @@ -471,19 +1193,19 @@ # For some reason, C-file dependencies have to come before mslib32__.dev -$(GLOBJ)gp_mslib.$(OBJ): $(GLSRC)gp_mslib.c $(AK) +$(GLOBJ)gp_mslib.$(OBJ): $(GLSRC)gp_mslib.c $(TOP_MAKEFILES) $(arch_h) $(AK) $(GLCCWIN) $(GLO_)gp_mslib.$(OBJ) $(C_) $(GLSRC)gp_mslib.c mslib32__=$(GLOBJ)gp_mslib.$(OBJ) -$(GLGEN)mslib32_.dev: $(mslib32__) $(ECHOGS_XE) $(GLGEN)mswin32_.dev +$(GLGEN)mslib32_.dev: $(mslib32__) $(ECHOGS_XE) $(GLGEN)mswin32_.dev $(TOP_MAKEFILES) $(SETMOD) $(GLGEN)mslib32_ $(mslib32__) $(ADDMOD) $(GLGEN)mslib32_ -include $(GLGEN)mswin32_.dev # ----------------------------- Main program ------------------------------ # # The library tester EXE -$(GS_XE): $(GS_ALL) $(DEVS_ALL) $(LIB_ONLY) $(LIBCTR) +$(GS_XE): $(GS_ALL) $(DEVS_ALL) $(LIB_ONLY) $(LIBCTR) $(TOP_MAKEFILES) copy $(ld_tr) $(GLGENDIR)\gslib32.tr echo $(GLOBJDIR)\gsromfs$(COMPILE_INITS).$(OBJ) >> $(GLGENDIR)\gslib32.tr echo $(GLOBJ)gsnogc.obj >> $(GLGENDIR)\gslib32.tr diff -Nru ghostscript-9.10~dfsg/base/msvctail.mak ghostscript-9.25~dfsg+1/base/msvctail.mak --- ghostscript-9.10~dfsg/base/msvctail.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/msvctail.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Common tail section for Microsoft Visual C++ 4.x/5.x, # Windows NT or Windows 95 platform. @@ -18,12 +18,13 @@ # edited 1997-06-xx by JD to factor out interpreter-specific sections # edited 2000-06-05 by lpd to handle empty MSINCDIR specially. +MSVCTAIL_MAK=$(GLSRC)msvctail.mak $(TOP_MAKEFILES) # -------------------------- Auxiliary programs --------------------------- # # This also creates the subdirectories since this (hopefully) will be the # first need. Too bad nmake doesn't have .BEFORE symbolic target. -$(GLGENDIR)\ccf32.tr: $(TOP_MAKEFILES) +$(GLGENDIR)\ccf32.tr: $(MSVCTAIL_MAK) -if not exist $(PSOBJDIR) mkdir $(PSOBJDIR) -if not exist $(PSGENDIR) mkdir $(PSGENDIR) -if not exist $(PSGENDIR)$(D)cups mkdir $(PSGENDIR)$(D)cups @@ -35,41 +36,49 @@ -if not exist $(BINDIR) mkdir $(BINDIR) echo $(GENOPT) -DCHECK_INTERRUPTS -D_Windows -D__WIN32__ > $(GLGENDIR)\ccf32.tr -$(ECHOGS_XE): $(GLSRC)echogs.c $(GLGENDIR)\ccf32.tr +$(ECHOGS_XE): $(GLSRC)echogs.c $(GLGENDIR)\ccf32.tr $(MSVCTAIL_MAK) $(CCAUX_) $(GLSRC)echogs.c $(AUXO_)echogs.obj /Fe$(ECHOGS_XE) $(CCAUX_TAIL) # Don't create genarch if it's not needed !ifdef GENARCH_XE !ifdef WIN64 # The genarch.exe that is generated is 64-bit, so the OS must be able to run it -$(GENARCH_XE): $(GLSRC)genarch.c $(GENARCH_DEPS) $(GLGENDIR)\ccf32.tr +$(GENARCH_XE): $(GLSRC)genarch.c $(GENARCH_DEPS) $(GLGENDIR)\ccf32.tr $(MSVCTAIL_MAK) $(CCAUX_) /Fo$(AUX)genarch.obj /Fe$(GENARCH_XE) $(GLSRC)genarch.c $(CCAUX_TAIL) !else -$(GENARCH_XE): $(GLSRC)genarch.c $(GENARCH_DEPS) $(GLGENDIR)\ccf32.tr +$(GENARCH_XE): $(GLSRC)genarch.c $(GENARCH_DEPS) $(GLGENDIR)\ccf32.tr $(MSVCTAIL_MAK) $(CCAUX_) /Fo$(AUX)genarch.obj /Fe$(GENARCH_XE) $(GLSRC)genarch.c $(CCAUX_TAIL) !endif !endif -$(GENCONF_XE): $(GLSRC)genconf.c $(GLGENDIR)\ccf32.tr $(GENCONF_DEPS) +$(GENCONF_XE): $(GLSRC)genconf.c $(GLGENDIR)\ccf32.tr $(GENCONF_DEPS) $(MSVCTAIL_MAK) $(CCAUX_) $(GLSRC)genconf.c /Fo$(AUX)genconf.obj /Fe$(GENCONF_XE) $(CCAUX_TAIL) -$(GENDEV_XE): $(GLSRC)gendev.c $(GLGENDIR)\ccf32.tr $(GENDEV_DEPS) +$(GENDEV_XE): $(GLSRC)gendev.c $(GLGENDIR)\ccf32.tr $(GENDEV_DEPS) $(MSVCTAIL_MAK) $(CCAUX_) $(GLSRC)gendev.c /Fo$(AUX)gendev.obj /Fe$(GENDEV_XE) $(CCAUX_TAIL) -$(GENHT_XE): $(GLSRC)genht.c $(GLGENDIR)\ccf32.tr $(GENHT_DEPS) +$(GENHT_XE): $(GLSRC)genht.c $(GLGENDIR)\ccf32.tr $(GENHT_DEPS) $(MSVCTAIL_MAK) $(CCAUX_) $(GENHT_CFLAGS) $(GLSRC)genht.c /Fo$(AUX)genht.obj /Fe$(GENHT_XE) $(CCAUX_TAIL) MKROMFS_OBJS=$(MKROMFS_ZLIB_OBJS) $(AUX)gp_ntfs.$(OBJ) $(AUX)gp_win32.$(OBJ) $(AUX)gpmisc.$(OBJ)\ $(AUX)gp_getnv.$(OBJ) $(AUX)gp_wutf8.$(OBJ) -$(MKROMFS_XE): $(GLSRC)mkromfs.c $(GLGENDIR)\ccf32.tr $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS) +$(MKROMFS_XE): $(GLSRC)mkromfs.c $(GLGENDIR)\ccf32.tr $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS) $(MSVCTAIL_MAK) $(CCAUX_) -I$(GLOBJ) -I$(ZSRCDIR) $(GLSRC)mkromfs.c /Fo$(AUX)mkromfs.obj /Fe$(MKROMFS_XE) $(MKROMFS_OBJS) $(CCAUX_TAIL) +$(PACKPS_XE): $(GLSRC)pack_ps.c $(GLSRC)stdpre.h $(MSVCTAIL_MAK) + $(CCAUX_) -I$(GLOBJ) -I$(ZSRCDIR) $(GLSRC)pack_ps.c /Fo$(AUX)pack_ps.obj /Fe$(PACKPS_XE) $(CCAUX_TAIL) + # -------------------------------- Library -------------------------------- # # See winlib.mak # ----------------------------- Main program ------------------------------ # +# ole32 is only used for xpsprint, but the pcl/language switch +# build systems don't have XPSPRINT set at this point, so we can't +# rely on it. Always offer the lib for linking, and the linker +# will drop it if unrequired. + LIBCTR=$(GLGEN)libc32.tr $(LIBCTR): $(TOP_MAKEFILES) @@ -83,6 +92,7 @@ echo winspool.lib >>$(LIBCTR) echo advapi32.lib >>$(LIBCTR) echo ws2_32.lib >>$(LIBCTR) + echo ole32.lib >>$(LIBCTR) !endif # end of msvctail.mak diff -Nru ghostscript-9.10~dfsg/base/openjpeg.mak ghostscript-9.25~dfsg+1/base/openjpeg.mak --- ghostscript-9.10~dfsg/base/openjpeg.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/openjpeg.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for Luratech lwf_jp2 library code. @@ -29,161 +29,173 @@ # This partial makefile compiles the openjpeg library for use in # Ghostscript. -OPEN_JPEG_MAK=$(GLSRC)openjpeg.mak +OPEN_JPEG_MAK=$(GLSRC)openjpeg.mak $(TOP_MAKEFILES) -OPEN_JPEG_SRC=$(JPXSRCDIR)$(D)libopenjpeg$(D) +OPEN_JPEG_SRC=$(JPXSRCDIR)$(D)src$(D)lib$(D)openjp2$(D) OPEN_JPEG_GEN=$(JPXOBJDIR)$(D) OPEN_JPEG_PREFIX=opj_ OPEN_JPEG_OBJ=$(JPXOBJDIR)$(D) -OPEN_JPEG_CONFIG_H=$(OPEN_JPEG_GEN)opj_config.h # source files to build from the CSDK source open_jpeg_OBJS = \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)bio.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)cidx_manager.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)cio.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)dwt.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)event.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)function_list.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)image.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)invert.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)j2k.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)j2k_lib.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)jp2.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)jpt.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)mct.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)mqc.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)openjpeg.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)phix_manager.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)pi.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)raw.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)ppix_manager.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)t1.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)t2.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tcd.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tgt.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)cidx_manager.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tpix_manager.$(OBJ) \ $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)thix_manager.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)ppix_manager.$(OBJ) \ - $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)phix_manager.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tpix_manager.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)thread.$(OBJ) \ + $(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)sparse_array.$(OBJ) open_jpeg_HDRS = \ $(OPEN_JPEG_SRC)bio.h \ + $(OPEN_JPEG_SRC)cidx_manager.h \ $(OPEN_JPEG_SRC)cio.h \ $(OPEN_JPEG_SRC)dwt.h \ $(OPEN_JPEG_SRC)event.h \ - $(OPEN_JPEG_SRC)fix.h \ + $(OPEN_JPEG_SRC)function_list.h \ $(OPEN_JPEG_SRC)image.h \ - $(OPEN_JPEG_SRC)int.h \ + $(OPEN_JPEG_SRC)indexbox_manager.h \ + $(OPEN_JPEG_SRC)invert.h \ $(OPEN_JPEG_SRC)j2k.h \ - $(OPEN_JPEG_SRC)j2k_lib.h \ $(OPEN_JPEG_SRC)jp2.h \ - $(OPEN_JPEG_SRC)jpt.h \ $(OPEN_JPEG_SRC)mct.h \ $(OPEN_JPEG_SRC)mqc.h \ $(OPEN_JPEG_SRC)openjpeg.h \ + $(OPEN_JPEG_SRC)opj_clock.h \ + $(OPEN_JPEG_SRC)opj_config.h \ + $(OPEN_JPEG_SRC)opj_config_private.h \ $(OPEN_JPEG_SRC)opj_includes.h \ + $(OPEN_JPEG_SRC)opj_intmath.h \ + $(OPEN_JPEG_SRC)opj_inttypes.h \ $(OPEN_JPEG_SRC)opj_malloc.h \ + $(OPEN_JPEG_SRC)opj_stdint.h \ $(OPEN_JPEG_SRC)pi.h \ - $(OPEN_JPEG_SRC)raw.h \ $(OPEN_JPEG_SRC)t1.h \ $(OPEN_JPEG_SRC)t1_luts.h \ $(OPEN_JPEG_SRC)t2.h \ $(OPEN_JPEG_SRC)tcd.h \ $(OPEN_JPEG_SRC)tgt.h \ - $(OPEN_JPEG_SRC)cidx_manager.h \ - $(OPEN_JPEG_SRC)indexbox_manager.h \ - -$(OPEN_JPEG_CONFIG_H): $(TOP_MAKEFILES) $(JPXSRCDIR)$(D)opj_config.h.in.user - $(CP_) $(JPXSRCDIR)$(D)opj_config.h.in.user $(OPEN_JPEG_CONFIG_H) + $(OPEN_JPEG_SRC)thread.h \ + $(OPEN_JPEG_SRC)tls_keys.h \ + $(OPEN_JPEG_SRC)sparse_array.h # switch in the selected library .dev -$(OPEN_JPEG_GEN)openjpeg.dev : $(TOP_MAKEFILES) $(OPEN_JPEG_GEN)openjpeg_$(SHARE_JPX).dev +$(OPEN_JPEG_GEN)openjpeg.dev : $(OPEN_JPEG_GEN)openjpeg_$(SHARE_JPX).dev \ + $(OPEN_JPEG_MAK) $(MAKEDIRS) $(CP_) $(OPEN_JPEG_GEN)openjpeg_$(SHARE_JPX).dev $(OPEN_JPEG_GEN)openjpeg.dev -# external link .dev -$(OPEN_JPEG_GEN)openjpeg_1.dev : $(TOP_MAKEFILES) $(OPEN_JPEG_MAK) $(ECHOGS_XE) - $(SETMOD) $(OPEN_JPEG_GEN)openjpeg_1 -lib lib_openjpeg +# external link .dev - empty, as we add the lib to LDFLAGS +$(OPEN_JPEG_GEN)openjpeg_1.dev : $(OPEN_JPEG_MAK) $(ECHOGS_XE) \ + $(OPEN_JPEG_MAK) $(MAKEDIRS) + $(SETMOD) $(OPEN_JPEG_GEN)openjpeg_1 # compile our own .dev -$(OPEN_JPEG_GEN)openjpeg_0.dev : $(TOP_MAKEFILES) $(OPEN_JPEG_MAK) $(ECHOGS_XE) $(open_jpeg_OBJS) +$(OPEN_JPEG_GEN)openjpeg_0.dev : $(ECHOGS_XE) $(open_jpeg_OBJS) \ + $(OPEN_JPEG_MAK) $(MAKEDIRS) $(SETMOD) $(OPEN_JPEG_GEN)openjpeg_0 $(open_jpeg_OBJS) # define our specific compiler -OPEN_JPEG_CC=$(CC) $(CFLAGS) $(D_)OPJ_STATIC$(_D) $(I_)$(OPEN_JPEG_GEN)$(_I) $(I_)$(JPX_OPENJPEG_I_)$(_I) $(I_)$(JPX_OPENJPEG_I_)$(D)..$(_I) $(JPXCF_) +OPEN_JPEG_CC=$(CC) $(CFLAGS) $(D_)OPJ_STATIC$(_D) $(D_)STANDARD_SLOW_VERSION$(_D) $(I_)$(OPEN_JPEG_GEN)$(_I) $(I_)$(JPX_OPENJPEG_I_)$(_I) $(I_)$(JPX_OPENJPEG_I_)$(D)..$(_I) $(JPXCF_) OPEN_JPEG_O=$(O_)$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX) -OPEN_JPEG_DEP=$(AK) $(OPEN_JPEG_MAK) +OPEN_JPEG_DEP=$(AK) $(OPEN_JPEG_MAK) $(MAKEDIRS) # explicit rules for building each source file # for simplicity we have every source file depend on all headers -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)bio.$(OBJ) : $(OPEN_JPEG_SRC)bio.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)bio.$(OBJ) : $(OPEN_JPEG_SRC)bio.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)bio.$(OBJ) $(C_) $(OPEN_JPEG_SRC)bio.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)cio.$(OBJ) : $(OPEN_JPEG_SRC)cio.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)cio.$(OBJ) : $(OPEN_JPEG_SRC)cio.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)cio.$(OBJ) $(C_) $(OPEN_JPEG_SRC)cio.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)dwt.$(OBJ) : $(OPEN_JPEG_SRC)dwt.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)dwt.$(OBJ) : $(OPEN_JPEG_SRC)dwt.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)dwt.$(OBJ) $(C_) $(OPEN_JPEG_SRC)dwt.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)event.$(OBJ) : $(OPEN_JPEG_SRC)event.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)event.$(OBJ) : $(OPEN_JPEG_SRC)event.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)event.$(OBJ) $(C_) $(OPEN_JPEG_SRC)event.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)image.$(OBJ) : $(OPEN_JPEG_SRC)image.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)function_list.$(OBJ) : $(OPEN_JPEG_SRC)function_list.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) + $(OPEN_JPEG_CC) $(OPEN_JPEG_O)function_list.$(OBJ) $(C_) $(OPEN_JPEG_SRC)function_list.c + +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)image.$(OBJ) : $(OPEN_JPEG_SRC)image.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)image.$(OBJ) $(C_) $(OPEN_JPEG_SRC)image.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)j2k.$(OBJ) : $(OPEN_JPEG_SRC)j2k.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) - $(OPEN_JPEG_CC) $(OPEN_JPEG_O)j2k.$(OBJ) $(C_) $(OPEN_JPEG_SRC)j2k.c +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)invert.$(OBJ) : $(OPEN_JPEG_SRC)invert.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) + $(OPEN_JPEG_CC) $(OPEN_JPEG_O)invert.$(OBJ) $(C_) $(OPEN_JPEG_SRC)invert.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)j2k_lib.$(OBJ) : $(OPEN_JPEG_SRC)j2k_lib.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) - $(OPEN_JPEG_CC) $(OPEN_JPEG_O)j2k_lib.$(OBJ) $(C_) $(OPEN_JPEG_SRC)j2k_lib.c +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)j2k.$(OBJ) : $(OPEN_JPEG_SRC)j2k.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) + $(OPEN_JPEG_CC) $(OPEN_JPEG_O)j2k.$(OBJ) $(C_) $(OPEN_JPEG_SRC)j2k.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)jp2.$(OBJ) : $(OPEN_JPEG_SRC)jp2.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)jp2.$(OBJ) : $(OPEN_JPEG_SRC)jp2.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)jp2.$(OBJ) $(C_) $(OPEN_JPEG_SRC)jp2.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)jpt.$(OBJ) : $(OPEN_JPEG_SRC)jpt.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) - $(OPEN_JPEG_CC) $(OPEN_JPEG_O)jpt.$(OBJ) $(C_) $(OPEN_JPEG_SRC)jpt.c - -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)mct.$(OBJ) : $(OPEN_JPEG_SRC)mct.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)mct.$(OBJ) : $(OPEN_JPEG_SRC)mct.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)mct.$(OBJ) $(C_) $(OPEN_JPEG_SRC)mct.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)mqc.$(OBJ) : $(OPEN_JPEG_SRC)mqc.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)mqc.$(OBJ) : $(OPEN_JPEG_SRC)mqc.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)mqc.$(OBJ) $(C_) $(OPEN_JPEG_SRC)mqc.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)openjpeg.$(OBJ) : $(OPEN_JPEG_SRC)openjpeg.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)openjpeg.$(OBJ) : $(OPEN_JPEG_SRC)openjpeg.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)openjpeg.$(OBJ) $(C_) $(OPEN_JPEG_SRC)openjpeg.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)pi.$(OBJ) : $(OPEN_JPEG_SRC)pi.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) - $(OPEN_JPEG_CC) $(OPEN_JPEG_O)pi.$(OBJ) $(C_) $(OPEN_JPEG_SRC)pi.c +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)opj_clock.$(OBJ) : $(OPEN_JPEG_SRC)opj_clock.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) + $(OPEN_JPEG_CC) $(OPEN_JPEG_O)opj_clock.$(OBJ) $(C_) $(OPEN_JPEG_SRC)opj_clock.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)raw.$(OBJ) : $(OPEN_JPEG_SRC)raw.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) - $(OPEN_JPEG_CC) $(OPEN_JPEG_O)raw.$(OBJ) $(C_) $(OPEN_JPEG_SRC)raw.c +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)pi.$(OBJ) : $(OPEN_JPEG_SRC)pi.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) + $(OPEN_JPEG_CC) $(OPEN_JPEG_O)pi.$(OBJ) $(C_) $(OPEN_JPEG_SRC)pi.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)t1.$(OBJ) : $(OPEN_JPEG_SRC)t1.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)t1.$(OBJ) : $(OPEN_JPEG_SRC)t1.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)t1.$(OBJ) $(C_) $(OPEN_JPEG_SRC)t1.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)t2.$(OBJ) : $(OPEN_JPEG_SRC)t2.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)t2.$(OBJ) : $(OPEN_JPEG_SRC)t2.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)t2.$(OBJ) $(C_) $(OPEN_JPEG_SRC)t2.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tcd.$(OBJ) : $(OPEN_JPEG_SRC)tcd.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tcd.$(OBJ) : $(OPEN_JPEG_SRC)tcd.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)tcd.$(OBJ) $(C_) $(OPEN_JPEG_SRC)tcd.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tgt.$(OBJ) : $(OPEN_JPEG_SRC)tgt.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tgt.$(OBJ) : $(OPEN_JPEG_SRC)tgt.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)tgt.$(OBJ) $(C_) $(OPEN_JPEG_SRC)tgt.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)cidx_manager.$(OBJ) : $(OPEN_JPEG_SRC)cidx_manager.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)cidx_manager.$(OBJ) : $(OPEN_JPEG_SRC)cidx_manager.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)cidx_manager.$(OBJ) $(C_) $(OPEN_JPEG_SRC)cidx_manager.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tpix_manager.$(OBJ) : $(OPEN_JPEG_SRC)tpix_manager.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)tpix_manager.$(OBJ) : $(OPEN_JPEG_SRC)tpix_manager.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)tpix_manager.$(OBJ) $(C_) $(OPEN_JPEG_SRC)tpix_manager.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)thix_manager.$(OBJ) : $(OPEN_JPEG_SRC)thix_manager.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)thix_manager.$(OBJ) : $(OPEN_JPEG_SRC)thix_manager.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)thix_manager.$(OBJ) $(C_) $(OPEN_JPEG_SRC)thix_manager.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)ppix_manager.$(OBJ) : $(OPEN_JPEG_SRC)ppix_manager.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)ppix_manager.$(OBJ) : $(OPEN_JPEG_SRC)ppix_manager.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)ppix_manager.$(OBJ) $(C_) $(OPEN_JPEG_SRC)ppix_manager.c -$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)phix_manager.$(OBJ) : $(OPEN_JPEG_SRC)phix_manager.c $(OPEN_JPEG_DEP) $(open_jpeg_HDRS) $(OPEN_JPEG_CONFIG_H) +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)phix_manager.$(OBJ) : $(OPEN_JPEG_SRC)phix_manager.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) $(OPEN_JPEG_CC) $(OPEN_JPEG_O)phix_manager.$(OBJ) $(C_) $(OPEN_JPEG_SRC)phix_manager.c +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)thread.$(OBJ) : $(OPEN_JPEG_SRC)thread.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) + $(OPEN_JPEG_CC) $(OPEN_JPEG_O)thread.$(OBJ) $(C_) $(OPEN_JPEG_SRC)thread.c + +$(OPEN_JPEG_OBJ)$(OPEN_JPEG_PREFIX)sparse_array.$(OBJ) : $(OPEN_JPEG_SRC)sparse_array.c $(open_jpeg_HDRS) $(OPEN_JPEG_DEP) + $(OPEN_JPEG_CC) $(OPEN_JPEG_O)sparse_array.$(OBJ) $(C_) $(OPEN_JPEG_SRC)sparse_array.c + # end of file diff -Nru ghostscript-9.10~dfsg/base/openvms.mak ghostscript-9.25~dfsg+1/base/openvms.mak --- ghostscript-9.10~dfsg/base/openvms.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/openvms.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for OpenVMS VAX and Alpha # @@ -128,10 +128,10 @@ # Define the jpeg2k library and source location. -# Define the directory where the lcms source is stored. -# See lcms.mak for more information +# Define the directory where the lcms2mt source is stored. +# See lcms2mt.mak for more information -LCMSSRCDIR=[.lcms] +LCMS2MTSRCDIR=[.lcms2mt] # Define the directory where the lcms2 source is stored. @@ -140,9 +140,9 @@ LCMS2SRCDIR=[.lcms2] # Which CMS are we using? -# Options are currently lcms or lcms2 +# Options are currently lcms2mt or lcms2 -WHICH_CMS=lcms2 +WHICH_CMS=lcms2mt # IJS has not been ported to OpenVMS. If you do the port, # you'll need to set these values. You'll also need to @@ -234,8 +234,8 @@ DEVICE_DEVS12=$(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pngmonod.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev -DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)ps2write.dev $(DD)epswrite.dev $(DD)txtwrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev -DEVICE_DEVS16=$(DD)bbox.dev $(DD)inkcov.dev +DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)ps2write.dev $(DD)eps2write.dev $(DD)txtwrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev +DEVICE_DEVS16=$(DD)bbox.dev $(DD)inkcov.dev $(DD)ink_cov.dev # Overflow from DEVS9 DEVICE_DEVS17=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev $(DD)pamcmyk32.dev DEVICE_DEVS18= @@ -453,7 +453,7 @@ # OpenVMS.dev -openvms__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_paper.$(OBJ) $(GLOBJ)gp_vms.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) +openvms__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_paper.$(OBJ) $(GLOBJ)gp_vms.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gp_nxpsprn.$(OBJ) $(GLGEN)openvms_.dev : $(openvms__) $(GLGEN)nosync.dev $(SETMOD) $(GLGEN)openvms_ $(openvms__) -include $(GLGEN)nosync diff -Nru ghostscript-9.10~dfsg/base/openvms.mmk ghostscript-9.25~dfsg+1/base/openvms.mmk --- ghostscript-9.10~dfsg/base/openvms.mmk 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/openvms.mmk 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for OpenVMS VAX and Alpha using MMK # @@ -246,7 +246,7 @@ DEVICE_DEVS12=$(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev -DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)epswrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev +DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)eps2write.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev DEVICE_DEVS16=$(DD)bbox.dev # Overflow from DEVS9 DEVICE_DEVS17=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev diff -Nru ghostscript-9.10~dfsg/base/pack_ps.c ghostscript-9.25~dfsg+1/base/pack_ps.c --- ghostscript-9.10~dfsg/base/pack_ps.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/pack_ps.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,447 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Pack a PostScript file into a C file containing an array of strings. */ + +/* The PostScript data is packed to remove excess whitespace and comments. + * Optionally, all header comments in the PostScript file can be copied + * over as comments in the C file. + * + * Usage: pack_ps [-o outfile] [-n name] [-c] ps_file + * + * options (must precede ps_file to be processed): + * + * -o outfile Output C file name. + * -n array_name Name of the array inside the generated C file. + * -c output PostScript header comments as C comments. + * + * ps_file Name of the PostScript file to be converted. + */ + +#define OUTFILE_NAME_DEFAULT "obj/packed_ps.c" +#define ARRAY_NAME_DEFAULT "packed_ps" + +#include "stdpre.h" +#include +#include +#include +#include + +#ifdef DEBUG_AUX +#define STRIP_PDFR_DEBUG_CALLS 0 /* Disabled for debug builds. */ +#else +/* Set to 1 to strip PDFR_DEBUG calls for release builds. */ +#define STRIP_PDFR_DEBUG_CALLS 0 /* Disabled for release builds. */ +#endif + +#if STRIP_PDFR_DEBUG_CALLS +/* Start and end prefixes for PDFR_DEBUG blocks. */ +#define PDFR_DEBUG_START_PREFIX "//PDFR_DEBUG" +#define PDFR_DEBUG_END_COMMENT_1 "% //PDFR_DEBUG" +#define PDFR_DEBUG_END_COMMENT_2 "%//PDFR_DEBUG" +#endif + +/* Forward references */ +static bool readline(FILE * in, char *str, int len); +static int pack_postscript_line(const char *inputline, char *outputline, char *comment); +static void usage(const char *outfilename, const char *arrayname); +int main(int argc, char *argv[]); + +/* Read a line from the input. */ +static bool +readline(FILE * in, char *str, int len) +{ + /* + * Unfortunately, we can't use fgets here, because the typical + * implementation only recognizes the EOL convention of the current + * platform. + */ + int i = 0, c = getc(in); + + if (c < 0) { + return false; + } + while (i < len - 1) { + if (c < 0 || c == 10) { /* ^J, Unix EOL */ + break; + } + if (c == 13) { /* ^M, Mac EOL */ + c = getc(in); + if (c != 10 && c >= 0) { /* ^M^J, PC EOL */ + ungetc(c, in); + } + break; + } + str[i++] = c; + c = getc(in); + } + str[i] = 0; + return true; +} + +/* + * Strip extraneous whitespace and comments from a line of PostScript code. + * Return a pointer to any string that remains, or NULL if the line contains + * no code. + * + * Stores the packed string in outputline, and any comment section in comment, + * as NULL-terminated strings. If there is no comment, the comment string will + * be set to an empty string. + * + * Returns the length of outputline. If the line contains no PostScript data + * other than whitespace or comments, this length will be zero. + * + * Note: the caller is responsible for allocating storage for all three strings, + * and this routine will modify both the outputline and comment parameters. + * Currently no overflow checking is performed. In practice, both outputline + * and comment will be equal to or shorter than the input line, but in the + * worst case (a line of all double-quotes or all backslashes, neither of + * which is legal PostScript) the output line could theoretically consume + * double the space of the input line. A large fixed size for all three + * strings, such as 4096, should be sufficient for practical purposes. + * + * Note: Although this routine resembles the "doit" method in mkromfs.c, it + * performs additional escaping of backslash and double-quote characters, since + * its output is intended to be embedded in a C string. + */ +static int +pack_postscript_line(const char *inputline, char *outputline, char *comment) +{ + const char *str = inputline; + const char *from; + char *to; + int in_string = 0; + + /* Clear the output strings. */ + outputline[0] = '\0'; + comment[0] = '\0'; + + while (*str == ' ' || *str == '\t') { /* strip leading whitespace */ + ++str; + } + if (*str == 0) { /* all whitespace */ + return 0; + } + if (!strncmp(str, "%END", 4)) { /* keep these for .skipeof */ + strcpy(outputline, str); + strcpy(comment, str); + return strlen(outputline); + } + + /* + * Copy the string over, removing: + * - All comments not within string literals; + * - Whitespace adjacent to '[' ']' '{' '}'; + * - Whitespace before '/' '(' '<'; + * - Whitespace after ')' '>'. + */ + for (from = str, to = outputline; (*to = *from) != 0; ++from, ++to) { + switch (*from) { + case '%': + if (!in_string) { + /* Store the rest of the line in the comment. */ + while (*from && (/* (*from == '%') || */ (*from == ' ') || (*from == '\t'))) { + from++; + } + strcpy(comment, from); + break; + } + continue; + case ' ': + case '\t': + if (to > outputline && !in_string && strchr(" \t>[]{})", to[-1])) { + --to; + } + continue; + case '(': + case '<': + case '/': + case '[': + case ']': + case '{': + case '}': + if (to > outputline && !in_string && strchr(" \t", to[-1])) { + *--to = *from; + } + if (*from == '(') { + ++in_string; + } + continue; + case ')': + --in_string; + continue; + case '\"': + /* Because we're writing to a C string, every double-quote we output needs to be escaped with a preceding backslash. */ + *to = '\\'; + *++to = *from; + continue; + case '\\': + /* Because we're writing to a C string, every backslash we output needs to be escaped with a preceding backslash. */ + *++to = '\\'; + + if (from[1] == '\\') { + *++to = '\\'; /* A double-backslash turns into four backslashes inside a C quote. */ + *++to = *++from; + } + else if (from[1] == '(' || from[1] == ')') { + *++to = *++from; /* Output as "\\(" or "\\)" */ + } + continue; + default: + continue; + } + break; + } + + /* Strip trailing whitespace from outputline. */ + while (to > outputline && (to[-1] == ' ' || to[-1] == '\t')) { + --to; + } + *to = 0; + + /* Strip trailing whitespace from the comment. */ + if (strlen(comment) > 0) { + int comment_len = strlen(comment); + char *ptr = comment + comment_len - 1; + + while ((*ptr == ' ') || (*ptr == '\t')) { + *(ptr--) = '\0'; + } + + /* If all that's left is the percent sign, skip it unless it's the only thing on the line. */ + if ((strlen (comment) == 1) && (strlen(outputline) != 0)) { + comment [0] = '\0'; + } + } + + /* Return line length, so 0 = no data found. */ + return strlen(outputline); +} + +static void +usage(const char *outfilename, const char *arrayname) +{ + printf("\n"); + printf(" Usage: pack_ps [-o outfile] [-n name] [-c] ps_file\n"); + printf("\n"); + printf(" options (must precede ps_file to be processed):\n"); + printf(" -o outfile default: %s - output file name\n", outfilename); + printf(" -n array_name default: %s - name of the array inside the generated C file.\n", arrayname); + printf(" -c output PostScript header comments as C comments.\n"); +} + +int +main(int argc, char *argv[]) +{ + const char *outfilename = OUTFILE_NAME_DEFAULT; + const char *arrayname = ARRAY_NAME_DEFAULT; + const char *infilename = NULL; + bool output_comments = false; + FILE *infile; + FILE *outfile; + + int atarg = 1; + int total_input_length = 0; + int total_output_length = 0; + int total_code_lines = 0; + int total_comment_header_lines = 0; +#if STRIP_PDFR_DEBUG_CALLS + int pdfr_debug_start_count = 0; + int pdfr_debug_end_count = 0; + bool skip_this_line = false; +#endif + time_t buildtime = 0; + char *env_source_date_epoch; + +#define INPUT_LINE_LENGTH_MAX 4096 + char inputline[INPUT_LINE_LENGTH_MAX]; + + /* At least an input file name must be provided. */ + if (argc < 2) { + usage(outfilename, arrayname); + exit(1); + } + + /* Process arguments denoted with dashes. */ + while (atarg < argc) { + if (argv[atarg][0] != '-') { + /* End of optional arguments */ + break; + } + switch (argv[atarg][1]) { + case 'o' : /* output file name */ + /* Skip to next argument */ + if (++atarg >= argc) { + usage(outfilename, arrayname); + exit(0); + } + outfilename = argv[atarg++]; + break; + + case 'n' : /* C array name for this block of code */ + /* Skip to next argument */ + if (++atarg >= argc) { + usage(outfilename, arrayname); + exit(0); + } + arrayname = argv[atarg++]; + break; + + case 'c' : /* Enable comments in output C file */ + /* Skip to next argument */ + output_comments = true; + atarg++; + break; + } + } + + /* The final argument is the file name to be processed. */ + if (atarg >= argc) { + usage(outfilename, arrayname); + exit(-1); + } + infilename = argv[atarg]; + + printf("%s:\n", argv[0]); + printf(" Input file: %s\n", infilename); + printf(" Output file: %s\n", outfilename); + printf(" Array name: %s\n", arrayname); + + infile = fopen(infilename, "r"); + if (infile == NULL) { + printf("Unable to open input file \"%s\"\n", infilename); + exit(-1); + } + outfile = fopen(outfilename, "w"); + if (outfile == NULL) { + fclose(infile); + printf("Unable to open output file \"%s\"\n", outfilename); + exit(-1); + } + + /* Output a header comment showing the source file and build time. */ + if ((env_source_date_epoch = getenv("SOURCE_DATE_EPOCH"))) { + buildtime = strtoul(env_source_date_epoch, NULL, 10); + } + if (!buildtime) { + buildtime = time(NULL); + } + fprintf(outfile,"/* Auto-generated from PostScript file \"%s\" at time %ld */\n", infilename, buildtime); + + while (readline(infile, inputline, INPUT_LINE_LENGTH_MAX)) { + + char packedline[INPUT_LINE_LENGTH_MAX]; + char comment[INPUT_LINE_LENGTH_MAX]; + int unpackedlen = strlen(inputline); + int packedlen = pack_postscript_line(inputline, packedline, comment); + int commentlen = strlen(comment); + +#if STRIP_PDFR_DEBUG_CALLS + skip_this_line = false; + if (!strncmp(packedline, PDFR_DEBUG_START_PREFIX, strlen(PDFR_DEBUG_START_PREFIX))) { + /* Start of PDFR_DEBUG command found. */ + pdfr_debug_start_count++; + if (pdfr_debug_start_count != pdfr_debug_end_count+1) { + printf ("ERROR: missing PDFR_DEBUG terminating comment for call %d.\n", pdfr_debug_start_count); + fclose(infile); + fclose(outfile); + exit(-1); + } + } + + /* Skip the line if we're in a PDFR_DEBUG block. By checking here before we look for the + * trailing comment, we can suppress single-line as well as multi-line PDFR_DEBUG blocks. + */ + if (pdfr_debug_start_count != pdfr_debug_end_count) { + skip_this_line = true; + } + + if ((!strncmp(comment, PDFR_DEBUG_END_COMMENT_1, strlen(PDFR_DEBUG_END_COMMENT_1))) || + (!strncmp(comment, PDFR_DEBUG_END_COMMENT_2, strlen(PDFR_DEBUG_END_COMMENT_2)))) { + + /* End of PDFR_DEBUG command found. */ + pdfr_debug_end_count++; + if (pdfr_debug_start_count != pdfr_debug_end_count) { + printf ("ERROR: extra PDFR_DEBUG terminating comment for call %d.\n", pdfr_debug_start_count+1); + fclose(infile); + fclose(outfile); + exit(-1); + } + } + + if (skip_this_line) { + continue; + } +#endif + if (packedlen > 0) { + total_code_lines++; + } + + total_input_length += unpackedlen; + total_output_length += packedlen; + + /* Output any comments at the head of the file if requested. */ + if (output_comments) { + if ((total_code_lines == 0) && (commentlen > 0)) { + total_comment_header_lines++; + + if (total_comment_header_lines == 1) { + fprintf(outfile, "/* %s\n", comment); + } + else { + fprintf(outfile, " * %s\n", comment); + } + } + else if ((total_code_lines == 1) && (total_comment_header_lines > 0) && (packedlen > 0)) { + fprintf(outfile, " */\n"); + } + } + + if (packedlen > 0) { + if (total_code_lines == 1) { + fprintf(outfile,"const char *%s [] = {\n", arrayname); + } + /* Output the line with no comment. */ + fprintf(outfile, "\"%s\\n\",\n", packedline); + } + } + if (total_code_lines > 0) { + fprintf(outfile, "0x00\n"); + fprintf(outfile, "};\n"); + } + +#if STRIP_PDFR_DEBUG_CALLS + /* Make sure no PDFR_DEBUG calls were left unmatched. */ + if (pdfr_debug_start_count != pdfr_debug_end_count) { + printf ("ERROR: missing final PDFR_DEBUG terminating comment.\n"); + fclose(infile); + fclose(outfile); + exit(-1); + } +#endif + + /* Display processing statistics. */ + printf(" Processed %d lines of PostScript data.\n", total_code_lines); + printf(" %d bytes of PostScript data packed down to %d bytes.\n", total_input_length, total_output_length); +#if STRIP_PDFR_DEBUG_CALLS + printf(" %d PDFR_DEBUG calls removed from the code.\n", pdfr_debug_start_count); +#endif + + /* Close files and exit with success. */ + fclose(infile); + fclose(outfile); + + return 0; +} diff -Nru ghostscript-9.10~dfsg/base/pcwin.mak ghostscript-9.25~dfsg+1/base/pcwin.mak --- ghostscript-9.10~dfsg/base/pcwin.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/pcwin.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,14 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for PC window system (MS Windows and OS/2) -specific device # drivers. # Define the name of this makefile. -PCWIN_MAK=$(GLSRC)pcwin.mak +PCWIN_MAK=$(GLSRC)pcwin.mak $(TOP_MAKEFILES) # We have to isolate these in their own file because the MS Windows code # requires special compilation switches, different from all other files @@ -28,56 +28,12 @@ gsdll_h=$(GLSRC)gsdll.h gsdllwin_h=$(GLSRC)gsdllwin.h -gdevmswn_h=$(DEVSRC)gdevmswn.h $(GDEVH)\ - $(dos__h) $(memory__h) $(string__h) $(windows__h)\ - $(gp_mswin_h) - -# This is deprecated and requires the interpreter / PSSRCDIR. -$(GLOBJ)gdevmswn.$(OBJ): $(DEVSRC)gdevmswn.c $(gdevmswn_h) $(gp_h) $(gpcheck_h)\ - $(gsdll_h) $(gsdllwin_h) $(gsparam_h) $(gdevpccm_h) - $(GLCCWIN) -I$(PSSRCDIR) -I$(DEVSRCDIR) $(GLO_)gdevmswn.$(OBJ) $(C_) $(DEVSRC)gdevmswn.c - -$(GLOBJ)gdevmsxf.$(OBJ): $(DEVSRC)gdevmsxf.c $(ctype__h) $(math__h) $(memory__h) $(string__h)\ - $(gdevmswn_h) $(gsstruct_h) $(gsutil_h) $(gxxfont_h) - $(GLCCWIN) $(GLO_)gdevmsxf.$(OBJ) $(C_) $(DEVSRC)gdevmsxf.c - -# An implementation using a DIB filled by an image device. -# This is deprecated and requires the interpreter / PSSRCDIR. -$(GLOBJ)gdevwdib.$(OBJ): $(DEVSRC)gdevwdib.c\ - $(gdevmswn_h) $(gsdll_h) $(gsdllwin_h) $(gxdevmem_h) - $(GLCCWIN) -I$(PSSRCDIR) $(GLO_)gdevwdib.$(OBJ) $(C_) $(DEVSRC)gdevwdib.c - -mswindll1_=$(GLOBJ)gdevmswn.$(OBJ) $(GLOBJ)gdevmsxf.$(OBJ) $(GLOBJ)gdevwdib.$(OBJ) -mswindll2_=$(GLOBJ)gdevemap.$(OBJ) $(GLOBJ)gdevpccm.$(OBJ) -mswindll_=$(mswindll1_) $(mswindll2_) -$(GLGEN)mswindll.dev: $(mswindll_) - $(SETDEV) $(GLGEN)mswindll $(mswindll1_) - $(ADDMOD) $(GLGEN)mswindll $(mswindll2_) - -### -------------------- The MS-Windows DDB 3.n printer ----------------- ### - -mswinprn_=$(GLOBJ)gdevwprn.$(OBJ) $(GLOBJ)gdevmsxf.$(OBJ) -$(DD)mswinprn.dev: $(mswinprn_) - $(SETDEV) $(DD)mswinprn $(mswinprn_) - -$(GLOBJ)gdevwprn.$(OBJ): $(GLSRC)gdevwprn.c $(gdevmswn_h) $(gp_h) - $(GLCCWIN) $(GLO_)gdevwprn.$(OBJ) $(C_) $(GLSRC)gdevwprn.c - ### -------------------- The MS-Windows DIB 3.n printer ----------------- ### mswinpr2_=$(GLOBJ)gdevwpr2.$(OBJ) -$(DD)mswinpr2.dev: $(mswinpr2_) $(GLD)page.dev +$(DD)mswinpr2.dev: $(mswinpr2_) $(GLD)page.dev $(PCWIN_MAK) $(SETPDEV) $(DD)mswinpr2 $(mswinpr2_) $(GLOBJ)gdevwpr2.$(OBJ): $(DEVSRC)gdevwpr2.c $(PDEVH) $(windows__h)\ - $(gdevpccm_h) $(gp_h) $(gp_mswin_h) $(gsicc_manage_h) + $(gdevpccm_h) $(gp_h) $(gp_mswin_h) $(gsicc_manage_h) $(PCWIN_MAK) $(GLCCWIN) $(GLO_)gdevwpr2.$(OBJ) $(C_) $(DEVSRC)gdevwpr2.c - -### --------------------------- The OS/2 printer ------------------------ ### - -os2prn_=$(GLOBJ)gdevos2p.$(OBJ) -$(DD)os2prn.dev: $(os2prn_) $(GLD)page.dev - $(SETPDEV) $(DD)os2prn $(os2prn_) - -$(GLOBJ)gdevos2p.$(OBJ): $(GLSRC)gdevos2p.c $(gp_h) $(gdevpccm_h) $(gdevprn_h) $(gscdefs_h) - $(GLCC) $(GLO_)gdevos2p.$(OBJ) $(C_) $(GLSRC)gdevos2p.c diff -Nru ghostscript-9.10~dfsg/base/pipe_.h ghostscript-9.25~dfsg+1/base/pipe_.h --- ghostscript-9.10~dfsg/base/pipe_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/pipe_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -33,13 +33,16 @@ # define pclose(file) _pclose(file) #else /* !__WIN32__ */ /* - * popen isn't POSIX-standard, so we declare it here. - * Because of inconsistent (and sometimes incorrect) header files, - * we must omit the argument list. Unfortunately, this sometimes causes - * more trouble than it cures. + * popen wasn't POSIX-standard from the beginning, and that resulted in + * inconsistent and incorrect prototypes and other issues. Hence we include + * a declaration here. + * But as it is now included in POSIX, we make this optional. */ +#if !defined(HAVE_POPEN_PROTO) || HAVE_POPEN_PROTO!=1 extern FILE *popen( /* const char *, const char * */ ); extern int pclose(FILE *); +#endif /* HAVE_POPEN_PROTO */ + #endif /* !__WIN32__ */ #endif /* pipe__INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/png_.h ghostscript-9.25~dfsg+1/base/png_.h --- ghostscript-9.10~dfsg/base/png_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/png_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/png.mak ghostscript-9.25~dfsg+1/base/png.mak --- ghostscript-9.10~dfsg/base/png.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/png.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for PNG (Portable Network Graphics) code. # Users of this makefile must define the following: @@ -61,10 +61,11 @@ # NB: we can't use the normal $(CC_) here because msvccmd.mak # adds /Za which conflicts with the libpng 1.5.x source. PNGCC=$(CC) $(CFLAGS) $(PNG_CFLAGS) $(I_)$(PI_)$(_I) $(I_)$(PNGGENDIR)$(_I) $(PF_) \ -$(D_)PNG_NO_ASSEMBLER_CODE$(_D) +$(D_)PNG_NO_ASSEMBLER_CODE$(_D) $(D_)PNG_INTEL_SSE_OPT=0$(_D) \ +$(D_)PNG_INTEL_SSE_IMPLEMENTATION=0$(_D) # Define the name of this makefile. -LIBPNG_MAK=$(GLSRC)png.mak +LIBPNG_MAK=$(GLSRC)png.mak $(TOP_MAKEFILES) png.clean : png.config-clean png.clean-not-config-clean @@ -78,10 +79,10 @@ $(RM_) $(pnglibconf_h) $(RM_) $(PNGGEN)lpg*.dev -$(pnglibconf_h) : $(PNGSRC)scripts$(D)pnglibconf.h.prebuilt +$(pnglibconf_h) : $(PNGSRC)scripts$(D)pnglibconf.h.prebuilt $(TOP_MAKEFILES) $(MAKEDIRS) $(CP_) $(PNGSRC)scripts$(D)pnglibconf.h.prebuilt $(pnglibconf_h) -PDEP=$(AK) $(pnglibconf_h) +PDEP=$(AK) $(pnglibconf_h) $(LIBPNG_MAK) $(MAKEDIRS) png_1=$(PNGOBJ)png.$(OBJ) $(PNGOBJ)pngmem.$(OBJ) $(PNGOBJ)pngerror.$(OBJ) $(PNGOBJ)pngset.$(OBJ) png_2=$(PNGOBJ)pngtrans.$(OBJ) $(PNGOBJ)pngwrite.$(OBJ) $(PNGOBJ)pngwtran.$(OBJ) $(PNGOBJ)pngwutil.$(OBJ) $(PNGOBJ)pngwio.$(OBJ) @@ -133,18 +134,19 @@ # Define the version of libpng.dev that we are actually using. -$(PNGGEN)libpng.dev : $(TOP_MAKEFILES) $(PNGGEN)libpng_$(SHARE_LIBPNG).dev +$(PNGGEN)libpng.dev : $(PNGGEN)libpng_$(SHARE_LIBPNG).dev $(LIBPNG_MAK) $(MAKEDIRS) $(CP_) $(PNGGEN)libpng_$(SHARE_LIBPNG).dev $(PNGGEN)libpng.dev # Define the shared version of libpng. # Note that it requires libz, which must be searched *after* libpng. -$(PNGGEN)libpng_1.dev : $(TOP_MAKEFILES) $(LIBPNG_MAK) $(ECHOGS_XE) $(PZGEN)zlibe.dev +$(PNGGEN)libpng_1.dev : $(ECHOGS_XE) $(PZGEN)zlibe.dev \ + $(LIBPNG_MAK) $(MAKEDIRS) $(SETMOD) $(PNGGEN)libpng_1 -lib $(LIBPNG_NAME) $(ADDMOD) $(PNGGEN)libpng_1 -include $(PZGEN)zlibe.dev # Define the non-shared version of libpng. $(PNGGEN)libpng_0.dev : $(LIBPNG_MAK) $(ECHOGS_XE) $(png_1) $(png_2) $(png_3)\ - $(PZGEN)zlibe.dev $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev + $(PZGEN)zlibe.dev $(PNGOBJ)pngwio.$(OBJ) $(PZGEN)crc32.dev $(MAKEDIRS) $(SETMOD) $(PNGGEN)libpng_0 $(png_1) $(ADDMOD) $(PNGGEN)libpng_0 $(png_2) $(ADDMOD) $(PNGGEN)libpng_0 $(png_3) diff -Nru ghostscript-9.10~dfsg/base/ramfs.c ghostscript-9.25~dfsg+1/base/ramfs.c --- ghostscript-9.10~dfsg/base/ramfs.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ramfs.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,485 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* + memory-based simulated file system + */ + +#include "unistd_.h" +#include "string_.h" +#include "gx.h" +#include "gserrors.h" +#include "gp.h" +#include "gscdefs.h" +#include "gsparam.h" +#include "gsstruct.h" +#include "ramfs.h" + +#define MACROBLOCK_REALLOC_MAX 128 + +typedef struct _ramfs { + struct _ramdirent * files; + struct _ramfs_enum* active_enums; + gs_memory_t *memory; + int blocksfree; + int last_error; +}__ramfs; + +gs_private_st_simple(st_ramfs, struct _ramfs, "gsram_ramfs"); + +struct _ramdirent { + char* filename; + struct _ramfile* inode; + struct _ramdirent* next; +}; + +gs_private_st_simple(st_ramdirent, struct _ramdirent, "gsram_ramdirent"); + +typedef struct _ramfile { + ramfs* fs; + int refcount; + int size; + int blocks; + int blocklist_size; + char** data; +} ramfile; + +gs_private_st_simple(st_ramfile, struct _ramfile, "gsram_ramfile"); + +struct _ramhandle { + ramfile * file; + int last_error; + int filepos; + int mode; +}; + +gs_private_st_simple(st_ramhandle, struct _ramhandle, "gsram_ramhandle"); + +struct _ramfs_enum { + ramfs* fs; + ramdirent * current; + struct _ramfs_enum* next; +}; + +gs_private_st_simple(st_ramfs_enum, struct _ramfs_enum, "gsram_ramfs_enum"); + +static void unlink_node(ramfile * inode); +static int ramfile_truncate(ramhandle * handle,int size); + +ramfs * ramfs_new(gs_memory_t *mem, int size) +{ + ramfs * fs = gs_alloc_struct(mem->non_gc_memory, ramfs, &st_ramfs, "ramfs_new"); + + if (fs == NULL) { + return NULL; + } + size = size/(RAMFS_BLOCKSIZE/1024); + fs->files = NULL; + fs->active_enums = NULL; + fs->blocksfree = size; + fs->last_error = 0; + fs->memory = mem->non_gc_memory; + return fs; +} + +/* This function makes no attempt to check that there are no open files or + enums. If there are any when this function is called, memory leakage will + result and any attempt to access the open files or enums will probably + cause a segfault. Caveat emptor, or something. +*/ +void ramfs_destroy(gs_memory_t *mem, ramfs * fs) +{ + ramdirent * ent; + + if(fs == NULL) return; + + ent = fs->files; + while(ent) { + ramdirent* prev; + gs_free_object(fs->memory, ent->filename, "ramfs_destroy, filename"); + unlink_node(ent->inode); + prev = ent; + ent = ent->next; + gs_free_object(fs->memory, prev, "ramfs_destroy, entry"); + } + gs_free_object(fs->memory, fs, "ramfs_destroy"); +} + +int ramfs_error(const ramfs* fs) { return fs->last_error; } + +static int resize(ramfile * file,int size) +{ + int newblocks = (size+RAMFS_BLOCKSIZE-1)/RAMFS_BLOCKSIZE; + void *buf; + + if(newblocks > file->blocks) { + /* allocate blocks for file as necessary */ + + if(newblocks-file->blocks > file->fs->blocksfree) { + return -RAMFS_NOSPACE; + } + if(file->blocklist_size < newblocks) { + int newsize = file->blocklist_size; + if (newsize > MACROBLOCK_REALLOC_MAX) { + newsize = ((newblocks+MACROBLOCK_REALLOC_MAX-1)/ + MACROBLOCK_REALLOC_MAX) * MACROBLOCK_REALLOC_MAX; + } else { + if(!newsize) newsize = 1; + while(newsize < newblocks) newsize *= 2; + } + buf = gs_alloc_bytes(file->fs->memory, newsize * sizeof(char*), "ramfs resize"); + if (!buf) + return gs_note_error(gs_error_VMerror); + memcpy(buf, file->data, file->blocklist_size * sizeof(char *)); + gs_free_object(file->fs->memory, file->data, "ramfs resize, free buffer"); + file->data = buf; + file->blocklist_size = newsize; + } + while(file->blocksdata[file->blocks] = + (char *)gs_alloc_bytes_immovable(file->fs->memory, RAMFS_BLOCKSIZE, "ramfs resize"); + if(!block) { + return -RAMFS_NOMEM; + } + file->blocks++; + file->fs->blocksfree--; + } + } else if (newblocks < file->blocks) { + /* don't bother shrinking the block array */ + file->fs->blocksfree += (file->blocks-newblocks); + while(file->blocks > newblocks) { + gs_free_object(file->fs->memory, file->data[--file->blocks], "ramfs resize"); + } + } + file->size = size; + return 0; +} + +static ramdirent * ramfs_findfile(const ramfs* fs,const char *filename) +{ + ramdirent * thisdirent = fs->files; + while(thisdirent) { + if(strcmp(thisdirent->filename,filename) == 0) break; + thisdirent = thisdirent->next; + } + return thisdirent; +} + +ramhandle * ramfs_open(gs_memory_t *mem, ramfs* fs,const char * filename,int mode) +{ + ramdirent * thisdirent; + ramfile* file; + ramhandle* handle; + + if(mode & (RAMFS_CREATE|RAMFS_APPEND)) mode |= RAMFS_WRITE; + + thisdirent = ramfs_findfile(fs,filename); + + if(!thisdirent) { + /* create file? */ + char * dirent_filename; + + if(!(mode & RAMFS_CREATE)) { + fs->last_error = RAMFS_NOTFOUND; + return NULL; + } + + thisdirent = gs_alloc_struct(fs->memory, ramdirent, &st_ramdirent, "new ram directory entry"); + file = gs_alloc_struct(fs->memory, ramfile, &st_ramfile, "new ram file"); + dirent_filename = (char *)gs_alloc_bytes(fs->memory, strlen(filename) + 1, "ramfs filename"); + if(!(thisdirent && file && dirent_filename)) { + gs_free_object(fs->memory, thisdirent, "error, cleanup directory entry"); + gs_free_object(fs->memory, file, "error, cleanup ram file"); + gs_free_object(fs->memory, dirent_filename, "error, cleanup ram filename"); + fs->last_error = RAMFS_NOMEM; + return NULL; + } + strcpy(dirent_filename,filename); + thisdirent->filename = dirent_filename; + file->refcount = 1; + file->size = 0; + file->blocks = 0; + file->blocklist_size = 0; + file->data = NULL; + file->fs = fs; + thisdirent->inode = file; + thisdirent->next = fs->files; + fs->files = thisdirent; + } + file = thisdirent->inode; + file->refcount++; + + handle = gs_alloc_struct(fs->memory, ramhandle, &st_ramhandle, "new ram directory entry"); + if(!handle) { + fs->last_error = RAMFS_NOMEM; + return NULL; + } + handle->file = file; + handle->last_error = 0; + handle->filepos = 0; + handle->mode = mode; + + if(mode & RAMFS_TRUNC) { + resize(file,0); + } + return handle; +} + +int ramfs_blocksize(ramfs * fs) { return RAMFS_BLOCKSIZE; } +int ramfs_blocksfree(ramfs * fs) { return fs->blocksfree; } +int ramfile_error(ramhandle * handle) { return handle->last_error; } + +static void unlink_node(ramfile * inode) +{ + int c; + + --inode->refcount; + if(inode->refcount) return; + + /* remove the file and its data */ + for(c=0;cblocks;c++) { + gs_free_object(inode->fs->memory, inode->data[c], "unlink node"); + } + inode->fs->blocksfree += c; + gs_free_object(inode->fs->memory, inode->data, "unlink node"); + gs_free_object(inode->fs->memory, inode, "unlink node"); +} + +int ramfs_unlink(ramfs * fs,const char *filename) +{ + ramdirent ** last; + ramdirent * thisdirent; + ramfs_enum* e; + + last = &fs->files; + while(1) { + if(!(thisdirent = *last)) { + fs->last_error = RAMFS_NOTFOUND; + return -1; + } + if(strcmp(thisdirent->filename,filename) == 0) break; + last = &(thisdirent->next); + } + + unlink_node(thisdirent->inode); + gs_free_object(fs->memory, thisdirent->filename, "unlink"); + (*last) = thisdirent->next; + + e = fs->active_enums; + /* advance enums that are pointing to the just-deleted file */ + while(e) { + if(e->current == thisdirent) e->current = thisdirent->next; + e = e->next; + } + gs_free_object(fs->memory, thisdirent, "unlink"); + return 0; +} + +int ramfs_rename(ramfs * fs,const char* oldname,const char* newname) +{ + ramdirent * thisdirent; + char * newnamebuf; + + thisdirent = ramfs_findfile(fs,oldname); + + if(!thisdirent) { + fs->last_error = RAMFS_NOTFOUND; + return -1; + } + + /* just in case */ + if(strcmp(oldname,newname) == 0) return 0; + + newnamebuf = (char *)gs_alloc_bytes(fs->memory, strlen(newname)+1, "ramfs rename"); + if(!newnamebuf) { + fs->last_error = RAMFS_NOMEM; + return -1; + } + + /* this may return RAMFS_NOTFOUND, which can be ignored. */ + ramfs_unlink(fs,newname); + + strcpy(newnamebuf,newname); + gs_free_object(fs->memory, thisdirent->filename, "ramfs rename"); + thisdirent->filename = newnamebuf; + return 0; +} + +ramfs_enum * ramfs_enum_new(ramfs * fs) +{ + ramfs_enum * e; + + e = gs_alloc_struct(fs->memory, ramfs_enum, &st_ramfs_enum, "new ramfs enumerator"); + if(!e) { + fs->last_error = RAMFS_NOMEM; + return NULL; + } + e->current = fs->files; + e->next = fs->active_enums; + e->fs = fs; + fs->active_enums = e; + return e; +} + +char* ramfs_enum_next(ramfs_enum * e) +{ + char * filename = NULL; + if(e->current) { + filename = e->current->filename; + e->current = e->current->next; + } + return filename; +} + +void ramfs_enum_end(ramfs_enum * e) +{ + ramfs_enum** last = &e->fs->active_enums; + while(*last) { + if(*last == e) { + *last = e->next; + break; + } + last = &(e->next); + } + gs_free_object(e->fs->memory, e, "free ramfs enumerator"); +} + +int ramfile_read(ramhandle * handle,void * buf,int len) +{ + ramfile * file = handle->file; + int left; + char *t = (char *)buf; + + if(len>file->size - handle->filepos) len = file->size-handle->filepos; + if(len<0) return 0; + + left = len; + while(left) { + char * p = file->data[handle->filepos/RAMFS_BLOCKSIZE]+handle->filepos%RAMFS_BLOCKSIZE; + int x = RAMFS_BLOCKSIZE-handle->filepos%RAMFS_BLOCKSIZE; + if(x>left) x = left; + + memcpy(t,p,x); + handle->filepos += x; + left -= x; + t += x; + } + return len; +} + +int ramfile_write(ramhandle * handle,const void * buf,int len) +{ + ramfile * file = handle->file; + int left; + char *t = (char *)buf; + + if(!(handle->mode & RAMFS_WRITE)) { + handle->last_error = RAMFS_NOACCESS; + return -1; + } + + if(handle->mode & RAMFS_APPEND) { + handle->filepos = file->size; + } + + if(file->size < handle->filepos) { + /* if this fails then pass the error on */ + if(ramfile_truncate(handle,handle->filepos) == -1) return -1; + } + + if(file->size < handle->filepos+len) { + int x = resize(file,handle->filepos+len); + if(x) { + handle->last_error = -x; + return -1; + } + } + + /* This is exactly the same as for reading, cept the copy is in the + other direction. */ + left = len; + while(left) { + char * p = file->data[handle->filepos/RAMFS_BLOCKSIZE] + + handle->filepos%RAMFS_BLOCKSIZE; + int x = RAMFS_BLOCKSIZE-handle->filepos%RAMFS_BLOCKSIZE; + if(x>left) x = left; + + memcpy(p,t,x); + handle->filepos += x; + left -= x; + t += x; + } + return len; +} + +int ramfile_seek(ramhandle * handle,int pos,int whence) +{ + /* Just set the handle's file position. The effects become noticeable + at the next read or write. + */ + if(whence == RAMFS_SEEK_CUR) { + handle->filepos += pos; + } else if(whence == RAMFS_SEEK_END) { + handle->filepos = handle->file->size+pos; + } else { + handle->filepos = pos; + } + return 0; +} + +int ramfile_size(ramhandle * handle) +{ + return handle->file->size; +} + +static int ramfile_truncate(ramhandle * handle,int size) +{ + ramfile * file = handle->file; + int oldsize = file->size; + int x = resize(file,size); + + if(x) { + handle->last_error = -x; + return -1; + } + if(oldsize >= size) return 0; + + /* file was expanded. fill the new space with zeros. */ + while(oldsize < file->size) { + char * p = file->data[oldsize/RAMFS_BLOCKSIZE]+oldsize%RAMFS_BLOCKSIZE; + int len = RAMFS_BLOCKSIZE - oldsize%RAMFS_BLOCKSIZE; + if(len>file->size-oldsize) len = file->size-oldsize; + oldsize += len; + memset(p,0,len); + } + return 0; +} + +void ramfile_close(ramhandle * handle) +{ + ramfile * file = handle->file; + unlink_node(file); + gs_free_object(handle->file->fs->memory, handle, "ramfs close"); +} + +int ramfile_tell(ramhandle* handle) +{ + return handle->filepos; +} + +int ramfile_eof(ramhandle* handle) +{ + return (handle->filepos >= handle->file->size); +} diff -Nru ghostscript-9.10~dfsg/base/ramfs.h ghostscript-9.25~dfsg+1/base/ramfs.h --- ghostscript-9.10~dfsg/base/ramfs.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ramfs.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,80 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +#ifndef __RAMFS_H__ +#define __RAMFS_H__ + +#include "stream.h" + +#define RAMFS_BLOCKSIZE 1024 + +typedef struct _ramfs ramfs; +typedef struct _ramdirent ramdirent; +typedef struct _ramhandle ramhandle; +typedef struct _ramfs_enum ramfs_enum; + +/* + ramfs_new: NOMEM + ramfs_open: NOTFOUND + ramfs_unlink: NOTFOUND + ramfs_enum_new: NOMEM + ramfs_enum_next: none + ramfs_enum_end: none + ramfile_read: none + ramfile_write: NOSPACE, NOMEM, NOACCESS + ramfile_seek: none + ramfile_pos: none + ramfile_close: none +*/ + +/* Error constants */ +#define RAMFS_NOTFOUND 2 +#define RAMFS_NOACCESS 5 +#define RAMFS_NOMEM 6 +#define RAMFS_NOSPACE 7 + +/* Open mode flags */ +#define RAMFS_READ s_mode_read /* 1 */ +#define RAMFS_WRITE s_mode_write /* 2 */ +#define RAMFS_SEEK s_mode_seek /* 4 */ +#define RAMFS_APPEND s_mode_append /* 8 */ +#define RAMFS_CREATE 16 +#define RAMFS_TRUNC 32 + +#define RAMFS_SEEK_SET 0 +#define RAMFS_SEEK_CUR 1 +#define RAMFS_SEEK_END 2 + +ramfs * ramfs_new(gs_memory_t *mem, int size); /* size is in KiB */ +void ramfs_destroy(gs_memory_t *, ramfs * fs); +int ramfs_error(const ramfs * fs); +ramhandle * ramfs_open(gs_memory_t *mem, ramfs * fs,const char * filename,int mode); +int ramfs_blocksize(ramfs * fs); +int ramfs_blocksfree(ramfs * fs); +int ramfs_unlink(ramfs * fs,const char *filename); +int ramfs_rename(ramfs * fs,const char *oldname,const char *newname); +ramfs_enum * ramfs_enum_new(ramfs * fs); +char* ramfs_enum_next(ramfs_enum * e); +void ramfs_enum_end(ramfs_enum * e); +int ramfile_read(ramhandle * handle,void * buf,int len); +int ramfile_write(ramhandle * handle,const void * buf,int len); +int ramfile_seek(ramhandle * handle,int pos,int whence); +int ramfile_eof(ramhandle * handle); +int ramfile_tell(ramhandle * handle); +int ramfile_size(ramhandle * handle); +void ramfile_close(ramhandle * handle); +int ramfile_error(ramhandle * handle); + +#endif /* __RAMFS_H__ */ diff -Nru ghostscript-9.10~dfsg/base/sa85d.c ghostscript-9.25~dfsg+1/base/sa85d.c --- ghostscript-9.10~dfsg/base/sa85d.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sa85d.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sa85d.h ghostscript-9.25~dfsg+1/base/sa85d.h --- ghostscript-9.10~dfsg/base/sa85d.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sa85d.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sa85x.h ghostscript-9.25~dfsg+1/base/sa85x.h --- ghostscript-9.10~dfsg/base/sa85x.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sa85x.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/saes.c ghostscript-9.25~dfsg+1/base/saes.c --- ghostscript-9.10~dfsg/base/saes.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/saes.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -120,6 +120,7 @@ gs_throw(gs_error_VMerror, "could not allocate aes context"); return ERRC; } + memset(state->ctx, 0x00, sizeof(aes_context)); if (state->keylength < 1 || state->keylength > SAES_MAX_KEYLENGTH) { gs_throw1(gs_error_rangecheck, "invalid aes key length (%d bytes)", state->keylength); @@ -174,7 +175,7 @@ complain. */ if (status == EOFC) { gs_throw(gs_error_rangecheck, "aes stream isn't a multiple of 16 bytes"); - return ERRC; + return 0; } return status; diff -Nru ghostscript-9.10~dfsg/base/saes.h ghostscript-9.25~dfsg+1/base/saes.h --- ghostscript-9.10~dfsg/base/saes.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/saes.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sarc4.c ghostscript-9.25~dfsg+1/base/sarc4.c --- ghostscript-9.10~dfsg/base/sarc4.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sarc4.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sarc4.h ghostscript-9.25~dfsg+1/base/sarc4.h --- ghostscript-9.10~dfsg/base/sarc4.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sarc4.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sbcp.c ghostscript-9.25~dfsg+1/base/sbcp.c --- ghostscript-9.10~dfsg/base/sbcp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sbcp.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sbcp.h ghostscript-9.25~dfsg+1/base/sbcp.h --- ghostscript-9.10~dfsg/base/sbcp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sbcp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sbhc.c ghostscript-9.25~dfsg+1/base/sbhc.c --- ghostscript-9.10~dfsg/base/sbhc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sbhc.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,283 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Bounded Huffman code filters */ -#include "memory_.h" -#include "stdio_.h" -#include "gdebug.h" -#include "strimpl.h" -#include "sbhc.h" -#include "shcgen.h" - -/* ------ BoundedHuffmanEncode ------ */ - -private_st_BHCE_state(); - -/* Initialize BoundedHuffmanEncode filter. */ -static int -s_BHCE_reinit(stream_state * st) -{ - stream_BHCE_state *const ss = (stream_BHCE_state *) st; - - ss->encode.count = ss->definition.num_values; - s_bhce_init_inline(ss); - return 0; -} -static int -s_BHCE_init(register stream_state * st) -{ - stream_BHCE_state *const ss = (stream_BHCE_state *) st; - hce_code *encode = ss->encode.codes = - (hce_code *) gs_alloc_byte_array(st->memory, - ss->definition.num_values, - sizeof(hce_code), "BHCE encode"); - - if (encode == 0) - return ERRC; -/****** WRONG ******/ - hc_make_encoding(encode, &ss->definition); - return s_BHCE_reinit(st); -} - -/* Release the filter. */ -static void -s_BHCE_release(stream_state * st) -{ - stream_BHCE_state *const ss = (stream_BHCE_state *) st; - - gs_free_object(st->memory, ss->encode.codes, "BHCE encode"); -} - -/* Process a buffer. */ -static int -s_BHCE_process(stream_state * st, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_BHCE_state *const ss = (stream_BHCE_state *) st; - const byte *p = pr->ptr; - const byte *rlimit = pr->limit; - byte *q = pw->ptr; - byte *wlimit = pw->limit - (hc_bits_size >> 3); - const hce_code *encode = ss->encode.codes; - uint num_values = ss->definition.num_values; - uint zero_runs = ss->EncodeZeroRuns; - uint zero_max = num_values - zero_runs + (ss->EndOfData ? 0 : 1); - uint zero_value = (zero_max > 1 ? 0 : 0x100); - int zeros = ss->zeros; - int status = 0; - - hce_declare_state; - - hce_load_state(); - while (p < rlimit && q < wlimit) { - uint value = *++p; - const hce_code *cp; - - if (value >= num_values) { - status = ERRC; - break; - } - if (value == zero_value) { /* Accumulate a run of zeros. */ - ++zeros; - if (zeros != zero_max) - continue; - /* We've scanned the longest run we can encode. */ - cp = &encode[zeros - 2 + zero_runs]; - zeros = 0; - hc_put_code((stream_hc_state *) ss, q, cp); - continue; - } - /* Check whether we need to put out a zero run. */ - if (zeros > 0) { - --p; - cp = (zeros == 1 ? &encode[0] : - &encode[zeros - 2 + zero_runs]); - zeros = 0; - hc_put_code((stream_hc_state *) ss, q, cp); - continue; - } - cp = &encode[value]; - hc_put_code((stream_hc_state *) ss, q, cp); - } - if (q >= wlimit) - status = 1; - wlimit = pw->limit; - if (last && status == 0) { - if (zeros > 0) { /* Put out a final run of zeros. */ - const hce_code *cp = (zeros == 1 ? &encode[0] : - &encode[zeros - 2 + zero_runs]); - - if (!hce_bits_available(cp->code_length)) - status = 1; - else { - hc_put_code((stream_hc_state *) ss, q, cp); - zeros = 0; - } - } - if (ss->EndOfData) { /* Put out the EOD code if we have room. */ - const hce_code *cp = &encode[num_values - 1]; - - if (!hce_bits_available(cp->code_length)) - status = 1; - else - hc_put_code((stream_hc_state *) ss, q, cp); - } else { - if (q >= wlimit) - status = 1; - } - if (!status) { - q = hc_put_last_bits((stream_hc_state *) ss, q); - goto ns; - } - } - hce_store_state(); - ns:pr->ptr = p; - pw->ptr = q; - ss->zeros = zeros; - return (p == rlimit ? 0 : 1); -} - -/* Stream template */ -const stream_template s_BHCE_template = -{&st_BHCE_state, s_BHCE_init, s_BHCE_process, - 1, hc_bits_size >> 3, s_BHCE_release, NULL, s_BHCE_reinit -}; - -/* ------ BoundedHuffmanDecode ------ */ - -private_st_BHCD_state(); - -#define hcd_initial_bits 7 /* arbitrary, >= 1 and <= 8 */ - -/* Initialize BoundedHuffmanDecode filter. */ -static int -s_BHCD_reinit(stream_state * st) -{ - stream_BHCD_state *const ss = (stream_BHCD_state *) st; - - ss->decode.count = ss->definition.num_values; - s_bhcd_init_inline(ss); - return 0; -} -static int -s_BHCD_init(register stream_state * st) -{ - stream_BHCD_state *const ss = (stream_BHCD_state *) st; - uint initial_bits = ss->decode.initial_bits = - min(hcd_initial_bits, ss->definition.num_counts); - uint dsize = hc_sizeof_decoding(&ss->definition, initial_bits); - hcd_code *decode = ss->decode.codes = - (hcd_code *) gs_alloc_byte_array(st->memory, dsize, - sizeof(hcd_code), "BHCD decode"); - - if (decode == 0) - return ERRC; -/****** WRONG ******/ - hc_make_decoding(decode, &ss->definition, initial_bits); - st->min_left = 1; - return s_BHCD_reinit(st); -} - -/* Release the filter. */ -static void -s_BHCD_release(stream_state * st) -{ - stream_BHCD_state *const ss = (stream_BHCD_state *) st; - - gs_free_object(st->memory, ss->decode.codes, "BHCD decode"); -} - -/* Process a buffer. */ -static int -s_BHCD_process(stream_state * st, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_BHCD_state *const ss = (stream_BHCD_state *) st; - - bhcd_declare_state; - byte *q = pw->ptr; - byte *wlimit = pw->limit; - const hcd_code *decode = ss->decode.codes; - uint initial_bits = ss->decode.initial_bits; - uint zero_runs = ss->EncodeZeroRuns; - int status = 0; - int eod = (ss->EndOfData ? ss->definition.num_values - 1 : -1); - - bhcd_load_state(); - z:for (; zeros > 0; --zeros) { - if (q >= wlimit) { - status = 1; - goto out; - } - *++q = 0; - } - for (;;) { - const hcd_code *cp; - int clen; - - hcd_ensure_bits(initial_bits, x1); - cp = &decode[hcd_peek_var_bits(initial_bits)]; - w1:if (q >= wlimit) { - status = 1; - break; - } - if ((clen = cp->code_length) > initial_bits) { - if (!hcd_bits_available(clen)) { /* We don't have enough bits for */ - /* all possible codes that begin this way, */ - /* but we might have enough for */ - /* the next code. */ -/****** NOT IMPLEMENTED YET ******/ - break; - } - clen -= initial_bits; - hcd_skip_bits(initial_bits); - hcd_ensure_bits(clen, out); /* can't exit */ - cp = &decode[cp->value + hcd_peek_var_bits(clen)]; - hcd_skip_bits(cp->code_length); - } else { - hcd_skip_bits(clen); - } - if (cp->value >= zero_runs) { - if (cp->value == eod) { - status = EOFC; - goto out; - } - /* This code represents a run of zeros, */ - /* not a single output value. */ - zeros = cp->value - zero_runs + 2; - goto z; - } - *++q = cp->value; - continue; - /* We don't have enough bits for all possible */ - /* codes, but we might have enough for */ - /* the next code. */ - x1:cp = &decode[(bits & ((1 << bits_left) - 1)) << - (initial_bits - bits_left)]; - if ((clen = cp->code_length) <= bits_left) - goto w1; - break; - } - out:bhcd_store_state(); - pw->ptr = q; - return status; -} - -/* Stream template */ -const stream_template s_BHCD_template = -{&st_BHCD_state, s_BHCD_init, s_BHCD_process, 1, 1, s_BHCD_release, - NULL, s_BHCD_reinit -}; diff -Nru ghostscript-9.10~dfsg/base/sbhc.h ghostscript-9.25~dfsg+1/base/sbhc.h --- ghostscript-9.10~dfsg/base/sbhc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sbhc.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Definitions for BoundedHuffman filters */ -/* Requires strimpl.h */ - -#ifndef sbhc_INCLUDED -# define sbhc_INCLUDED - -#include "shc.h" - -/* - * The BoundedHuffman filters extend the basic Huffman coding model by - * providing the ability to encode runs of zeros as a single data item, - * and by providing an end-of-data (EOD) marker. - */ -#define max_zero_run 100 - -/* Common state */ -#define stream_BHC_state_common\ - stream_hc_state_common;\ - hc_definition definition;\ - /* The client sets the following before initialization. */\ - bool EndOfData;\ - uint EncodeZeroRuns;\ - /* The following are updated dynamically. */\ - int zeros /* # of zeros scanned or left to output */ -typedef struct stream_BHC_state_s { - stream_BHC_state_common; -} stream_BHC_state; - -/* BoundedHuffmanEncode */ -typedef struct stream_BHCE_state_s { - stream_BHC_state_common; - hce_table encode; -} stream_BHCE_state; - -#define private_st_BHCE_state() /* in sbhc.c */\ - gs_private_st_ptrs3(st_BHCE_state, stream_BHCE_state,\ - "BoundedHuffmanEncode state", bhce_enum_ptrs, bhce_reloc_ptrs,\ - definition.counts, definition.values, encode.codes) -extern const stream_template s_BHCE_template; - -#define s_bhce_init_inline(ss)\ - (s_hce_init_inline(ss), (ss)->zeros = 0) - -/* BoundedHuffmanDecode */ -typedef struct stream_BHCD_state_s { - stream_BHC_state_common; - hcd_table decode; -} stream_BHCD_state; - -#define private_st_BHCD_state() /* in sbhc.c */\ - gs_private_st_ptrs3(st_BHCD_state, stream_BHCD_state,\ - "BoundedHuffmanDecode state", bhcd_enum_ptrs, bhcd_reloc_ptrs,\ - definition.counts, definition.values, decode.codes) -extern const stream_template s_BHCD_template; - -#define s_bhcd_init_inline(ss)\ - (s_hcd_init_inline(ss), (ss)->zeros = 0) - -/* Declare variables that hold the decoder state. */ -#define bhcd_declare_state\ - hcd_declare_state;\ - int zeros - -/* Load the state from the stream. */ -/* Free variables: pr, ss, p, rlimit, bits, bits_left, zeros. */ -#define bhcd_load_state()\ - hcd_load_state(), zeros = ss->zeros - -/* Store the state back in the stream. */ -/* Free variables: pr, ss, p, bits, bits_left, zeros. */ -#define bhcd_store_state()\ - hcd_store_state(), ss->zeros = zeros - -#endif /* sbhc_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/sbtx.h ghostscript-9.25~dfsg+1/base/sbtx.h --- ghostscript-9.10~dfsg/base/sbtx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sbtx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sbwbs.c ghostscript-9.25~dfsg+1/base/sbwbs.c --- ghostscript-9.10~dfsg/base/sbwbs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sbwbs.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,546 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Burrows/Wheeler block sorting compression filters */ -#include "stdio_.h" -#include "memory_.h" -#include /* for qsort */ -#include "gdebug.h" -#include "strimpl.h" -#include "sfilter.h" -#include "sbwbs.h" - -/* ------ Common code for streams that buffer a block ------ */ - -private_st_buffered_state(); - -/* Initialize */ -static void -s_buffered_set_defaults(stream_state * st) -{ - stream_buffered_state *const ss = (stream_buffered_state *) st; - - /* Clear pointers */ - ss->buffer = 0; -} -static int -s_buffered_no_block_init(stream_state * st) -{ - stream_buffered_state *const ss = (stream_buffered_state *) st; - - ss->buffer = 0; - ss->filling = true; - ss->bpos = 0; - return 0; -} -static int -s_buffered_block_init(stream_state * st) -{ - stream_buffered_state *const ss = (stream_buffered_state *) st; - - s_buffered_no_block_init(st); - ss->buffer = gs_alloc_bytes(st->memory, ss->BlockSize, "buffer"); - if (ss->buffer == 0) - return ERRC; -/****** WRONG ******/ - return 0; -} - -/* Continue filling the buffer if needed. */ -/* Return 0 if the buffer isn't full yet, 1 if it is full or if */ -/* we reached the end of input data. */ -/* In the latter case, also set filling = false. */ -/* Note that this procedure doesn't take pw as an argument. */ -static int -s_buffered_process(stream_state * st, stream_cursor_read * pr, bool last) -{ - stream_buffered_state *const ss = (stream_buffered_state *) st; - register const byte *p = pr->ptr; - const byte *rlimit = pr->limit; - uint count = rlimit - p; - uint left = ss->bsize - ss->bpos; - - if (!ss->filling) - return 1; - if (left < count) - count = left; - if_debug3m('w', st->memory, "[w]buffering %d bytes to position %d, last = %s\n", - count, ss->bpos, (last ? "true" : "false")); - memcpy(ss->buffer + ss->bpos, p + 1, count); - pr->ptr = p += count; - ss->bpos += count; - if (ss->bpos == ss->bsize || (p == rlimit && last)) { - ss->filling = false; - return 1; - } - return 0; -} - -/* Release */ -static void -s_buffered_release(stream_state * st) -{ - stream_buffered_state *const ss = (stream_buffered_state *) st; - - gs_free_object(st->memory, ss->buffer, "buffer"); -} - -/* ------ Common code for Burrows/Wheeler block sorting filters ------ */ - -private_st_BWBS_state(); -static void s_BWBS_release(stream_state *); - -/* Set default parameter values (actually, just clear pointers). */ -static void -s_BWBS_set_defaults(stream_state * st) -{ - stream_BWBS_state *const ss = (stream_BWBS_state *) st; - - s_buffered_set_defaults(st); - ss->offsets = 0; -} - -/* Initialize */ -static int -bwbs_init(stream_state * st, uint osize) -{ - stream_BWBS_state *const ss = (stream_BWBS_state *) st; - int code; - - ss->bsize = ss->BlockSize; - code = s_buffered_block_init(st); - if (code != 0) - return code; - ss->offsets = (void *)gs_alloc_bytes(st->memory, osize, - "BWBlockSort offsets"); - if (ss->offsets == 0) { - s_BWBS_release(st); - return ERRC; -/****** WRONG ******/ - } - ss->I = -1; /* haven't read I yet */ - return 0; -} - -/* Release the filter. */ -static void -s_BWBS_release(stream_state * st) -{ - stream_BWBS_state *const ss = (stream_BWBS_state *) st; - - gs_free_object(st->memory, ss->offsets, "BWBlockSort offsets"); - s_buffered_release(st); -} - -/* ------ BWBlockSortEncode ------ */ - -/* Initialize */ -static int -s_BWBSE_init(stream_state * st) -{ - stream_BWBS_state *const ss = (stream_BWBS_state *) st; - - return bwbs_init(st, ss->BlockSize * sizeof(int)); -} - -/* Compare two rotated strings for sorting. */ -static stream_BWBS_state *bwbs_compare_ss; -static int -bwbs_compare_rotations(const void *p1, const void *p2) -{ - const byte *buffer = bwbs_compare_ss->buffer; - const byte *s1 = buffer + *(const int *)p1; - const byte *s2 = buffer + *(const int *)p2; - const byte *start1; - const byte *end; - int swap; - - if (*s1 != *s2) - return (*s1 < *s2 ? -1 : 1); - if (s1 < s2) - swap = 1; - else { - const byte *t = s1; - - s1 = s2; - s2 = t; - swap = -1; - } - start1 = s1; - end = buffer + bwbs_compare_ss->N; - for (s1++, s2++; s2 < end; s1++, s2++) - if (*s1 != *s2) - return (*s1 < *s2 ? -swap : swap); - s2 = buffer; - for (; s1 < end; s1++, s2++) - if (*s1 != *s2) - return (*s1 < *s2 ? -swap : swap); - s1 = buffer; - for (; s1 < start1; s1++, s2++) - if (*s1 != *s2) - return (*s1 < *s2 ? -swap : swap); - return 0; -} -/* Sort the strings. */ -static void -bwbse_sort(const byte * buffer, uint * indices, int N) -{ - offsets_full Cs; - -#define C Cs.v - /* Sort the strings. We start with a radix sort. */ - uint sum = 0, j, ch; - - memset(C, 0, sizeof(Cs)); - for (j = 0; j < N; j++) - C[buffer[j]]++; - for (ch = 0; ch <= 255; ch++) { - sum += C[ch]; - C[ch] = sum - C[ch]; - } - for (j = 0; j < N; j++) - indices[C[buffer[j]]++] = j; - /* Now C[ch] = the number of strings that start */ - /* with a character less than or equal to ch. */ - sum = 0; - /* qsort each bucket produced by the radix sort. */ - for (ch = 0; ch <= 255; sum = C[ch], ch++) - qsort(indices + sum, C[ch] - sum, - sizeof(*indices), - bwbs_compare_rotations); -#undef C -} - -/* Encode a buffer */ -static int -s_BWBSE_process(stream_state * st, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_BWBS_state *const ss = (stream_BWBS_state *) st; - register byte *q = pw->ptr; - byte *wlimit = pw->limit; - uint wcount = wlimit - q; - uint *indices = ss->offsets; - - if (ss->filling) { - int status, j, N; - byte *buffer = ss->buffer; - if (wcount < sizeof(int) * 2) - return 1; - - /* Continue filling the buffer. */ - status = s_buffered_process(st, pr, last); - if (!status) - return 0; - ss->N = N = ss->bpos; - /* We reverse the string before encoding it, */ - /* so it will come out of the decoder correctly. */ - for (j = N / 2 - 1; j >= 0; j--) { - byte *p0 = &buffer[j]; - byte *p1 = &buffer[N - 1 - j]; - byte b = *p0; - - *p0 = *p1; - *p1 = b; - } - /* Save st in a static, because that's the only way */ - /* we can pass it to the comparison procedure (ugh). */ - bwbs_compare_ss = ss; - /* Sort the strings. */ - bwbse_sort(buffer, indices, N); - /* Find the unrotated string. */ - for (j = 0; j < N; j++) - if (indices[j] == 0) { - ss->I = j; - break; - } - for (j = sizeof(int); --j >= 0;) - *++q = (byte) (N >> (j * 8)); - for (j = sizeof(int); --j >= 0;) - *++q = (byte) (ss->I >> (j * 8)); - ss->bpos = 0; - } - /* We're reading out of the buffer, writing the permuted string. */ - while (q < wlimit && ss->bpos < ss->N) { - int i = indices[ss->bpos++]; - - *++q = ss->buffer[(i == 0 ? ss->N - 1 : i - 1)]; - } - if (ss->bpos == ss->N) { - ss->filling = true; - ss->bpos = 0; - } - pw->ptr = q; - if (q == wlimit) - return 1; - return 0; -} - -/* Stream template */ -const stream_template s_BWBSE_template = { - &st_BWBS_state, s_BWBSE_init, s_BWBSE_process, sizeof(int) * 2, 1, - s_BWBS_release, s_BWBS_set_defaults -}; - -/* ------ BWBlockSortDecode ------ */ - -#define SHORT_OFFSETS - -#ifdef SHORT_OFFSETS - -/* - * Letting S[0..N-1] be the data block before depermutation, we need - * a table P[0..N-1] that maps the index i to O(S[i],i), where O(c,i) is - * the number of occurrences of c in S before position i. - * We observe that for a fixed c, O(c,i) is monotonic with i, - * and falls in the range 0 .. i; consequently, if 0 <= i <= j, - * 0 <= O(c,j) - O(c,i) <= j - i. Proceeding from this observation, - * rather than allocate an entire int to each entry of P, - * we construct three tables as follows: - * P2[k,c] = O(c,k*65536) for k = 0 .. (N-1)/65536; - * each entry requires an int. - * P1[k,c] = O(c,k*4096) - P2[k/16,c] for k = 0 .. (N-1)/4096; - * each entry falls in the range 0 .. 15*4096 and hence - * requires 16 bits. - * P0[i] = O(S[i],i) - P1[i/4096,S[i]] for i = 0 .. N-1; - * each entry falls in the range 0 .. 4095 and hence - * requires 12 bits. - * Since the value we need in the decompression loop is actually - * P[i] + C[S[i]], where C[c] is the sum of O(0,N) ... O(c-1,N), - * we add C[c] into P2[k,c] for all k. - */ - /*typedef struct { uint v[256]; } offsets_full; *//* in sbwbs.h */ -typedef struct { - bits16 v[256]; -} offsets_4k; - -#if arch_sizeof_int > 2 -# define ceil_64k(n) (((n) + 0xffff) >> 16) -#else -# define ceil_64k(n) 1 -#endif -#define ceil_4k(n) (((n) + 0xfff) >> 12) -#define offset_space(bsize)\ - (ceil_64k(bsize) * sizeof(offsets_full) +\ - ceil_4k(bsize) * sizeof(offsets_4k) +\ - ((bsize + 1) >> 1) * 3) - -#else /* !SHORT_OFFSETS */ - -#define offset_space(bsize)\ - (bsize * sizeof(int)) - -#endif /* (!)SHORT_OFFSETS */ - -/* Initialize */ -static int -s_BWBSD_init(stream_state * st) -{ - stream_BWBS_state *const ss = (stream_BWBS_state *) st; - uint bsize = ss->BlockSize; - - return bwbs_init(st, offset_space(bsize)); -} - -/* Construct the decoding tables. */ - -#ifdef SHORT_OFFSETS - -static void -bwbsd_construct_offsets(stream_BWBS_state * sst, offsets_full * po64k, - offsets_4k * po4k, byte * po1, int N) -{ - offsets_full Cs; - -#define C Cs.v - uint i1; - byte *b = sst->buffer; - offsets_full *p2 = po64k - 1; - offsets_4k *p1 = po4k; - byte *p0 = po1; - - memset(C, 0, sizeof(Cs)); - for (i1 = 0; i1 < ceil_4k(N); i1++, p1++) { - int j; - - if (!(i1 & 15)) - *++p2 = Cs; - for (j = 0; j < 256; j++) - p1->v[j] = C[j] - p2->v[j]; - j = (N + 1 - (i1 << 12)) >> 1; - if (j > 4096 / 2) - j = 4096 / 2; - for (; j > 0; j--, b += 2, p0 += 3) { - byte b0 = b[0]; - uint d0 = C[b0]++ - (p1->v[b0] + p2->v[b0]); - byte b1 = b[1]; - uint d1 = C[b1]++ - (p1->v[b1] + p2->v[b1]); - - p0[0] = d0 >> 4; - p0[1] = (byte) ((d0 << 4) + (d1 >> 8)); - p0[2] = (byte) d1; - } - } - /* If the block length is odd, discount the extra byte. */ - if (N & 1) - C[sst->buffer[N]]--; - /* Compute the cumulative totals in C. */ - { - int sum = 0, ch; - - for (ch = 0; ch <= 255; ch++) { - sum += C[ch]; - C[ch] = sum - C[ch]; - } - } - /* Add the C values back into the 64K table, */ - /* which saves an addition of C[b] in the decoding loop. */ - { - int i2, ch; - - for (p2 = po64k, i2 = ceil_64k(N); i2 > 0; p2++, i2--) - for (ch = 0; ch < 256; ch++) - p2->v[ch] += C[ch]; - } -#undef C -} - -#else /* !SHORT_OFFSETS */ - -static void -bwbsd_construct_offsets(stream_BWBS_state * sst, int *po, int N) -{ - offsets_full Cs; - -#define C Cs.v - uint i; - byte *b = sst->buffer; - int *p = po; - - memset(C, 0, sizeof(Cs)); - for (i = 0; i < N; i++, p++, b++) - *p = C[*b]++; - /* Compute the cumulative totals in C. */ - { - int sum = 0, ch; - - for (ch = 0; ch <= 255; ch++) { - sum += C[ch]; - C[ch] = sum - C[ch]; - } - } - /* Add the C values back into the offsets. */ - for (i = 0, b = sst->buffer, p = po; i < N; i++, b++, p++) - *p += C[*b]; -#undef C -} - -#endif /* (!)SHORT_OFFSETS */ - -/* Decode a buffer */ -static int -s_BWBSD_process(stream_state * st, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_BWBS_state *const ss = (stream_BWBS_state *) st; - register const byte *p = pr->ptr; - const byte *rlimit = pr->limit; - uint count = rlimit - p; - register byte *q = pw->ptr; - byte *wlimit = pw->limit; - -#ifdef SHORT_OFFSETS - uint BlockSize = ss->BlockSize; - offsets_full *po64k = ss->offsets; - offsets_4k *po4k = (offsets_4k *) (po64k + ceil_64k(BlockSize)); - byte *po1 = (byte *) (po4k + ceil_4k(BlockSize)); - -#else /* !SHORT_OFFSETS */ - int *po = ss->offsets; - -#endif /* (!)SHORT_OFFSETS */ - - if (ss->I < 0) { /* Read block parameters */ - int I, N, j; - if (count < sizeof(int) * 2) - return 0; - for (N = 0, j = 0; j < sizeof(int); j++) - - N = (N << 8) + *++p; - for (I = 0, j = 0; j < sizeof(int); j++) - - I = (I << 8) + *++p; - ss->N = N; - ss->I = I; - if_debug2m('w', ss->memory, "[w]N=%d I=%d\n", N, I); - pr->ptr = p; - if (N < 0 || N > ss->BlockSize || I < 0 || I >= N) - return ERRC; - if (N == 0) - return EOFC; - count -= sizeof(int) * 2; - - ss->bpos = 0; - ss->bsize = N; - } - if (ss->filling) { /* Continue filling the buffer. */ - if (!s_buffered_process(st, pr, last)) - return 0; - /* Construct the inverse sort order. */ -#ifdef SHORT_OFFSETS - bwbsd_construct_offsets(ss, po64k, po4k, po1, ss->bsize); -#else /* !SHORT_OFFSETS */ - bwbsd_construct_offsets(ss, po, ss->bsize); -#endif /* (!)SHORT_OFFSETS */ - ss->bpos = 0; - ss->i = ss->I; - } - /* We're reading out of the buffer. */ - while (q < wlimit && ss->bpos < ss->bsize) { - int i = ss->i; - byte b = ss->buffer[i]; - -#ifdef SHORT_OFFSETS - uint d; - const byte *pd = &po1[(i >> 1) + i]; - - *++q = b; - if (!(i & 1)) - d = ((uint) pd[0] << 4) + (pd[1] >> 4); - else - d = ((pd[0] & 0xf) << 8) + pd[1]; - ss->i = po64k[i >> 16].v[b] + po4k[i >> 12].v[b] + d; -#else /* !SHORT_OFFSETS */ - *++q = b; - ss->i = po[i]; -#endif /* (!)SHORT_OFFSETS */ - ss->bpos++; - } - if (ss->bpos == ss->bsize) { - ss->I = -1; - ss->filling = true; - } - pw->ptr = q; - if (q == wlimit) - return 1; - return 0; -} - -/* Stream template */ -const stream_template s_BWBSD_template = { - &st_BWBS_state, s_BWBSD_init, s_BWBSD_process, 1, sizeof(int) * 2, - s_BWBS_release, s_BWBS_set_defaults -}; diff -Nru ghostscript-9.10~dfsg/base/sbwbs.h ghostscript-9.25~dfsg+1/base/sbwbs.h --- ghostscript-9.10~dfsg/base/sbwbs.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sbwbs.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Definitions for BWBlockSort (Burroughs-Wheeler) filters */ -/* Requires scommon.h; strimpl.h if any templates are referenced */ - -#ifndef sbwbs_INCLUDED -# define sbwbs_INCLUDED - -/* Common framework for streams that buffer a block for processing */ -#define stream_buffered_state_common\ - stream_state_common;\ - /* The client may set the following before initialization, */\ - /* or the stream may set it later. */\ - int BlockSize;\ - /* The init procedure sets the following, */\ - /* if BlockSize has been set. */\ - byte *buffer; /* [BlockSize] */\ - /* The following are updated dynamically. */\ - bool filling; /* true if filling buffer, */\ - /* false if emptying */\ - int bsize; /* size of current block (<= BlockSize) */\ - int bpos /* current index within buffer */ -typedef struct stream_buffered_state_s { - stream_buffered_state_common; -} stream_buffered_state; - -#define private_st_buffered_state() /* in sbwbs.c */\ - gs_private_st_ptrs1(st_buffered_state, stream_buffered_state,\ - "stream_buffered state", sbuf_enum_ptrs, sbuf_reloc_ptrs, buffer) - -/* BWBlockSortEncode/Decode */ -typedef struct of_ { - uint v[256]; -} offsets_full; -typedef struct stream_BWBS_state_s { - stream_buffered_state_common; - /* The init procedure sets the following. */ - void *offsets; /* permutation indices when writing, */ - /* multi-level indices when reading */ - /* The following are updated dynamically. */ - int N; /* actual length of block */ - /* The following are only used when decoding. */ - int I; /* index of unrotated string */ - int i; /* next index in encoded string */ -} stream_BWBS_state; -typedef stream_BWBS_state stream_BWBSE_state; -typedef stream_BWBS_state stream_BWBSD_state; - -#define private_st_BWBS_state() /* in sbwbs.c */\ - gs_private_st_suffix_add1(st_BWBS_state, stream_BWBS_state,\ - "BWBlockSortEncode/Decode state", bwbs_enum_ptrs, bwbs_reloc_ptrs,\ - st_buffered_state, offsets) -extern const stream_template s_BWBSE_template; -extern const stream_template s_BWBSD_template; - -#endif /* sbwbs_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/scanchar.h ghostscript-9.25~dfsg+1/base/scanchar.h --- ghostscript-9.10~dfsg/base/scanchar.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scanchar.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/scantab.c ghostscript-9.25~dfsg+1/base/scantab.c --- ghostscript-9.10~dfsg/base/scantab.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scantab.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/scfd.c ghostscript-9.25~dfsg+1/base/scfd.c --- ghostscript-9.10~dfsg/base/scfd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scfd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -26,6 +26,8 @@ private_st_CFD_state(); +#define CFD_BUFFER_SLOP 4 + static inline int get_run(stream_CFD_state *ss, stream_cursor_read *pr, const cfd_node decode[], int initial_bits, int min_bits, int *runlen, const char *str); @@ -57,20 +59,20 @@ s_hcd_init_inline(ss); /* Because skip_white_pixels can look as many as 4 bytes ahead, */ /* we need to allow 4 extra bytes at the end of the row buffers. */ - ss->lbuf = gs_alloc_bytes(st->memory, raster + 4, "CFD lbuf"); + ss->lbuf = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP, "CFD lbuf"); ss->lprev = 0; if (ss->lbuf == 0) return ERRC; /****** WRONG ******/ memset(ss->lbuf, white, raster); - memset(ss->lbuf + raster, 0xaa, 4); /* for Valgrind */ + memset(ss->lbuf + raster, 0xaa, CFD_BUFFER_SLOP); /* for Valgrind */ if (ss->K != 0) { - ss->lprev = gs_alloc_bytes(st->memory, raster + 4, "CFD lprev"); + ss->lprev = gs_alloc_bytes(st->memory, raster + CFD_BUFFER_SLOP, "CFD lprev"); if (ss->lprev == 0) return ERRC; /****** WRONG ******/ /* Clear the initial reference line for 2-D encoding. */ memset(ss->lprev, white, raster); /* Ensure that the scan of the reference line will stop. */ - memset(ss->lprev + raster, 0xaa, 4); + memset(ss->lprev + raster, 0xaa, CFD_BUFFER_SLOP); } ss->k_left = min(ss->K, 0); ss->run_color = 0; @@ -206,8 +208,16 @@ cfd_load_state(); (void)rlimit; + if (q >= ss->lbuf + ss->raster + CFD_BUFFER_SLOP) { + return(-1); + } + if ( (*rlen) > qbit ) { + if (q + ((*rlen - qbit) >> 3) > ss->lbuf + ss->raster + CFD_BUFFER_SLOP) { + return(-1); + } + if (q >= ss->lbuf) { *q++ ^= (1 << qbit) - 1; } @@ -215,6 +225,7 @@ q++; } (*rlen) -= qbit; + switch ( (*rlen) >> 3 ) { case 7: /* original rlen possibly >= 64 */ @@ -790,7 +801,7 @@ /* Remember that count counts *down*. */ prev_count += rlen - vertical_0; /* a1 */ if_debug2m('W', ss->memory, " vertical %d -> %d\n", - rlen - vertical_0, prev_count); + (int)(rlen - vertical_0), prev_count); } /* Now either invert or skip from count */ /* to prev_count, and reset count. */ diff -Nru ghostscript-9.10~dfsg/base/scfdgen.c ghostscript-9.25~dfsg+1/base/scfdgen.c --- ghostscript-9.10~dfsg/base/scfdgen.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scfdgen.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/scfdtab.c ghostscript-9.25~dfsg+1/base/scfdtab.c --- ghostscript-9.10~dfsg/base/scfdtab.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scfdtab.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/scfe.c ghostscript-9.25~dfsg+1/base/scfe.c --- ghostscript-9.10~dfsg/base/scfe.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scfe.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -133,11 +133,13 @@ /* * The worst case for encoding is alternating white and black pixels. * For 1-D encoding, the worst case is 9 bits per 2 pixels; for 2-D - * (horizontal), 12 bits per 2 pixels. To fill out a scan line, + * (horizontal), 12 bits per 2 pixels. However, for 2D vertical encoding + * an offset 3 vertically encoded requires 7 bits of encoding. So we need + * to allow 14 bits for this, not 12 (see bug 696413). To fill out a scan line, * we may add up to 6 12-bit EOL codes. */ int code_bytes = - ((columns * (ss->K == 0 ? 9 : 12)) >> 4) + 20; /* add slop */ + (((columns * (ss->K == 0 ? 9 : 14)) + 15) >> 4) + 20; /* add slop */ int raster = ss->raster = ROUND_UP((columns + 7) >> 3, ss->DecodedByteAlign); diff -Nru ghostscript-9.10~dfsg/base/scfetab.c ghostscript-9.25~dfsg+1/base/scfetab.c --- ghostscript-9.10~dfsg/base/scfetab.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scfetab.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/scf.h ghostscript-9.25~dfsg+1/base/scf.h --- ghostscript-9.10~dfsg/base/scf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -40,7 +40,7 @@ * hence 1.5 * ceil(N / 2560) bytes. Taking the largest safe stream * buffer size as 32K, we arrive at the following maximum width: */ -#if arch_sizeof_int > 2 +#if ARCH_SIZEOF_INT > 2 # define cfe_max_width (2560 * 32000 * 2 / 3) #else # define cfe_max_width (max_int - 40) /* avoid overflows */ @@ -154,7 +154,7 @@ #if defined(SKIP_PIXELS_USING_INTS) && (ARCH_LOG2_SIZEOF_INT >= 2) && (ARCH_ALIGN_INT_MOD <= 4) && (ARCH_LOG2_SIZEOF_SHORT >= 1) && (ARCH_ALIGN_SHORT_MOD <= 2) -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN #define BYTE0OF2(S) ((byte)(S>>8)) #define BYTE1OF2(S) ((byte)S) #define BYTE0OF4(S) ((byte)(S>>24)) diff -Nru ghostscript-9.10~dfsg/base/scfparam.c ghostscript-9.25~dfsg+1/base/scfparam.c --- ghostscript-9.10~dfsg/base/scfparam.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scfparam.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/scfx.h ghostscript-9.25~dfsg+1/base/scfx.h --- ghostscript-9.10~dfsg/base/scfx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scfx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/scommon.h ghostscript-9.25~dfsg+1/base/scommon.h --- ghostscript-9.10~dfsg/base/scommon.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/scommon.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sdcparam.c ghostscript-9.25~dfsg+1/base/sdcparam.c --- ghostscript-9.10~dfsg/base/sdcparam.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sdcparam.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -38,6 +38,7 @@ { dctp("Picky", gs_param_type_int, jpeg_stream_data, Picky), dctp("Relax", gs_param_type_int, jpeg_stream_data, Relax), + dctp("Height", gs_param_type_int, jpeg_stream_data, Height), gs_param_item_end }; @@ -86,7 +87,7 @@ static int quant_param_string(gs_param_string * pstr, int count, const UINT16 * pvals, - floatp QFactor, gs_memory_t * mem) + double QFactor, gs_memory_t * mem) { byte *data; int code = 0; @@ -96,7 +97,7 @@ if (data == 0) return_error(gs_error_VMerror); for (i = 0; i < count; ++i) { - floatp val = pvals[jpeg_inverse_order(i)] / QFactor; + double val = pvals[jpeg_inverse_order(i)] / QFactor; data[i] = (val < 1 ? (code = 1) : val > 255 ? (code = 255) : (byte) val); @@ -109,7 +110,7 @@ static int quant_param_array(gs_param_float_array * pfa, int count, const UINT16 * pvals, - floatp QFactor, gs_memory_t * mem) + double QFactor, gs_memory_t * mem) { float *data; int i; @@ -140,7 +141,7 @@ JQUANT_TBL **table_ptrs; JQUANT_TBL **default_table_ptrs; gs_param_array quant_tables; - floatp QFactor = pdct->QFactor; + double QFactor = pdct->QFactor; int i; int code; @@ -261,7 +262,6 @@ gs_param_string *huff_data; gs_param_string_array hta; int num_in_tables; - jpeg_component_info *comp_info; JHUFF_TBL **dc_table_ptrs; JHUFF_TBL **ac_table_ptrs; int i; @@ -271,7 +271,6 @@ dc_table_ptrs = pdct->data.compress->cinfo.dc_huff_tbl_ptrs; ac_table_ptrs = pdct->data.compress->cinfo.ac_huff_tbl_ptrs; num_in_tables = pdct->data.compress->cinfo.input_components * 2; - comp_info = pdct->data.compress->cinfo.comp_info; } else { dc_table_ptrs = pdct->data.decompress->dinfo.dc_huff_tbl_ptrs; ac_table_ptrs = pdct->data.decompress->dinfo.ac_huff_tbl_ptrs; @@ -279,7 +278,6 @@ if (dc_table_ptrs[i - 1] || ac_table_ptrs[i - 1]) break; num_in_tables = i * 2; - comp_info = NULL; /* do not set for decompress case */ } /****** byte_array IS WRONG ******/ huff_data = (gs_param_string *) @@ -333,34 +331,52 @@ int i; gs_param_string bytes; gs_param_float_array floats; + gs_param_int_array ints; int code = param_read_string(plist, key, &bytes); switch (code) { case 0: if (bytes.size < start + count) { code = gs_note_error(gs_error_rangecheck); - break; + } else { + for (i = 0; i < count; ++i) + pvals[i] = (UINT8) bytes.data[start + i]; + code = 0; } - for (i = 0; i < count; ++i) - pvals[i] = (UINT8) bytes.data[start + i]; - return 0; + break; default: /* might be a float array */ - code = param_read_float_array(plist, key, &floats); + code = param_read_int_array(plist, key, &ints); if (!code) { - if (floats.size < start + count) { + if (ints.size < start + count) { code = gs_note_error(gs_error_rangecheck); - break; + } else { + for (i = 0; i < count; ++i) { + pvals[i] = ints.data[start + i]; + } + code = 0; } - for (i = 0; i < count; ++i) { - float v = floats.data[start + i]; - - if (v < 0 || v > 255) { + } else { + code = param_read_float_array(plist, key, &floats); + if (!code) { + if (floats.size < start + count) { code = gs_note_error(gs_error_rangecheck); - break; + } else { + for (i = 0; i < count; ++i) { + float v = floats.data[start + i]; + + if (v < 0 || v > 255) { + code = gs_note_error(gs_error_rangecheck); + break; + } + pvals[i] = (UINT8) (v + 0.5); + } } - pvals[i] = (UINT8) (v + 0.5); - } + if (code >= 0) + code = 0; + } else + code = 1; } + break; } if (code < 0) param_signal_error(plist, key, code); @@ -370,7 +386,7 @@ /* Get N quantization values from an array or a string. */ static int quant_params(gs_param_list * plist, gs_param_name key, int count, - UINT16 * pvals, floatp QFactor) + UINT16 * pvals, double QFactor) { int i; gs_param_string bytes; diff -Nru ghostscript-9.10~dfsg/base/sdcparam.h ghostscript-9.25~dfsg+1/base/sdcparam.h --- ghostscript-9.10~dfsg/base/sdcparam.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sdcparam.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sdctc.c ghostscript-9.25~dfsg+1/base/sdctc.c --- ghostscript-9.10~dfsg/base/sdctc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sdctc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,6 +19,12 @@ #include "jpeglib_.h" #include "strimpl.h" #include "sdct.h" +#include "sjpeg.h" + +extern const stream_template s_DCTE_template; +extern const stream_template s_DCTD_template; + +static void stream_dct_finalize(const gs_memory_t *cmem, void *vptr); public_st_DCT_state(); @@ -40,3 +46,38 @@ ss->Markers.data = 0; ss->Markers.size = 0; } + +static void +stream_dct_finalize(const gs_memory_t *cmem, void *vptr) +{ + stream_state *const st = vptr; + stream_DCT_state *const ss = (stream_DCT_state *) st; + (void)cmem; /* unused */ + + if (st->templat->process == s_DCTE_template.process) { + gs_jpeg_destroy(ss); + if (ss->data.compress != NULL) { + gs_free_object(ss->data.common->memory, ss->data.compress, + "s_DCTE_release"); + ss->data.compress = NULL; + } + /* Switch the template pointer back in case we still need it. */ + st->templat = &s_DCTE_template; + } + else { + gs_jpeg_destroy(ss); + if (ss->data.decompress != NULL) { + if (ss->data.decompress->scanline_buffer != NULL) { + gs_free_object(gs_memory_stable(ss->data.common->memory), + ss->data.decompress->scanline_buffer, + "s_DCTD_release(scanline_buffer)"); + ss->data.decompress->scanline_buffer = NULL; + } + gs_free_object(ss->data.common->memory, ss->data.decompress, + "s_DCTD_release"); + ss->data.decompress = NULL; + } + /* Switch the template pointer back in case we still need it. */ + st->templat = &s_DCTD_template; + } +} diff -Nru ghostscript-9.10~dfsg/base/sdctd.c ghostscript-9.25~dfsg+1/base/sdctd.c --- ghostscript-9.10~dfsg/base/sdctd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sdctd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -73,6 +73,17 @@ static void dctd_term_source(j_decompress_ptr dinfo) { + char EOI[2] = {0xff, 0xD9}; + + jpeg_decompress_data *jddp = + (jpeg_decompress_data *) ((char *)dinfo - + offset_of(jpeg_decompress_data, dinfo)); + + if (jddp->PassThrough && jddp->PassThroughfn) { + (jddp->PassThroughfn)(jddp->device, (byte *)EOI, 2); + (jddp->PassThroughfn)(jddp->device, NULL, 0); + } + return; } /* Set the defaults for the DCTDecode filter. */ @@ -137,6 +148,33 @@ return o - i; } +static void +update_jpeg_header_height(JOCTET *d, size_t len, int height) +{ + int marker_len; + + for (d += 2; len > 9 && d[0] == 0xFF; d += marker_len) + { + int declared_height; + + marker_len = 2 + (d[2] << 8) + d[3]; + if (marker_len > len) + break; + len -= marker_len; + + /* We can only safely rewrite non-differential SOF markers */ + if (d[1] < 0xC0 || (0xC3 < d[1] && d[1] < 0xC9) || 0xCB < d[1]) + continue; + + declared_height = (d[5]<<8) | d[6]; + if (declared_height == 0 || declared_height > height) + { + d[5] = height>>8; + d[6] = height; + } + } +} + /* Process a buffer */ static int s_DCTD_process(stream_state * st, stream_cursor_read * pr, @@ -146,6 +184,7 @@ jpeg_decompress_data *jddp = ss->data.decompress; struct jpeg_source_mgr *src = jddp->dinfo.src; int code; + byte *Buf; if_debug3m('w', st->memory, "[wdd]process avail=%u, skip=%u, last=%d\n", (uint) (pr->limit - pr->ptr), (uint) jddp->skip, last); @@ -153,17 +192,25 @@ long avail = pr->limit - pr->ptr; if (avail < jddp->skip) { + if (jddp->PassThrough && jddp->PassThroughfn) + (jddp->PassThroughfn)(jddp->device, (byte *)pr->ptr + 1, (byte *)pr->limit - (byte *)pr->ptr); + jddp->skip -= avail; pr->ptr = pr->limit; if (!last) return 0; /* need more data */ jddp->skip = 0; /* don't skip past input EOD */ } + Buf = (byte *)pr->ptr + 1; pr->ptr += jddp->skip; + if (jddp->PassThrough && jddp->PassThroughfn) + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); + jddp->skip = 0; } src->next_input_byte = pr->ptr + 1; src->bytes_in_buffer = pr->limit - pr->ptr; + Buf = (byte *)pr->ptr + 1; jddp->input_eod = last; switch (ss->phase) { case 0: /* not initialized yet */ @@ -172,21 +219,38 @@ * even though neither the standard nor Adobe's own * documentation mention this. */ + if (jddp->PassThrough && jddp->PassThroughfn && !jddp->StartedPassThrough) { + jddp->StartedPassThrough = 1; + (jddp->PassThroughfn)(jddp->device, NULL, 1); + } while (pr->ptr < pr->limit && pr->ptr[1] != 0xff) pr->ptr++; - if (pr->ptr == pr->limit) + if (pr->ptr == pr->limit) { + if (jddp->PassThrough && jddp->PassThroughfn) + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); return 0; + } src->next_input_byte = pr->ptr + 1; src->bytes_in_buffer = pr->limit - pr->ptr; ss->phase = 1; /* falls through */ case 1: /* reading header markers */ + if (ss->data.common->Height != 0) + { + /* Deliberate and naughty. We cast away a const pointer + * here and write to a supposedly read-only stream. */ + union { const byte *c; byte *u; } u; + u.c = pr->ptr+1; + update_jpeg_header_height(u.u, src->bytes_in_buffer, ss->data.common->Height); + } if ((code = gs_jpeg_read_header(ss, TRUE)) < 0) return ERRC; pr->ptr = (jddp->faked_eoi ? pr->limit : src->next_input_byte - 1); switch (code) { case JPEG_SUSPENDED: + if (jddp->PassThrough && jddp->PassThroughfn) + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); return 0; /*case JPEG_HEADER_OK: */ } @@ -225,8 +289,11 @@ return ERRC; pr->ptr = (jddp->faked_eoi ? pr->limit : src->next_input_byte - 1); - if (code == 0) + if (code == 0) { + if (jddp->PassThrough && jddp->PassThroughfn) + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); return 0; + } ss->scan_line_size = jddp->dinfo.output_width * jddp->dinfo.output_components; if_debug4m('w', ss->memory, "[wdd]width=%u, components=%d, scan_line_size=%u, min_out_size=%u\n", @@ -259,9 +326,25 @@ tomove); pw->ptr += tomove; jddp->bytes_in_scanline -= tomove; - if (jddp->bytes_in_scanline != 0) + /* calculate room after the copy, + * PXL typically provides room 1 exactly 1 scan, so avail == 0 + * PDF/PS provide enough room, so avail >= 0 + * XPS provides room ro complete image, and expects complet image copied + * PCL,PXL,PDF,PS copy 1 scan at a time. + */ + avail -= tomove; + if ((jddp->bytes_in_scanline != 0) || /* no room for complete scan */ + ((jddp->bytes_in_scanline == 0) && (tomove > 0) && /* 1 scancopy completed */ + (avail < tomove) && /* still room for 1 more scan */ + (jddp->dinfo.output_height > jddp->dinfo.output_scanline))) /* more scans to do */ + { + if (jddp->PassThrough && jddp->PassThroughfn) { + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); + } return 1; /* need more room */ + } } + /* while not done with image, decode 1 scan, otherwise fall into phase 4 */ while (jddp->dinfo.output_height > jddp->dinfo.output_scanline) { int read; byte *samples; @@ -269,8 +352,12 @@ if (jddp->scanline_buffer != NULL) samples = jddp->scanline_buffer; else { - if ((uint) (pw->limit - pw->ptr) < ss->scan_line_size) + if ((uint) (pw->limit - pw->ptr) < ss->scan_line_size) { + if (jddp->PassThrough && jddp->PassThroughfn) { + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); + } return 1; /* need more room */ + } samples = pw->ptr + 1; } read = gs_jpeg_read_scanlines(ss, &samples, 1); @@ -299,6 +386,9 @@ (pr->limit - pr->ptr >= ss->templat->min_in_size) && (compact_jpeg_buffer(pr) == 0)) return ERRC; + if (jddp->PassThrough && jddp->PassThroughfn) { + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); + } return 0; /* need more data */ } if (jddp->scanline_buffer != NULL) { @@ -310,6 +400,8 @@ ss->phase = 4; /* falls through */ case 4: /* end of image; scan for EOI */ + if (jddp->PassThrough && jddp->PassThroughfn) + (jddp->PassThroughfn)(jddp->device, Buf, pr->ptr - (Buf - 1)); if ((code = gs_jpeg_finish_decompress(ss)) < 0) return ERRC; pr->ptr = @@ -325,25 +417,8 @@ return ERRC; } -/* Release the stream */ -static void -s_DCTD_release(stream_state * st) -{ - stream_DCT_state *const ss = (stream_DCT_state *) st; - - gs_jpeg_destroy(ss); - if (ss->data.decompress->scanline_buffer != NULL) - gs_free_object(gs_memory_stable(ss->data.common->memory), - ss->data.decompress->scanline_buffer, - "s_DCTD_release(scanline_buffer)"); - gs_free_object(ss->data.common->memory, ss->data.decompress, - "s_DCTD_release"); - /* Switch the template pointer back in case we still need it. */ - st->templat = &s_DCTD_template; -} - /* Stream template */ const stream_template s_DCTD_template = -{&st_DCT_state, s_DCTD_init, s_DCTD_process, 2000, 4000, s_DCTD_release, +{&st_DCT_state, s_DCTD_init, s_DCTD_process, 2000, 4000, NULL, s_DCTD_set_defaults }; diff -Nru ghostscript-9.10~dfsg/base/sdcte.c ghostscript-9.25~dfsg+1/base/sdcte.c --- ghostscript-9.10~dfsg/base/sdcte.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sdcte.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -266,22 +266,8 @@ return ERRC; } -/* Release the stream */ -static void -s_DCTE_release(stream_state * st) -{ - stream_DCT_state *const ss = (stream_DCT_state *) st; - - gs_jpeg_destroy(ss); - if (ss->data.common) - gs_free_object(ss->data.common->memory, ss->data.compress, - "s_DCTE_release"); - /* Switch the template pointer back in case we still need it. */ - st->templat = &s_DCTE_template; -} - /* Stream template */ const stream_template s_DCTE_template = -{&st_DCT_state, s_DCTE_init, s_DCTE_process, 1000, 4000, s_DCTE_release, +{&st_DCT_state, s_DCTE_init, s_DCTE_process, 1000, 4000, NULL, s_DCTE_set_defaults }; diff -Nru ghostscript-9.10~dfsg/base/sdct.h ghostscript-9.25~dfsg+1/base/sdct.h --- ghostscript-9.10~dfsg/base/sdct.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sdct.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -26,33 +26,31 @@ /* ------ DCT filters ------ */ /* - * We don't want to allocate JPEG's private data directly from - * the C heap, but we must allocate it as immovable; and to avoid - * garbage collection issues, we must keep GC-traceable pointers - * to every block allocated. - */ -typedef struct jpeg_block_s jpeg_block_t; -struct jpeg_block_s { - jpeg_block_t *next; - void *data; -}; -#define private_st_jpeg_block() /* in sjpegc.c */\ - gs_private_st_ptrs2(st_jpeg_block, jpeg_block_t, "jpeg_block_t",\ - jpeg_block_enum_ptrs, jpeg_block_reloc_ptrs, next, data) - -/* * Define the stream state. * The jpeg_xxx_data structs are allocated in immovable memory * to simplify use of the IJG library. */ +/* The pointer "blocks" has been replaced with "dummy" as it is no longer needed, + * but "dummy" is there in its place to maintain consistency in allocations + * between the decode and encode filters: both are allocated with alloc_struct + * (which is used to allocate structures with pointers known to the garbage collector), + * removing "dummy" would mean alloc_struct for decoding filters, and alloc_bytes + * for encoding filters (with no pointers known to the garbage collector). + * + * dummy can be enumerated/reloc'ed by the garbage collection but as + * dummy == NULL *always* + * the garbage collector will just skip over it. + */ #define jpeg_stream_data_common\ /* We put a copy of the stream template here, because */\ /* the minimum buffer sizes depend on the image parameters. */\ stream_template templat;\ struct jpeg_error_mgr err;\ gsfix_jmp_buf exit_jmpbuf;\ - gs_memory_t *memory; /* heap for library allocations */\ - jpeg_block_t *blocks; /* ptr to allocated data block list */\ + gs_memory_t *memory; /* heap */\ + gs_memory_t *cmem; /* chunk allocator for library allocations */\ + byte *dummy; /* see comment above */\ + int Height; /* For JPEG files using a DNL (Define Number of Lines) marker */\ /* The following are documented in Adobe TN 5116. */\ int Picky; /* 0 or 1 */\ int Relax /* 0 or 1 */ @@ -64,9 +62,10 @@ /* Define initialization for the non-library part of the stream state. */ #define jpeg_stream_data_common_init(pdata)\ BEGIN\ + (pdata)->Height = 0;\ (pdata)->Picky = 0;\ (pdata)->Relax = 0;\ - (pdata)->blocks = 0;\ + (pdata)->dummy = 0;\ END typedef struct jpeg_compress_data_s { @@ -81,7 +80,10 @@ extern_st(st_jpeg_compress_data); #define public_st_jpeg_compress_data() /* in sdcte.c */\ gs_public_st_ptrs1(st_jpeg_compress_data, jpeg_compress_data,\ - "JPEG compress data", jpeg_compress_data_enum_ptrs, jpeg_compress_data_reloc_ptrs, blocks) + "JPEG compress data", jpeg_compress_data_enum_ptrs, jpeg_compress_data_reloc_ptrs, dummy) + +#define DCTD_PassThrough(proc)\ + int proc(void *d, byte *Buffer, int Size) typedef struct jpeg_decompress_data_s { jpeg_stream_data_common; @@ -94,12 +96,19 @@ bool faked_eoi; /* true when fill_input_buffer inserted EOI */ byte *scanline_buffer; /* buffer for oversize scanline, or NULL */ uint bytes_in_scanline; /* # of bytes remaining to output from same */ + int PassThrough; /* 0 or 1 */ + bool StartedPassThrough; /* Don't signal multiple starts for the same decode */ + DCTD_PassThrough((*PassThroughfn)); /* We don't want the stream code or + * JPEG code to have to handle devices + * so we use a function at the interpreter level + */ + void *device; /* The device we need to send PassThrough data to */ } jpeg_decompress_data; #define private_st_jpeg_decompress_data() /* in zfdctd.c */\ gs_private_st_ptrs2(st_jpeg_decompress_data, jpeg_decompress_data,\ "JPEG decompress data", jpeg_decompress_data_enum_ptrs,\ - jpeg_decompress_data_reloc_ptrs, blocks, scanline_buffer) + jpeg_decompress_data_reloc_ptrs, dummy, scanline_buffer) /* The stream state itself. This is kept in garbage-collectable memory. */ typedef struct stream_DCT_state_s { @@ -134,8 +143,8 @@ /* the encoding and decoding filters. */ extern_st(st_DCT_state); #define public_st_DCT_state() /* in sdctc.c */\ - gs_public_st_const_strings1_ptrs1(st_DCT_state, stream_DCT_state,\ - "DCTEncode/Decode state", dct_enum_ptrs, dct_reloc_ptrs, Markers, data.common) + gs_public_st_const_strings1_ptrs1_final(st_DCT_state, stream_DCT_state,\ + "DCTEncode/Decode state", dct_enum_ptrs, dct_reloc_ptrs, stream_dct_finalize, Markers, data.common) /* * NOTE: the client *must* invoke the set_defaults procedure in the * template before calling the init procedure. diff -Nru ghostscript-9.10~dfsg/base/sddparam.c ghostscript-9.25~dfsg+1/base/sddparam.c --- ghostscript-9.10~dfsg/base/sddparam.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sddparam.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sdeparam.c ghostscript-9.25~dfsg+1/base/sdeparam.c --- ghostscript-9.10~dfsg/base/sdeparam.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sdeparam.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/seexec.c ghostscript-9.25~dfsg+1/base/seexec.c --- ghostscript-9.10~dfsg/base/seexec.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/seexec.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/setjmp_.h ghostscript-9.25~dfsg+1/base/setjmp_.h --- ghostscript-9.10~dfsg/base/setjmp_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/setjmp_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -29,8 +29,15 @@ #define gsfix_jmp_buf_align ((size_t)&((gsfix_jmp_buf_test*)0)->j) +/* We previously used sizeof(jmp_buf) + gsfix_jmp_buf_align for the + content of gsfix_jmp_buf, but the compiler (gcc/clang) considered + gsfix_jmp_buf_align to be a variable which meant a variable sized + array, and that's not allowed. + Using 2 * sizeof(jmp_buf) solves that. It is slightly wasteful but + this is not an object that many instances will exist at a given time. + */ typedef struct { - unsigned char stuff[sizeof(jmp_buf) + gsfix_jmp_buf_align]; + unsigned char stuff[sizeof(jmp_buf) * 2]; } gsfix_jmp_buf; /* This could be moved into a function, but it's fairly harmless as a macro. */ diff -Nru ghostscript-9.10~dfsg/base/sfilter1.c ghostscript-9.25~dfsg+1/base/sfilter1.c --- ghostscript-9.10~dfsg/base/sfilter1.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sfilter1.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,338 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Filters included in Level 1 systems: NullEncode/Decode, PFBDecode, */ +/* SubFileDecode. */ +#include "stdio_.h" /* includes std.h */ +#include "memory_.h" +#include "strimpl.h" +#include "sfilter.h" + +/* ------ PFBDecode ------ */ + +private_st_PFBD_state(); + +/* Initialize the state */ +static int +s_PFBD_init(stream_state * st) +{ + stream_PFBD_state *const ss = (stream_PFBD_state *) st; + + ss->record_type = -1; + return 0; +} + +/* Process a buffer */ +static int +s_PFBD_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + stream_PFBD_state *const ss = (stream_PFBD_state *) st; + register const byte *p = pr->ptr; + register byte *q = pw->ptr; + int rcount, wcount; + int c; + int status = 0; + +top: + rcount = pr->limit - p; + wcount = pw->limit - q; + switch (ss->record_type) { + case -1: /* new record */ + if (rcount < 2) + goto out; + if (p[1] != 0x80) + goto err; + c = p[2]; + switch (c) { + case 1: + case 2: + break; + case 3: + status = EOFC; + p += 2; + goto out; + default: + p += 2; + goto err; + } + if (rcount < 6) + goto out; + ss->record_type = c; + ss->record_left = p[3] + ((uint) p[4] << 8) + + ((ulong) p[5] << 16) + + ((ulong) p[6] << 24); + + /* Check for an invalid counter found in an Adobe font, bug 689617 */ + if (ss->record_left == 0 && ss->record_type == 1) { + if (p + 7 < pr->limit) { + if (p[6] == 128) + ; /* normal empty block */ + else { + ss->record_type = 4; /* ASCII stuff between blocks */ + ss->record_left = ~0; + } + } else { + if (!last) + goto out; + } + } + p += 6; + goto top; + case 1: /* text data */ + /* Translate \r to \n. */ + { + int count = (wcount < rcount ? (status = 1, wcount) : rcount); + + if (count > ss->record_left) + count = ss->record_left, + status = 0; + ss->record_left -= count; + for (; count != 0; count--) { + c = *++p; + *++q = (c == '\r' ? '\n' : c); + } + } + break; + case 2: /* binary data */ + if (ss->binary_to_hex) { + /* Translate binary to hex. */ + int count; + const char *const hex_digits = "0123456789abcdef"; + + wcount >>= 1; /* 2 chars per input byte */ + count = (wcount < rcount ? (status = 1, wcount) : rcount); + if (count > ss->record_left) + count = ss->record_left, + status = 0; + ss->record_left -= count; + for (; count != 0; count--) { + c = *++p; + q[1] = hex_digits[c >> 4]; + q[2] = hex_digits[c & 0xf]; + q += 2; + } + } else { /* Just read binary data. */ + int count = (wcount < rcount ? (status = 1, wcount) : rcount); + + if (count > ss->record_left) + count = ss->record_left, + status = 0; + ss->record_left -= count; + memcpy(q + 1, p + 1, count); + p += count; + q += count; + } + break; + case 4: + /* Treat the text after empty ASCII block as ACSII stream */ + /* Translate \r to \n. */ + { + int count = (wcount < rcount ? (status = 1, wcount) : rcount); + for (; count != 0; count--) { + c = *++p; + if (c == 128) + { --p; + ss->record_left = 0; + break; + } + *++q = (c == '\r' ? '\n' : c); + } + } + break; + } + if (ss->record_left == 0) { + ss->record_type = -1; + goto top; + } +out: + pr->ptr = p; + pw->ptr = q; + return status; +err: + pr->ptr = p; + pw->ptr = q; + return ERRC; +} + +/* Stream template */ +const stream_template s_PFBD_template = { + &st_PFBD_state, s_PFBD_init, s_PFBD_process, 6, 2 +}; + +/* ------ SubFileDecode ------ */ + +private_st_SFD_state(); + +/* Set default parameter values. */ +static void +s_SFD_set_defaults(stream_state * st) +{ + stream_SFD_state *const ss = (stream_SFD_state *) st; + + ss->count = 0; + ss->eod.data = 0; + ss->eod.size = 0; + ss->skip_count = 0; +} + +/* Initialize the stream */ +static int +s_SFD_init(stream_state * st) +{ + stream_SFD_state *const ss = (stream_SFD_state *) st; + + ss->match = 0; + ss->copy_count = 0; + ss->min_left = (ss->eod.size != 0); + + return 0; +} + +/* Refill the buffer */ +static int +s_SFD_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + stream_SFD_state *const ss = (stream_SFD_state *) st; + register const byte *p = pr->ptr; + register byte *q = pw->ptr; + const byte *rlimit = pr->limit; + byte *wlimit = pw->limit; + int status = 0; + + if (ss->eod.size == 0) { /* Just read, with no EOD pattern. */ + int rcount = rlimit - p; + int wcount = wlimit - q; + int count; + + if (rcount <= ss->skip_count) { /* skipping */ + ss->skip_count -= rcount; + pr->ptr = rlimit; + return 0; + } else if (ss->skip_count > 0) { + rcount -= ss->skip_count; + pr->ptr = p += ss->skip_count; + ss->skip_count = 0; + } + count = min(rcount, wcount); + if (ss->count == 0) /* no EOD limit */ + return stream_move(pr, pw); + else if (ss->count > count) { /* not EOD yet */ + ss->count -= count; + return stream_move(pr, pw); + } else { /* We're going to reach EOD. */ + count = ss->count; + if (count > 0) { + memcpy(q + 1, p + 1, count); + pr->ptr = p + count; + pw->ptr = q + count; + } + ss->count = -1; + return EOFC; + } + } else { /* Read looking for an EOD pattern. */ + const byte *pattern = ss->eod.data; + uint match = ss->match; + +cp: + /* Check whether we're still copying a partial match. */ + if (ss->copy_count) { + int count = min(wlimit - q, ss->copy_count); + + memcpy(q + 1, ss->eod.data + ss->copy_ptr, count); + ss->copy_count -= count; + ss->copy_ptr += count; + q += count; + if (ss->copy_count != 0) { /* hit wlimit */ + status = 1; + goto xit; + } else if (ss->count < 0) { + status = EOFC; + goto xit; + } + } + while (p < rlimit) { + int c = *++p; + + if (c == pattern[match]) { + if (++match == ss->eod.size) { + if (ss->skip_count > 0) { + q = pw->ptr; /* undo any writes */ + ss->skip_count--; + match = 0; + continue; + } + /* + * We use if/else rather than switch because the value + * is long, which is not supported as a switch value in + * pre-ANSI C. + */ + if (ss->count <= 0) { + status = EOFC; + goto xit; + } else if (ss->count == 1) { + ss->count = -1; + } else + ss->count--; + ss->copy_ptr = 0; + ss->copy_count = match; + match = 0; + goto cp; + } + continue; + } + /* + * No match here, back up to find the longest one. + * This may be quadratic in string_size, but + * we don't expect this to be a real problem. + */ + if (match > 0) { + int end = match; + + while (match > 0) { + match--; + if (!memcmp(pattern, pattern + end - match, match)) + break; + } + /* + * Copy the unmatched initial portion of + * the EOD string to the output. + */ + p--; + ss->copy_ptr = 0; + ss->copy_count = end - match; + goto cp; + } + if (q == wlimit) { + p--; + status = 1; + break; + } + *++q = c; + } +xit: pr->ptr = p; + if (ss->skip_count <= 0) + pw->ptr = q; + ss->match = match; + } + return status; +} + +/* Stream template */ +const stream_template s_SFD_template = { + &st_SFD_state, s_SFD_init, s_SFD_process, 1, 1, 0, s_SFD_set_defaults +}; diff -Nru ghostscript-9.10~dfsg/base/sfilter2.c ghostscript-9.25~dfsg+1/base/sfilter2.c --- ghostscript-9.10~dfsg/base/sfilter2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sfilter2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -50,7 +50,7 @@ byte *wlimit = pw->limit; int status = 0; int prev = ss->last_char; - int count; + unsigned int count; if_debug3m('w', ss->memory, "[w85]initial ss->count = %d, rcount = %d, wcount = %d\n", ss->count, (int)(rlimit - p), (int)(wlimit - q)); @@ -65,7 +65,8 @@ status = 1; break; } - *++q = prev = '\n'; + /* No need to update 'prev' in this case as its overwritten with 'z' below */ + *++q = '\n'; qn = q + LINE_LIMIT; if_debug1m('w', ss->memory, "[w85]EOL at %d bytes written\n", (int)(q - pw->ptr)); diff -Nru ghostscript-9.10~dfsg/base/sfilter.h ghostscript-9.25~dfsg+1/base/sfilter.h --- ghostscript-9.10~dfsg/base/sfilter.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sfilter.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -89,9 +89,9 @@ typedef struct stream_SFD_state_s { stream_state_common; /* The following parameters are set by the client. */ - long count; /* # of chars or EODs to scan over */ + int64_t count; /* # of chars or EODs to scan over */ gs_const_string eod; - long skip_count; /* # of initial chars or records to skip */ + int64_t skip_count; /* # of initial chars or records to skip */ /* The following change dynamically. */ uint match; /* # of matched chars not copied to output */ uint copy_count; /* # of matched characters left to copy */ diff -Nru ghostscript-9.10~dfsg/base/sfxboth.c ghostscript-9.25~dfsg+1/base/sfxboth.c --- ghostscript-9.10~dfsg/base/sfxboth.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sfxboth.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sfxcommon.c ghostscript-9.25~dfsg+1/base/sfxcommon.c --- ghostscript-9.10~dfsg/base/sfxcommon.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sfxcommon.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -23,6 +23,7 @@ #include "gp.h" #include "gserrors.h" #include "stream.h" +#include "assert_.h" #define DEFAULT_BUFFER_SIZE 2048 const uint file_default_buffer_size = DEFAULT_BUFFER_SIZE; @@ -66,6 +67,14 @@ FILE *file; char fmode[4]; /* r/w/a, [+], [b], null */ +#ifdef DEBUG + if (strlen(gp_fmode_binary_suffix) > 0) { + if (strchr(file_access, gp_fmode_binary_suffix[0]) != NULL) + dmprintf(mem, "\nWarning: spurious 'b' character in file access mode\n"); + assert(strchr(file_access, gp_fmode_binary_suffix[0]) == NULL); + } +#endif + if (!iodev) iodev = iodev_default(mem); code = file_prepare_stream(fname, len, file_access, buffer_size, ps, fmode, mem); @@ -84,7 +93,8 @@ *ps = NULL; return code; } - file_init_stream(*ps, file, fmode, (*ps)->cbuf, (*ps)->bsize); + if (file_init_stream(*ps, file, fmode, (*ps)->cbuf, (*ps)->bsize) != 0) + return_error(gs_error_ioerror); return 0; } @@ -127,20 +137,22 @@ * Set up a file stream on an OS file. The caller has allocated the * stream and buffer. */ -void +int file_init_stream(stream *s, FILE *file, const char *fmode, byte *buffer, uint buffer_size) { switch (fmode[0]) { case 'a': - sappend_file(s, file, buffer, buffer_size); + if (sappend_file(s, file, buffer, buffer_size) != 0) + return ERRC; break; case 'r': /* Defeat buffering for terminals. */ { struct stat rstat; - fstat(fileno(file), &rstat); + if (fstat(fileno(file), &rstat) != 0) + return ERRC; sread_file(s, file, buffer, (S_ISCHR(rstat.st_mode) ? 1 : buffer_size)); } @@ -152,6 +164,7 @@ s->file_modes |= s_mode_read | s_mode_write; s->save_close = s->procs.close; s->procs.close = file_close_file; + return 0; } /* Prepare a stream with a file name. */ @@ -179,8 +192,10 @@ return_error(gs_error_VMerror); /* Allocate the buffer. */ buffer = gs_alloc_bytes(mem, buffer_size, "file_prepare_stream(buffer)"); - if (buffer == 0) + if (buffer == 0) { + gs_free_object(mem, s, "file_prepare_stream"); return_error(gs_error_VMerror); + } if (fname != 0) { memcpy(buffer, fname, len); buffer[len] = 0; /* terminate string */ diff -Nru ghostscript-9.10~dfsg/base/sfxfd.c ghostscript-9.25~dfsg+1/base/sfxfd.c --- ghostscript-9.10~dfsg/base/sfxfd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sfxfd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -128,7 +128,7 @@ s->file = file; s->file_modes = s->modes; s->file_offset = 0; - s->file_limit = max_long; + s->file_limit = S_FILE_LIMIT_MAX; } /* Confine reading to a subfile. This is primarily for reusable streams. */ @@ -141,7 +141,7 @@ sread_subfile(stream *s, gs_offset_t start, gs_offset_t length) { if (s->file == 0 || s->modes != s_mode_read + s_mode_seek || - s->file_offset != 0 || s->file_limit != max_long || + s->file_offset != 0 || s->file_limit != S_FILE_LIMIT_MAX || ((s->position < start || s->position > start + length) && sseek(s, start) < 0) ) @@ -226,7 +226,7 @@ again: max_count = pw->limit - pw->ptr; status = 1; - if (s->file_limit < max_long) { + if (s->file_limit < S_FILE_LIMIT_MAX) { gs_offset_t limit_count = s->file_offset + s->file_limit - ltell(fd); if (max_count > limit_count) @@ -269,7 +269,7 @@ s->file = file; s->file_modes = s->modes; s->file_offset = 0; /* in case we switch to reading later */ - s->file_limit = max_long; /* ibid. */ + s->file_limit = S_FILE_LIMIT_MAX; } /* Initialize for appending to an OS file. */ void diff -Nru ghostscript-9.10~dfsg/base/sfxstdio.c ghostscript-9.25~dfsg+1/base/sfxstdio.c --- ghostscript-9.10~dfsg/base/sfxstdio.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sfxstdio.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -70,7 +70,7 @@ s->file = file; s->file_modes = s->modes; s->file_offset = 0; - s->file_limit = sizeof(gs_offset_t) > 4 ? max_int64_t : max_long; + s->file_limit = (sizeof(gs_offset_t) > 4 ? max_int64_t : max_long); } /* Confine reading to a subfile. This is primarily for reusable streams. */ @@ -78,9 +78,9 @@ sread_subfile(stream *s, gs_offset_t start, gs_offset_t length) { if (s->file == 0 || s->modes != s_mode_read + s_mode_seek || - s->file_offset != 0 || s->file_limit != max_long || - ((s->position < start || s->position > start + length) && - sseek(s, start) < 0) + s->file_offset != 0 || + s->file_limit != S_FILE_LIMIT_MAX || + ((s->position < start || s->position > start + length) && sseek(s, start) < 0) ) return ERRC; s->position -= start; @@ -161,7 +161,7 @@ int status = 1; int count; - if (s->file_limit < max_long) { + if (s->file_limit < S_FILE_LIMIT_MAX) { gs_offset_t limit_count = s->file_offset + s->file_limit - gp_ftell_64(file); if (max_count > limit_count) @@ -193,17 +193,19 @@ s->file = file; s->file_modes = s->modes; s->file_offset = 0; /* in case we switch to reading later */ - s->file_limit = sizeof(gs_offset_t) > 4 ? max_int64_t : max_long; /* ibid. */ + s->file_limit = S_FILE_LIMIT_MAX; } /* Initialize for appending to an OS file. */ -void +int sappend_file(register stream * s, FILE * file, byte * buf, uint len) { swrite_file(s, file, buf, len); s->modes = s_mode_write + s_mode_append; /* no seek */ s->file_modes = s->modes; - gp_fseek_64(file, 0L, SEEK_END); + if (gp_fseek_64(file, 0L, SEEK_END) != 0) + return ERRC; s->position = gp_ftell_64(file); + return 0; } /* Procedures for writing on a file */ static int @@ -279,9 +281,11 @@ pos = stell(s); if_debug2m('s', s->memory, "[s]switch 0x%"PRIx64" to write at %"PRId64"\n", (uint64_t) s, (int64_t)pos); - gp_fseek_64(file, pos, SEEK_SET); + if (gp_fseek_64(file, pos, SEEK_SET) != 0) + return ERRC; if (modes & s_mode_append) { - sappend_file(s, file, s->cbuf, s->cbsize); /* sets position */ + if (sappend_file(s, file, s->cbuf, s->cbsize)!= 0) /* sets position */ + return ERRC; } else { swrite_file(s, file, s->cbuf, s->cbsize); s->position = pos; @@ -295,7 +299,8 @@ (uint64_t) s, (int64_t)pos); if (sflush(s) < 0) return ERRC; - gp_fseek_64(file, 0L, SEEK_CUR); /* pacify C library */ + if (gp_fseek_64(file, 0L, SEEK_CUR) != 0) + return ERRC; sread_file(s, file, s->cbuf, s->cbsize); s->modes |= modes & s_mode_append; /* don't lose append info */ s->position = pos; diff -Nru ghostscript-9.10~dfsg/base/sha2.c ghostscript-9.25~dfsg+1/base/sha2.c --- ghostscript-9.10~dfsg/base/sha2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sha2.c 2018-09-13 10:02:01.000000000 +0000 @@ -240,7 +240,7 @@ * library -- they are intended for private internal visibility/use * only. */ -void SHA512_Last(SHA512_CTX*); +void pSHA512_Last(SHA512_CTX*); void pSHA256_Transform(SHA256_CTX*, const sha2_word32*); void pSHA512_Transform(SHA512_CTX*, const sha2_word64*); @@ -646,7 +646,7 @@ usedspace = 0; } -char *SHA256_End(SHA256_CTX* context, char buffer[]) { +char *pSHA256_End(SHA256_CTX* context, char buffer[]) { sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; int i; @@ -669,16 +669,16 @@ return buffer; } -char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { +char* pSHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { SHA256_CTX context; pSHA256_Init(&context); pSHA256_Update(&context, data, len); - return SHA256_End(&context, digest); + return pSHA256_End(&context, digest); } /*** SHA-512: *********************************************************/ -void SHA512_Init(SHA512_CTX* context) { +void pSHA512_Init(SHA512_CTX* context) { if (context == (SHA512_CTX*)0) { return; } @@ -855,7 +855,7 @@ #endif /* SHA2_UNROLL_TRANSFORM */ -void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { +void pSHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { @@ -903,7 +903,7 @@ usedspace = freespace = 0; } -void SHA512_Last(SHA512_CTX* context) { +void pSHA512_Last(SHA512_CTX* context) { unsigned int usedspace; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; @@ -944,7 +944,7 @@ pSHA512_Transform(context, (sha2_word64*)context->buffer); } -void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { +void pSHA512_Final(sha2_byte digest[], SHA512_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ @@ -952,7 +952,7 @@ /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { - SHA512_Last(context); + pSHA512_Last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN @@ -973,7 +973,7 @@ MEMSET_BZERO(context, sizeof(*context)); } -char *SHA512_End(SHA512_CTX* context, char buffer[]) { +char *pSHA512_End(SHA512_CTX* context, char buffer[]) { sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; int i; @@ -981,7 +981,7 @@ assert(context != (SHA512_CTX*)0); if (buffer != (char*)0) { - SHA512_Final(digest, context); + pSHA512_Final(digest, context); for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; @@ -996,16 +996,16 @@ return buffer; } -char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { +char* pSHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { SHA512_CTX context; - SHA512_Init(&context); - SHA512_Update(&context, data, len); - return SHA512_End(&context, digest); + pSHA512_Init(&context); + pSHA512_Update(&context, data, len); + return pSHA512_End(&context, digest); } /*** SHA-384: *********************************************************/ -void SHA384_Init(SHA384_CTX* context) { +void pSHA384_Init(SHA384_CTX* context) { if (context == (SHA384_CTX*)0) { return; } @@ -1014,11 +1014,11 @@ context->bitcount[0] = context->bitcount[1] = 0; } -void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { - SHA512_Update((SHA512_CTX*)context, data, len); +void pSHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + pSHA512_Update((SHA512_CTX*)context, data, len); } -void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { +void pSHA384_Final(sha2_byte digest[], SHA384_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ @@ -1026,7 +1026,7 @@ /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { - SHA512_Last((SHA512_CTX*)context); + pSHA512_Last((SHA512_CTX*)context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN @@ -1047,7 +1047,7 @@ MEMSET_BZERO(context, sizeof(*context)); } -char *SHA384_End(SHA384_CTX* context, char buffer[]) { +char *pSHA384_End(SHA384_CTX* context, char buffer[]) { sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; int i; @@ -1055,7 +1055,7 @@ assert(context != (SHA384_CTX*)0); if (buffer != (char*)0) { - SHA384_Final(digest, context); + pSHA384_Final(digest, context); for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; @@ -1070,10 +1070,10 @@ return buffer; } -char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { +char* pSHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { SHA384_CTX context; - SHA384_Init(&context); - SHA384_Update(&context, data, len); - return SHA384_End(&context, digest); + pSHA384_Init(&context); + pSHA384_Update(&context, data, len); + return pSHA384_End(&context, digest); } diff -Nru ghostscript-9.10~dfsg/base/sha2.h ghostscript-9.25~dfsg+1/base/sha2.h --- ghostscript-9.10~dfsg/base/sha2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sha2.h 2018-09-13 10:02:01.000000000 +0000 @@ -118,40 +118,40 @@ void pSHA256_Init(SHA256_CTX *); void pSHA256_Update(SHA256_CTX*, const uint8_t*, size_t); void pSHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); +char* pSHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* pSHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); -void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); - -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); -void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); +void pSHA384_Init(SHA384_CTX*); +void pSHA384_Update(SHA384_CTX*, const uint8_t*, size_t); +void pSHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* pSHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* pSHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void pSHA512_Init(SHA512_CTX*); +void pSHA512_Update(SHA512_CTX*, const uint8_t*, size_t); +void pSHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* pSHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* pSHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #else /* SHA2_USE_INTTYPES_H */ void pSHA256_Init(SHA256_CTX *); void pSHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); void pSHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); -char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); +char* pSHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* pSHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); -void SHA384_Init(SHA384_CTX*); -void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); -void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); -char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); -char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); - -void SHA512_Init(SHA512_CTX*); -void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); -void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); -char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); -char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); +void pSHA384_Init(SHA384_CTX*); +void pSHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); +void pSHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* pSHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* pSHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void pSHA512_Init(SHA512_CTX*); +void pSHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); +void pSHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* pSHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* pSHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #endif /* SHA2_USE_INTTYPES_H */ @@ -160,20 +160,20 @@ void pSHA256_Init(); void pSHA256_Update(); void pSHA256_Final(); -char* SHA256_End(); -char* SHA256_Data(); +char* pSHA256_End(); +char* pSHA256_Data(); -void SHA384_Init(); -void SHA384_Update(); -void SHA384_Final(); -char* SHA384_End(); -char* SHA384_Data(); - -void SHA512_Init(); -void SHA512_Update(); -void SHA512_Final(); -char* SHA512_End(); -char* SHA512_Data(); +void pSHA384_Init(); +void pSHA384_Update(); +void pSHA384_Final(); +char* pSHA384_End(); +char* pSHA384_Data(); + +void pSHA512_Init(); +void pSHA512_Update(); +void pSHA512_Final(); +char* pSHA512_End(); +char* pSHA512_Data(); #endif /* NOPROTO */ diff -Nru ghostscript-9.10~dfsg/base/shc.c ghostscript-9.25~dfsg+1/base/shc.c --- ghostscript-9.10~dfsg/base/shc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/shc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/shcgen.c ghostscript-9.25~dfsg+1/base/shcgen.c --- ghostscript-9.10~dfsg/base/shcgen.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/shcgen.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,481 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Generate (bounded) Huffman code definitions from frequencies, */ -/* and tables from definitions. */ -#include "memory_.h" -#include "stdio_.h" -#include /* for qsort */ -#include "gdebug.h" -#include "gserrors.h" -#include "gsmemory.h" -#include "scommon.h" -#include "shc.h" -#include "shcgen.h" - -/* ------ Frequency -> definition procedure ------ */ - -/* Define a node for the Huffman code tree. */ -typedef struct count_node_s count_node; -struct count_node_s { - long freq; /* frequency of value */ - uint value; /* data value being encoded */ - uint code_length; /* length of Huffman code */ - count_node *next; /* next node in freq-sorted list */ - count_node *left; /* left child in tree (smaller code_length) */ - count_node *right; /* right child in tree (greater code_length) */ -}; - -#ifdef DEBUG -# define debug_print_nodes(mem, nodes, n, tag, lengths)\ - if ( gs_debug_c('W') ) print_nodes_proc(mem, nodes, n, tag, lengths); -static void -print_nodes_proc(const gs_memory_t *mem, const count_node * nodes, int n, const char *tag, int lengths) -{ - int i; - - dmlprintf1(mem, "[w]---------------- %s ----------------\n", tag); - for (i = 0; i < n; ++i) - dmlprintf7(mem, "[w]node %d: f=%ld v=%d len=%d N=%d L=%d R=%d\n", - i, nodes[i].freq, nodes[i].value, nodes[i].code_length, - (nodes[i].next == 0 ? -1 : (int)(nodes[i].next - nodes)), - (nodes[i].left == 0 ? -1 : (int)(nodes[i].left - nodes)), - (nodes[i].right == 0 ? -1 : (int)(nodes[i].right - nodes))); - for (i = lengths; i > 0;) { - int j = i; - int len = nodes[--j].code_length; - - while (j > 0 && nodes[j - 1].code_length == len) - --j; - dmlprintf2(mem, "[w]%d codes of length %d\n", i - j, len); - i = j; - } -} -#else -# define debug_print_nodes(mem, nodes, n, tag, lengths) DO_NOTHING -#endif - -/* Node comparison procedures for sorting. */ -#define pn1 ((const count_node *)p1) -#define pn2 ((const count_node *)p2) -/* Sort by decreasing frequency. */ -static int -compare_freqs(const void *p1, const void *p2) -{ - long diff = pn2->freq - pn1->freq; - - return (diff < 0 ? -1 : diff > 0 ? 1 : 0); -} -/* Sort by increasing code length, and secondarily by decreasing frequency. */ -static int -compare_code_lengths(const void *p1, const void *p2) -{ - int diff = pn1->code_length - pn2->code_length; - - return (diff < 0 ? -1 : diff > 0 ? 1 : compare_freqs(p1, p2)); -} -/* Sort by increasing code value. */ -static int -compare_values(const void *p1, const void *p2) -{ - return (pn1->value < pn2->value ? -1 : - pn1->value > pn2->value ? 1 : 0); -} -#undef pn1 -#undef pn2 - -/* Adjust code lengths so that none of them exceeds max_length. */ -/* We break this out just to help organize the code; it's only called */ -/* from one place in hc_compute. */ -static void -hc_limit_code_lengths(count_node * nodes, uint num_values, int max_length) -{ - int needed; /* # of max_length codes we need to free up */ - count_node *longest = nodes + num_values; - - { /* Compute the number of additional max_length codes */ - /* we need to make available. */ - int length = longest[-1].code_length; - int next_length; - int avail = 0; - - while ((next_length = longest[-1].code_length) > max_length) { - avail >>= length - next_length; - length = next_length; - (--longest)->code_length = max_length; - ++avail; - } - needed = (nodes + num_values - longest) - - (avail >>= (length - max_length)); - if_debug2('W', "[w]avail=%d, needed=%d\n", - avail, needed); - } - /* Skip over all max_length codes. */ - while (longest[-1].code_length == max_length) - --longest; - - /* - * To make available a code of length N, suppose that the next - * shortest used code is of length M. - * We take the lowest-frequency code of length M and change it - * to M+1; we then have to compensate by reducing the length of - * some of the highest-frequency codes of length N, as follows: - * M new lengths for codes of length N - * --- ----------- - * N-1 (none) - * N-2 N-1 - * 0; --needed) { /* longest points to the first code of length max_length. */ - /* Since codes are sorted by increasing code length, */ - /* longest-1 is the desired code of length M. */ - int M1 = ++(longest[-1].code_length); - - switch (max_length - M1) { - case 0: /* M == N-1 */ - --longest; - break; - case 1: /* M == N-2 */ - longest++->code_length = M1; - break; - default: - longest->code_length = M1 + 1; - longest[1].code_length = M1 + 1; - longest[2].code_length--; - longest += 3; - } - } -} - -/* Compute an optimal Huffman code from an input data set. */ -/* The client must have set all the elements of *def. */ -int -hc_compute(hc_definition * def, const long *freqs, gs_memory_t * mem) -{ - uint num_values = def->num_values; - count_node *nodes = - (count_node *) gs_alloc_byte_array(mem, num_values * 2 - 1, - sizeof(count_node), "hc_compute"); - int i; - count_node *lowest; - count_node *comb; - - if (nodes == 0) - return_error(gs_error_VMerror); - - /* Create leaf nodes for the input data. */ - for (i = 0; i < num_values; ++i) - nodes[i].freq = freqs[i], nodes[i].value = i; - - /* Create a list sorted by increasing frequency. */ - /* Also initialize the tree structure. */ - qsort(nodes, num_values, sizeof(count_node), compare_freqs); - for (i = 0; i < num_values; ++i) - nodes[i].next = &nodes[i - 1], - nodes[i].code_length = 0, - nodes[i].left = nodes[i].right = 0; - nodes[0].next = 0; - debug_print_nodes(mem, nodes, num_values, "after sort", 0); - - /* Construct the Huffman code tree. */ - for (lowest = &nodes[num_values - 1], comb = &nodes[num_values];; - ++comb - ) { - count_node *pn1 = lowest; - count_node *pn2 = pn1->next; - long freq = pn1->freq + pn2->freq; - - /* Create a parent for the two lowest-frequency nodes. */ - lowest = pn2->next; - comb->freq = freq; - if (pn1->code_length <= pn2->code_length) - comb->left = pn1, comb->right = pn2, - comb->code_length = pn2->code_length + 1; - else - comb->left = pn2, comb->right = pn1, - comb->code_length = pn1->code_length + 1; - if (lowest == 0) /* no nodes left to combine */ - break; - /* Insert comb in the sorted list. */ - if (freq < lowest->freq) - comb->next = lowest, lowest = comb; - else { - count_node *here = lowest; - - while (here->next != 0 && freq >= here->next->freq) - here = here->next; - comb->next = here->next; - here->next = comb; - } - } - - /* comb (i.e., &nodes[num_values * 2 - 2] is the root of the tree. */ - /* Note that the left and right children of an interior node */ - /* were constructed before, and therefore have lower indices */ - /* in the nodes array than, the parent node. Thus we can assign */ - /* the code lengths (node depths) in a single descending-order */ - /* sweep. */ - comb++->code_length = 0; - while (comb > nodes + num_values) { - --comb; - comb->left->code_length = comb->right->code_length = - comb->code_length + 1; - } - debug_print_nodes(mem, nodes, num_values * 2 - 1, "after combine", 0); - - /* Sort the leaves again by code length. */ - qsort(nodes, num_values, sizeof(count_node), compare_code_lengths); - debug_print_nodes(mem, nodes, num_values, "after re-sort", num_values); - - /* Limit the code length to def->num_counts. */ - hc_limit_code_lengths(nodes, num_values, def->num_counts); - debug_print_nodes(mem, nodes, num_values, "after limit", num_values); - - /* Sort within each code length by increasing code value. */ - /* This doesn't affect data compression, but it makes */ - /* the code definition itself compress better using our */ - /* incremental encoding. */ - for (i = num_values; i > 0;) { - int j = i; - int len = nodes[--j].code_length; - - while (j > 0 && nodes[j - 1].code_length == len) - --j; - qsort(&nodes[j], i - j, sizeof(count_node), compare_values); - i = j; - } - - /* Extract the definition from the nodes. */ - memset(def->counts, 0, sizeof(*def->counts) * (def->num_counts + 1)); - for (i = 0; i < num_values; ++i) { - def->values[i] = nodes[i].value; - def->counts[nodes[i].code_length]++; - } - - /* All done, release working storage. */ - gs_free_object(mem, nodes, "hc_compute"); - return 0; -} - -/* ------ Byte string <-> definition procedures ------ */ - -/* - * We define a compressed representation for (well-behaved) definitions - * as a byte string. A "well-behaved" definition is one where if - * code values A and B have the same code length and A < B, - * A precedes B in the values table of the definition, and hence - * A's encoding lexicographically precedes B's. - * - * The successive bytes in the compressed string give the code lengths for - * runs of decoded values, in the form nnnnllll where nnnn is the number of - * consecutive values -1 and llll is the code length -1. - */ - -/* Convert a definition to a byte string. */ -/* The caller must provide the byte string, of length def->num_values. */ -/* Assume (do not check) that the definition is well-behaved. */ -/* Return the actual length of the string. */ -int -hc_bytes_from_definition(byte * dbytes, const hc_definition * def) -{ - int i, j; - byte *bp = dbytes; - const byte *lp = dbytes; - const byte *end = dbytes + def->num_values; - const ushort *values = def->values; - - /* Temporarily use the output string as a map from */ - /* values to code lengths. */ - for (i = 1; i <= def->num_counts; i++) - for (j = 0; j < def->counts[i]; j++) - bp[*values++] = i; - - /* Now construct the actual string. */ - while (lp < end) { - const byte *vp; - byte len = *lp; - - for (vp = lp + 1; vp < end && vp < lp + 16 && *vp == len;) - vp++; - *bp++ = ((vp - lp - 1) << 4) + (len - 1); - lp = vp; - } - - return bp - dbytes; -} - -/* Extract num_counts and num_values from a byte string. */ -void -hc_sizes_from_bytes(hc_definition * def, const byte * dbytes, int num_bytes) -{ - uint num_counts = 0, num_values = 0; - int i; - - for (i = 0; i < num_bytes; i++) { - int n = (dbytes[i] >> 4) + 1; - int l = (dbytes[i] & 15) + 1; - - if (l > num_counts) - num_counts = l; - num_values += n; - } - def->num_counts = num_counts; - def->num_values = num_values; -} - -/* Convert a byte string back to a definition. */ -/* The caller must initialize *def, including allocating counts and values. */ -void -hc_definition_from_bytes(hc_definition * def, const byte * dbytes) -{ - int v, i; - ushort counts[max_hc_length + 1]; - - /* Make a first pass to set the counts for each code length. */ - memset(counts, 0, sizeof(counts[0]) * (def->num_counts + 1)); - for (i = 0, v = 0; v < def->num_values; i++) { - int n = (dbytes[i] >> 4) + 1; - int l = (dbytes[i] & 15) + 1; - - counts[l] += n; - v += n; - } - - /* Now fill in the definition. */ - memcpy(def->counts, counts, sizeof(counts[0]) * (def->num_counts + 1)); - for (i = 1, v = 0; i <= def->num_counts; i++) { - uint prev = counts[i]; - - counts[i] = v; - v += prev; - } - for (i = 0, v = 0; v < def->num_values; i++) { - int n = (dbytes[i] >> 4) + 1; - int l = (dbytes[i] & 15) + 1; - int j; - - for (j = 0; j < n; n++) - def->values[counts[l]++] = v++; - } -} - -/* ------ Definition -> table procedures ------ */ - -/* Generate the encoding table from the definition. */ -/* The size of the encode array is def->num_values. */ -void -hc_make_encoding(hce_code * encode, const hc_definition * def) -{ - uint next = 0; - const ushort *pvalue = def->values; - uint i, k; - - for (i = 1; i <= def->num_counts; i++) { - for (k = 0; k < def->counts[i]; k++, pvalue++, next++) { - hce_code *pce = encode + *pvalue; - - pce->code = next; - pce->code_length = i; - } - next <<= 1; - } -} - -/* We decode in two steps, first indexing into a table with */ -/* a fixed number of bits from the source, and then indexing into */ -/* an auxiliary table if necessary. (See shc.h for details.) */ - -/* Calculate the size of the decoding table. */ -uint -hc_sizeof_decoding(const hc_definition * def, int initial_bits) -{ - uint size = 1 << initial_bits; - uint carry = 0, mask = (uint) ~ 1; - uint i; - - for (i = initial_bits + 1; i <= def->num_counts; - i++, carry <<= 1, mask <<= 1 - ) { - carry += def->counts[i]; - size += carry & mask; - carry &= ~mask; - } - return size; -} - -/* Generate the decoding tables. */ -void -hc_make_decoding(hcd_code * decode, const hc_definition * def, - int initial_bits) -{ /* Make entries for single-dispatch codes. */ - { - hcd_code *pcd = decode; - const ushort *pvalue = def->values; - uint i, k, d; - - for (i = 0; i <= initial_bits; i++) { - for (k = 0; k < def->counts[i]; k++, pvalue++) { - for (d = 1 << (initial_bits - i); d > 0; - d--, pcd++ - ) - pcd->value = *pvalue, - pcd->code_length = i; - } - } - } - /* Make entries for two-dispatch codes. */ - /* By working backward, we can do this more easily */ - /* in a single pass. */ - { - uint dsize = hc_sizeof_decoding(def, initial_bits); - hcd_code *pcd = decode + (1 << initial_bits); - hcd_code *pcd2 = decode + dsize; - const ushort *pvalue = def->values + def->num_values; - uint entries_left = 0, slots_left = 0, mult_shift = 0; - uint i = def->num_counts + 1, j; - - for (;;) { - if (slots_left == 0) { - if (entries_left != 0) { - slots_left = 1 << (i - initial_bits); - mult_shift = 0; - continue; - } - if (--i <= initial_bits) - break; - entries_left = def->counts[i]; - continue; - } - if (entries_left == 0) { - entries_left = def->counts[--i]; - mult_shift++; - continue; - } - --entries_left, --pvalue; - for (j = 1 << mult_shift; j > 0; j--) { - --pcd2; - pcd2->value = *pvalue; - pcd2->code_length = i - initial_bits; - } - if ((slots_left -= 1 << mult_shift) == 0) { - --pcd; - pcd->value = pcd2 - decode; - pcd->code_length = i + mult_shift; - } - } - } -} diff -Nru ghostscript-9.10~dfsg/base/shcgen.h ghostscript-9.25~dfsg+1/base/shcgen.h --- ghostscript-9.10~dfsg/base/shcgen.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/shcgen.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Interface for Huffman code generation */ -/* Requires shc.h */ - -#ifndef shcgen_INCLUDED -# define shcgen_INCLUDED - -/* Compute an optimal Huffman code from an input data set. */ -/* The client must have set all the elements of *def. */ -/* The definition is guaranteed to be well-behaved. */ -int hc_compute(hc_definition * def, const long *freqs, gs_memory_t * mem); - -/* Convert a definition to a byte string. */ -/* The caller must provide the byte string, of length def->num_values. */ -/* Assume (do not check) that the definition is well-behaved. */ -/* Return the actual length of the string. */ -int hc_bytes_from_definition(byte * dbytes, const hc_definition * def); - -/* Extract num_counts and num_values from a byte string. */ -void hc_sizes_from_bytes(hc_definition * def, const byte * dbytes, int num_bytes); - -/* Convert a byte string back to a definition. */ -/* The caller must initialize *def, including allocating counts and values. */ -void hc_definition_from_bytes(hc_definition * def, const byte * dbytes); - -/* Generate the encoding table from the definition. */ -/* The size of the encode array is def->num_values. */ -void hc_make_encoding(hce_code * encode, const hc_definition * def); - -/* Calculate the size of the decoding table. */ -uint hc_sizeof_decoding(const hc_definition * def, int initial_bits); - -/* Generate the decoding tables. */ -void hc_make_decoding(hcd_code * decode, const hc_definition * def, - int initial_bits); - -#endif /* shcgen_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/shc.h ghostscript-9.25~dfsg+1/base/shc.h --- ghostscript-9.10~dfsg/base/shc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/shc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -74,7 +74,7 @@ stream_hc_state_common; } stream_hc_state; -#define hc_bits_size (arch_sizeof_int * 8) +#define hc_bits_size (ARCH_SIZEOF_INT * 8) #define s_hce_init_inline(ss)\ ((ss)->bits = 0, (ss)->bits_left = hc_bits_size) #define s_hcd_init_inline(ss)\ diff -Nru ghostscript-9.10~dfsg/base/sidscale.c ghostscript-9.25~dfsg+1/base/sidscale.c --- ghostscript-9.10~dfsg/base/sidscale.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sidscale.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -88,23 +88,34 @@ ss->dda_x = ss->dda_x_init; if_debug1m('W', ss->memory, "[W]idownscale_x color %d:", c); - for ( i = 0; i < WidthIn; tp += Colors) { - int endx; - dda_next_assign(ss->dda_x, endx); - if (firstline) - *tp = *pp; - else { - if ((polarity_additive && (*pp < *tp)) || - (!polarity_additive && (*pp > *tp)) ) + if (polarity_additive) { + for ( i = 0; i < WidthIn; tp += Colors) { + int endx; + dda_next_assign(ss->dda_x, endx); + if (firstline || *pp < *tp) *tp = *pp; + i++; pp += Colors; + while (i < endx) { + if (*pp < *tp) + *tp = *pp; + i++; pp += Colors; + } + if_debug1m('W', ss->memory, " %d", *tp); } - i++; pp += Colors; - while (i < endx) { - if (*pp < *tp) + } else { + for ( i = 0; i < WidthIn; tp += Colors) { + int endx; + dda_next_assign(ss->dda_x, endx); + if (firstline || *pp > *tp) *tp = *pp; - i++; pp += Colors; + i++; pp += Colors; + while (i < endx) { + if (*pp > *tp) + *tp = *pp; + i++; pp += Colors; + } + if_debug1m('W', ss->memory, " %d", *tp); } - if_debug1m('W', ss->memory, " %d", *tp); } if_debug0m('W', ss->memory, "\n"); } @@ -116,23 +127,34 @@ ss->dda_x = ss->dda_x_init; if_debug1m('W', ss->memory, "[W]idownscale_x color %d:", c); - for ( i = 0; i < WidthIn; tp += Colors) { - int endx; - dda_next_assign(ss->dda_x,endx); - if (firstline) - *tp = *pp; - else { - if ((polarity_additive && (*pp < *tp)) || - (!polarity_additive && (*pp > *tp)) ) + if (polarity_additive) { + for ( i = 0; i < WidthIn; tp += Colors) { + int endx; + dda_next_assign(ss->dda_x,endx); + if (firstline || *pp < *tp) *tp = *pp; + i++; pp += Colors; + while (i < endx) { + if (*pp < *tp) + *tp = *pp; + i++; pp += Colors; + } + if_debug1m('W', ss->memory, " %d", *tp); } - i++; pp += Colors; - while (i < endx) { - if (*pp < *tp) + } else { + for ( i = 0; i < WidthIn; tp += Colors) { + int endx; + dda_next_assign(ss->dda_x,endx); + if (firstline || *pp > *tp) *tp = *pp; - i++; pp += Colors; + i++; pp += Colors; + while (i < endx) { + if (*pp > *tp) + *tp = *pp; + i++; pp += Colors; + } + if_debug1m('W', ss->memory, " %d", *tp); } - if_debug1m('W', ss->memory, " %d", *tp); } if_debug0m('W', ss->memory, "\n"); } @@ -263,8 +285,8 @@ /* Check whether we need to deliver any output. */ top: - ss->params.Active = (ss->src_y >= ss->params.TopMargin && - ss->src_y <= ss->params.TopMargin + ss->params.PatchHeightIn); + ss->params.Active = (ss->src_y >= ss->params.TopMarginIn && + ss->src_y <= ss->params.TopMarginIn + ss->params.PatchHeightIn); if (cur_y > ss->dst_y) { /* Deliver some or all of the current scaled row. */ diff -Nru ghostscript-9.10~dfsg/base/sidscale.h ghostscript-9.25~dfsg+1/base/sidscale.h --- ghostscript-9.10~dfsg/base/sidscale.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sidscale.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/siinterp.c ghostscript-9.25~dfsg+1/base/siinterp.c --- ghostscript-9.10~dfsg/base/siinterp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/siinterp.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/siinterp.h ghostscript-9.25~dfsg+1/base/siinterp.h --- ghostscript-9.10~dfsg/base/siinterp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/siinterp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/simscale.c ghostscript-9.25~dfsg+1/base/simscale.c --- ghostscript-9.10~dfsg/base/simscale.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/simscale.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/simscale.h ghostscript-9.25~dfsg+1/base/simscale.h --- ghostscript-9.10~dfsg/base/simscale.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/simscale.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/siscale.c ghostscript-9.25~dfsg+1/base/siscale.c --- ghostscript-9.10~dfsg/base/siscale.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/siscale.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,6 +22,7 @@ #include "gdebug.h" #include "strimpl.h" #include "siscale.h" +#include "gxfrac.h" /* * Image scaling code is based on public domain code from @@ -30,9 +31,13 @@ /* ---------------- ImageScaleEncode/Decode ---------------- */ +#define CONTRIB_SHIFT 12 +#define CONTRIB_SCALE (1<n; - const byte *pp = raster + clp->first_pixel; - const CONTRIB *cp = items + clp->index; - - switch ( Colors ) { - case 1: - for ( ; j > 0; pp += 1, ++cp, --j ) - weight += *pp * cp->weight; - break; - case 3: - for ( ; j > 0; pp += 3, ++cp, --j ) - weight += *pp * cp->weight; - break; - default: - for ( ; j > 0; pp += Colors, ++cp, --j ) - weight += *pp * cp->weight; - } - pixel = (int)(weight + 0.5); - if_debug1('W', " %g", weight); - *tp = (byte)CLAMP(pixel, 0, 255); - } - } else { /* sizeofPixelIn == 2 */ - const bits16 *raster = (const bits16 *)src + c; - for ( i = 0; i < tmp_width; tp += Colors, ++clp, ++i ) { - double weight = 0; - int pixel, j = clp->n; - const bits16 *pp = raster + clp->first_pixel; - const CONTRIB *cp = items + clp->index; - - switch ( Colors ) { - case 1: - for ( ; j > 0; pp += 1, ++cp, --j ) - weight += *pp * cp->weight; - break; - case 3: - for ( ; j > 0; pp += 3, ++cp, --j ) - weight += *pp * cp->weight; - break; - default: - for ( ; j > 0; pp += Colors, ++cp, --j ) - weight += *pp * cp->weight; - } - pixel = (int)(weight + 0.5); - if_debug1('W', " %g", weight); - *tp = (byte)CLAMP(pixel, 0, 255); + for ( i = 0; i < tmp_width; tp += Colors, ++clp, ++i ) { + int weight = 0; + int j = clp->n; + const byte *gs_restrict pp = raster + clp->first_pixel; + const CONTRIB *gs_restrict cp = items + clp->index; + + for ( ; j > 0; pp += Colors, ++cp, --j ) + weight += *pp * cp->weight; + weight = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", weight); + *tp = (byte)CLAMP(weight, 0, 255); + } + if_debug0('W', "\n"); + } +} + +static void +zoom_x1_1(byte * gs_restrict tmp, const void /*PixelIn */ * gs_restrict src, + int skip, int tmp_width, int Colors, const CLIST * gs_restrict contrib, + const CONTRIB * gs_restrict items) +{ + contrib += skip; + tmp += Colors * skip; + + if_debug0('W', "[W]zoom_x:"); + + for ( ; tmp_width != 0; --tmp_width ) { + int j = contrib->n; + const byte *gs_restrict pp = ((const byte *)src) + contrib->first_pixel; + const CONTRIB *gs_restrict cp = items + (contrib++)->index; + int weight0 = 0; + + for ( ; j > 0; --j ) { + weight0 += *pp++ * (cp++)->weight; + } + if_debug1('W', " %x", weight0); + weight0 = (weight0 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + *tmp++ = (byte)CLAMP(weight0, 0, 255); + } + if_debug0('W', "\n"); +} + +static void +zoom_x1_3(byte * gs_restrict tmp, const void /*PixelIn */ * gs_restrict src, + int skip, int tmp_width, int Colors, const CLIST * gs_restrict contrib, + const CONTRIB * gs_restrict items) +{ + contrib += skip; + tmp += Colors * skip; + + if_debug0('W', "[W]zoom_x:"); + + for ( ; tmp_width != 0; --tmp_width ) { + int j = contrib->n; + const byte *gs_restrict pp = ((const byte *)src) + contrib->first_pixel; + const CONTRIB *gs_restrict cp = items + (contrib++)->index; + int weight0 = 0; + int weight1 = 0; + int weight2 = 0; + + for ( ; j > 0; --j ) { + int weight = (cp++)->weight; + weight0 += *pp++ * weight; + weight1 += *pp++ * weight; + weight2 += *pp++ * weight; + } + if_debug3('W', " (%x %x %x)", weight0, weight1, weight2); + weight0 = (weight0 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + weight1 = (weight1 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + weight2 = (weight2 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + *tmp++ = (byte)CLAMP(weight0, 0, 255); + *tmp++ = (byte)CLAMP(weight1, 0, 255); + *tmp++ = (byte)CLAMP(weight2, 0, 255); + } + if_debug0('W', "\n"); +} + +static void +zoom_x1_4(byte * gs_restrict tmp, const void /*PixelIn */ * gs_restrict src, + int skip, int tmp_width, int Colors, const CLIST * gs_restrict contrib, + const CONTRIB * gs_restrict items) +{ + contrib += skip; + tmp += Colors * skip; + + if_debug0('W', "[W]zoom_x:"); + + for ( ; tmp_width != 0; --tmp_width ) { + int j = contrib->n; + const byte *gs_restrict pp = ((const byte *)src) + contrib->first_pixel; + const CONTRIB *gs_restrict cp = items + (contrib++)->index; + int weight0 = 0; + int weight1 = 0; + int weight2 = 0; + int weight3 = 0; + + for ( ; j > 0; --j ) { + int weight = (cp++)->weight; + weight0 += *pp++ * weight; + weight1 += *pp++ * weight; + weight2 += *pp++ * weight; + weight3 += *pp++ * weight; + } + if_debug4('W', " (%x %x %x %x)", weight0, weight1, weight2, weight3); + weight0 = (weight0 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + weight1 = (weight1 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + weight2 = (weight2 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + weight3 = (weight3 + CONTRIB_ROUND)>>CONTRIB_SHIFT; + *tmp++ = (byte)CLAMP(weight0, 0, 255); + *tmp++ = (byte)CLAMP(weight1, 0, 255); + *tmp++ = (byte)CLAMP(weight2, 0, 255); + *tmp++ = (byte)CLAMP(weight3, 0, 255); + } + if_debug0('W', "\n"); +} + +static void +zoom_x2(byte * gs_restrict tmp, const void /*PixelIn */ * gs_restrict src, + int skip, int tmp_width, int Colors, const CLIST * gs_restrict contrib, + const CONTRIB * gs_restrict items) +{ + int c, i; + + contrib += skip; + tmp += Colors * skip; + + for (c = 0; c < Colors; ++c) { + byte *gs_restrict tp = tmp + c; + const CLIST *gs_restrict clp = contrib; + const bits16 *gs_restrict raster = (const bits16 *)src + c; + + if_debug1('W', "[W]zoom_x color %d:", c); + for ( i = 0; i < tmp_width; tp += Colors, ++clp, ++i ) { + int weight = 0; + int j = clp->n; + const bits16 *gs_restrict pp = raster + clp->first_pixel; + const CONTRIB *gs_restrict cp = items + clp->index; + + switch ( Colors ) { + case 1: + for ( ; j > 0; pp += 1, ++cp, --j ) + weight += *pp * cp->weight; + break; + case 3: + for ( ; j > 0; pp += 3, ++cp, --j ) + weight += *pp * cp->weight; + break; + default: + for ( ; j > 0; pp += Colors, ++cp, --j ) + weight += *pp * cp->weight; } + weight = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", weight); + *tp = (byte)CLAMP(weight, 0, 255); } if_debug0('W', "\n"); } @@ -356,53 +483,369 @@ * This is simpler because we can treat all columns identically * without regard to the number of samples per pixel. */ +static inline void +zoom_y1_4(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + int w0 = cbp[0].weight; + int w1 = cbp[1].weight; + int w2 = cbp[2].weight; + int w3 = cbp[3].weight; + byte *gs_restrict d; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((byte *)dst)+skip; + for (; width > 0; width--) { + int weight; + + weight = tmp[ 0] * w0; + weight += tmp[ kn] * w1; + weight += tmp[2*kn] * w2; + weight += tmp[3*kn] * w3; + tmp++; + + weight = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", weight); + *d++ = (byte)CLAMP(weight, 0, 0xff); + } + if_debug0('W', "\n"); +} +static inline void +zoom_y1_5(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + int w0 = cbp[0].weight; + int w1 = cbp[1].weight; + int w2 = cbp[2].weight; + int w3 = cbp[3].weight; + int w4 = cbp[4].weight; + byte *gs_restrict d; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((byte *)dst)+skip; + for (; width > 0; width--) { + int weight; + + weight = tmp[ 0] * w0; + weight += tmp[ kn] * w1; + weight += tmp[2*kn] * w2; + weight += tmp[3*kn] * w3; + weight += tmp[4*kn] * w4; + tmp++; + + weight = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", weight); + *d++ = (byte)CLAMP(weight, 0, 0xff); + } + if_debug0('W', "\n"); +} +static inline void +template_zoom_y1(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items, int n) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int cn = contrib->n; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + byte *gs_restrict d; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((byte *)dst)+skip; + for (; width > 0; width--) { + int weight = 0; + const byte *gs_restrict pp = tmp++; + int pixel, j; + const CONTRIB *cp = cbp; + + for (j = cn; j > 0; pp += kn, ++cp, --j) + weight += *pp * cp->weight; + pixel = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", pixel); + *d++ = (byte)CLAMP(pixel, 0, 0xff); + } + if_debug0('W', "\n"); +} + +static void zoom_y1(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + switch(contrib->n) { + case 4: + zoom_y1_4(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + case 5: + zoom_y1_5(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + default: + template_zoom_y1(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items, contrib->n); + break; + } +} + +static inline void +zoom_y2_4(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + bits16 *gs_restrict d; + int w0 = cbp[0].weight; + int w1 = cbp[1].weight; + int w2 = cbp[2].weight; + int w3 = cbp[3].weight; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((bits16 *)dst) + skip; + for (; width > 0; width--) { + int weight; + int pixel; + + weight = tmp[ 0] * w0; + weight += tmp[ kn] * w1; + weight += tmp[2*kn] * w2; + weight += tmp[3*kn] * w3; + tmp++; + pixel = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", pixel); + *d++ = (bits16)CLAMP(pixel, 0, 0xffff); + } + if_debug0('W', "\n"); +} +static inline void +zoom_y2_5(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + bits16 *gs_restrict d; + int w0 = cbp[0].weight; + int w1 = cbp[1].weight; + int w2 = cbp[2].weight; + int w3 = cbp[3].weight; + int w4 = cbp[4].weight; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((bits16 *)dst) + skip; + for (; width > 0; width--) { + int weight; + int pixel; + + weight = tmp[ 0] * w0; + weight += tmp[ kn] * w1; + weight += tmp[2*kn] * w2; + weight += tmp[3*kn] * w3; + weight += tmp[4*kn] * w4; + tmp++; + pixel = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", pixel); + *d++ = (bits16)CLAMP(pixel, 0, 0xffff); + } + if_debug0('W', "\n"); +} +static inline void +zoom_y2_n(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int cn = contrib->n; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + bits16 *gs_restrict d; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((bits16 *)dst) + skip; + for (; width > 0; width--) { + int weight = 0; + const byte *gs_restrict pp = tmp++; + int pixel, j; + const CONTRIB *gs_restrict cp = cbp; + + for (j = cn; j > 0; pp += kn, ++cp, --j) + weight += *pp * cp->weight; + pixel = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", pixel); + *d++ = (bits16)CLAMP(pixel, 0, 0xffff); + } + if_debug0('W', "\n"); +} static void -zoom_y(void /*PixelOut */ *dst, int sizeofPixelOut, uint MaxValueOut, - const byte * tmp, int skip, int WidthOut, int Stride, - int Colors, const CLIST * contrib, const CONTRIB * items) +zoom_y2(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + switch (contrib->n) { + case 4: + zoom_y2_4(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + case 5: + zoom_y2_5(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + default: + zoom_y2_n(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + } +} + +static inline void +zoom_y2_frac_4(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + bits16 *gs_restrict d; + int w0 = cbp[0].weight; + int w1 = cbp[1].weight; + int w2 = cbp[2].weight; + int w3 = cbp[3].weight; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((bits16 *)dst) + skip; + for (; width > 0; width--) { + int weight; + int pixel; + + weight = tmp[ 0] * w0; + weight += tmp[ kn] * w1; + weight += tmp[2*kn] * w2; + weight += tmp[3*kn] * w3; + tmp++; + pixel = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", pixel); + *d++ = (bits16)CLAMP(pixel, 0, frac_1); + } + if_debug0('W', "\n"); +} +static inline void +zoom_y2_frac_5(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + int kn = Stride * Colors; + int width = WidthOut * Colors; + int first_pixel = contrib->first_pixel; + const CONTRIB *gs_restrict cbp = items + contrib->index; + bits16 *gs_restrict d; + int w0 = cbp[0].weight; + int w1 = cbp[1].weight; + int w2 = cbp[2].weight; + int w3 = cbp[3].weight; + int w4 = cbp[4].weight; + + if_debug0('W', "[W]zoom_y: "); + + skip *= Colors; + tmp += first_pixel + skip; + d = ((bits16 *)dst) + skip; + for (; width > 0; width--) { + int weight; + int pixel; + + weight = tmp[ 0] * w0; + weight += tmp[ kn] * w1; + weight += tmp[2*kn] * w2; + weight += tmp[3*kn] * w3; + weight += tmp[4*kn] * w4; + tmp++; + pixel = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", pixel); + *d++ = (bits16)CLAMP(pixel, 0, frac_1); + } + if_debug0('W', "\n"); +} +static inline void +zoom_y2_frac_n(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) { int kn = Stride * Colors; int width = WidthOut * Colors; int cn = contrib->n; int first_pixel = contrib->first_pixel; - const CONTRIB *cbp = items + contrib->index; - int kc; - int max_weight = MaxValueOut; + const CONTRIB *gs_restrict cbp = items + contrib->index; + bits16 *gs_restrict d; if_debug0('W', "[W]zoom_y: "); skip *= Colors; - width += skip; - if (sizeofPixelOut == 1) { - for ( kc = skip; kc < width; ++kc ) { - double weight = 0; - const byte *pp = &tmp[kc + first_pixel]; - int pixel, j = cn; - const CONTRIB *cp = cbp; - - for ( ; j > 0; pp += kn, ++cp, --j ) - weight += *pp * cp->weight; - pixel = (int)(weight + 0.5); - if_debug1('W', " %x", pixel); - ((byte *)dst)[kc] = (byte)CLAMP(pixel, 0, max_weight); - } - } else { /* sizeofPixelOut == 2 */ - for ( kc = skip; kc < width; ++kc ) { - double weight = 0; - const byte *pp = &tmp[kc + first_pixel]; - int pixel, j = cn; - const CONTRIB *cp = cbp; - - for ( ; j > 0; pp += kn, ++cp, --j ) - weight += *pp * cp->weight; - pixel = (int)(weight + 0.5); - if_debug1('W', " %x", pixel); - ((bits16 *)dst)[kc] = (bits16)CLAMP(pixel, 0, max_weight); - } + tmp += first_pixel + skip; + d = ((bits16 *)dst) + skip; + for (; width > 0; width--) { + int weight = 0; + const byte *gs_restrict pp = tmp++; + int pixel, j; + const CONTRIB *gs_restrict cp = cbp; + + for (j = cn; j > 0; pp += kn, ++cp, --j) + weight += *pp * cp->weight; + pixel = (weight + CONTRIB_ROUND)>>CONTRIB_SHIFT; + if_debug1('W', " %x", pixel); + *d++ = (bits16)CLAMP(pixel, 0, frac_1); } if_debug0('W', "\n"); } +static void +zoom_y2_frac(void /*PixelOut */ * gs_restrict dst, + const byte * gs_restrict tmp, int skip, int WidthOut, int Stride, + int Colors, const CLIST * gs_restrict contrib, const CONTRIB * gs_restrict items) +{ + switch (contrib->n) { + case 4: + zoom_y2_frac_4(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + case 5: + zoom_y2_frac_5(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + default: + zoom_y2_frac_n(dst, tmp, skip, WidthOut, Stride, Colors, contrib, items); + break; + } +} /* ------ Stream implementation ------ */ /* Forward references */ @@ -412,11 +855,15 @@ static void calculate_dst_contrib(stream_IScale_state * ss, int y) { - uint row_size = ss->params.WidthOut * ss->params.spp_interp; + + int abs_interp_limit = ss->params.abs_interp_limit; + int limited_WidthOut = (ss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_EntireHeightOut = (ss->params.EntireHeightOut + abs_interp_limit - 1) / abs_interp_limit; + uint row_size = limited_WidthOut * ss->params.spp_interp; int last_index = calculate_contrib(&ss->dst_next_list, ss->dst_items, - (double)ss->params.EntireHeightOut / ss->params.EntireHeightIn, - y, ss->src_y_offset, ss->params.EntireHeightOut, ss->params.EntireHeightIn, + (double)limited_EntireHeightOut / ss->params.EntireHeightIn, + y, ss->src_y_offset, limited_EntireHeightOut, ss->params.EntireHeightIn, 1, ss->params.HeightIn, ss->max_support, row_size, (double)ss->params.MaxValueOut / 255, ss->filter_width, ss->filter, ss->min_scale); @@ -436,7 +883,7 @@ i >= first_index_mod ? ss->dst_items[i - first_index_mod].weight : 0); - if_debug1m('W', ss->memory, " %f", shuffle[i].weight); + if_debug1m('W', ss->memory, " %d", shuffle[i].weight); } memcpy(ss->dst_items, shuffle, ss->max_support * sizeof(CONTRIB)); ss->dst_next_list.n = ss->max_support; @@ -445,7 +892,7 @@ if_debug0m('W', ss->memory, "\n"); } -/* Set default parameter values (actually, just clear pointers). */ +/* Set default parameter values (actually, just clear pointers) */ static void s_IScale_set_defaults(stream_state * st) { @@ -473,6 +920,11 @@ { stream_IScale_state *const ss = (stream_IScale_state *) st; gs_memory_t *mem = ss->memory; + int abs_interp_limit = ss->params.abs_interp_limit; + int limited_WidthOut = (ss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_HeightOut = (ss->params.HeightOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_EntireWidthOut = (ss->params.EntireWidthOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_EntireHeightOut = (ss->params.EntireHeightOut + abs_interp_limit - 1) / abs_interp_limit; ss->sizeofPixelIn = ss->params.BitsPerComponentIn / 8; ss->sizeofPixelOut = ss->params.BitsPerComponentOut / 8; @@ -483,32 +935,30 @@ ss->src_offset = 0; ss->dst_y = 0; ss->src_y_offset = ss->params.src_y_offset; - ss->dst_size = - ss->params.WidthOut * ss->sizeofPixelOut * ss->params.spp_interp; + ss->dst_size = limited_WidthOut * ss->sizeofPixelOut * ss->params.spp_interp; ss->dst_offset = 0; /* create intermediate image to hold horizontal zoom */ - ss->max_support = vert->contrib_pixels((double)ss->params.EntireHeightOut/ - ss->params.EntireHeightIn); + ss->max_support = vert->contrib_pixels((double)limited_EntireHeightOut / + (abs_interp_limit * ss->params.EntireHeightIn)); ss->filter_width = vert->filter_width; ss->filter = vert->filter; ss->min_scale = vert->min_scale; ss->tmp = (byte *) gs_alloc_byte_array(mem, ss->max_support, - (ss->params.WidthOut * - ss->params.spp_interp), + (limited_WidthOut * ss->params.spp_interp), "image_scale tmp"); ss->contrib = (CLIST *) gs_alloc_byte_array(mem, - max(ss->params.WidthOut, - ss->params.HeightOut), + max(limited_WidthOut, + limited_HeightOut), sizeof(CLIST), "image_scale contrib"); ss->items = (CONTRIB *) gs_alloc_byte_array(mem, (horiz->contrib_pixels( - (double)ss->params.EntireWidthOut / + (double)limited_EntireWidthOut / ss->params.EntireWidthIn) * - ss->params.WidthOut), + limited_WidthOut), sizeof(CONTRIB), "image_scale contrib[*]"); ss->dst_items = (CONTRIB *) gs_alloc_byte_array(mem, @@ -516,7 +966,7 @@ sizeof(CONTRIB), "image_scale contrib_dst[*]"); /* Allocate buffers for 1 row of source and destination. */ ss->dst = - gs_alloc_byte_array(mem, ss->params.WidthOut * ss->params.spp_interp, + gs_alloc_byte_array(mem, limited_WidthOut * ss->params.spp_interp, ss->sizeofPixelOut, "image_scale dst"); ss->src = gs_alloc_byte_array(mem, ss->params.WidthIn * ss->params.spp_interp, @@ -536,21 +986,46 @@ * the line buffer). These cause valgrind to be upset. To avoid * this, we preset the buffer to known values. */ memset((byte *)ss->tmp, 0, - ss->max_support * ss->params.WidthOut * ss->params.spp_interp); + ss->max_support * limited_WidthOut * ss->params.spp_interp); #endif /* Pre-calculate filter contributions for a row. */ calculate_contrib(ss->contrib, ss->items, - (double)ss->params.EntireWidthOut / ss->params.EntireWidthIn, - 0, 0, ss->params.WidthOut, ss->params.WidthIn, - ss->params.WidthOut, ss->params.WidthIn, ss->params.WidthIn, + (double)limited_EntireWidthOut / ss->params.EntireWidthIn, + 0, 0, limited_WidthOut, ss->params.WidthIn, + limited_WidthOut, ss->params.WidthIn, ss->params.WidthIn, ss->params.spp_interp, 255. / ss->params.MaxValueIn, horiz->filter_width, horiz->filter, horiz->min_scale); /* Prepare the weights for the first output row. */ calculate_dst_contrib(ss, 0); - return 0; + if (ss->sizeofPixelIn == 2) + ss->zoom_x = zoom_x2; + else { + switch (ss->params.spp_interp) { + case 1: + ss->zoom_x = zoom_x1_1; + break; + case 3: + ss->zoom_x = zoom_x1_3; + break; + case 4: + ss->zoom_x = zoom_x1_4; + break; + default: + ss->zoom_x = zoom_x1; + break; + } + } + if (ss->sizeofPixelOut == 1) + ss->zoom_y = zoom_y1; + else if (ss->params.MaxValueOut == frac_1) + ss->zoom_y = zoom_y2_frac; + else + ss->zoom_y = zoom_y2; + + return 0; } static const filter_defn_s Mitchell_defn = @@ -575,13 +1050,16 @@ stream_IScale_state *const ss = (stream_IScale_state *) st; const filter_defn_s *horiz = &Mitchell_defn; const filter_defn_s *vert = &Mitchell_defn; + int abs_interp_limit = ss->params.abs_interp_limit; + int limited_EntireWidthOut = (ss->params.EntireWidthOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_EntireHeightOut = (ss->params.EntireHeightOut + abs_interp_limit - 1) / abs_interp_limit; /* By default we use the mitchell filter, but if we are scaling down * (either on the horizontal or the vertical axis) then use the simple * interpolation filter for that axis. */ - if (ss->params.EntireWidthOut < ss->params.EntireWidthIn) + if (limited_EntireWidthOut < ss->params.EntireWidthIn) horiz = &Interp_defn; - if (ss->params.EntireHeightOut < ss->params.EntireHeightIn) + if (limited_EntireHeightOut < ss->params.EntireHeightIn) vert = &Interp_defn; return do_init(st, horiz, vert); @@ -593,18 +1071,23 @@ stream_cursor_write * pw, bool last) { stream_IScale_state *const ss = (stream_IScale_state *) st; + int abs_interp_limit = ss->params.abs_interp_limit; + int limited_WidthOut = (ss->params.WidthOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_HeightOut = (ss->params.HeightOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_PatchWidthOut = (ss->params.PatchWidthOut + abs_interp_limit - 1) / abs_interp_limit; + int limited_LeftMarginOut = (ss->params.LeftMarginOut) / abs_interp_limit; /* Check whether we need to deliver any output. */ top: - ss->params.Active = (ss->src_y >= ss->params.TopMargin && - ss->src_y <= ss->params.TopMargin + ss->params.PatchHeightIn); + ss->params.Active = (ss->src_y >= ss->params.TopMarginIn && + ss->src_y <= ss->params.TopMarginIn + ss->params.PatchHeightIn); while (ss->src_y > ss->dst_last_index) { /* We have enough horizontally scaled temporary rows */ /* to generate a vertically scaled output row. */ uint wleft = pw->limit - pw->ptr; - if (ss->dst_y == ss->params.HeightOut) + if (ss->dst_y == limited_HeightOut) return EOFC; if (wleft == 0) return 1; @@ -619,13 +1102,11 @@ } /* Apply filter to zoom vertically from tmp to dst. */ if (ss->params.Active) - zoom_y(row, /* Where to scale to */ - ss->sizeofPixelOut, /* 1 (8 bit) or 2 (16bit) output */ - ss->params.MaxValueOut, /* output value scale */ + ss->zoom_y(row, /* Where to scale to */ ss->tmp, /* Line buffer */ - ss->params.LeftMarginOut, /* Skip */ - ss->params.PatchWidthOut, /* How many pixels to produce */ - ss->params.WidthOut, /* Stride */ + limited_LeftMarginOut, /* Skip */ + limited_PatchWidthOut, /* How many pixels to produce */ + limited_WidthOut, /* Stride */ ss->params.spp_interp, /* Color count */ &ss->dst_next_list, ss->dst_items); /* Idiotic C coercion rules allow T* and void* to be */ @@ -647,7 +1128,7 @@ } /* Advance to the next output row. */ adv:++ss->dst_y; - if (ss->dst_y != ss->params.HeightOut) + if (ss->dst_y != limited_HeightOut) calculate_dst_contrib(ss, ss->dst_y); } @@ -678,13 +1159,12 @@ if_debug2('w', "[w]zoom_x y = %d to tmp row %d\n", ss->src_y, (ss->src_y % ss->max_support)); if (ss->params.Active) - zoom_x(/* Where to scale to (dst line address in tmp buffer) */ + ss->zoom_x(/* Where to scale to (dst line address in tmp buffer) */ ss->tmp + (ss->src_y % ss->max_support) * - ss->params.WidthOut * ss->params.spp_interp, + limited_WidthOut * ss->params.spp_interp, row, /* Where to scale from */ - ss->sizeofPixelIn, /* 1 (8 bit) or 2 (16bit) */ - ss->params.LeftMarginOut, /* Line skip */ - ss->params.PatchWidthOut, /* How many pixels to produce */ + limited_LeftMarginOut, /* Line skip */ + limited_PatchWidthOut, /* How many pixels to produce */ ss->params.spp_interp, /* Color count */ ss->contrib, ss->items); pr->ptr += rcount; diff -Nru ghostscript-9.10~dfsg/base/siscale.h ghostscript-9.25~dfsg+1/base/siscale.h --- ghostscript-9.10~dfsg/base/siscale.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/siscale.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sisparam.h ghostscript-9.25~dfsg+1/base/sisparam.h --- ghostscript-9.10~dfsg/base/sisparam.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sisparam.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,6 +20,8 @@ #ifndef sisparam_INCLUDED # define sisparam_INCLUDED +#include "gxfixed.h" /* for fixed */ +#include "gxdda.h" /* for gx_dda_fixed_point */ /* * Image scaling streams all use a common set of parameters to define the * input and output data. That is what we define here. @@ -56,33 +58,108 @@ * Finally, we may actually only be rendering a smaller 'patch' of this * due to restriction by a clip path etc (say 16x16) - this size is * PatchWidthIn by PatchHeightIn, and would scale to be PatchWidthOut by - * PatchHeightOut. + * PatchHeightOut. We don't really need PatchHeightOut. + * + * There is one additional complication: Due to the 'support' requirements + * of the scalers, we need to decode a slightly larger area than we + * might think. Accordingly, we are fed 2 different rectangles. drect + * tell us the area that must be decoded - we use this to calculate + * the 'In' values. rrect tells us the area that must be rendered - we + * use this to calculate the 'Out' values. + * + * Scale from: + * + * <-------------------EntireWidthIn---------------------> + * +-----------------------------------------------------+ ^ + * | Conceptual Source Image ^ | | + * | | | | + * | src_y_offset | | + * | | | | + * |<-SX-><--------------WidthIn--------------> v | | + * | +-penum->rect-----------------------+ ^ | | + * | | ^ | | | EntireHeightIn + * | | | | | | | + * | | TopMarginIn | | | | + * | | | | | | | + * | | v | | | | + * | | +-penum->drect--+ | | | | + * | | | ^ | | HeightIn | | + * | | | | | | | | | + * | |<-LeftMarginIn->| PatchHeightIn | | | | | + * | | | | | | | | | + * | | | v | | | | | + * | | +---------------+ | | | | + * | | <-PatchWidthIn--> | | | | + * | +-----------------------------------+ v | | + * | | | + * +-----------------------------------------------------+ v + * + * To: + * + * <--------------------EntireWidthOut----------------------> + * +--------------------------------------------------------+ ^ + * | Conceptual Destination Image ^ | | + * | | | | + * | DY | | + * | | | | + * |<-DX-><---------------WidthOut--------------> v | | + * | +-------------------------------------+ ^ | | + * | | ^ | | | EntireHeightOut + * | | | | | | | + * | | TopMarginOut | | | | + * | | | | | | | + * | | v | | | | + * | | +-penum->rrect*--+ | | | | + * | | | ^ | | HeightOut | | + * | | | | | | | | | + * | |<-LeftMarginOut->| PatchHeightOut | | | | | + * | | | | | | | | | + * | | | v | | | | | + * | | +----------------+ | | | | + * | | <-PatchWidthOut--> | | | | + * | +-------------------------------------+ v | | + * | | | + * +--------------------------------------------------------+ v + * + * * Note that this rectangle is derived from penum->rrect, + * with appropriate scale factors! + * + * Certain values in this diagram are not currently used within + * gs. DX and SX are always 0, due to banding cutting only on + * Y. If there are cases where the clist code is truncating + * the width of images, then we will be getting incorrect (read + * "marginally sub optimal") results. DY is not supplied, which + * I suspect leads to each band being potentially off by a subpixel + * amount in the Y direction. */ typedef struct stream_image_scale_params_s { int spp_decode; /* >= 1 */ int spp_interp; /* If we do CM first, may not equal spp_decode */ /* 0 < MaxValueIn < 1 << BitsPerComponentIn */ - int PatchWidthIn, PatchHeightIn; /* The sizes we need to render > 0 */ - int PatchWidthOut, PatchHeightOut; /* The sizes we need to render > 0 */ int BitsPerComponentIn; /* bits per input value, 8 or 16 */ uint MaxValueIn; /* max value of input component, */ int BitsPerComponentOut; /* bits per output value, 8 or 16 */ uint MaxValueOut; /* max value of output component, */ /* 0 < MaxValueOut < 1 << BitsPerComponentOut*/ - int WidthIn, HeightIn; /* The sizes for which we get data > 0 */ - int WidthOut, HeightOut; /* > 0 */ bool ColorPolarityAdditive; /* needed by SpecialDownScale filter */ + bool early_cm; /* If this is set, then we will perform + color managment before interpolating */ int src_y_offset; /* Offset of the subimage (data) in the source image. */ + int abs_interp_limit; /* limitation of how far to interpolate */ int EntireWidthIn; /* Height of entire input image. */ int EntireHeightIn; /* Height of entire input image. */ int EntireWidthOut; /* Height of entire output image. */ int EntireHeightOut; /* Height of entire output image. */ - bool early_cm; /* If this is set, then we will perform - color managment before interpolating */ + int WidthIn, HeightIn; /* The sizes for which we get data > 0 */ + int WidthOut, HeightOut; /* > 0 */ + int PatchWidthIn, PatchHeightIn; /* The sizes we need to render > 0 (source) */ + int PatchWidthOut, PatchHeightOut; /* The sizes we need to render > 0 (destination) */ int LeftMarginIn; int LeftMarginOut; - int TopMargin; + int TopMarginIn; + int TopMarginOut; int Active; + gx_dda_fixed_point scale_dda; /* used to scale limited interpolation up to actual size */ } stream_image_scale_params_t; /* Define a generic image scaling stream state. */ diff -Nru ghostscript-9.10~dfsg/base/sjbig2.c ghostscript-9.25~dfsg+1/base/sjbig2.c --- ghostscript-9.10~dfsg/base/sjbig2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjbig2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -39,15 +39,13 @@ private_st_jbig2decode_state(); /* creates a gc object for our state, defined in sjbig2.h */ /* error callback for jbig2 decoder */ -static int -s_jbig2decode_error(void *error_callback_data, const char *msg, Jbig2Severity severity, +static void +s_jbig2decode_error(void *callback_data, const char *msg, Jbig2Severity severity, int32_t seg_idx) { - stream_jbig2decode_state *const state = - (stream_jbig2decode_state *) error_callback_data; + s_jbig2_callback_data_t *error_data = (s_jbig2_callback_data_t *)callback_data; const char *type; char segment[22]; - int code = 0; switch (severity) { case JBIG2_SEVERITY_DEBUG: @@ -59,26 +57,25 @@ case JBIG2_SEVERITY_FATAL: type = "FATAL ERROR decoding image:"; /* pass the fatal error upstream if possible */ - code = gs_error_ioerror; - if (state != NULL) state->error = code; + if (error_data != NULL) error_data->error = gs_error_ioerror; break;; default: type = "unknown message:"; break;; } if (seg_idx == -1) segment[0] = '\0'; else gs_sprintf(segment, "(segment 0x%02x)", seg_idx); - if (state) + if (error_data) { - if (severity == JBIG2_SEVERITY_FATAL) { - dmlprintf3(state->memory, "jbig2dec %s %s %s\n", type, msg, segment); + if (severity == JBIG2_SEVERITY_FATAL || severity == JBIG2_SEVERITY_WARNING) { + dmlprintf3(error_data->memory, "jbig2dec %s %s %s\n", type, msg, segment); } else { - if_debug3m('w', state->memory, "[w] jbig2dec %s %s %s\n", type, msg, segment); + if_debug3m('w', error_data->memory, "[w] jbig2dec %s %s %s\n", type, msg, segment); } } else { /* - FIXME error_callback_data should be updated so that jbig2_ctx_new is not called + FIXME s_jbig2_callback_data_t should be updated so that jbig2_ctx_new is not called with a NULL argument (see jbig2.h) and we never reach here with a NULL state */ if (severity == JBIG2_SEVERITY_FATAL) { @@ -87,8 +84,6 @@ if_debug3('w', "[w] jbig2dec %s %s %s\n", type, msg, segment); } } - - return code; } /* invert the bits in a buffer */ @@ -128,6 +123,7 @@ if (code) { /* error parsing the global stream */ + jbig2_ctx_free(ctx); *result = NULL; return code; } @@ -166,14 +162,28 @@ { stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss; Jbig2GlobalCtx *global_ctx = state->global_ctx; /* may be NULL */ - state->error = 0; + int code = 0; - /* initialize the decoder with the parsed global context if any */ - state->decode_ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, - global_ctx, s_jbig2decode_error, ss); + state->callback_data = (s_jbig2_callback_data_t *)gs_alloc_bytes( + ss->memory->non_gc_memory, + sizeof(s_jbig2_callback_data_t), + "s_jbig2decode_init(callback_data)"); + if (state->callback_data) { + state->callback_data->memory = ss->memory->non_gc_memory; + state->callback_data->error = 0; + /* initialize the decoder with the parsed global context if any */ + state->decode_ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, + global_ctx, s_jbig2decode_error, state->callback_data); + + code = state->callback_data->error; + } + else { + code = gs_error_VMerror; + } state->image = 0; - return (state->error); + + return_error (code); } /* process a section of the input and return any decoded data. @@ -202,7 +212,7 @@ jbig2_complete_page(state->decode_ctx); } /* handle fatal decoding errors reported through our callback */ - if (state->error) return state->error; + if (state->callback_data->error) return state->callback_data->error; } if (out_size > 0) { if (image == NULL) { @@ -238,11 +248,26 @@ if (state->decode_ctx) { if (state->image) jbig2_release_page(state->decode_ctx, state->image); + state->image = NULL; jbig2_ctx_free(state->decode_ctx); + state->decode_ctx = NULL; + } + if (state->callback_data) { + gs_memory_t *mem = state->callback_data->memory; + gs_free_object(mem, state->callback_data, "s_jbig2decode_release(callback_data)"); + state->callback_data = NULL; } /* the interpreter takes care of freeing the global_ctx */ } +void +s_jbig2decode_finalize(const gs_memory_t *cmem, void *vptr) +{ + (void)cmem; + + s_jbig2decode_release((stream_state *)vptr); +} + /* set stream defaults. this hook exists to avoid confusing the gc with bogus pointers. we use it similarly just to NULL all the pointers. @@ -259,7 +284,7 @@ state->decode_ctx = NULL; state->image = NULL; state->offset = 0; - state->error = 0; + state->callback_data = NULL; } /* stream template */ diff -Nru ghostscript-9.10~dfsg/base/sjbig2.h ghostscript-9.25~dfsg+1/base/sjbig2.h --- ghostscript-9.10~dfsg/base/sjbig2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjbig2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,6 +24,12 @@ #include "scommon.h" #include +typedef struct s_jbig2_callback_data_s +{ + gs_memory_t *memory; + int error; +} s_jbig2_callback_data_t; + /* See zfjbig2.c for details. */ typedef struct s_jbig2_global_data_s { void *data; @@ -38,14 +44,16 @@ Jbig2Ctx *decode_ctx; Jbig2Image *image; long offset; /* offset into the image bitmap of the next byte to be returned */ - int error; + s_jbig2_callback_data_t *callback_data; /* is allocated in non-gc memory */ } stream_jbig2decode_state; +struct_proc_finalize(s_jbig2decode_finalize); + #define private_st_jbig2decode_state() \ - gs_private_st_ptrs1(st_jbig2decode_state, stream_jbig2decode_state,\ + gs_private_st_ptrs1_final(st_jbig2decode_state, stream_jbig2decode_state,\ "jbig2decode filter state", jbig2decode_state_enum_ptrs,\ - jbig2decode_state_reloc_ptrs, global_struct) + jbig2decode_state_reloc_ptrs, s_jbig2decode_finalize, global_struct) extern const stream_template s_jbig2decode_template; /* call ins to process the JBIG2Globals parameter */ diff -Nru ghostscript-9.10~dfsg/base/sjbig2_luratech.c ghostscript-9.25~dfsg+1/base/sjbig2_luratech.c --- ghostscript-9.10~dfsg/base/sjbig2_luratech.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjbig2_luratech.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -66,12 +66,12 @@ s_jbig2decode_global_data *global = NULL; global = malloc(sizeof(*global)); - if (global == NULL) return gs_error_VMerror; + if (global == NULL) return_error(gs_error_VMerror); global->data = malloc(size); if (global->data == NULL) { free(global); - return gs_error_VMerror; + return_error(gs_error_VMerror); } memcpy(global->data, data, size); global->size = size; @@ -99,7 +99,7 @@ { stream_jbig2decode_state *state = (stream_jbig2decode_state*)ss; if (state == NULL) - return gs_error_VMerror; + return_error(gs_error_VMerror); state->global_struct = gd; if (gd != NULL) { @@ -230,7 +230,7 @@ /* allocate the input buffer if needed */ if (state->inbuf == NULL) { state->inbuf = malloc(JBIG2_BUFFER_SIZE); - if (state->inbuf == NULL) return gs_error_VMerror; + if (state->inbuf == NULL) return_error(gs_error_VMerror); state->insize = JBIG2_BUFFER_SIZE; state->infill = 0; } @@ -246,7 +246,7 @@ if_debug1m('s', state->memory, "[s]jbig2decode growing input buffer to %lu bytes\n", new_size); new = realloc(state->inbuf, new_size); - if (new == NULL) return gs_error_VMerror; + if (new == NULL) return_error(gs_error_VMerror); state->inbuf = new; state->insize = new_size; @@ -488,6 +488,7 @@ state->outsize = 0; state->outfill = 0; state->offset = 0; + state->jb2_encode = false; return 0; } @@ -504,6 +505,7 @@ long out_size = pw->limit - pw->ptr; long available, segment; JB2_Error err; + JB2_Export_Format format[] = {cJB2_Export_Format_Stream_For_PDF, cJB2_Export_Format_JB2}; /* Be greedy in filling our internal line buffer so we always make read progress on a stream. */ @@ -557,7 +559,7 @@ unfortunately we can't serialize this across process calls */ err = JB2_Document_Export_Document(state->doc, s_jbig2encode_write, state, - cJB2_Export_Format_Stream_For_PDF); + format[state->jb2_encode]); if (err != cJB2_Error_OK) return ERRC; } @@ -573,7 +575,11 @@ else return EOFC; /* all done */ } - /* something went wrong above */ + /* no data. */ + if (in_size == 0 && !last) + return 0; + + /* something went wrong above. */ return ERRC; } diff -Nru ghostscript-9.10~dfsg/base/sjbig2_luratech.h ghostscript-9.25~dfsg+1/base/sjbig2_luratech.h --- ghostscript-9.10~dfsg/base/sjbig2_luratech.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjbig2_luratech.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -74,6 +74,7 @@ unsigned long outsize; /* bytes available in the buffer */ unsigned long outfill; /* bytes written to the buffer */ unsigned long offset; /* bytes written from the buffer */ + bool jb2_encode; /* are we writing a jb2 file (true), or a stream for a PDF (false) */ } stream_jbig2encode_state; diff -Nru ghostscript-9.10~dfsg/base/sjpegc.c ghostscript-9.25~dfsg+1/base/sjpegc.c --- ghostscript-9.10~dfsg/base/sjpegc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpegc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,6 +24,10 @@ #include "strimpl.h" #include "sdct.h" #include "sjpeg.h" +#include "gsmchunk.h" + +typedef void *backing_store_ptr; +#include "jmemcust.h" /* Ghostscript uses a non-public interface to libjpeg in order to @@ -38,44 +42,6 @@ #include "gconfig_.h" -#if SHARE_JPEG == 0 -/* Don't use the non-public insterface if we're linking to a shared lib */ -#ifdef DONT_HAVE_JMEMSYS_H - -void * -jpeg_get_small(j_common_ptr cinfo, size_t size); - -void -jpeg_free_small(j_common_ptr cinfo, void *object, size_t size); - -void FAR * -jpeg_get_large(j_common_ptr cinfo, size_t size); - -void -jpeg_free_large(j_common_ptr cinfo, void FAR * object, size_t size); -typedef void *backing_store_ptr; - -long -jpeg_mem_available(j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated); - -void -jpeg_open_backing_store(j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed); - -long -jpeg_mem_init(j_common_ptr cinfo); - -void -jpeg_mem_term(j_common_ptr cinfo); - -#else -#include "jmemsys.h" /* for prototypes */ -#endif -#endif /* SHAREJPEG == 0 */ - -private_st_jpeg_block(); - /* * Error handling routines (these replace corresponding IJG routines from * jpeg/jerror.c). These are used for both compression and decompression. @@ -140,7 +106,7 @@ /* Format the error message */ (*cinfo->err->format_message) (cinfo, buffer); (*st->report_error) ((stream_state *) st, buffer); - return gs_error_ioerror; /* caller will do return_error() */ + return_error(gs_error_ioerror); /* caller will do return_error() */ } /* @@ -175,115 +141,92 @@ { if (st->data.common && setjmp(find_jmp_buf(st->data.common->exit_jmpbuf))) return_error(gs_jpeg_log_error(st)); - if (st->data.compress) + + if (st->data.compress){ jpeg_destroy((j_common_ptr) & st->data.compress->cinfo); + gs_jpeg_mem_term((j_common_ptr) & st->data.compress->cinfo); + } return 0; } #if SHARE_JPEG == 0 -/* Don't use the non-public insterface if we're linking to a shared lib */ -/* - * These routines replace the low-level memory manager of the IJG library. - * They pass malloc/free calls to the Ghostscript memory manager. - * Note we do not need these to be declared in any GS header file. - */ +static void *gs_j_mem_alloc(j_common_ptr cinfo, size_t size) +{ + gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv); -static inline jpeg_compress_data * -cinfo2jcd(j_common_ptr cinfo) -{ /* We use the offset of cinfo in jpeg_compress data here, but we */ - /* could equally well have used jpeg_decompress_data. */ - return (jpeg_compress_data *) - ((byte *)cinfo - offset_of(jpeg_compress_data, cinfo)); -} - -static void * -jpeg_alloc(j_common_ptr cinfo, size_t size, const char *info) -{ - jpeg_compress_data *jcd = cinfo2jcd(cinfo); - gs_memory_t *mem = jcd->memory; - - jpeg_block_t *p = gs_alloc_struct_immovable(mem, jpeg_block_t, - &st_jpeg_block, "jpeg_alloc(block)"); - void *data = gs_alloc_bytes_immovable(mem, size, info); - - if (p == 0 || data == 0) { - gs_free_object(mem, data, info); - gs_free_object(mem, p, "jpeg_alloc(block)"); - return 0; - } - p->data = data; - p->next = jcd->blocks; - jcd->blocks = p; - return data; + return(gs_alloc_bytes(mem, size, "JPEG allocation")); } -static void -jpeg_free(j_common_ptr cinfo, void *data, const char *info) +static void gs_j_mem_free(j_common_ptr cinfo, void *object, size_t size) { - jpeg_compress_data *jcd = cinfo2jcd(cinfo); - gs_memory_t *mem = jcd->memory; - jpeg_block_t *p = jcd->blocks; - jpeg_block_t **pp = &jcd->blocks; - - gs_free_object(mem, data, info); - while(p && p->data != data) - { pp = &p->next; - p = p->next; - } - if(p == 0) - lprintf1("Freeing unrecorded JPEG data 0x%lx!\n", (ulong)data); - else - *pp = p->next; - gs_free_object(mem, p, "jpeg_free(block)"); -} + gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv); -void * -jpeg_get_small(j_common_ptr cinfo, size_t size) -{ - return jpeg_alloc(cinfo, size, "JPEG small internal data allocation"); + gs_free_object(mem, object, "JPEG free"); } -void -jpeg_free_small(j_common_ptr cinfo, void *object, size_t size) +static long gs_j_mem_init (j_common_ptr cinfo) { - jpeg_free(cinfo, object, "Freeing JPEG small internal data"); -} + gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv); + gs_memory_t *cmem = NULL; -void FAR * -jpeg_get_large(j_common_ptr cinfo, size_t size) -{ - return jpeg_alloc(cinfo, size, "JPEG large internal data allocation"); -} + if (gs_memory_chunk_wrap(&(cmem), mem) < 0) { + return (-1); + } + + (void)jpeg_cust_mem_set_private(GET_CUST_MEM_DATA(cinfo), cmem); -void -jpeg_free_large(j_common_ptr cinfo, void FAR * object, size_t size) -{ - jpeg_free(cinfo, object, "Freeing JPEG large internal data"); + return 0; } -long -jpeg_mem_available(j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) +static void gs_j_mem_term (j_common_ptr cinfo) { - return max_bytes_needed; -} + gs_memory_t *cmem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv); + gs_memory_t *mem = gs_memory_chunk_target(cmem); -void -jpeg_open_backing_store(j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - ERREXIT(cinfo, JERR_NO_BACKING_STORE); + gs_memory_chunk_release(cmem); + + (void)jpeg_cust_mem_set_private(GET_CUST_MEM_DATA(cinfo), mem); } +#endif /* SHAREJPEG == 0 */ -long -jpeg_mem_init(j_common_ptr cinfo) + +int gs_jpeg_mem_init (gs_memory_t *mem, j_common_ptr cinfo) { - return 0; /* just set max_memory_to_use to 0 */ + int code = 0; +#if SHARE_JPEG == 0 + jpeg_cust_mem_data custm, *custmptr; + + memset(&custm, 0x00, sizeof(custm)); + + if (!jpeg_cust_mem_init(&custm, (void *) mem, gs_j_mem_init, gs_j_mem_term, NULL, + gs_j_mem_alloc, gs_j_mem_free, + gs_j_mem_alloc, gs_j_mem_free, NULL)) { + code = gs_note_error(gs_error_VMerror); + } + if (code == 0) { + custmptr = (jpeg_cust_mem_data *)gs_alloc_bytes(mem->non_gc_memory, sizeof(custm) + sizeof(void *), "JPEG custom memory descriptor"); + if (!custmptr) { + code = gs_note_error(gs_error_VMerror); + } + else { + memcpy(custmptr, &custm, sizeof(custm)); + cinfo->client_data = custmptr; + } + } +#endif /* SHAREJPEG == 0 */ + return code; } void -jpeg_mem_term(j_common_ptr cinfo) +gs_jpeg_mem_term(j_common_ptr cinfo) { - /* no work */ -} +#if SHARE_JPEG == 0 + if (cinfo->client_data) { + jpeg_cust_mem_data *custmptr = (jpeg_cust_mem_data *)cinfo->client_data; + gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv); + + gs_free_object(mem, custmptr, "gs_jpeg_mem_term"); + cinfo->client_data = NULL; + } #endif /* SHAREJPEG == 0 */ +} diff -Nru ghostscript-9.10~dfsg/base/sjpegd.c ghostscript-9.25~dfsg+1/base/sjpegd.c --- ghostscript-9.10~dfsg/base/sjpegd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpegd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -39,6 +39,10 @@ return_error(gs_jpeg_log_error(st)); jpeg_stream_data_common_init(st->data.decompress); + + if (gs_jpeg_mem_init (st->memory, (j_common_ptr)&st->data.decompress->dinfo) < 0) + return_error(gs_error_VMerror); + jpeg_create_decompress(&st->data.decompress->dinfo); return 0; } diff -Nru ghostscript-9.10~dfsg/base/sjpege.c ghostscript-9.25~dfsg+1/base/sjpege.c --- ghostscript-9.10~dfsg/base/sjpege.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpege.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -38,6 +38,10 @@ return_error(gs_jpeg_log_error(st)); jpeg_stream_data_common_init(st->data.compress); + + if (gs_jpeg_mem_init (st->memory, (j_common_ptr)&st->data.compress->cinfo) < 0) + return_error(gs_error_VMerror); + jpeg_create_compress(&st->data.compress->cinfo); return 0; } diff -Nru ghostscript-9.10~dfsg/base/sjpeg.h ghostscript-9.25~dfsg+1/base/sjpeg.h --- ghostscript-9.10~dfsg/base/sjpeg.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpeg.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -28,7 +28,7 @@ * (b) it catches any error exit from the IJG code and converts it into * an error return value per Ghostscript custom. A negative return * value is an error code, except for gs_jpeg_alloc_xxx which return - * NULL (indicating e_VMerror). + * NULL (indicating gs_error_VMerror). */ /* Common to encode/decode */ @@ -65,4 +65,9 @@ JSAMPARRAY scanlines, int max_lines); int gs_jpeg_finish_decompress(stream_DCT_state * st); +int gs_jpeg_mem_init (gs_memory_t *mem, j_common_ptr cinfo); + +void +gs_jpeg_mem_term(j_common_ptr cinfo); + #endif /* sjpeg_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/sjpx_luratech.c ghostscript-9.25~dfsg+1/base/sjpx_luratech.c --- ghostscript-9.10~dfsg/base/sjpx_luratech.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpx_luratech.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -331,7 +331,7 @@ /* allocate the input buffer if needed */ if (state->inbuf == NULL) { state->inbuf = s_jpx_alloc(JPX_BUFFER_SIZE, (JP2_Callback_Param)state->memory->non_gc_memory); - if (state->inbuf == NULL) return gs_error_VMerror; + if (state->inbuf == NULL) return_error(gs_error_VMerror); state->inbuf_size = JPX_BUFFER_SIZE; state->inbuf_fill = 0; } @@ -348,7 +348,7 @@ new_size); new = gs_resize_object(state->memory->non_gc_memory, state->inbuf, new_size, "s_jpxd_inbuf"); - if (new == NULL) return gs_error_VMerror; + if (new == NULL) return_error(gs_error_VMerror); state->inbuf = new; state->inbuf_size = new_size; @@ -397,6 +397,7 @@ state->alpha = false; state->image_is_indexed = false; + state->colorspace = gs_jpx_cs_rgb; } /* write component mapping into 'clut' and return number of used components @@ -504,6 +505,7 @@ if_debug1m('w', state->memory, "[w]jpxd image has %d components\n", state->ncomp); + state->bpc = 0; { const char *cspace = "unknown"; err = JP2_Decompress_GetProp(state->handle, @@ -541,6 +543,8 @@ case cJP2_Colorspace_Palette_RGBa: cspace = "indexed sRGB"; state->image_is_indexed = true; + if (state->colorspace != gs_jpx_cs_indexed) + state->bpc = 8; break; case cJP2_Colorspace_Palette_RGB_YCCa: cspace = "indexed sRGB YCrCb"; @@ -570,7 +574,6 @@ or depth, so we take the maximum of the component values */ state->width = 0; state->height = 0; - state->bpc = 0; { int comp; int width, height; @@ -876,7 +879,7 @@ #if defined(JP2_LICENSE_NUM_1) && defined(JP2_LICENSE_NUM_2) /* set license keys if appropriate */ - err = JP2_Decompress_SetLicense(state->handle, + err = JP2_Compress_SetLicense(state->handle, JP2_LICENSE_NUM_1, JP2_LICENSE_NUM_2); if (err != cJP2_Error_OK) { dmlprintf1(state->memory, "Luratech JP2 error %d setting license\n", (int)err); @@ -1073,6 +1076,15 @@ gs_free_object(state->memory->non_gc_memory, state->inbuf, "s_jpxe_release(inbuf)"); } +int sjpxd_create(gs_memory_t *mem) +{ + return 0; +} + +void sjpxd_destroy(gs_memory_t *mem) +{ +} + /* encoder stream template */ const stream_template s_jpxe_template = { &st_jpxe_state, diff -Nru ghostscript-9.10~dfsg/base/sjpx_luratech.h ghostscript-9.25~dfsg+1/base/sjpx_luratech.h --- ghostscript-9.10~dfsg/base/sjpx_luratech.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpx_luratech.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sjpx_none.c ghostscript-9.25~dfsg+1/base/sjpx_none.c --- ghostscript-9.10~dfsg/base/sjpx_none.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpx_none.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,28 @@ +/* Copyright (C) 2001-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + +/* Dummy for no JPX support */ +#include "memory_.h" + + +int sjpxd_create(gs_memory_t *mem) +{ + return 0; +} + +void sjpxd_destroy(gs_memory_t *mem) +{ +} + diff -Nru ghostscript-9.10~dfsg/base/sjpx_openjpeg.c ghostscript-9.25~dfsg+1/base/sjpx_openjpeg.c --- ghostscript-9.10~dfsg/base/sjpx_openjpeg.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpx_openjpeg.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -22,6 +22,171 @@ #include "gdebug.h" #include "strimpl.h" #include "sjpx_openjpeg.h" +#include "gxsync.h" +#include "assert_.h" +#if !defined(SHARE_JPX) || (SHARE_JPX == 0) +#include "opj_malloc.h" +#endif +/* Some locking to get around the criminal lack of context + * in the openjpeg library. */ +#if !defined(SHARE_JPX) || (SHARE_JPX == 0) +static gs_memory_t *opj_memory; +#endif + +int sjpxd_create(gs_memory_t *mem) +{ +#if !defined(SHARE_JPX) || (SHARE_JPX == 0) + gs_lib_ctx_t *ctx = mem->gs_lib_ctx; + +#ifdef MEMENTO_SQUEEZE_BUILD + ctx->sjpxd_private = NULL; +#else + ctx->sjpxd_private = gx_monitor_label(gx_monitor_alloc(mem), "sjpxd_monitor"); + if (ctx->sjpxd_private == NULL) + return gs_error_VMerror; +#endif +#endif + return 0; +} + +void sjpxd_destroy(gs_memory_t *mem) +{ +#if (!defined(SHARE_JPX) || (SHARE_JPX == 0)) && !defined(MEMENTO_SQUEEZE_BUILD) + gs_lib_ctx_t *ctx = mem->gs_lib_ctx; + + gx_monitor_free((gx_monitor_t *)ctx->sjpxd_private); + ctx->sjpxd_private = NULL; +#endif +} + +static int opj_lock(gs_memory_t *mem) +{ +#if !defined(SHARE_JPX) || (SHARE_JPX == 0) + int ret; + +#ifdef MEMENTO_SQUEEZE_BUILD + ret = 0; +#else + gs_lib_ctx_t *ctx = mem->gs_lib_ctx; + + ret = gx_monitor_enter((gx_monitor_t *)ctx->sjpxd_private); +#endif + assert(opj_memory == NULL); + opj_memory = mem->non_gc_memory; + return ret; +#else + return 0; +#endif +} + +static int opj_unlock(gs_memory_t *mem) +{ +#if !defined(SHARE_JPX) || (SHARE_JPX == 0) + gs_lib_ctx_t *ctx = mem->gs_lib_ctx; + + assert(opj_memory != NULL); + opj_memory = NULL; +#ifdef MEMENTO_SQUEEZE_BUILD + (void)ctx; + return 0; +#else + return gx_monitor_leave((gx_monitor_t *)ctx->sjpxd_private); +#endif +#else + return 0; +#endif +} + +#if !defined(SHARE_JPX) || (SHARE_JPX == 0) +/* Allocation routines that use the memory pointer given above */ +void *opj_malloc(size_t size) +{ + if (size == 0) + return NULL; + + assert(opj_memory != NULL); + + return (void *)gs_alloc_bytes(opj_memory, size, "opj_malloc"); +} + +void *opj_calloc(size_t n, size_t size) +{ + void *ptr; + + /* FIXME: Check for overflow? */ + size *= n; + + ptr = opj_malloc(size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +void *opj_realloc(void *ptr, size_t size) +{ + if (ptr == NULL) + return opj_malloc(size); + + if (size == 0) + { + opj_free(ptr); + return NULL; + } + + return gs_resize_object(opj_memory, ptr, size, "opj_malloc"); +} + +void opj_free(void *ptr) +{ + gs_free_object(opj_memory, ptr, "opj_malloc"); +} + +static inline void * opj_aligned_malloc_n(size_t size, size_t align) +{ + uint8_t *ptr; + int off; + + if (size == 0) + return NULL; + + size += align + sizeof(uint8_t); + ptr = opj_malloc(size); + if (ptr == NULL) + return NULL; + off = align - (((int)(intptr_t)ptr) & (align - 1)); + ptr[off-1] = off; + return ptr + off; +} + +void * opj_aligned_malloc(size_t size) +{ + return opj_aligned_malloc_n(size, 16); +} + +void *opj_aligned_32_malloc(size_t size) +{ + return opj_aligned_malloc_n(size, 32); +} + +void opj_aligned_free(void* ptr_) +{ + uint8_t *ptr = (uint8_t *)ptr_; + uint8_t off; + if (ptr == NULL) + return; + + off = ptr[-1]; + opj_free((void *)(((unsigned char *)ptr) - off)); +} + +#if 0 +/* UNUSED currently, and moderately tricky, so deferred until required */ +void * opj_aligned_realloc(void *ptr, size_t size) +{ + return opj_realloc(ptr, size); +} +#endif +#endif gs_private_st_simple(st_jpxd_state, stream_jpxd_state, "JPXDecode filter state"); /* creates a gc object for our state, @@ -29,148 +194,225 @@ static int s_opjd_accumulate_input(stream_jpxd_state *state, stream_cursor_read * pr); -/* initialize the steam. - this involves allocating the stream and image structures, and - initializing the decoder. - */ -static int -s_opjd_init(stream_state * ss) +static OPJ_SIZE_T sjpx_stream_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data) { - stream_jpxd_state *const state = (stream_jpxd_state *) ss; - opj_dparameters_t parameters; /* decompression parameters */ + stream_block *sb = (stream_block *)p_user_data; + OPJ_SIZE_T len; - /* get a decoder handle */ - state->opj_dinfo_p = opj_create_decompress(CODEC_JP2); + len = sb->size - sb->pos; + if (sb->size < sb->pos) + len = 0; + if (len == 0) + return (OPJ_SIZE_T)-1; /* End of file! */ + if ((OPJ_SIZE_T)len > p_nb_bytes) + len = p_nb_bytes; + memcpy(p_buffer, sb->data + sb->pos, len); + sb->pos += len; + return len; +} - if (state->opj_dinfo_p == NULL) - return_error(gs_error_VMerror); +static OPJ_OFF_T sjpx_stream_skip(OPJ_OFF_T skip, void * p_user_data) +{ + stream_block *sb = (stream_block *)p_user_data; - /* catch events using our callbacks and give a local context */ - /* opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); */ + if (skip > sb->size - sb->pos) + skip = sb->size - sb->pos; + sb->pos += skip; + return sb->pos; +} - /* set decoding parameters to default values */ - opj_set_default_decoder_parameters(¶meters); +static OPJ_BOOL sjpx_stream_seek(OPJ_OFF_T seek_pos, void * p_user_data) +{ + stream_block *sb = (stream_block *)p_user_data; - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(state->opj_dinfo_p, ¶meters); + if (seek_pos > sb->size) + return OPJ_FALSE; + sb->pos = seek_pos; + return OPJ_TRUE; +} + +static void sjpx_error_callback(const char *msg, void *ptr) +{ + dlprintf1("openjpeg error: %s", msg); +} + +static void sjpx_info_callback(const char *msg, void *ptr) +{ +#ifdef DEBUG + /* prevent too many messages during normal build */ + dlprintf1("openjpeg info: %s", msg); +#endif +} + +static void sjpx_warning_callback(const char *msg, void *ptr) +{ + dlprintf1("openjpeg warning: %s", msg); +} + +/* initialize the stream */ +static int +s_opjd_init(stream_state * ss) +{ + stream_jpxd_state *const state = (stream_jpxd_state *) ss; + state->codec = NULL; state->image = NULL; - state->inbuf = NULL; - state->inbuf_size = 0; - state->inbuf_fill = 0; + state->sb.data= NULL; + state->sb.size = 0; + state->sb.pos = 0; + state->sb.fill = 0; state->out_offset = 0; - state->img_offset = 0; state->pdata = NULL; state->sign_comps = NULL; + state->stream = NULL; + state->row_data = NULL; return 0; } -/* calculate the real component data idx after scaling */ -static inline unsigned long -get_scaled_idx(stream_jpxd_state *state, int compno, unsigned long idx, unsigned long x, unsigned long y) -{ - if (state->samescale) - return idx; - - return (y/state->image->comps[compno].dy*state->width + x)/state->image->comps[compno].dx; -} - -/* convert state->image from YCrCb to RGB */ +/* setting the codec format, + allocating the stream and image structures, and + initializing the decoder. + */ static int -s_jpxd_ycc_to_rgb(stream_jpxd_state *state) +s_opjd_set_codec_format(stream_state * ss, OPJ_CODEC_FORMAT format) { - unsigned int max_value = ~(-1 << state->image->comps[0].prec); /* maximum of channel value */ - int flip_value = 1 << (state->image->comps[0].prec-1); - int p[3], q[3], i; - int sgnd[2]; /* Cr, Cb */ - unsigned long x, y, idx; - int *row_bufs[3]; + stream_jpxd_state *const state = (stream_jpxd_state *) ss; + opj_dparameters_t parameters; /* decompression parameters */ - if (state->out_numcomps != 3) - return -1; + /* set decoding parameters to default values */ + opj_set_default_decoder_parameters(¶meters); - for (i=0; i<2; i++) - sgnd[i] = state->image->comps[i+1].sgnd; + /* get a decoder handle */ + state->codec = opj_create_decompress(format); + if (state->codec == NULL) + return_error(gs_error_VMerror); - for (i=0; i<3; i++) - row_bufs[i] = (int *)gs_alloc_byte_array(state->memory->non_gc_memory, sizeof(int)*state->width, 1, "s_jpxd_ycc_to_rgb"); + /* catch events using our callbacks */ + opj_set_error_handler(state->codec, sjpx_error_callback, stderr); + opj_set_info_handler(state->codec, sjpx_info_callback, stderr); + opj_set_warning_handler(state->codec, sjpx_warning_callback, stderr); - if (!row_bufs[0] || !row_bufs[1] || !row_bufs[2]) - return_error(gs_error_VMerror); + if (state->colorspace == gs_jpx_cs_indexed) { + parameters.flags |= OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG; + } - idx=0; - for (y=0; yheight; y++) + /* setup the decoder decoding parameters using user parameters */ + if (!opj_setup_decoder(state->codec, ¶meters)) { - /* backup one row. the real buffer might be overriden when there is scale */ - for (i=0; i<3; i++) - { - if ((y % state->image->comps[i].dy) == 0) /* get the buffer once every dy rows */ - memcpy(row_bufs[i], &(state->image->comps[i].data[get_scaled_idx(state, i, idx, 0, y)]), sizeof(int)*state->width/state->image->comps[i].dx); - } - for (x=0; xwidth; x++, idx++) - { - for (i = 0; i < 3; i++) - p[i] = row_bufs[i][x/state->image->comps[i].dx]; - - if (!sgnd[0]) - p[1] -= flip_value; - if (!sgnd[1]) - p[2] -= flip_value; - - /* rotate to RGB */ -#ifdef JPX_USE_IRT - q[1] = p[0] - ((p[1] + p[2])>>2); - q[0] = p[1] + q[1]; - q[2] = p[2] + q[1]; -#else - q[0] = (int)((double)p[0] + 1.402 * p[2]); - q[1] = (int)((double)p[0] - 0.34413 * p[1] - 0.71414 * p[2]); - q[2] = (int)((double)p[0] + 1.772 * p[1]); -#endif - /* clamp */ - for (i = 0; i < 3; i++){ - if (q[i] < 0) q[i] = 0; - else if (q[i] > max_value) q[i] = max_value; - } + dlprintf("openjpeg: failed to setup the decoder!\n"); + return ERRC; + } - /* write out the pixel */ - for (i = 0; i < 3; i++) - state->image->comps[i].data[get_scaled_idx(state, i, idx, x, y)] = q[i]; - } + /* open a byte stream */ + state->stream = opj_stream_default_create(OPJ_TRUE); + if (state->stream == NULL) + { + dlprintf("openjpeg: failed to open a byte stream!\n"); + return ERRC; } - for (i=0; i<3; i++) - gs_free_object(state->memory->non_gc_memory, row_bufs[i],"s_jpxd_ycc_to_rgb"); + opj_stream_set_read_function(state->stream, sjpx_stream_read); + opj_stream_set_skip_function(state->stream, sjpx_stream_skip); + opj_stream_set_seek_function(state->stream, sjpx_stream_seek); return 0; } +static void +ycc_to_rgb_8(unsigned char *row, unsigned long row_size) +{ + unsigned char y; + signed char u, v; + int r,g,b; + do + { + y = row[0]; + u = row[1] - 128; + v = row[2] - 128; + r = (int)((double)y + 1.402 * v); + if (r < 0) + r = 0; + if (r > 255) + r = 255; + g = (int)((double)y - 0.34413 * u - 0.71414 * v); + if (g < 0) + g = 0; + if (g > 255) + g = 255; + b = (int)((double)y + 1.772 * u); + if (b < 0) + b = 0; + if (b > 255) + b = 255; + row[0] = r; + row[1] = g; + row[2] = b; + row += 3; + row_size -= 3; + } + while (row_size); +} + +static void +ycc_to_rgb_16(unsigned char *row, unsigned long row_size) +{ + unsigned short y; + signed short u, v; + int r,g,b; + do + { + y = (row[0]<<8) | row[1]; + u = ((row[2]<<8) | row[3]) - 32768; + v = ((row[4]<<8) | row[5]) - 32768; + r = (int)((double)y + 1.402 * v); + if (r < 0) + r = 0; + if (r > 65535) + r = 65535; + g = (int)((double)y - 0.34413 * u - 0.71414 * v); + if (g < 0) + g = 0; + if (g > 65535) + g = 65535; + b = (int)((double)y + 1.772 * u); + if (b < 0) + b = 0; + if (b > 65535) + b = 65535; + row[0] = r>>8; + row[1] = r; + row[2] = g>>8; + row[3] = g; + row[4] = b>>8; + row[5] = b; + row += 6; + row_size -= 6; + } + while (row_size); +} + static int decode_image(stream_jpxd_state * const state) { - opj_cio_t *cio = NULL; int numprimcomp = 0, alpha_comp = -1, compno, rowbytes; - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)state->opj_dinfo_p, state->inbuf, state->inbuf_fill); - if (cio == NULL) - return ERRC; + /* read header */ + if (!opj_read_header(state->stream, state->codec, &(state->image))) + { + dlprintf("openjpeg: failed to read header\n"); + return ERRC; + } /* decode the stream and fill the image structure */ - state->image = opj_decode(state->opj_dinfo_p, cio, state->colorspace == gs_jpx_cs_indexed); - if(state->image == NULL) + if (!opj_decode(state->codec, state->stream, state->image)) { dlprintf("openjpeg: failed to decode image!\n"); - opj_cio_close(cio); return ERRC; } - /* close the byte stream */ - opj_cio_close(cio); - /* check dimension and prec */ if (state->image->numcomps == 0) - return ERRC; + return ERRC; state->width = state->image->comps[0].w; state->height = state->image->comps[0].h; @@ -189,26 +431,22 @@ state->samescale = false; } - - /* find alpha component and regular color component by channel definition */ - for(compno = 0; compno < state->image->numcomps; compno++) + /* find alpha component and regular colour component by channel definition */ + for (compno = 0; compno < state->image->numcomps; compno++) { - if (state->image->comps[compno].typ == CTYPE_COLOR) + if (state->image->comps[compno].alpha == 0x00) numprimcomp++; - else if (state->image->comps[compno].typ == CTYPE_OPACITY) + else if (state->image->comps[compno].alpha == 0x01) alpha_comp = compno; } /* color space and number of components */ switch(state->image->color_space) { - case CLRSPC_GRAY: + case OPJ_CLRSPC_GRAY: state->colorspace = gs_jpx_cs_gray; break; - case CLRSPC_CMYK: - state->colorspace = gs_jpx_cs_cmyk; - break; - case CLRSPC_UNKNOWN: /* make the best guess based on number of channels */ + case OPJ_CLRSPC_UNKNOWN: /* make the best guess based on number of channels */ { if (numprimcomp < 3) { @@ -224,7 +462,7 @@ } break; } - default: /* CLRSPC_SRGB, CLRSPC_SYCC, CLRSPC_ERGB, CLRSPC_EYCC */ + default: /* OPJ_CLRSPC_SRGB, OPJ_CLRSPC_SYCC, OPJ_CLRSPC_EYCC */ state->colorspace = gs_jpx_cs_rgb; } @@ -245,10 +483,6 @@ rowbytes = (state->width*state->bpp*state->out_numcomps+7)/8; state->totalbytes = rowbytes*state->height; - /* convert input from YCC to RGB */ - if (state->image->color_space == CLRSPC_SYCC || state->image->color_space == CLRSPC_EYCC) - s_jpxd_ycc_to_rgb(state); - state->pdata = (int **)gs_alloc_byte_array(state->memory->non_gc_memory, sizeof(int*)*state->image->numcomps, 1, "decode_image(pdata)"); if (!state->pdata) return_error(gs_error_VMerror); @@ -271,181 +505,175 @@ static int process_one_trunk(stream_jpxd_state * const state, stream_cursor_write * pw) { - /* read data from image to pw */ - unsigned long out_size = pw->limit - pw->ptr; - int bytepp1 = state->bpp/8; /* bytes / pixel for one output component */ - int bytepp = state->out_numcomps*state->bpp/8; /* bytes / pixel all components */ - unsigned long write_size = min(out_size-(bytepp?(out_size%bytepp):0), state->totalbytes-state->out_offset); - unsigned long in_offset = state->out_offset*8/state->bpp/state->out_numcomps; /* component data offset */ - int shift_bit = state->bpp-state->image->comps[0].prec; /*difference between input and output bit-depth*/ - int img_numcomps = min(state->out_numcomps, state->image->numcomps), /* the actual number of channel data used */ - compno; - unsigned long i; int b; - byte *pend = pw->ptr+write_size+1; /* end of write data */ - - if (state->bpp < 8) - in_offset = state->img_offset; - - pw->ptr++; - - if (state->alpha && state->alpha_comp == -1) - {/* return 0xff for all */ - memset(pw->ptr, 0xff, write_size); - pw->ptr += write_size; - } - else if (state->samescale) - { - if (state->alpha) - state->pdata[0] = &(state->image->comps[state->alpha_comp].data[in_offset]); - else - { - for (compno=0; compnopdata[compno] = &(state->image->comps[compno].data[in_offset]); - } - if (shift_bit == 0 && state->bpp == 8) /* optimized for the most common case */ - { - while (pw->ptr < pend) - { - for (compno=0; compnoptr++) = *(state->pdata[compno]++) + state->sign_comps[compno]; /* copy input buffer to output */ - } - } - else - { - if ((state->bpp%8)==0) - { - while (pw->ptr < pend) - { - for (compno=0; compnoptr++) = (((*(state->pdata[compno]) << shift_bit) >> (8*(bytepp1-b-1)))) - + (b==0 ? state->sign_comps[compno] : 0); /* split and shift input int to output bytes */ - state->pdata[compno]++; - } - } - } - else - { - /* shift_bit = 0, bpp < 8 */ - unsigned long image_total = state->width*state->height; - int bt=0; int bit_pos = 0; - int rowbytes = (state->width*state->bpp*state->out_numcomps+7)/8; /*row bytes */ - int currowcnt = state->out_offset % rowbytes; /* number of bytes filled in current row */ - int start_comp = (currowcnt*8) % img_numcomps; /* starting component for this round of output*/ - if (start_comp != 0) - { - for (compno=start_comp; compnoimg_offset < image_total) - { - bt <<= state->bpp; - bt += *(state->pdata[compno]-1) + state->sign_comps[compno]; - } - bit_pos += state->bpp; - if (bit_pos >= 8) - { - *(pw->ptr++) = bt >> (bit_pos-8); - bit_pos -= 8; - bt &= (1<ptr < pend) - { - for (compno=0; compnoimg_offset < image_total) - { - bt <<= state->bpp; - bt += *(state->pdata[compno]++) + state->sign_comps[compno]; - } - bit_pos += state->bpp; - if (bit_pos >= 8) - { - *(pw->ptr++) = bt >> (bit_pos-8); - bit_pos -= 8; - bt &= (1<img_offset++; - if (bit_pos != 0 && state->img_offset % state->width == 0) - { - /* row padding */ - *(pw->ptr++) = bt << (8 - bit_pos); - bit_pos = 0; - bt = 0; - } - } - } - } - } - else - { - /* sampling required */ - unsigned long y_offset = in_offset / state->width; - unsigned long x_offset = in_offset % state->width; - while (pw->ptr < pend) - { - if ((state->bpp%8)==0) - { - if (state->alpha) - { - int in_offset_scaled = (y_offset/state->image->comps[state->alpha_comp].dy*state->width + x_offset)/state->image->comps[state->alpha_comp].dx; - for (b=0; bptr++) = (((state->image->comps[state->alpha_comp].data[in_offset_scaled] << shift_bit) >> (8*(bytepp1-b-1)))) + /* read data from image to pw */ + unsigned long out_size = pw->limit - pw->ptr; + int bytepp1 = state->bpp/8; /* bytes / pixel for one output component */ + int bytepp = state->out_numcomps*state->bpp/8; /* bytes / pixel all components */ + unsigned long write_size = min(out_size-(bytepp?(out_size%bytepp):0), state->totalbytes-state->out_offset); + int shift_bit = state->bpp-state->image->comps[0].prec; /*difference between input and output bit-depth*/ + int img_numcomps = min(state->out_numcomps, state->image->numcomps); /* the actual number of channel data used */ + int compno; + unsigned long i; + int b; + byte *row; + unsigned int x_offset; + unsigned int y_offset; + unsigned int row_size = (state->width * state->out_numcomps * state->bpp + 7)>>3; + + /* If nothing to write, nothing to do */ + if (write_size == 0) + return 0; + + if (state->row_data == NULL) + { + state->row_data = gs_alloc_byte_array(state->memory->non_gc_memory, row_size, 1, "jpxd_openjpeg(row_data)"); + if (state->row_data == NULL) + return gs_error_VMerror; + } + + while (state->out_offset != state->totalbytes) + { + y_offset = state->out_offset / row_size; + x_offset = state->out_offset % row_size; + + if (x_offset == 0) + { + /* Decode another rows worth */ + row = state->row_data; + if (state->alpha && state->alpha_comp == -1) + { + /* return 0xff for all */ + memset(row, 0xff, row_size); + } + else if (state->samescale) + { + if (state->alpha) + state->pdata[0] = &(state->image->comps[state->alpha_comp].data[y_offset * state->width]); + else + { + for (compno=0; compnopdata[compno] = &(state->image->comps[compno].data[y_offset * state->width]); + } + if (shift_bit == 0 && state->bpp == 8) /* optimized for the most common case */ + { + for (i = state->width; i > 0; i--) + for (compno=0; compnopdata[compno]++) + state->sign_comps[compno]; /* copy input buffer to output */ + } + else if ((state->bpp%8)==0) + { + for (i = state->width; i > 0; i--) + { + for (compno=0; compnopdata[compno]) << shift_bit) >> (8*(bytepp1-b-1)))) + + (b==0 ? state->sign_comps[compno] : 0); /* split and shift input int to output bytes */ + state->pdata[compno]++; + } + } + } + else + { + /* shift_bit = 0, bpp < 8 */ + int bt=0; + int bit_pos = 0; + for (i = state->width; i > 0; i--) + { + for (compno=0; compnobpp; + bt += *(state->pdata[compno]++) + state->sign_comps[compno]; + bit_pos += state->bpp; + if (bit_pos >= 8) + { + *row++ = bt >> (bit_pos-8); + bit_pos -= 8; + bt &= (1<bpp%8)==0) + { + /* sampling required */ + if (state->alpha) + { + for (i = 0; i < state->width; i++) + { + int in_offset_scaled = (y_offset/state->image->comps[state->alpha_comp].dy*state->width + i)/state->image->comps[state->alpha_comp].dx; + for (b=0; bimage->comps[state->alpha_comp].data[in_offset_scaled] << shift_bit) >> (8*(bytepp1-b-1)))) + (b==0 ? state->sign_comps[state->alpha_comp] : 0); - } - else - { - for (compno=0; compnoimage->comps[compno].dy*state->width + x_offset)/state->image->comps[compno].dx; - for (b=0; bptr++) = (((state->image->comps[compno].data[in_offset_scaled] << shift_bit) >> (8*(bytepp1-b-1)))) - + (b==0 ? state->sign_comps[compno] : 0); - } - } - x_offset++; - if (x_offset >= state->width) - { - y_offset++; - x_offset = 0; - } - } - else - { - unsigned long image_total = state->width*state->height; - int compno = state->alpha ? state->alpha_comp : 0; - /* only grayscale can have such bit-depth, also shift_bit = 0, bpp < 8 */ - int bt=0; - for (i=0; i<8/state->bpp; i++) - { - bt = bt<bpp; - if (state->img_offset < image_total && !(i!=0 && state->img_offset % state->width == 0)) - { - int in_offset_scaled = (y_offset/state->image->comps[compno].dy*state->width + x_offset)/state->image->comps[compno].dx; - bt += state->image->comps[compno].data[in_offset_scaled] + state->sign_comps[compno]; - state->img_offset++; - x_offset++; - if (x_offset >= state->width) - { - y_offset++; - x_offset = 0; - } - } - } - *(pw->ptr++) = bt; - } - } - } - state->out_offset += write_size; - pw->ptr--; - if (state->out_offset == state->totalbytes) - return EOFC; /* all data returned */ - else - return 1; /* need more calls */ - } + } + } + else + { + for (i = 0; i < state->width; i++) + { + for (compno=0; compnoimage->comps[compno].dy*state->width + i)/state->image->comps[compno].dx; + for (b=0; bimage->comps[compno].data[in_offset_scaled] << shift_bit) >> (8*(bytepp1-b-1)))) + + (b==0 ? state->sign_comps[compno] : 0); + } + } + } + } + else + { + int compno = state->alpha ? state->alpha_comp : 0; + int bt=0; + int ppbyte1 = 8/state->bpp; + /* sampling required */ + /* only grayscale can have such bit-depth, also shift_bit = 0, bpp < 8 */ + for (i = 0; i < state->width; i++) + { + for (b=0; bimage->comps[compno].dy*state->width + i)/state->image->comps[compno].dx; + bt = bt<bpp; + bt += state->image->comps[compno].data[in_offset_scaled] + state->sign_comps[compno]; + } + *row++ = bt; + } + } + + if (state->image->color_space == OPJ_CLRSPC_SYCC || state->image->color_space == OPJ_CLRSPC_EYCC) + { + /* bpp >= 8 always, as bpp < 8 only for grayscale */ + if (state->bpp == 8) + ycc_to_rgb_8(state->row_data, row_size); + else + ycc_to_rgb_16(state->row_data, row_size); + } + } + + pw->ptr++; + i = (write_size > (unsigned long)(row_size - x_offset)) ? (row_size - x_offset) : (unsigned int)write_size; + memcpy(pw->ptr, &state->row_data[x_offset], i); + pw->ptr += i; + pw->ptr--; + state->out_offset += i; + write_size -= i; + if (write_size == 0) + break; + } + + if (state->out_offset == state->totalbytes) + return EOFC; /* all data returned */ + else + return 1; /* need more calls */ +} /* process a section of the input and return any decoded data. see strimpl.h for return codes. @@ -456,23 +684,65 @@ { stream_jpxd_state *const state = (stream_jpxd_state *) ss; long in_size = pr->limit - pr->ptr; - - if (state->opj_dinfo_p == NULL) - return ERRC; + int locked = 0; + int code; if (in_size > 0) { /* buffer available data */ - s_opjd_accumulate_input(state, pr); + code = opj_lock(ss->memory); + if (code < 0) return code; + locked = 1; + + code = s_opjd_accumulate_input(state, pr); + if (code < 0) return code; + + if (state->codec == NULL) { + /* state->sb.size is non-zero after successful + accumulate_input(); 1 is probably extremely rare */ + if (state->sb.data[0] == 0xFF && ((state->sb.size == 1) || (state->sb.data[1] == 0x4F))) + code = s_opjd_set_codec_format(ss, OPJ_CODEC_J2K); + else + code = s_opjd_set_codec_format(ss, OPJ_CODEC_JP2); + if (code < 0) + { + (void)opj_unlock(ss->memory); + return code; + } + } } if (last == 1) { if (state->image == NULL) { - int ret = decode_image(state); + int ret; + + if (locked == 0) + { + ret = opj_lock(ss->memory); + if (ret < 0) return ret; + locked = 1; + } + +#if OPJ_VERSION_MAJOR >= 2 && OPJ_VERSION_MINOR >= 1 + opj_stream_set_user_data(state->stream, &(state->sb), NULL); +#else + opj_stream_set_user_data(state->stream, &(state->sb)); +#endif + opj_stream_set_user_data_length(state->stream, state->sb.size); + ret = decode_image(state); if (ret != 0) + { + (void)opj_unlock(ss->memory); return ret; + } + } + + if (locked) + { + code = opj_unlock(ss->memory); + if (code < 0) return code; } /* copy out available data */ @@ -480,6 +750,9 @@ } + if (locked) + return opj_unlock(ss->memory); + /* ask for more data */ return 0; } @@ -501,23 +774,38 @@ { stream_jpxd_state *const state = (stream_jpxd_state *) ss; + /* empty stream or failed to accumulate */ + if (state->codec == NULL) + return; + + (void)opj_lock(ss->memory); + /* free image data structure */ if (state->image) opj_image_destroy(state->image); + + /* free stream */ + if (state->stream) + opj_stream_destroy(state->stream); /* free decoder handle */ - if (state->opj_dinfo_p) - opj_destroy_decompress(state->opj_dinfo_p); + if (state->codec) + opj_destroy_codec(state->codec); + + (void)opj_unlock(ss->memory); /* free input buffer */ - if (state->inbuf) - gs_free_object(state->memory->non_gc_memory, state->inbuf, "s_opjd_release(inbuf)"); + if (state->sb.data) + gs_free_object(state->memory->non_gc_memory, state->sb.data, "s_opjd_release(sb.data)"); if (state->pdata) gs_free_object(state->memory->non_gc_memory, state->pdata, "s_opjd_release(pdata)"); if (state->sign_comps) gs_free_object(state->memory->non_gc_memory, state->sign_comps, "s_opjd_release(sign_comps)"); + + if (state->row_data) + gs_free_object(state->memory->non_gc_memory, state->row_data, "s_opjd_release(row_data)"); } @@ -527,31 +815,31 @@ long in_size = pr->limit - pr->ptr; /* grow the input buffer if needed */ - if (state->inbuf_size < state->inbuf_fill + in_size) + if (state->sb.size < state->sb.fill + in_size) { unsigned char *new_buf; - unsigned long new_size = state->inbuf_size==0 ? in_size : state->inbuf_size; + unsigned long new_size = state->sb.size==0 ? in_size : state->sb.size; - while (new_size < state->inbuf_fill + in_size) + while (new_size < state->sb.fill + in_size) new_size = new_size << 1; if_debug1('s', "[s]opj growing input buffer to %lu bytes\n", new_size); - if (state->inbuf == NULL) + if (state->sb.data == NULL) new_buf = (byte *) gs_alloc_byte_array(state->memory->non_gc_memory, new_size, 1, "s_opjd_accumulate_input(alloc)"); else - new_buf = (byte *) gs_resize_object(state->memory->non_gc_memory, state->inbuf, new_size, "s_opjd_accumulate_input(resize)"); + new_buf = (byte *) gs_resize_object(state->memory->non_gc_memory, state->sb.data, new_size, "s_opjd_accumulate_input(resize)"); if (new_buf == NULL) return_error( gs_error_VMerror); - state->inbuf = new_buf; - state->inbuf_size = new_size; + state->sb.data = new_buf; + state->sb.size = new_size; } /* copy the available input into our buffer */ /* note that the gs stream library uses offset-by-one indexing of its buffers while we use zero indexing */ - memcpy(state->inbuf + state->inbuf_fill, pr->ptr + 1, in_size); - state->inbuf_fill += in_size; + memcpy(state->sb.data + state->sb.fill, pr->ptr + 1, in_size); + state->sb.fill += in_size; pr->ptr += in_size; return 0; @@ -565,5 +853,5 @@ 1024, 1024, /* min in and out buffer sizes we can handle should be ~32k,64k for efficiency? */ s_opjd_release, - s_opjd_set_defaults + s_opjd_set_defaults }; diff -Nru ghostscript-9.10~dfsg/base/sjpx_openjpeg.h ghostscript-9.25~dfsg+1/base/sjpx_openjpeg.h --- ghostscript-9.10~dfsg/base/sjpx_openjpeg.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sjpx_openjpeg.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -33,6 +33,14 @@ gs_jpx_cs_indexed /* PDF image wants raw index values */ } gs_jpx_cs; +typedef struct stream_block_s +{ + unsigned char *data; + unsigned long size; + unsigned long pos; + unsigned long fill; +} stream_block; + /* Stream state for the jpx codec using openjpeg * We rely on our finalization call to free the * associated handle and pointers. @@ -40,26 +48,26 @@ typedef struct stream_jpxd_state_s { stream_state_common; /* a define from scommon.h */ - opj_dinfo_t *opj_dinfo_p; - opj_image_t *image; - int width, height, bpp; - bool samescale; + opj_codec_t *codec; + opj_stream_t *stream; + opj_image_t *image; + int width, height, bpp; + bool samescale; - gs_jpx_cs colorspace; /* requested output colorspace */ + gs_jpx_cs colorspace; /* requested output colorspace */ bool alpha; /* return opacity channel */ - unsigned char *inbuf; /* input data buffer */ - unsigned long inbuf_size; - unsigned long inbuf_fill; - - unsigned long totalbytes; /* output total */ - unsigned long out_offset; /* output bytes already returned previously */ - unsigned long img_offset; /* offset in the image data buffer for each channel, only used when output bpp%8 !=0 */ - - int **pdata; /* pointers to image data */ - int out_numcomps; /* real number of channels to use */ - int alpha_comp; /* input index of alpha channel */ - int *sign_comps; /* compensate for signed data (signed => unsigned) */ + stream_block sb; + + unsigned long totalbytes; /* output total */ + unsigned long out_offset; /* output bytes already returned previously */ + + int **pdata; /* pointers to image data */ + int out_numcomps; /* real number of channels to use */ + int alpha_comp; /* input index of alpha channel */ + int *sign_comps; /* compensate for signed data (signed => unsigned) */ + + unsigned char *row_data; } stream_jpxd_state; extern const stream_template s_jpxd_template; diff -Nru ghostscript-9.10~dfsg/base/slzwc.c ghostscript-9.25~dfsg+1/base/slzwc.c --- ghostscript-9.10~dfsg/base/slzwc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/slzwc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/slzwd.c ghostscript-9.25~dfsg+1/base/slzwd.c --- ghostscript-9.10~dfsg/base/slzwd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/slzwd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -117,6 +117,7 @@ int code_escape = 1 << ss->InitialCodeLength; int eod = code_eod; bool low_order = ss->FirstBitLowOrder; + bool old_tiff = ss->OldTiff; uint len; int c; byte b; @@ -241,10 +242,10 @@ * equal to next_code. */ if (code >= next_code) { - if (code > next_code) { + if ((code > next_code) || (prev_code < 0)) { #ifdef DEBUG - mlprintf2(ss->memory, "[W]code = %d > next_code = %d\n", - code, next_code); + mlprintf3(ss->memory, "[W]code = %d > next_code = %d or prev_code = %d < 0\n", + code, next_code, prev_code); #endif status = ERRC; goto out; @@ -323,7 +324,7 @@ * lzw_decode_max every time: just checking at power * of 2 boundaries stops us one code too soon. */ - if (next_code == lzw_decode_max) { + if (!old_tiff && next_code == lzw_decode_max) { /* * A few anomalous files have one data item too many before the * reset code. We think this is a bug in the application that @@ -363,12 +364,14 @@ status = ERRC; goto out; } - dc_next->datum = b; /* added char of string */ - dc_next->len = min(prev_len, 254) + 1; - dc_next->prefix = prev_code; - dc_next++; - if_debug4m('W', ss->memory, "[W]adding 0x%x=0x%x+%c(%d)\n", - next_code, prev_code, b, min(len, 255)); + if (next_code < lzw_decode_max) { + dc_next->datum = b; /* added char of string */ + dc_next->len = min(prev_len, 254) + 1; + dc_next->prefix = prev_code; + dc_next++; + if_debug4m('W', ss->memory, "[W]adding 0x%x=0x%x+%c(%d)\n", + next_code, prev_code, b, min(len, 255)); + } if (++next_code == switch_code) { /* Crossed a power of 2. */ /* We have to make a strange special check for */ /* reaching the end of the code space. */ diff -Nru ghostscript-9.10~dfsg/base/slzwe.c ghostscript-9.25~dfsg+1/base/slzwe.c --- ghostscript-9.10~dfsg/base/slzwe.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/slzwe.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/slzwx.h ghostscript-9.25~dfsg+1/base/slzwx.h --- ghostscript-9.10~dfsg/base/slzwx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/slzwx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -32,7 +32,8 @@ */ bool FirstBitLowOrder; /* decoding only */ bool BlockData; /* decoding only */ - int EarlyChange; /* decoding only */ + bool EarlyChange; /* decoding only */ + bool OldTiff; /* decoding only */ /* The following are updated dynamically. */ uint bits; /* buffer for input bits */ int bits_left; /* Decode: # of valid bits left, [0..7] */ @@ -64,6 +65,7 @@ (ss)->FirstBitLowOrder = false,\ (ss)->BlockData = false,\ (ss)->EarlyChange = 1,\ + (ss)->OldTiff = 0,\ /* Clear pointers */\ (ss)->table.decode /*=encode*/ = 0) extern const stream_template s_LZWD_template; diff -Nru ghostscript-9.10~dfsg/base/smd5.c ghostscript-9.25~dfsg+1/base/smd5.c --- ghostscript-9.10~dfsg/base/smd5.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/smd5.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/smd5.h ghostscript-9.25~dfsg+1/base/smd5.h --- ghostscript-9.10~dfsg/base/smd5.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/smd5.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -20,7 +20,7 @@ #ifndef smd5_INCLUDED # define smd5_INCLUDED -#include "md5.h" +#include "gsmd5.h" /* * The MD5Encode filter accepts an arbitrary amount of input data, and then, diff -Nru ghostscript-9.10~dfsg/base/smtf.c ghostscript-9.25~dfsg+1/base/smtf.c --- ghostscript-9.10~dfsg/base/smtf.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/smtf.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* MoveToFront filters */ -#include "stdio_.h" -#include "strimpl.h" -#include "smtf.h" - -/* ------ MoveToFrontEncode/Decode ------ */ - -private_st_MTF_state(); - -/* Initialize */ -static int -s_MTF_init(stream_state * st) -{ - stream_MTF_state *const ss = (stream_MTF_state *) st; - int i; - - for (i = 0; i < 256; i++) - ss->prev.b[i] = (byte) i; - return 0; -} - -/* Encode a buffer */ -static int -s_MTFE_process(stream_state * st, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_MTF_state *const ss = (stream_MTF_state *) st; - register const byte *p = pr->ptr; - register byte *q = pw->ptr; - const byte *rlimit = pr->limit; - uint count = rlimit - p; - uint wcount = pw->limit - q; - int status = - (count < wcount ? 0 : (rlimit = p + wcount, 1)); - - while (p < rlimit) { - byte b = *++p; - int i; - byte prev = b, repl; - - for (i = 0; (repl = ss->prev.b[i]) != b; i++) - ss->prev.b[i] = prev, prev = repl; - ss->prev.b[i] = prev; - *++q = (byte) i; - } - pr->ptr = p; - pw->ptr = q; - return status; -} - -/* Stream template */ -const stream_template s_MTFE_template = { - &st_MTF_state, s_MTF_init, s_MTFE_process, 1, 1 -}; - -/* Decode a buffer */ -static int -s_MTFD_process(stream_state * st, stream_cursor_read * pr, - stream_cursor_write * pw, bool last) -{ - stream_MTF_state *const ss = (stream_MTF_state *) st; - register const byte *p = pr->ptr; - register byte *q = pw->ptr; - const byte *rlimit = pr->limit; - uint count = rlimit - p; - uint wcount = pw->limit - q; - int status = (count <= wcount ? 0 : (rlimit = p + wcount, 1)); - - /* Cache the first few entries in local variables. */ - byte - v0 = ss->prev.b[0], v1 = ss->prev.b[1], - v2 = ss->prev.b[2], v3 = ss->prev.b[3]; - - while (p < rlimit) { - byte first; - - /* Zeros far outnumber all other bytes in the BWBS */ - /* code; check for them first. */ - if (*++p == 0) { - *++q = v0; - continue; - } - switch (*p) { - default: - { - uint b = *p; - byte *bp = &ss->prev.b[b]; - - *++q = first = *bp; -#if arch_sizeof_long == 4 - ss->prev.b[3] = v3; -#endif - /* Move trailing entries individually. */ - for (;; bp--, b--) { - *bp = bp[-1]; - if (!(b & (sizeof(long) - 1))) - break; - } - /* Move in long-size chunks. */ - for (; (b -= sizeof(long)) != 0;) { - bp -= sizeof(long); - -#if arch_is_big_endian - *(ulong *) bp = - (*(ulong *) bp >> 8) | - ((ulong) bp[-1] << ((sizeof(long) - 1) * 8)); - -#else - *(ulong *) bp = (*(ulong *) bp << 8) | bp[-1]; -#endif - } - } -#if arch_sizeof_long > 4 /* better be 8! */ - goto m7; - case 7: - *++q = first = ss->prev.b[7]; -m7: ss->prev.b[7] = ss->prev.b[6]; - goto m6; - case 6: - *++q = first = ss->prev.b[6]; -m6: ss->prev.b[6] = ss->prev.b[5]; - goto m5; - case 5: - *++q = first = ss->prev.b[5]; -m5: ss->prev.b[5] = ss->prev.b[4]; - goto m4; - case 4: - *++q = first = ss->prev.b[4]; -m4: ss->prev.b[4] = v3; -#endif - goto m3; - case 3: - *++q = first = v3; -m3: v3 = v2, v2 = v1, v1 = v0, v0 = first; - break; - case 2: - *++q = first = v2; - v2 = v1, v1 = v0, v0 = first; - break; - case 1: - *++q = first = v1; - v1 = v0, v0 = first; - break; - } - } - ss->prev.b[0] = v0; - ss->prev.b[1] = v1; - ss->prev.b[2] = v2; - ss->prev.b[3] = v3; - pr->ptr = p; - pw->ptr = q; - return status; -} - -/* Stream template */ -const stream_template s_MTFD_template = { - &st_MTF_state, s_MTF_init, s_MTFD_process, 1, 1, - NULL, NULL, s_MTF_init -}; diff -Nru ghostscript-9.10~dfsg/base/smtf.h ghostscript-9.25~dfsg+1/base/smtf.h --- ghostscript-9.10~dfsg/base/smtf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/smtf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/spdiff.c ghostscript-9.25~dfsg+1/base/spdiff.c --- ghostscript-9.10~dfsg/base/spdiff.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spdiff.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/spdiffx.h ghostscript-9.25~dfsg+1/base/spdiffx.h --- ghostscript-9.10~dfsg/base/spdiffx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spdiffx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/spngp.c ghostscript-9.25~dfsg+1/base/spngp.c --- ghostscript-9.10~dfsg/base/spngp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spngp.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -66,7 +66,7 @@ long bits_per_row = (long)bits_per_pixel * ss->Columns; byte *prev_row = 0; -#if arch_sizeof_long > arch_sizeof_int +#if ARCH_SIZEOF_LONG > ARCH_SIZEOF_INT if (bits_per_row > max_uint * 7L) return ERRC; /****** WRONG ******/ #endif diff -Nru ghostscript-9.10~dfsg/base/spngpx.h ghostscript-9.25~dfsg+1/base/spngpx.h --- ghostscript-9.10~dfsg/base/spngpx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spngpx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/spprint.c ghostscript-9.25~dfsg+1/base/spprint.c --- ghostscript-9.10~dfsg/base/spprint.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spprint.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -106,7 +106,7 @@ /* Print (a) floating point number(s) using a format. */ /* See gdevpdfx.h for why this is needed. */ const char * -pprintg1(stream * s, const char *format, floatp v) +pprintg1(stream * s, const char *format, double v) { const char *fp = pprintf_scan(s, format); char dot, str[150]; @@ -132,24 +132,24 @@ return pprintf_scan(s, fp + 2); } const char * -pprintg2(stream * s, const char *format, floatp v1, floatp v2) +pprintg2(stream * s, const char *format, double v1, double v2) { return pprintg1(s, pprintg1(s, format, v1), v2); } const char * -pprintg3(stream * s, const char *format, floatp v1, floatp v2, floatp v3) +pprintg3(stream * s, const char *format, double v1, double v2, double v3) { return pprintg2(s, pprintg1(s, format, v1), v2, v3); } const char * -pprintg4(stream * s, const char *format, floatp v1, floatp v2, floatp v3, - floatp v4) +pprintg4(stream * s, const char *format, double v1, double v2, double v3, + double v4) { return pprintg2(s, pprintg2(s, format, v1, v2), v3, v4); } const char * -pprintg6(stream * s, const char *format, floatp v1, floatp v2, floatp v3, - floatp v4, floatp v5, floatp v6) +pprintg6(stream * s, const char *format, double v1, double v2, double v3, + double v4, double v5, double v6) { return pprintg3(s, pprintg3(s, format, v1, v2, v3), v4, v5, v6); } diff -Nru ghostscript-9.10~dfsg/base/spprint.h ghostscript-9.25~dfsg+1/base/spprint.h --- ghostscript-9.10~dfsg/base/spprint.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spprint.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -41,15 +41,15 @@ * These functions return a pointer to the next %-element of the format, or * to the terminating 0. */ -const char *pprintg1(stream * s, const char *format, floatp v); -const char *pprintg2(stream * s, const char *format, floatp v1, floatp v2); +const char *pprintg1(stream * s, const char *format, double v); +const char *pprintg2(stream * s, const char *format, double v1, double v2); const char *pprintg3(stream * s, const char *format, - floatp v1, floatp v2, floatp v3); + double v1, double v2, double v3); const char *pprintg4(stream * s, const char *format, - floatp v1, floatp v2, floatp v3, floatp v4); + double v1, double v2, double v3, double v4); const char *pprintg6(stream * s, const char *format, - floatp v1, floatp v2, floatp v3, floatp v4, - floatp v5, floatp v6); + double v1, double v2, double v3, double v4, + double v5, double v6); /* * The rest of these printing functions exist solely because the ANSI C diff -Nru ghostscript-9.10~dfsg/base/spsdf.c ghostscript-9.25~dfsg+1/base/spsdf.c --- ghostscript-9.10~dfsg/base/spsdf.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spsdf.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/spsdf.h ghostscript-9.25~dfsg+1/base/spsdf.h --- ghostscript-9.10~dfsg/base/spsdf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spsdf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/spwgd.c ghostscript-9.25~dfsg+1/base/spwgd.c --- ghostscript-9.10~dfsg/base/spwgd.c 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spwgd.c 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,178 @@ +/* Copyright (C) 2017-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* PWGDecode filter */ +#include "stdio_.h" /* includes std.h */ +#include "memory_.h" +#include "strimpl.h" +#include "spwgx.h" + +/* ------ RunLengthDecode ------ */ + +private_st_PWGD_state(); + +/* Set defaults */ +static void +s_PWGD_set_defaults(stream_state * st) +{ + stream_PWGD_state *const ss = (stream_PWGD_state *) st; + + (ss)->bpp = PWG_default_bpp; + (ss)->width = PWG_default_width; +} + +/* Initialize */ +static int +s_PWGD_init(stream_state * st) +{ + stream_PWGD_state *const ss = (stream_PWGD_state *) st; + + (ss)->line_pos = 0; + (ss)->line_rep = 0; + (ss)->state = 0; + (ss)->line_buffer = NULL; + + return 0; +} + +/* Refill the buffer */ +static int +s_PWGD_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + stream_PWGD_state *const ss = (stream_PWGD_state *) st; + register const byte *p = pr->ptr; + register byte *q = pw->ptr; + const byte *rlimit = pr->limit; + byte *wlimit = pw->limit; + int bpp = (ss->bpp+7)>>3; + int wb = ss->width * bpp; + int line_pos = ss->line_pos; + + if (ss->line_buffer == NULL) { + ss->line_buffer = + gs_alloc_bytes_immovable(gs_memory_stable(ss->memory), + wb, + "s_PWGD_process(line_buffer)"); + if (ss->line_buffer == NULL) + return ERRC; + } + + while (1) { + if (ss->state == 0) { + /* Copy any buffered data out */ + if (ss->line_rep > 0) { + int avail = wb - line_pos; + if (avail > wlimit - q) + avail = wlimit - q; + if (avail != 0) + memcpy(q+1, &ss->line_buffer[line_pos], avail); + line_pos += avail; + q += avail; + if (line_pos == wb) { + line_pos = 0; + ss->line_rep--; + } + goto data_produced; + } + /* Now unpack data into the line buffer */ + /* Awaiting line repeat value */ + if (p == rlimit) + goto need_data; + ss->line_rep = (*++p) + 1; + ss->state = 1; /* Wait for pixel repeat */ + } + if (ss->state == 1) { + int rep; + /* Awaiting pixel repeat value */ + if (p == rlimit) + goto need_data; + rep = *++p; + if (rep < 0x80) { + /* Repeat the next pixel multiple times */ + ss->state = (rep+1) * bpp + 1; + if (line_pos + ss->state - 1 > wb) + /* Too many repeats for this line! */ + goto error; + } else { + /* Copy colors */ + ss->state = -(257 - rep) * bpp; + if (line_pos + -ss->state > wb) + /* Too many pixels for this line! */ + goto error; + } + } + if (ss->state > 1) { + /* Repeating a single pixel */ + int pixel_pos = line_pos % bpp; + int avail = bpp - pixel_pos; + if (avail > rlimit - p) + avail = rlimit - p; + if (avail != 0) + memcpy(&ss->line_buffer[line_pos], p+1, avail); + p += avail; + line_pos += avail; + pixel_pos += avail; + ss->state -= avail; + if (pixel_pos != bpp) + goto need_data; + while (ss->state > 1) { + memcpy(&ss->line_buffer[line_pos], &ss->line_buffer[line_pos - bpp], bpp); + line_pos += bpp; + ss->state -= bpp; + } + if (line_pos == wb) { + line_pos = 0; + ss->state = 0; + } else + ss->state = 1; + } + if (ss->state < 0) { + /* Copying literals */ + int avail = -ss->state; + if (avail > rlimit - p) + avail = rlimit - p; + memcpy(&ss->line_buffer[line_pos], p + 1, avail); + p += avail; + ss->state += avail; + line_pos += avail; + if (ss->state) + goto need_data; + ss->state = 1; + } + } +need_data: + { + int status = 0; /* Need input data */ + if (0) { +error: + status = ERRC; + } else if (0) { +data_produced: + status = 1; /* Need output space */ + } + pr->ptr = p; + pw->ptr = q; + ss->line_pos = line_pos; + return status; + } +} + +/* Stream template */ +const stream_template s_PWGD_template = { + &st_PWGD_state, s_PWGD_init, s_PWGD_process, 1, 1, NULL, + s_PWGD_set_defaults +}; diff -Nru ghostscript-9.10~dfsg/base/spwgx.h ghostscript-9.25~dfsg+1/base/spwgx.h --- ghostscript-9.10~dfsg/base/spwgx.h 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/spwgx.h 2018-09-13 10:02:01.000000000 +0000 @@ -0,0 +1,48 @@ +/* Copyright (C) 2017-2018 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, + modified or distributed except as expressly authorized under the terms + of the license contained in the file LICENSE in this distribution. + + Refer to licensing information at http://www.artifex.com or contact + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. +*/ + + +/* Definitions for PWG compatible RunLength filters */ +/* Requires scommon.h; strimpl.h if any templates are referenced */ + +#ifndef spwgx_INCLUDED +# define spwgx_INCLUDED + +/* Common state */ +#define stream_PWG_state_common\ + stream_state_common;\ + int width;\ + int bpp + +/* No encode for now */ + +/* PWG RunLengthDecode */ +typedef struct stream_PWGD_state_s { + stream_PWG_state_common; + int line_pos; /* Byte Position on the current line (0 to bpp*width-1) */ + int line_rep; /* Number of times this line should be repeated */ + byte *line_buffer; /* Pointer to line buffer */ + int state; /* 0 = Waiting for line_rep byte, 1 = Waiting for repeat, > 1 => copy n-1 bytes literally into linebuffer, < 0 => -n bytes of repeats */ +} stream_PWGD_state; + +/* Needed a default width. Stole it from fax. */ +#define PWG_default_width (1728) +#define PWG_default_bpp (8) + +#define private_st_PWGD_state() /* in spwgd.c */\ + gs_private_st_simple(st_PWGD_state, stream_PWGD_state, "PWGDecode state") +extern const stream_template s_PWGD_template; + +#endif /* spwgx_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/srdline.h ghostscript-9.25~dfsg+1/base/srdline.h --- ghostscript-9.10~dfsg/base/srdline.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/srdline.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/srld.c ghostscript-9.25~dfsg+1/base/srld.c --- ghostscript-9.10~dfsg/base/srld.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/srld.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/srle.c ghostscript-9.25~dfsg+1/base/srle.c --- ghostscript-9.10~dfsg/base/srle.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/srle.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/srlx.h ghostscript-9.25~dfsg+1/base/srlx.h --- ghostscript-9.10~dfsg/base/srlx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/srlx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ssha2.c ghostscript-9.25~dfsg+1/base/ssha2.c --- ghostscript-9.10~dfsg/base/ssha2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ssha2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ssha2.h ghostscript-9.25~dfsg+1/base/ssha2.h --- ghostscript-9.10~dfsg/base/ssha2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ssha2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/sstring.c ghostscript-9.25~dfsg+1/base/sstring.c --- ghostscript-9.10~dfsg/base/sstring.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sstring.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -334,6 +334,7 @@ continue; case char_EOL: c = '\n'; + /* fall through */ default: check_q(1); break; diff -Nru ghostscript-9.10~dfsg/base/sstring.h ghostscript-9.25~dfsg+1/base/sstring.h --- ghostscript-9.10~dfsg/base/sstring.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/sstring.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/stat_.h ghostscript-9.25~dfsg+1/base/stat_.h --- ghostscript-9.10~dfsg/base/stat_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stat_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -44,9 +44,18 @@ * for both the function name and the structure name. */ #ifdef _MSC_VER -# define stat _stat +# define stat __stat64 +# define struct_stat struct __stat64 +# define fstat _fstat64 +#else +#define struct_stat struct stat #endif +/* Find permissions for file */ +/* Ideally this would defined in gp.h, but the macroisms mean it has to be + * defined here. */ +extern int gp_stat(const char *path, struct stat *buf); + /* * Some (System V?) systems test for directories in a slightly different way. */ diff -Nru ghostscript-9.10~dfsg/base/std.h ghostscript-9.25~dfsg+1/base/std.h --- ghostscript-9.10~dfsg/base/std.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/std.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -25,18 +25,6 @@ #include "arch.h" /* - * Define lower-case versions of the architecture parameters for backward - * compatibility. - */ -#define arch_log2_sizeof_short ARCH_LOG2_SIZEOF_SHORT -#define arch_log2_sizeof_int ARCH_LOG2_SIZEOF_INT -#define arch_log2_sizeof_long ARCH_LOG2_SIZEOF_LONG -#define arch_sizeof_ptr ARCH_SIZEOF_PTR -#define arch_sizeof_float ARCH_SIZEOF_FLOAT -#define arch_sizeof_double ARCH_SIZEOF_DOUBLE -#define arch_is_big_endian ARCH_IS_BIG_ENDIAN -#define arch_arith_rshift ARCH_ARITH_RSHIFT -/* * Define the alignment that the memory manager must preserve. * We assume all alignment moduli are powers of 2. * NOTE: we require that malloc align blocks at least this strictly. @@ -52,16 +40,10 @@ #define ARCH_SIZEOF_LONG (1 << ARCH_LOG2_SIZEOF_LONG) #define ARCH_SIZEOF_LONG_LONG (1 << ARCH_LOG2_SIZEOF_LONG_LONG) #define ARCH_INTS_ARE_SHORT (ARCH_SIZEOF_INT == ARCH_SIZEOF_SHORT) -/* Backward compatibility */ -#define arch_sizeof_short ARCH_SIZEOF_SHORT -#define arch_sizeof_int ARCH_SIZEOF_INT -#define arch_sizeof_long ARCH_SIZEOF_LONG /* Define whether we are on a large- or small-memory machine. */ /* Currently, we assume small memory and 16-bit ints are synonymous. */ #define ARCH_SMALL_MEMORY (ARCH_SIZEOF_INT <= 2) -/* Backward compatibility */ -#define arch_small_memory ARCH_SMALL_MEMORY /* Define unsigned 16- and 32-bit types. These are needed in */ /* a surprising number of places that do bit manipulation. */ @@ -78,11 +60,11 @@ /* Minimum and maximum values for the signed types. */ /* Avoid casts, to make them acceptable to strict ANSI compilers. */ -#define min_short (-1 << (arch_sizeof_short * 8 - 1)) +#define min_short (-1 << (ARCH_SIZEOF_SHORT * 8 - 1)) #define max_short (~min_short) -#define min_int (-1 << (arch_sizeof_int * 8 - 1)) +#define min_int (-1 << (ARCH_SIZEOF_INT * 8 - 1)) #define max_int (~min_int) -#define min_long (-1L << (arch_sizeof_long * 8 - 1)) +#define min_long (-1L << (ARCH_SIZEOF_LONG * 8 - 1)) #define max_long (~min_long) #define min_int64_t (-((int64_t)1) << (sizeof(int64_t) * 8 - 1)) @@ -116,11 +98,11 @@ /* Define a reliable arithmetic right shift. */ /* Must use arith_rshift_1 for a shift by a literal 1. */ #define arith_rshift_slow(x,n) ((x) < 0 ? ~(~(x) >> (n)) : (x) >> (n)) -#if arch_arith_rshift == 2 +#if ARCH_ARITH_RSHIFT == 2 # define arith_rshift(x,n) ((x) >> (n)) # define arith_rshift_1(x) ((x) >> 1) #else -#if arch_arith_rshift == 1 /* OK except for n=1 */ +#if ARCH_ARITH_RSHIFT == 1 /* OK except for n=1 */ # define arith_rshift(x,n) ((x) >> (n)) # define arith_rshift_1(x) arith_rshift_slow(x,1) #else @@ -424,6 +406,7 @@ void emprintf_program_ident(const gs_memory_t *mem, const char *program_name, long revision_number); +const char *gs_program_family_name(void); const char *gs_program_name(void); long gs_revision_number(void); diff -Nru ghostscript-9.10~dfsg/base/stdint_.h ghostscript-9.25~dfsg+1/base/stdint_.h --- ghostscript-9.10~dfsg/base/stdint_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stdint_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -138,37 +138,36 @@ # define PRIu32 "I32u" # define PRIu64 "I64u" # define PRIx64 "I64x" -# else - -# ifndef PRId32 -# define PRId32 "d" -# endif +# endif +#endif -# ifndef PRId64 -# define PRId64 "lld" -# endif +/* Even if we have inttypes.h, these may not be defined */ +# ifndef PRId32 +# define PRId32 "d" +# endif -# ifndef PRIi32 -# define PRIi32 "i" -# endif +# ifndef PRId64 +# define PRId64 "lld" +# endif -# ifndef PRIi64 -# define PRIi64 "lli" -# endif +# ifndef PRIi32 +# define PRIi32 "i" +# endif -# ifndef PRIu32 -# define PRIu32 "u" -# endif +# ifndef PRIi64 +# define PRIi64 "lli" +# endif -# ifndef PRIu64 -# define PRIu64 "llu" -# endif +# ifndef PRIu32 +# define PRIu32 "u" +# endif -# ifndef PRIx64 -# define PRIx64 "llx" -# endif +# ifndef PRIu64 +# define PRIu64 "llu" +# endif +# ifndef PRIx64 +# define PRIx64 "llx" # endif -#endif #endif /* stdint__INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/stdio_.h ghostscript-9.25~dfsg+1/base/stdio_.h --- ghostscript-9.10~dfsg/base/stdio_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stdio_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -73,9 +73,12 @@ # if _MSC_VER < 1500 /* VS 2008 has vsnprintf */ # define vsnprintf _vsnprintf # endif +# if _MSC_VER<1900 /* Microsoft Visual C++ 2005 doesn't properly define snprintf */ -int snprintf(char *buffer, size_t count, const char *format , ...); -#endif +/* But, finally, with VS 2014 and above, Microsoft has snprintf */ + int snprintf(char *buffer, size_t count, const char *format , ...); +# endif +#endif /* _MSC_VER */ /* for our non-localizing (v)s(n)printf() functions */ /* only *really* required for floating point conversions */ diff -Nru ghostscript-9.10~dfsg/base/stdpn.h ghostscript-9.25~dfsg+1/base/stdpn.h --- ghostscript-9.10~dfsg/base/stdpn.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stdpn.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Pn macros for pre-ANSI compiler compatibility */ - -#ifndef stdpn_INCLUDED -# define stdpn_INCLUDED - -/* - * We formerly supported "traditional" (pre-ANSI) C compilers, by using - * these macros for formal parameter lists and defining them as empty - * for pre-ANSI compilers, with the syntax - * resulttype func(Pn(arg1, ..., argn)); - * However, we no longer support pre-ANSI compilers; these macros are - * deprecated (should not be used in new code), and eventually will be - * removed. - */ - -#define P0() void -#define P1(t1) t1 -#define P2(t1,t2) t1,t2 -#define P3(t1,t2,t3) t1,t2,t3 -#define P4(t1,t2,t3,t4) t1,t2,t3,t4 -#define P5(t1,t2,t3,t4,t5) t1,t2,t3,t4,t5 -#define P6(t1,t2,t3,t4,t5,t6) t1,t2,t3,t4,t5,t6 -#define P7(t1,t2,t3,t4,t5,t6,t7) t1,t2,t3,t4,t5,t6,t7 -#define P8(t1,t2,t3,t4,t5,t6,t7,t8) t1,t2,t3,t4,t5,t6,t7,t8 -#define P9(t1,t2,t3,t4,t5,t6,t7,t8,t9) t1,t2,t3,t4,t5,t6,t7,t8,t9 -#define P10(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10 -#define P11(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11 -#define P12(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12 -#define P13(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13 -#define P14(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14 -#define P15(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15 -#define P16(t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16) t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16 - -#endif /* stdpn_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/stdpre.h ghostscript-9.25~dfsg+1/base/stdpre.h --- ghostscript-9.10~dfsg/base/stdpre.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stdpre.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,8 +19,11 @@ #ifndef stdpre_INCLUDED # define stdpre_INCLUDED +/* if we define _LARGEFILE64_SOURCE zlib tries to include unistd.h */ +#ifndef _MSC_VER /* Ghostscript uses transitional LFS functions. */ #define _LARGEFILE64_SOURCE 1 +#endif #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 @@ -90,6 +93,27 @@ # define volatile /* */ #endif +/* restrict is standard in C99, but not in all C++ compilers. */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ == 199901L /* C99 */ +# if defined(HAVE_RESTRICT) && HAVE_RESTRICT==1 +# define gs_restrict restrict +# else /* defined(HAVE_RESTRICT) && HAVE_RESTRICT==1 */ +# define gs_restrict +# endif /* defined(HAVE_RESTRICT) && HAVE_RESTRICT==1 */ +#elif defined(_MSC_VER) && _MSC_VER >= 1500 /* MSVC 9 or newer */ +# define gs_restrict __restrict +#elif __GNUC__ >= 3 /* GCC 3 or newer */ +# if defined(HAVE_RESTRICT) && HAVE_RESTRICT==1 +# define gs_restrict __restrict +# else /* defined(HAVE_RESTRICT) && HAVE_RESTRICT==1 */ +# define gs_restrict +# endif /* defined(HAVE_RESTRICT) && HAVE_RESTRICT==1 */ +#else /* Unknown or ancient */ +# define gs_restrict +#endif + + + /* Disable 'inline' if the compiler can't handle it. */ #ifdef __DECC # undef inline @@ -106,6 +130,15 @@ # endif #endif +/* Define ourselves a 'forceinline' we can use to more forcefully + * tell the compiler to inline something. On all but MSVC this can + * drop back to inline. */ +#ifdef _MSC_VER +#define forceinline __forceinline +#else +#define forceinline inline +#endif + /* * Provide a way to include inline procedures in header files, regardless of * whether the compiler (A) doesn't support inline at all, (B) supports it @@ -256,6 +289,9 @@ typedef unsigned int uint; typedef unsigned long ulong; +/* And for signed char */ +typedef signed char schar; + /* Since sys/types.h may define one or more of these (depending on * the platform), we have to take steps to prevent name clashes. * Unfortunately this can clobber valid definitions for the size- @@ -270,12 +306,14 @@ #define uint uint_ #define ushort ushort_ #define ulong ulong_ +#define schar schar_ #include #undef bool #undef uchar #undef uint #undef ushort #undef ulong +#undef schar /* * Define a Boolean type. Even though we would like it to be @@ -299,12 +337,21 @@ * an enum in the (MacOS) Universal Interfaces. The only way around this is to escape * our own definitions wherever MacTypes.h is included. */ +#if defined(_MSC_VER) && _MSC_VER >= 1900 +/* VS 2014 defines bool already, but has it as _Bool (a 1 byte thing). + * We can't live with that. */ +#undef false +#define false ((bool)0) +#undef true +#define true ((bool)1) +#else #ifndef __MACOS__ #undef false #define false ((bool)0) #undef true #define true ((bool)1) #endif /* __MACOS__ */ +#endif /* * Compilers disagree as to whether macros used in macro arguments @@ -362,16 +409,6 @@ #define round_down(v, m) ROUND_DOWN(v, m) /* - * In pre-ANSI C, float parameters get converted to double. - * However, if we pass a float to a function that has been declared - * with a prototype, and the parameter has been declared as float, - * the ANSI standard specifies that the parameter is left as float. - * To avoid problems caused by missing prototypes, - * we declare almost all float parameters as double. - */ -typedef double floatp; - -/* * Because of C's strange insistence that ; is a terminator and not a * separator, compound statements {...} are not syntactically equivalent to * single statements. Therefore, we define here a compound-statement @@ -402,16 +439,6 @@ #define client_name_string(cname) (cname) /* - * Define the now-deprecated Pn macros for pre-ANSI compiler compatibility. - * The double-inclusion check is replicated here because of the way that - * jconfig.h is constructed. - */ -#ifndef stdpn_INCLUDED -# define stdpn_INCLUDED -#include "stdpn.h" -#endif /* stdpn_INCLUDED */ - -/* * Define success and failure codes for 'exit'. The only system on which * they are different is VMS with older DEC C versions. We aren't sure * in what version DEC C started being compatible with the rest of the diff -Nru ghostscript-9.10~dfsg/base/stream.c ghostscript-9.25~dfsg+1/base/stream.c --- ghostscript-9.10~dfsg/base/stream.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stream.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -432,8 +432,11 @@ stream_proc_release((*release)) = st->templat->release; if (release != 0) (*release) (st); - if (st != (stream_state *) s && st->memory != 0) - gs_free_object(st->memory, st, "s_std_close"); + if (st != (stream_state *) s && st->memory != 0) { + gs_memory_t *mem = st->memory; + st->memory = NULL; + gs_free_object(mem, st, "s_std_close"); + } s->state = (stream_state *) s; } s_disable(s); @@ -458,10 +461,11 @@ ) s_process_read_buf(s); if (left <= min_left && - (left == 0 || (status != EOFC && status != ERRC)) + (left <= 0 || (status != EOFC && status != ERRC)) ) { /* Compact the stream so stell will return the right result. */ - stream_compact(s, true); + if (left == 0) + stream_compact(s, true); if (status == EOFC && close_at_eod && s->close_at_eod) { status = sclose(s); if (status == 0) @@ -495,7 +499,11 @@ int sungetc(register stream * s, byte c) { - if (!s_is_reading(s) || s->srptr < s->cbuf || *(s->srptr) != c) + /* cbuf == NULL means this stream is stdin, and we shouldn't + unread from stdin, ever. + */ + if (s->cbuf == NULL || !s_is_reading(s) || + s->srptr < s->cbuf || *(s->srptr) != c) return ERRC; s->srptr--; return 0; diff -Nru ghostscript-9.10~dfsg/base/stream.h ghostscript-9.25~dfsg+1/base/stream.h --- ghostscript-9.10~dfsg/base/stream.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stream.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -190,6 +190,8 @@ stream_enum_ptrs, stream_reloc_ptrs, stream_finalize) #define STREAM_NUM_PTRS 6 +#define S_FILE_LIMIT_MAX (sizeof(gs_offset_t) > 4 ? max_int64_t : max_long) + /* Initialize the checking IDs of a stream. */ #define s_init_ids(s) ((s)->read_id = (s)->write_id = 1) #define s_init_read_id(s) ((s)->read_id = 1, (s)->write_id = 0) @@ -341,7 +343,7 @@ uint, stream **, char[4], gs_memory_t *); /* Set up a file stream on an OS file. */ -void file_init_stream(stream *, FILE *, const char *, byte *, uint); +int file_init_stream(stream *, FILE *, const char *, byte *, uint); /* Open a file stream, optionally on an OS file. */ int file_open_stream(const char *, uint, const char *, @@ -363,7 +365,7 @@ #define check_file(svar,op)\ BEGIN\ check_type(*(op), t_file);\ - if ( file_is_invalid(svar, op) ) return_error(e_invalidaccess);\ + if ( file_is_invalid(svar, op) ) return_error(gs_error_ioerror);\ END /* Close a file stream. */ @@ -379,8 +381,8 @@ sread_string_reusable(stream *, const byte *, uint), swrite_string(stream *, byte *, uint); void sread_file(stream *, FILE *, byte *, uint), - swrite_file(stream *, FILE *, byte *, uint), - sappend_file(stream *, FILE *, byte *, uint); + swrite_file(stream *, FILE *, byte *, uint); +int sappend_file(stream *, FILE *, byte *, uint); /* Confine reading to a subfile. This is primarily for reusable streams. */ int sread_subfile(stream *s, gs_offset_t start, gs_offset_t length); diff -Nru ghostscript-9.10~dfsg/base/strimpl.h ghostscript-9.25~dfsg+1/base/strimpl.h --- ghostscript-9.10~dfsg/base/strimpl.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/strimpl.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/string_.h ghostscript-9.25~dfsg+1/base/string_.h --- ghostscript-9.10~dfsg/base/string_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/string_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -37,6 +37,15 @@ # ifdef MEMORY__NEED_MEMMOVE # define memmove(dest,src,len) gs_memmove(dest,src,len) # endif +# ifdef _MSC_VER +# define strcasecmp stricmp /* MSC doesn't have the POSIX functions */ +# define strncasecmp strnicmp +# endif #endif +#include "gsstrtok.h" +#include "gsstrl.h" + +#define strtok DO_NOT_USE_STRTOK + #endif /* string__INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/strmio.c ghostscript-9.25~dfsg+1/base/strmio.c --- ghostscript-9.10~dfsg/base/strmio.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/strmio.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -67,7 +67,7 @@ s->position = 0; code = ssetfilename(s, (const byte *)path, strlen(path)); if (code < 0) { - /* Only error is e_VMerror */ + /* Only error is gs_error_VMerror */ sclose(s); gs_free_object(s->memory, s, "sfopen: allocation error"); # define EMSG "sfopen: allocation error setting path name into stream.\n" @@ -89,6 +89,8 @@ uint nread; code = sgets(s, ptr, size*count, &nread); + if (code < 0) + return code; return nread*size; } diff -Nru ghostscript-9.10~dfsg/base/strmio.h ghostscript-9.25~dfsg+1/base/strmio.h --- ghostscript-9.10~dfsg/base/strmio.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/strmio.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -35,6 +35,9 @@ * If iodev_default is the '%os' device, then the file will be on the host * file system transparently to the caller. The "%os%" prefix can be used * to explicilty access the host file system. + * + * NOTE: sfopen() always opens files in "binary" mode on systems where that + * is applicable - so callers should not do so themselves. */ stream * sfopen(const char *path, const char *mode, gs_memory_t *mem); diff -Nru ghostscript-9.10~dfsg/base/stub.mak ghostscript-9.25~dfsg+1/base/stub.mak --- ghostscript-9.10~dfsg/base/stub.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/stub.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # # empty "stub" makefile - used to stand in for an optional makefile diff -Nru ghostscript-9.10~dfsg/base/szlibc.c ghostscript-9.25~dfsg+1/base/szlibc.c --- ghostscript-9.10~dfsg/base/szlibc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/szlibc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/szlibd.c ghostscript-9.25~dfsg+1/base/szlibd.c --- ghostscript-9.10~dfsg/base/szlibd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/szlibd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/szlibe.c ghostscript-9.25~dfsg+1/base/szlibe.c --- ghostscript-9.10~dfsg/base/szlibe.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/szlibe.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/szlibx.h ghostscript-9.25~dfsg+1/base/szlibx.h --- ghostscript-9.10~dfsg/base/szlibx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/szlibx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/szlibxx.h ghostscript-9.25~dfsg+1/base/szlibxx.h --- ghostscript-9.10~dfsg/base/szlibxx.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/szlibxx.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/tiff.mak ghostscript-9.25~dfsg+1/base/tiff.mak --- ghostscript-9.10~dfsg/base/tiff.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/tiff.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for libtiff. # Users of this makefile must define the following: @@ -31,11 +31,11 @@ TIFFCONF_H=$(TIFFCONF)libtiff$(D)tiffconf$(TIFFCONFIG_SUFFIX).h # Define the name of this makefile. -LIBTIFF_MAK=$(GLSRC)tiff.mak +LIBTIFF_MAK=$(GLSRC)tiff.mak $(TOP_MAKEFILES) -TIFFCC=$(CC_) $(I_)$(TI_) $(II)$(JI_)$(_I) $(PF_) +TIFFCC=$(CC_) $(TIFF_CFLAGS) $(I_)$(TI_) $(II)$(JI_)$(_I) $(PF_) -TIFFDEP = $(AK) $(TIFFGEN)tif_config.h $(TIFFGEN)tiffconf.h +TIFFDEP = $(AK) $(TIFFGEN)tif_config.h $(TIFFGEN)tiffconf.h $(LIBTIFF_MAK) $(MAKEDIRS) gstiffio_h=$(GLSRC)gstiffio.h tiff_1=$(TIFFOBJ)tif_aux.$(OBJ) $(TIFFOBJ)tif_close.$(OBJ) $(TIFFOBJ)tif_codec.$(OBJ) $(TIFFOBJ)tif_color.$(OBJ) @@ -51,11 +51,11 @@ tiff_10=$(TIFFOBJ)tif_zip.$(OBJ) tiff_11=$(TIFFOBJ)gstiffio.$(OBJ) -$(TIFFSRC)libtiff$(D)tif_config.unix.h : $(TIFFSRC)libtiff$(D)tif_config.h.in +$(TIFFSRC)libtiff$(D)tif_config.unix.h : $(TIFFSRC)libtiff$(D)tif_config.h.in $(LIBTIFF_MAK) cd $(TIFFSRC) && ./configure $(CP_) $(TIFFCONF)libtiff$(D)tif_config.h $(TIFFCONF)libtiff$(D)tif_config.unix.h -$(TIFFSRC)libtiff$(D)tiffconf.unix.h : $(TIFFSRC)libtiff$(D)tiffconf.h.in +$(TIFFSRC)libtiff$(D)tiffconf.unix.h : $(TIFFSRC)libtiff$(D)tiffconf.h.in $(LIBTIFF_MAK) cd $(TIFFSRC) && ./configure $(CP_) $(TIFFCONF)libtiff$(D)tiffconf.h $(TIFFCONF)libtiff$(D)tiffconf.unix.h @@ -184,24 +184,31 @@ # instead of the platform specific files above, we include our own which stubs out # the platform specific code, and routes via the Ghostscript I/O functions. -$(TIFFOBJ)gstiffio.$(OBJ) : $(GLSRC)gstiffio.c $(gstiffio_h) $(PDEVH) $(stdint__h) $(stdio__h) $(time__h)\ - $(gscdefs_h) $(gstypes_h) $(stream_h) $(strmio_h) $(malloc__h) - $(TIFFCC) $(TIFFO_)gstiffio.$(OBJ) $(D_)SHARE_LIBTIFF=$(SHARE_LIBTIFF) $(C_) $(GLSRC)gstiffio.c +$(TIFFOBJ)gstiffio_0.$(OBJ) : $(GLSRC)gstiffio.c $(gstiffio_h) $(PDEVH) $(stdint__h) $(stdio__h) $(time__h)\ + $(gscdefs_h) $(gstypes_h) $(stream_h) $(strmio_h) $(malloc__h) $(TIFFDEP) + $(TIFFCC) $(TIFFO_)gstiffio_0.$(OBJ) $(D_)SHARE_LIBTIFF=$(SHARE_LIBTIFF) $(C_) $(GLSRC)gstiffio.c + +$(TIFFOBJ)gstiffio_1.$(OBJ) : $(GLSRC)gstiffio.c $(gstiffio_h) $(PDEVH) $(stdint__h) $(stdio__h) $(time__h)\ + $(gscdefs_h) $(gstypes_h) $(stream_h) $(strmio_h) $(malloc__h) $(LIBTIFF_MAK) $(MAKEDIRS) + $(TIFFCC) $(TIFFO_)gstiffio_1.$(OBJ) $(D_)SHARE_LIBTIFF=$(SHARE_LIBTIFF) $(C_) $(GLSRC)gstiffio.c -$(TIFFGEN)tif_config.h: $(TIFFCONFIG_H) +$(TIFFOBJ)gstiffio.$(OBJ) : $(TIFFOBJ)gstiffio_$(SHARE_LIBTIFF).$(OBJ) $(LIBTIFF_MAK) $(MAKEDIRS) + $(CP_) $(TIFFOBJ)gstiffio_$(SHARE_LIBTIFF).$(OBJ) $(TIFFOBJ)gstiffio.$(OBJ) + +$(TIFFGEN)tif_config.h: $(TIFFCONFIG_H) $(LIBTIFF_MAK) $(MAKEDIRS) $(CP_) $(TIFFCONFIG_H) $(TIFFGEN)tif_config.h -$(TIFFGEN)tiffconf.h: $(TIFFCONF_H) +$(TIFFGEN)tiffconf.h: $(TIFFCONF_H) $(LIBTIFF_MAK) $(MAKEDIRS) $(CP_) $(TIFFCONF_H) $(TIFFGEN)tiffconf.h # Define the version of libtiff.dev that we are actually using. -$(TIFFGEN)libtiff.dev : $(TOP_MAKEFILES) $(TIFFGEN)libtiff_$(SHARE_LIBTIFF).dev +$(TIFFGEN)libtiff.dev : $(TIFFGEN)libtiff_$(SHARE_LIBTIFF).dev $(LIBTIFF_MAK) $(MAKEDIRS) $(CP_) $(TIFFGEN)libtiff_$(SHARE_LIBTIFF).dev $(TIFFGEN)libtiff.dev # Define the shared version. -$(TIFFGEN)libtiff_1.dev : $(TOP_MAKEFILES) $(LIBTIFF_MAK) $(ECHOGS_XE) $(JPEGGEN)jpegd.dev $(JPEGGEN)jpege.dev \ - $(tiff_11) +$(TIFFGEN)libtiff_1.dev : $(LIBTIFF_MAK) $(ECHOGS_XE) $(JPEGGEN)jpegd.dev $(JPEGGEN)jpege.dev \ + $(tiff_11) $(MAKEDIRS) $(SETMOD) $(TIFFGEN)libtiff_1 $(tiff_11) $(ADDMOD) $(TIFFGEN)libtiff_1 -lib $(LIBTIFF_NAME) $(ADDMOD) $(TIFFGEN)libtiff_1 -include $(JPEGGEN)jpegd.dev @@ -211,7 +218,7 @@ $(TIFFGEN)libtiff_0.dev : $(LIBTIFF_MAK) $(ECHOGS_XE) \ $(tiff_1) $(tiff_2) $(tiff_3) $(tiff_4) $(tiff_5) \ $(tiff_6) $(tiff_7) $(tiff_8) $(tiff_9) $(tiff_10) $(tiff_11) \ - $(JPEGGEN)jpegd.dev $(JPEGGEN)jpege.dev + $(JPEGGEN)jpegd.dev $(JPEGGEN)jpege.dev $(MAKEDIRS) $(SETMOD) $(TIFFGEN)libtiff_0 $(tiff_1) $(ADDMOD) $(TIFFGEN)libtiff_0 $(tiff_2) $(ADDMOD) $(TIFFGEN)libtiff_0 $(tiff_3) diff -Nru ghostscript-9.10~dfsg/base/time_.h ghostscript-9.25~dfsg+1/base/time_.h --- ghostscript-9.10~dfsg/base/time_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/time_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/trio.mak ghostscript-9.25~dfsg+1/base/trio.mak --- ghostscript-9.10~dfsg/base/trio.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/trio.mak 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. -# All Rights Reserved. -# -# This software is provided AS-IS with no warranty, either express or -# implied. -# -# This software is distributed under license and may not be copied, -# modified or distributed except as expressly authorized under the terms -# of the license contained in the file LICENSE in this distribution. -# -# Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. -# -# makefile for trio - locale-less s(n)printf/s(n)canf -# -# Users of this makefile must define the following: -# TRIO_CFLAGS - Compiler flags for building the source, -# TRIOSRCDIR - the expat source top-level directory, -# TIOOBJDIR - directory for object files. - -# Define the name of this makefile -TRIO_MAK=$(GLSRCDIR)$(D)trio.mak - -# local aliases -TRIOSRC=$(TRIOSRCDIR)$(D) -TRIOOBJ=$(TRIOOBJDIR)$(D) -TRIOO_=$(O_)$(TRIOOBJ) - -TRIOCFLAGS=$(CFLAGS) $(TRIO_CFLAGS) $(D_)TRIO_EMBED_STRING$(_D) $(D_)TRIO_FEATURE_CLOSURE=0$(_D) \ -$(D_)TRIO_FEATURE_DYNAMICSTRING=0$(_D) $(D_)TRIO_MINIMAL=0$(_D) \ -$(D_)TRIO_FEATURE_USER_DEFINED=0$(_D) $(D_)TRIO_EXTENSION=0$(_D)\ -$(D_)TRIO_FUNC_TO_FLOAT$(_D) $(I_)$(TRIOSRCDIR)$(_I) \ -$(D_)TRIO_MALLOC=no_malloc$(_D) $(D_)TRIO_REALLOC=no_realloc$(_D) $(D_)TRIO_FREE=no_free$(_D) - - -# NB: we can't use the normal $(CC_) here because msvccmd.mak -# adds /Za which conflicts with the trio source. -TRIOCC=$(CC) $(TRIOCFLAGS) - -TRIOOBJS=$(TRIOOBJ)triostr.$(OBJ) $(TRIOOBJ)trio.$(OBJ) $(TRIOOBJ)trionan.$(OBJ) - -triodef_h=$(TRIOSRC)triodef.h -trio_h=$(TRIOSRC)trio.h -triop_h=$(TRIOSRC)triop.h -triostr_h=$(TRIOSRC)triostr.h - -TRIOHDRS=$(triodef_h) $(trio_h) $(triop_h) $(triostr_h) - -$(TRIOOBJ)triostr.$(OBJ) : $(TRIOSRC)triostr.c $(TRIOHDRS) $(TRIO_MAK) - $(TRIOCC) $(TRIOO_)triostr.$(OBJ) $(C_) $(TRIOSRC)triostr.c - -$(TRIOOBJ)trio.$(OBJ) : $(TRIOSRC)trio.c $(TRIOHDRS) $(TRIO_MAK) - $(TRIOCC) $(TRIOO_)trio.$(OBJ) $(C_) $(TRIOSRC)trio.c - -$(TRIOOBJ)trionan.$(OBJ) : $(TRIOSRC)trionan.c $(TRIOHDRS) $(TRIO_MAK) - $(TRIOCC) $(TRIOO_)trionan.$(OBJ) $(C_) $(TRIOSRC)trionan.c diff -Nru ghostscript-9.10~dfsg/base/ttcalc.c ghostscript-9.25~dfsg+1/base/ttcalc.c --- ghostscript-9.10~dfsg/base/ttcalc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttcalc.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttcalc.h ghostscript-9.25~dfsg+1/base/ttcalc.h --- ghostscript-9.10~dfsg/base/ttcalc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttcalc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttcommon.h ghostscript-9.25~dfsg+1/base/ttcommon.h --- ghostscript-9.10~dfsg/base/ttcommon.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttcommon.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttconf.h ghostscript-9.25~dfsg+1/base/ttconf.h --- ghostscript-9.10~dfsg/base/ttconf.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttconf.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttconfig.h ghostscript-9.25~dfsg+1/base/ttconfig.h --- ghostscript-9.10~dfsg/base/ttconfig.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttconfig.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttfinp.c ghostscript-9.25~dfsg+1/base/ttfinp.c --- ghostscript-9.10~dfsg/base/ttfinp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttfinp.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttfinp.h ghostscript-9.25~dfsg+1/base/ttfinp.h --- ghostscript-9.10~dfsg/base/ttfinp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttfinp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttfmain.c ghostscript-9.25~dfsg+1/base/ttfmain.c --- ghostscript-9.10~dfsg/base/ttfmain.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttfmain.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -276,6 +276,8 @@ self->nFlags = ttfReader__UShort(r); r->Seek(r, self->t_head.nPos + offset_of(sfnt_FontHeader, unitsPerEm)); self->nUnitsPerEm = ttfReader__UShort(r); + if (self->nUnitsPerEm <= 0) + self->nUnitsPerEm = 1024; r->Seek(r, self->t_head.nPos + offset_of(sfnt_FontHeader, indexToLocFormat)); self->nIndexToLocFormat = ttfReader__UShort(r); r->Seek(r, self->t_maxp.nPos + offset_of(sfnt_maxProfileTable, numGlyphs)); @@ -704,11 +706,11 @@ else if (code == TT_Err_Invalid_Engine) error = fPatented; else { - /* We have a range or errors that can be caused by + /* We have a range of errors that can be caused by * bad bytecode */ - if (error >= TT_Err_Invalid_Opcode - || error <= TT_Err_Invalid_Displacement) { + if ((int)code >= TT_Err_Invalid_Opcode + && (int)code <= TT_Err_Invalid_Displacement) { error = fBadInstruction; } else { @@ -734,11 +736,11 @@ for (i = 0; i < gOutline->contourCount; i++) endPoints[i] = ttfReader__Short(r); for (i = 1; i < gOutline->contourCount; i++) - if (endPoints[i - 1] >= endPoints[i]) { + if (endPoints[i - 1] < 0 || endPoints[i - 1] >= endPoints[i]) { error = fBadFontData; goto ex; } nPoints = gOutline->pointCount = endPoints[gOutline->contourCount - 1] + 1; - if (self->nPointsTotal + nPoints + 2 > exec->n_points) { + if (nPoints < 0 || self->nPointsTotal + nPoints + 2 > exec->n_points) { error = fBadFontData; goto ex; } n_ins = ttfReader__Short(r); @@ -882,11 +884,11 @@ ttfFont *pFont = self->pFont; ttfExport *exp = self->exp; TExecution_Context *exec = pFont->exec; - TGlyph_Zone *pts = &exec->pts; - short* endP = pts->contours; - byte* onCurve = pts->touch; - F26Dot6* x = pts->org_x; - F26Dot6* y = pts->org_y; + TGlyph_Zone *epts = &exec->pts; + short* endP = epts->contours; + byte* onCurve = epts->touch; + F26Dot6* x = epts->org_x; + F26Dot6* y = epts->org_y; F26Dot6 px, py; short sp, ctr; FloatPoint p0, p1, p2, p3; @@ -1040,7 +1042,5 @@ self->post_transform.c /= pFont->nUnitsPerEm; self->post_transform.d /= pFont->nUnitsPerEm; } - if (error != fNoError && error != fPatented) - return error; return error; } diff -Nru ghostscript-9.10~dfsg/base/ttfmemd.c ghostscript-9.25~dfsg+1/base/ttfmemd.c --- ghostscript-9.10~dfsg/base/ttfmemd.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttfmemd.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttfmemd.h ghostscript-9.25~dfsg+1/base/ttfmemd.h --- ghostscript-9.10~dfsg/base/ttfmemd.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttfmemd.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttfoutl.h ghostscript-9.25~dfsg+1/base/ttfoutl.h --- ghostscript-9.10~dfsg/base/ttfoutl.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttfoutl.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,6 +19,9 @@ #ifndef incl_ttfoutl #define incl_ttfoutl +/* For memento */ +#include "malloc_.h" + #ifndef TFace_defined #define TFace_defined typedef struct _TFace TFace; diff -Nru ghostscript-9.10~dfsg/base/ttfsfnt.h ghostscript-9.25~dfsg+1/base/ttfsfnt.h --- ghostscript-9.10~dfsg/base/ttfsfnt.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttfsfnt.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* Changes after Apple: replaced non-portable types with ISO/IEC 988:1999 exact-size types */ diff -Nru ghostscript-9.10~dfsg/base/ttinterp.c ghostscript-9.25~dfsg+1/base/ttinterp.c --- ghostscript-9.10~dfsg/base/ttinterp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttinterp.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -1782,7 +1782,8 @@ CUR.step_ins = FALSE; /* See JMPR below */ - if(CUR.code[CUR.IP] != 0x2D && CUR.code[CUR.IP - 1] == 0x2D) + if(CUR.IP > CUR.codeSize || + (CUR.code[CUR.IP] != 0x2D && CUR.code[CUR.IP - 1] == 0x2D)) CUR.IP -= 1; } } @@ -1793,10 +1794,17 @@ static void Ins_JMPR( INS_ARG ) { + if ( BOUNDS(CUR.IP + args[0], CUR.codeSize ) ) + { + CUR.error = TT_Err_Invalid_Reference; + return; + } + CUR.IP += (Int)(args[0]); CUR.step_ins = FALSE; - if(CUR.code[CUR.IP] != 0x2D && CUR.code[CUR.IP - 1] == 0x2D) + if(CUR.IP > CUR.codeSize || + (CUR.code[CUR.IP] != 0x2D && CUR.code[CUR.IP - 1] == 0x2D)) /* The JPMR is meant to stop at the ENDF instruction to finish * the function. However the programmer made a mistake, and ended * up one byte too far. I suspect that some TT interpreters handle this @@ -2457,7 +2465,9 @@ static void Ins_WCVTF( INS_ARG ) { +#ifdef DEBUG int ov; +#endif if ( BOUNDS( args[0], CUR.cvtSize ) ) { @@ -2465,9 +2475,13 @@ return; } +#ifdef DEBUG ov = CUR.cvt[args[0]]; +#endif CUR.cvt[args[0]] = FUnits_To_Pixels( EXEC_ARGS args[1] ); +#ifdef DEBUG DBG_PRINT3(" cvt[%d]%d:=%d", args[0], ov, CUR.cvt[args[0]]); +#endif } /*******************************************/ @@ -3414,18 +3428,25 @@ TT_F26Dot6 dy, Bool touch ) { - if ( CUR.GS.freeVector.x != 0 ) + if (point >= CUR.n_points) { - CUR.zp2.cur_x[point] += dx; - if ( touch ) - CUR.zp2.touch[point] |= TT_Flag_Touched_X; + CUR.error = TT_Err_Invalid_Reference; } - - if ( CUR.GS.freeVector.y != 0 ) + else { - CUR.zp2.cur_y[point] += dy; - if ( touch ) - CUR.zp2.touch[point] |= TT_Flag_Touched_Y; + if ( CUR.GS.freeVector.x != 0 ) + { + CUR.zp2.cur_x[point] += dx; + if ( touch ) + CUR.zp2.touch[point] |= TT_Flag_Touched_X; + } + + if ( CUR.GS.freeVector.y != 0 ) + { + CUR.zp2.cur_y[point] += dy; + if ( touch ) + CUR.zp2.touch[point] |= TT_Flag_Touched_Y; + } } } @@ -3762,7 +3783,8 @@ point = (Int)args[0]; - if ( BOUNDS( args[0], CUR.zp1.n_points ) ) + if ( BOUNDS( args[0], CUR.zp1.n_points ) || + BOUNDS( CUR.GS.rp0, CUR.zp0.n_points) ) { /* Current version of FreeType silently ignores this out of bounds error * and drops the instruction, see bug #691121 @@ -3850,7 +3872,8 @@ /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ if ( BOUNDS( args[0], CUR.zp1.n_points ) || - BOUNDS( args[1]+1, CUR.cvtSize+1 ) ) + BOUNDS( args[1]+1, CUR.cvtSize+1 ) || + BOUNDS(CUR.GS.rp0, CUR.zp0.n_points) ) { CUR.error = TT_Err_Invalid_Reference; return; @@ -4101,7 +4124,7 @@ distance = CUR_Func_project( CUR.zp0.cur_x[p2] - CUR.zp1.cur_x[p1], CUR.zp0.cur_y[p2] - - CUR.zp1.cur_x[p1] ) / 2; + CUR.zp1.cur_y[p1] ) / 2; CUR_Func_move( &CUR.zp1, p1, distance ); @@ -4120,7 +4143,9 @@ Int point; (void)args; - if ( CUR.top < CUR.GS.loop ) + if ( CUR.top < CUR.GS.loop || + BOUNDS(CUR.GS.rp1, CUR.zp0.n_points) || + BOUNDS(CUR.GS.rp2, CUR.zp1.n_points)) { CUR.error = TT_Err_Invalid_Reference; return; @@ -4340,56 +4365,62 @@ contour = 0; point = 0; - - do + if (contour > CUR.n_contours - 1) { - end_point = CUR.pts.contours[contour]; - first_point = point; - - while ( point <= end_point && (CUR.pts.touch[point] & mask) == 0 ) - point++; - - if ( point <= end_point ) + CUR.error = TT_Err_Invalid_Reference; + } + else + { + do { - first_touched = point; - cur_touched = point; + end_point = CUR.pts.contours[contour]; + first_point = point; - point++; + while ( point <= end_point && (CUR.pts.touch[point] & mask) == 0 ) + point++; - while ( point <= end_point ) + if ( point <= end_point ) { - if ( (CUR.pts.touch[point] & mask) != 0 ) - { - Interp( (Int)(cur_touched + 1), - (Int)(point - 1), - (Int)cur_touched, - (Int)point, - &V ); - cur_touched = point; - } + first_touched = point; + cur_touched = point; point++; - } - if ( cur_touched == first_touched ) - Shift( (Int)first_point, (Int)end_point, (Int)cur_touched, &V ); - else - { - Interp((Int)(cur_touched + 1), - (Int)(end_point), - (Int)(cur_touched), - (Int)(first_touched), - &V ); - - Interp((Int)(first_point), - (Int)(first_touched - 1), - (Int)(cur_touched), - (Int)(first_touched), - &V ); + while ( point <= end_point ) + { + if ( (CUR.pts.touch[point] & mask) != 0 ) + { + Interp( (Int)(cur_touched + 1), + (Int)(point - 1), + (Int)cur_touched, + (Int)point, + &V ); + cur_touched = point; + } + + point++; + } + + if ( cur_touched == first_touched ) + Shift( (Int)first_point, (Int)end_point, (Int)cur_touched, &V ); + else + { + Interp((Int)(cur_touched + 1), + (Int)(end_point), + (Int)(cur_touched), + (Int)(first_touched), + &V ); + + Interp((Int)(first_point), + (Int)(first_touched - 1), + (Int)(cur_touched), + (Int)(first_touched), + &V ); + } } - } - contour++; - } while ( contour < CUR.pts.n_contours ); + contour++; + } while ( contour < CUR.pts.n_contours ); + } } /**********************************************/ @@ -4921,7 +4952,9 @@ Int A; PDefRecord WITH; PCallRecord WITH1; +#if defined(DEBUG) && !defined(GS_THREADSAFE) bool bFirst; +#endif bool dbg_prt = (DBG_PRT_FUN != NULL); # ifdef DEBUG ttfMemory *mem = exc->current_face->font->tti->ttf_memory; @@ -4969,8 +5002,9 @@ CUR.error = Result; goto _LExit; } +#if defined(DEBUG) && !defined(GS_THREADSAFE) bFirst = true; - +#endif do { CALC_Length(); @@ -5097,7 +5131,6 @@ break; default: - CUR.error = CUR.error; goto _LErrorLabel; break; } diff -Nru ghostscript-9.10~dfsg/base/ttinterp.h ghostscript-9.25~dfsg+1/base/ttinterp.h --- ghostscript-9.10~dfsg/base/ttinterp.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttinterp.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttload.c ghostscript-9.25~dfsg+1/base/ttload.c --- ghostscript-9.10~dfsg/base/ttload.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttload.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttload.h ghostscript-9.25~dfsg+1/base/ttload.h --- ghostscript-9.10~dfsg/base/ttload.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttload.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttmisc.h ghostscript-9.25~dfsg+1/base/ttmisc.h --- ghostscript-9.10~dfsg/base/ttmisc.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttmisc.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/ttobjs.c ghostscript-9.25~dfsg+1/base/ttobjs.c --- ghostscript-9.10~dfsg/base/ttobjs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttobjs.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -666,6 +666,28 @@ if ( error ) goto Fin; + exec->zp0 = exec->pts; + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + + exec->GS.gep0 = 1; + exec->GS.gep1 = 1; + exec->GS.gep2 = 1; + + exec->GS.projVector.x = 0x4000; + exec->GS.projVector.y = 0x0000; + + exec->GS.freeVector = exec->GS.projVector; + exec->GS.dualVector = exec->GS.projVector; + + exec->GS.round_state = 1; + exec->GS.loop = 1; + + /* some glyphs leave something on the stack. so we clean it */ + /* before a new execution. */ + exec->top = 0; + exec->callTop = 0; + error = RunIns( exec ); Unset_CodeRange(exec); } @@ -781,6 +803,28 @@ if (error) goto Fin; + exec->zp0 = exec->pts; + exec->zp1 = exec->pts; + exec->zp2 = exec->pts; + + exec->GS.gep0 = 1; + exec->GS.gep1 = 1; + exec->GS.gep2 = 1; + + exec->GS.projVector.x = 0x4000; + exec->GS.projVector.y = 0x0000; + + exec->GS.freeVector = exec->GS.projVector; + exec->GS.dualVector = exec->GS.projVector; + + exec->GS.round_state = 1; + exec->GS.loop = 1; + + /* some glyphs leave something on the stack. so we clean it */ + /* before a new execution. */ + exec->top = 0; + exec->callTop = 0; + error = RunIns( exec ); Unset_CodeRange(exec); } diff -Nru ghostscript-9.10~dfsg/base/ttobjs.h ghostscript-9.25~dfsg+1/base/ttobjs.h --- ghostscript-9.10~dfsg/base/ttobjs.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ttobjs.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/tttables.h ghostscript-9.25~dfsg+1/base/tttables.h --- ghostscript-9.10~dfsg/base/tttables.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/tttables.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/tttype.h ghostscript-9.25~dfsg+1/base/tttype.h --- ghostscript-9.10~dfsg/base/tttype.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/tttype.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/tttypes.h ghostscript-9.25~dfsg+1/base/tttypes.h --- ghostscript-9.10~dfsg/base/tttypes.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/tttypes.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/turboc.cfg ghostscript-9.25~dfsg+1/base/turboc.cfg --- ghostscript-9.10~dfsg/base/turboc.cfg 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/turboc.cfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ --wdup -wret -wstr -w-stu -wsus -wvoi -wzst --waus -wdef -w-eff -w-par -w-pia -w-rch -wrvl --w-amb -w-amp -w-nod -w-stv -wuse --wapt -w-cln -wcpt -wdgn -wrpt -w-sig -w-ucp --N diff -Nru ghostscript-9.10~dfsg/base/ugcclib.mak ghostscript-9.25~dfsg+1/base/ugcclib.mak --- ghostscript-9.10~dfsg/base/ugcclib.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/ugcclib.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for Unix / gcc library testing. @@ -62,10 +62,11 @@ JBIG2_LIB=jbig2dec JBIG2SRCDIR=jbig2dec -# Define the directory where the lcms source is stored. -# See lcms.mak for more information +# Define the directory where the lcms2mt source is stored. +# See lcms2mt.mak for more information -LCMSSRCDIR=lcms +SHARE_LCMS=0 +LCMS2MTSRCDIR=lcms2mt # Define the directory where the lcms2 source is stored. # See lcms2.mak for more information diff -Nru ghostscript-9.10~dfsg/base/unistd_.h ghostscript-9.25~dfsg+1/base/unistd_.h --- ghostscript-9.10~dfsg/base/unistd_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unistd_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -50,6 +50,10 @@ # define isatty(fd) _isatty(fd) # define setmode(fd, mode) _setmode(fd, mode) #else + /* _XOPEN_SOURCE 500 define is needed to get + * access to pread and pwrite */ +# define _XOPEN_SOURCE 500 +# define __USE_UNIX98 # include #endif diff -Nru ghostscript-9.10~dfsg/base/unixansi.mak ghostscript-9.25~dfsg+1/base/unixansi.mak --- ghostscript-9.10~dfsg/base/unixansi.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unixansi.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for Unix/ANSI C/X11 configuration. @@ -156,8 +156,6 @@ TIFFCONFIG_SUFFIX=.unix LIBTIFF_NAME=tiff -TRIOSRCDIR=trio - # Define the directory where the zlib sources are stored. # See zlib.mak for more information. @@ -180,7 +178,7 @@ # See lcms.mak for more information SHARE_LCMS=0 -LCMSSRCDIR=lcms +LCMS2MTSRCDIR=lcms2mt # Define the directory where the lcms2 source is stored. # See lcms2.mak for more information @@ -188,9 +186,9 @@ LCMS2SRCDIR=lcms2 # Which CMS are we using? -# Options are currently lcms or lcms2 +# Options are currently lcms2mt or lcms2 -WHICH_CMS=lcms2 +WHICH_CMS=lcms2mt # Define the directory where the ijs source is stored, # and the process forking method to use for the server. @@ -251,6 +249,10 @@ LDFLAGS=$(XLDFLAGS) +GS_LDFLAGS=$(LDFLAGS) +PCL_LDFLAGS=$(LDFLAGS) +XPS_LDFLAGS=$(LDFLAGS) + # Define any extra libraries to link into the executable. # ISC Unix 2.2 wants -linet. # SCO Unix needs -lsocket if you aren't including the X11 driver. @@ -358,14 +360,14 @@ DEVICE_DEVS12=$(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pngmonod.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev -DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)pswrite.dev $(DD)ps2write.dev $(DD)epswrite.dev $(DD)txtwrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev -DEVICE_DEVS16=$(DD)bbox.dev $(DD)inkcov.dev +DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)ps2write.dev $(DD)eps2write.dev $(DD)txtwrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev +DEVICE_DEVS16=$(DD)bbox.dev $(DD)inkcov.dev $(DD)ink_cov.dev $(DD)pdfimage8.dev $(DD)pdfimage24.dev $(DD)pdfimage32.dev $(DD)PCLm.dev # Overflow from DEVS9 DEVICE_DEVS17=$(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev $(DD)pamcmyk32.dev DEVICE_DEVS18= DEVICE_DEVS19= DEVICE_DEVS20= -DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)pamcmyk32.dev +DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev $(DD)pamcmyk32.dev $(DD)psdcmykog.dev $(DD)fpng.dev # ---------------------------- End of options --------------------------- # @@ -398,7 +400,6 @@ include $(GLSRCDIR)/unixhead.mak include $(GLSRCDIR)/gs.mak -include $(GLSRCDIR)/trio.mak # psromfs.mak must precede lib.mak include $(PSSRCDIR)/psromfs.mak include $(GLSRCDIR)/lib.mak diff -Nru ghostscript-9.10~dfsg/base/unix-aux.mak ghostscript-9.25~dfsg+1/base/unix-aux.mak --- ghostscript-9.10~dfsg/base/unix-aux.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unix-aux.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,15 +9,15 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Partial makefile common to all Unix configurations. # This makefile contains the build rules for the auxiliary programs such as # echogs, and the 'platform' modules. # Define the name of this makefile. -UNIX_AUX_MAK=$(GLSRC)unix-aux.mak +UNIX_AUX_MAK=$(GLSRC)unix-aux.mak $(TOP_MAKEFILES) # -------------------------------- Library -------------------------------- # @@ -28,61 +28,52 @@ # Unix platforms other than System V, and also System V Release 4 # (SVR4) platforms. -unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_upapr.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gp_unix_cache.$(OBJ) -$(GLGEN)unix_.dev: $(unix__) $(GLD)nosync.dev $(GLD)smd5.dev +unix__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_upapr.$(OBJ) $(GLOBJ)gp_unix.$(OBJ)\ + $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_stdia.$(OBJ)\ + $(GLOBJ)gp_nxpsprn.$(OBJ) + +$(GLGEN)unix_.dev: $(unix__) $(GLD)nosync.dev $(GLD)smd5.dev $(UNIX_AUX_MAK) $(MAKEDIRS) $(SETMOD) $(GLGEN)unix_ $(unix__) -include $(GLD)nosync $(ADDMOD) $(GLGEN)unix_ -include $(GLD)smd5 $(GLOBJ)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\ - $(pipe__h) $(string__h) $(time__h) $(gx_h) $(gsexit_h) $(gp_h) $(MAKEDIRS) + $(pipe__h) $(string__h) $(time__h) $(gx_h) $(gsexit_h) $(gp_h) $(UNIX_AUX_MAK) $(MAKEDIRS) $(GLCC) $(FONTCONFIG_CFLAGS) $(GLO_)gp_unix.$(OBJ) $(C_) $(GLSRC)gp_unix.c $(AUX)gp_unix.$(OBJ): $(GLSRC)gp_unix.c $(AK)\ $(pipe__h) $(string__h) $(time__h)\ - $(gx_h) $(gsexit_h) $(gp_h) $(MAKEDIRS) - $(GLCCAUX) $(FONTCONFIG_CFLAGS) $(AUXO_)gp_unix.$(OBJ) $(C_) $(GLSRC)gp_unix.c - -$(GLOBJ)gp_unix_cache.$(OBJ): $(GLSRC)gp_unix_cache.c $(AK)\ - $(stdio__h) $(string__h) $(time__h) $(gconfigd_h) $(gp_h) $(md5_h)\ - $(MAKEDIRS) - $(GLCC) $(GLO_)gp_unix_cache.$(OBJ) $(C_) $(GLSRC)gp_unix_cache.c + $(gx_h) $(gsexit_h) $(gp_h) $(UNIX_AUX_MAK) $(MAKEDIRS) + $(GLCCAUX) $(AUXO_)gp_unix.$(OBJ) $(C_) $(GLSRC)gp_unix.c # assume all Unix platforms support unbuffered read $(GLOBJ)gp_stdia.$(OBJ): $(GLSRC)gp_stdia.c $(AK)\ - $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h) $(MAKEDIRS) + $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h) $(UNIX_AUX_MAK) $(MAKEDIRS) $(GLCC) $(GLO_)gp_stdia.$(OBJ) $(C_) $(GLSRC)gp_stdia.c $(AUX)gp_stdia.$(OBJ): $(GLSRC)gp_stdia.c $(AK)\ - $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h) $(MAKEDIRS) + $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h) $(UNIX_AUX_MAK) $(MAKEDIRS) $(GLCCAUX) $(AUXO_)gp_stdia.$(OBJ) $(C_) $(GLSRC)gp_stdia.c -# System V platforms other than SVR4, which lack some system calls, -# but have pipes. -sysv__=$(GLOBJ)gp_getnv.$(OBJ) $(GLOBJ)gp_upapr.$(OBJ) $(GLOBJ)gp_unix.$(OBJ) $(GLOBJ)gp_unifs.$(OBJ) $(GLOBJ)gp_unifn.$(OBJ) $(GLOBJ)gp_sysv.$(OBJ) -$(GLGEN)sysv_.dev: $(sysv__) $(GLD)nosync.dev - $(SETMOD) $(GLGEN)sysv_ $(sysv__) -include $(GLD)nosync - -$(GLOBJ)gp_sysv.$(OBJ): $(GLSRC)gp_sysv.c $(stdio__h) $(time__h) $(AK)\ - $(MAKEDIRS) - $(GLCC) $(GLO_)gp_sysv.$(OBJ) $(C_) $(GLSRC)gp_sysv.c - # -------------------------- Auxiliary programs --------------------------- # -$(ECHOGS_XE): $(GLSRC)echogs.c $(AK) $(stdpre_h) $(MAKEDIRS) +$(ECHOGS_XE): $(GLSRC)echogs.c $(AK) $(stdpre_h) $(UNIX_AUX_MAK) $(MAKEDIRS) $(CCAUX_) $(I_)$(GLSRCDIR)$(_I) $(O_)$(ECHOGS_XE) $(GLSRC)echogs.c $(AUXEXTRALIBS) +$(PACKPS_XE): $(GLSRC)pack_ps.c $(stdpre_h) $(UNIX_AUX_MAK) $(MAKEDIRS) + $(CCAUX_) $(I_)$(GLSRCDIR)$(_I) $(O_)$(PACKPS_XE) $(GLSRC)pack_ps.c $(AUXEXTRALIBS) + # On the RS/6000 (at least), compiling genarch.c with gcc with -O # produces a buggy executable. -$(GENARCH_XE): $(GLSRC)genarch.c $(AK) $(GENARCH_DEPS) $(MAKEDIRS) +$(GENARCH_XE): $(GLSRC)genarch.c $(AK) $(GENARCH_DEPS) $(UNIX_AUX_MAK) $(MAKEDIRS) $(CCAUX_) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENARCH_XE) $(GLSRC)genarch.c $(AUXEXTRALIBS) -$(GENCONF_XE): $(GLSRC)genconf.c $(AK) $(GENCONF_DEPS) $(MAKEDIRS) +$(GENCONF_XE): $(GLSRC)genconf.c $(AK) $(GENCONF_DEPS) $(UNIX_AUX_MAK) $(MAKEDIRS) $(CCAUX_) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENCONF_XE) $(GLSRC)genconf.c $(AUXEXTRALIBS) -$(GENDEV_XE): $(GLSRC)gendev.c $(AK) $(GENDEV_DEPS) $(MAKEDIRS) +$(GENDEV_XE): $(GLSRC)gendev.c $(AK) $(GENDEV_DEPS) $(UNIX_AUX_MAK) $(MAKEDIRS) $(CCAUX_) $(I_)$(GLSRCDIR)$(_I) $(O_)$(GENDEV_XE) $(GLSRC)gendev.c $(AUXEXTRALIBS) -$(GENHT_XE): $(GLSRC)genht.c $(AK) $(GENHT_DEPS) $(MAKEDIRS) +$(GENHT_XE): $(GLSRC)genht.c $(AK) $(GENHT_DEPS) $(UNIX_AUX_MAK) $(MAKEDIRS) $(CCAUX_) $(GENHT_CFLAGS) $(O_)$(GENHT_XE) $(GLSRC)genht.c $(AUXEXTRALIBS) # To get GS to use the system zlib, you remove/hide the gs/zlib directory @@ -92,8 +83,8 @@ $(AUX)gscdefs.$(OBJ) $(AUX)gp_unix.$(OBJ) $(AUX)gp_unifs.$(OBJ) $(AUX)gp_unifn.$(OBJ) \ $(AUX)gp_stdia.$(OBJ) $(AUX)gsutil.$(OBJ) $(AUX)memento.$(OBJ) -$(MKROMFS_XE)_0: $(GLSRC)mkromfs.c $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS_0) - $(CCAUX_) $(GENOPT) $(CFLAGS) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLOBJ)$(_I) $(I_)$(ZSRCDIR)$(_I) $(GLSRC)mkromfs.c $(O_)$(MKROMFS_XE)_0 $(MKROMFS_OBJS_0) $(AUXEXTRALIBS) +$(MKROMFS_XE)_0: $(GLSRC)mkromfs.c $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS_0) $(UNIX_AUX_MAK) $(MAKEDIRS) + $(CCAUX_) $(GENOPTAUX) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLOBJ)$(_I) $(I_)$(ZSRCDIR)$(_I) $(GLSRC)mkromfs.c $(O_)$(MKROMFS_XE)_0 $(MKROMFS_OBJS_0) $(AUXEXTRALIBS) # .... and one using the zlib library linked via the command line MKROMFS_OBJS_1=$(AUX)gscdefs.$(OBJ) \ @@ -101,10 +92,10 @@ $(AUX)gp_unix.$(OBJ) $(AUX)gp_unifs.$(OBJ) $(AUX)gp_unifn.$(OBJ) \ $(AUX)gp_stdia.$(OBJ) $(AUX)gsutil.$(OBJ) -$(MKROMFS_XE)_1: $(GLSRC)mkromfs.c $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS_1) - $(CCAUX_) $(GENOPT) $(CFLAGS) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLOBJ)$(_I) $(I_)$(ZSRCDIR)$(_I) $(GLSRC)mkromfs.c $(O_)$(MKROMFS_XE)_1 $(MKROMFS_OBJS_1) $(AUXEXTRALIBS) +$(MKROMFS_XE)_1: $(GLSRC)mkromfs.c $(MKROMFS_COMMON_DEPS) $(MKROMFS_OBJS_1) $(UNIX_AUX_MAK) $(MAKEDIRS) + $(CCAUX_) $(GENOPTAUX) $(I_)$(GLSRCDIR)$(_I) $(I_)$(GLOBJ)$(_I) $(I_)$(ZSRCDIR)$(_I) $(GLSRC)mkromfs.c $(O_)$(MKROMFS_XE)_1 $(MKROMFS_OBJS_1) $(AUXEXTRALIBS) -$(MKROMFS_XE): $(MKROMFS_XE)_$(SHARE_ZLIB) $(MAKEDIRS) +$(MKROMFS_XE): $(MKROMFS_XE)_$(SHARE_ZLIB) $(UNIX_AUX_MAK) $(MAKEDIRS) $(CP_) $(MKROMFS_XE)_$(SHARE_ZLIB) $(MKROMFS_XE) # Query the environment to construct gconfig_.h. @@ -113,7 +104,7 @@ # The "empty" $(ECHOGS_XE) lines just append a white space line to the # header file. INCLUDE=/usr/include -$(gconfig__h): $(UNIX_AUX_MAK) $(ECHOGS_XE) +$(gconfig__h): $(UNIX_AUX_MAK) $(ECHOGS_XE) $(UNIX_AUX_MAK) $(MAKEDIRS) $(ECHOGS_XE) -w $(gconfig__h) -x 2f2a -s This file was generated automatically by unix-aux.mak. -s -x 2a2f $(ECHOGS_XE) -a $(gconfig__h) diff -Nru ghostscript-9.10~dfsg/base/unix-dll.mak ghostscript-9.25~dfsg+1/base/unix-dll.mak --- ghostscript-9.10~dfsg/base/unix-dll.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unix-dll.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Partial makefile for Unix shared library target @@ -24,6 +24,8 @@ # export LD_LIBRARY_PATH=/insert-path-here/sobin # export GS_LIB=/insert-path-here/lib +UNIX_DLL_MAK=$(GLSRC)unix-dll.mak $(TOP_MAKEFILES) + # Location for building shared object SODIRPREFIX=so SODEBUGDIRPREFIX=sodebug @@ -37,6 +39,18 @@ GSSOC_XE=$(BINDIR)/$(GSSOC_XENAME) GSSOC=$(BINDIR)/$(GSSOC_XENAME) +PCLSOC_XENAME=$(PCL_SO_BASE)c$(XE) +PCLSOC_XE=$(BINDIR)/$(PCLSOC_XENAME) +PCLSOC=$(BINDIR)/$(PCLSOC_XENAME) + +XPSSOC_XENAME=$(XPS_SO_BASE)c$(XE) +XPSSOC_XE=$(BINDIR)/$(XPSSOC_XENAME) +XPSSOC=$(BINDIR)/$(XPSSOC_XENAME) + +GPDLSOC_XENAME=$(GPDL_SO_BASE)c$(XE) +GPDLSOC_XE=$(BINDIR)/$(GPDLSOC_XENAME) +GPDLSOC=$(BINDIR)/$(GPDLSOC_XENAME) + # loader suporting display device using Gtk+ GSSOX_XENAME=$(GS_SO_BASE)x$(XE) GSSOX_XE=$(BINDIR)/$(GSSOX_XENAME) @@ -44,22 +58,35 @@ # shared library GS_SONAME_BASE=lib$(GS_SO_BASE) +PCL_SONAME_BASE=lib$(PCL_SO_BASE) +XPS_SONAME_BASE=lib$(XPS_SO_BASE) +GPDL_SONAME_BASE=lib$(GPDL_SO_BASE) # GNU/Linux GS_SOEXT=$(SO_LIB_EXT) GS_DLLEXT=$(DLL_EXT) GS_SONAME=$(GS_SONAME_BASE)$(GS_SOEXT)$(GS_DLLEXT) - GS_SONAME_MAJOR=$(GS_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(GS_DLLEXT) - GS_SONAME_MAJOR_MINOR=$(GS_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MINOR)$(GS_DLLEXT) +PCL_SONAME=$(PCL_SONAME_BASE)$(GS_SOEXT)$(GS_DLLEXT) +PCL_SONAME_MAJOR=$(PCL_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(GS_DLLEXT) +PCL_SONAME_MAJOR_MINOR=$(PCL_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MINOR)$(GS_DLLEXT) + +XPS_SONAME=$(XPS_SONAME_BASE)$(GS_SOEXT)$(GS_DLLEXT) +XPS_SONAME_MAJOR=$(XPS_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(GS_DLLEXT) +XPS_SONAME_MAJOR_MINOR=$(XPS_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MINOR)$(GS_DLLEXT) + +GPDL_SONAME=$(GPDL_SONAME_BASE)$(GS_SOEXT)$(GS_DLLEXT) +GPDL_SONAME_MAJOR=$(GPDL_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(GS_DLLEXT) +GPDL_SONAME_MAJOR_MINOR=$(GPDL_SONAME_BASE)$(GS_SOEXT)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MAJOR)$(SO_LIB_VERSION_SEPARATOR)$(GS_VERSION_MINOR)$(GS_DLLEXT) + #LDFLAGS_SO=-shared -Wl,-soname=$(GS_SONAME_MAJOR) # NOTE: the value of LD_SET_DT_SONAME for, for example, Solaris ld, must contain the # trailing space to separation it from the value of the option. For GNU ld and -# similar linkers it must containt the trailing "=" +# similar linkers it must containt the trailing "=" # LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(GS_SONAME_MAJOR) @@ -73,36 +100,134 @@ #LDFLAGS_SO=-dynamiclib -install_name $(FRAMEWORK_NAME) GS_SO=$(BINDIR)/$(GS_SONAME) -GS_SO_MAJOR=$(BINDIR)/$(GS_SONAME_MAJOR) +GS_SO_MAJOR=$(BINDIR)/$(GS_SONAME_MAJOR) GS_SO_MAJOR_MINOR=$(BINDIR)/$(GS_SONAME_MAJOR_MINOR) +PCL_SO=$(BINDIR)/$(PCL_SONAME) +PCL_SO_MAJOR=$(BINDIR)/$(PCL_SONAME_MAJOR) +PCL_SO_MAJOR_MINOR=$(BINDIR)/$(PCL_SONAME_MAJOR_MINOR) + +XPS_SO=$(BINDIR)/$(XPS_SONAME) +XPS_SO_MAJOR=$(BINDIR)/$(XPS_SONAME_MAJOR) +XPS_SO_MAJOR_MINOR=$(BINDIR)/$(XPS_SONAME_MAJOR_MINOR) + +GPDL_SO=$(BINDIR)/$(GPDL_SONAME) +GPDL_SO_MAJOR=$(BINDIR)/$(GPDL_SONAME_MAJOR) +GPDL_SO_MAJOR_MINOR=$(BINDIR)/$(GPDL_SONAME_MAJOR_MINOR) + # Shared object is built by redefining GS_XE in a recursive make. # Create symbolic links to the Ghostscript interpreter library -$(GS_SO): $(GS_SO_MAJOR) +$(GS_SO): $(GS_SO_MAJOR) $(UNIX_DLL_MAK) $(MAKEDIRS) $(RM_) $(GS_SO) ln -s $(GS_SONAME_MAJOR_MINOR) $(GS_SO) -$(GS_SO_MAJOR): $(GS_SO_MAJOR_MINOR) +$(GS_SO_MAJOR): $(GS_SO_MAJOR_MINOR) $(UNIX_DLL_MAK) $(MAKEDIRS) $(RM_) $(GS_SO_MAJOR) ln -s $(GS_SONAME_MAJOR_MINOR) $(GS_SO_MAJOR) +$(PCL_SO): $(PCL_SO_MAJOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(PCL_SO) + ln -s $(PCL_SONAME_MAJOR_MINOR) $(PCL_SO) + +$(PCL_SO_MAJOR): $(PCL_SO_MAJOR_MINOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(PCL_SO_MAJOR) + ln -s $(PCL_SONAME_MAJOR_MINOR) $(PCL_SO_MAJOR) + +$(XPS_SO): $(XPS_SO_MAJOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(XPS_SO) + ln -s $(XPS_SONAME_MAJOR_MINOR) $(XPS_SO) + +$(XPS_SO_MAJOR): $(XPS_SO_MAJOR_MINOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(XPS_SO_MAJOR) + ln -s $(XPS_SONAME_MAJOR_MINOR) $(XPS_SO_MAJOR) + +$(GPDL_SO): $(GPDL_SO_MAJOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(GPDL_SO) + ln -s $(GPDL_SONAME_MAJOR_MINOR) $(GPDL_SO) + +$(GPDL_SO_MAJOR): $(GPDL_SO_MAJOR_MINOR) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(RM_) $(GPDL_SO_MAJOR) + ln -s $(GPDL_SONAME_MAJOR_MINOR) $(GPDL_SO_MAJOR) + + +gs-so-links-subtarget: $(GS_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(NO_OP) + +gpcl6-so-links-subtarget: $(PCL_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(NO_OP) + +gxps-so-links-subtarget: $(XPS_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(NO_OP) + +gpdl-so-links-subtarget: $(GPDL_SO) $(UNIX_DLL_MAK) $(MAKEDIRS) + $(NO_OP) + +# dummy for when only GS source is available +-so-links-subtarget: $(UNIX_DLL_MAK) $(MAKEDIRS) + $(NO_OP) + # Build the small Ghostscript loaders, with Gtk+ and without -$(GSSOC_XE): $(GS_SO) $(PSSRC)$(SOC_LOADER) - $(GLCC) -g -o $(GSSOC_XE) $(PSSRC)dxmainc.c \ - -L$(BINDIR) -l$(GS_SO_BASE) - -$(GSSOX_XE): $(GS_SO) $(PSSRC)$(SOC_LOADER) - $(GLCC) -g $(SOC_CFLAGS) -o $(GSSOX_XE) $(PSSRC)$(SOC_LOADER) \ - -L$(BINDIR) -l$(GS_SO_BASE) $(SOC_LIBS) +$(GSSOC_XE): gs-so-links-subtarget $(PSSRC)dxmainc.c $(UNIX_DLL_MAK) $(MAKEDIRS) + $(GLCC) $(GLO_)dxmainc.$(OBJ) $(C_) $(PSSRC)dxmainc.c + $(GLCC) -L$(BINDIR) $(LDFLAGS) $(O_) $(GSSOC_XE) $(GLOBJ)dxmainc.$(OBJ) -l$(GS_SO_BASE) + +$(GSSOX_XE): gs-so-links-subtarget $(PSSRC)$(SOC_LOADER).c $(UNIX_DLL_MAK) $(MAKEDIRS) + $(GLCC) $(SOC_CFLAGS) $(GLO_)$(SOC_LOADER).$(OBJ) $(C_) $(PSSRC)$(SOC_LOADER).c + $(GLCC) -L$(BINDIR) $(LDFLAGS) $(O_) $(GSSOX_XE) $(GLOBJ)$(SOC_LOADER).$(OBJ) -l$(GS_SO_BASE) $(SOC_LIBS) + +$(PCLSOC_XE): gpcl6-so-links-subtarget $(UNIX_DLL_MAK) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) $(MAKEDIRS) + $(GLCC) -L$(BINDIR) $(LDFLAGS) $(O_) $(PCLSOC_XE) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) -l$(PCL_SO_BASE) + +$(XPSSOC_XE): gxps-so-links-subtarget $(UNIX_DLL_MAK) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) $(MAKEDIRS) + $(GLCC) -L$(BINDIR) $(LDFLAGS) $(O_) $(XPSSOC_XE) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) -l$(XPS_SO_BASE) + +$(GPDLSOC_XE): gpdl-so-links-subtarget $(UNIX_DLL_MAK) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) $(MAKEDIRS) + $(GLCC) -L$(BINDIR) $(LDFLAGS) $(O_) $(GPDLSOC_XE) $(PLOBJ)$(REALMAIN_SRC).$(OBJ) -l$(GPDL_SO_BASE) + +gpcl6-so-loader: $(PCLSOC_XE) + $(NO_OP) + +gxps-so-loader: $(XPSSOC_XE) + $(NO_OP) + +gpdl-so-loader: $(GPDLSOC_XE) + $(NO_OP) + +# dummy for when only GS source is available +-so-loader: + $(NO_OP) + + +gs-so-strip: + $(STRIP_XE) $(STRIP_XE_OPTS) $(GS_XE) + +gpcl6-so-strip: + $(STRIP_XE) $(STRIP_XE_OPTS) $(GPCL_XE) + +gxps-so-strip: + $(STRIP_XE) $(STRIP_XE_OPTS) $(GXPS_XE) + +gpdl-so-strip: + $(STRIP_XE)$(STRIP_XE_OPTS) $(GPDL_XE) + +# dummy for when only GS source is available +-so-strip: + $(NO_OP) + # ------------------------- Recursive make targets ------------------------- # SODEFS=\ - GS_XE=$(BINDIR)/$(GS_SONAME_MAJOR_MINOR)\ - DISPLAY_DEV=$(DD)display.dev\ - STDIO_IMPLEMENTATION=c\ + GS_DOT_O= \ + REALMAIN_OBJ= \ + GS_XE=$(BINDIR)/$(GS_SONAME_MAJOR_MINOR) \ + GPCL_XE=$(BINDIR)/$(PCL_SONAME_MAJOR_MINOR) \ + GXPS_XE=$(BINDIR)/$(XPS_SONAME_MAJOR_MINOR) \ + GPDL_XE=$(BINDIR)/$(GPDL_SONAME_MAJOR_MINOR) \ + DISPLAY_DEV=$(DD)display.dev \ + STDIO_IMPLEMENTATION=c \ BUILDDIRPREFIX=$(BUILDDIRPREFIX) SODEFS_FINAL=\ @@ -116,37 +241,67 @@ # Normal shared object so: - @if test -z "$(MAKE)" -o -z "`$(MAKE) --version 2>&1 | grep GNU`";\ + @if test -z "$(MAKE) $(SUB_MAKE_OPTION)" -o -z "`$(MAKE) $(SUB_MAKE_OPTION) --version 2>&1 | grep GNU`";\ + then echo "Warning: this target requires gmake";\ + fi + $(MAKE) $(SUB_MAKE_OPTION) so-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + +so-only: + @if test -z "$(MAKE) $(SUB_MAKE_OPTION)" -o -z "`$(MAKE) $(SUB_MAKE_OPTION) --version 2>&1 | grep GNU`";\ then echo "Warning: this target requires gmake";\ fi - $(MAKE) so-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) so-only-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) gs-so-links-subtarget \ + $(PCL_TARGET)-so-links-subtarget \ + $(XPS_TARGET)-so-links-subtarget \ + $(GPDL_TARGET)-so-links-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + + +so-only-stripped: + $(MAKE) $(SUB_MAKE_OPTION) so-only-stripped-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) gs-so-links-subtarget \ + $(PCL_TARGET)-so-links-subtarget \ + $(XPS_TARGET)-so-links-subtarget \ + $(GPDL_TARGET)-so-links-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) # Debug shared object +so-onlydebug: + @if test -z "$(MAKE) $(SUB_MAKE_OPTION)" -o -z "`$(MAKE) $(SUB_MAKE_OPTION) --version 2>&1 | grep GNU`";\ + then echo "Warning: this target requires gmake";\ + fi + $(MAKE) $(SUB_MAKE_OPTION) so-only-subtarget GENOPT='-DDEBUG' BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) + sodebug: - @if test -z "$(MAKE)" -o -z "`$(MAKE) --version 2>&1 | grep GNU`";\ + @if test -z "$(MAKE) $(SUB_MAKE_OPTION)" -o -z "`$(MAKE) $(SUB_MAKE_OPTION) --version 2>&1 | grep GNU`";\ then echo "Warning: this target requires gmake";\ fi - $(MAKE) so-subtarget GENOPT='-DDEBUG' BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) CFLAGS_STANDARD="$(CFLAGS_DEBUG)" so-subtarget GENOPT='-DDEBUG' BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) -so-subtarget: - $(MAKE) $(SODEFS) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS)'\ +so-only-subtarget: + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS)'\ CFLAGS='$(CFLAGS_STANDARD) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix)\ directories - $(MAKE) $(SODEFS) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS)'\ + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS)'\ CFLAGS='$(CFLAGS_STANDARD) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix)\ $(AUXDIR)/echogs$(XEAUX) $(AUXDIR)/genarch$(XEAUX) - $(MAKE) $(SODEFS) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS) $(LDFLAGS_SO)'\ - CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)'\ - prefix=$(prefix) - $(MAKE) $(SODEFS_FINAL) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS)'\ + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) GENOPT='$(GENOPT)' GS_LDFLAGS='$(LDFLAGS) $(GS_LDFLAGS_SO)'\ + PCL_LDFLAGS='$(LDFLAGS) $(PCL_LDFLAGS_SO)' XPS_LDFLAGS='$(LDFLAGS) $(XPS_LDFLAGS_SO)' \ + PDL_LDFLAGS='$(LDFLAGS) $(PDL_LDFLAGS_SO)' CFLAGS='$(CFLAGS_STANDARD) $(CFLAGS_SO) \ + $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix) + +so-only-stripped-subtarget: so-only-subtarget + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) gs-so-strip $(PCL_TARGET)-so-strip $(XPS_TARGET)-so-strip $(GPDL_TARGET)-so-strip + +so-subtarget: so-only-subtarget + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS_FINAL) GENOPT='$(GENOPT)' LDFLAGS='$(LDFLAGS)'\ CFLAGS='$(CFLAGS_STANDARD) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS)' prefix=$(prefix)\ - $(GSSOC_XE) $(GSSOX_XE) + $(GSSOC_XE) $(GSSOX_XE) $(PCL_TARGET)-so-loader $(XPS_TARGET)-so-loader $(GPDL_TARGET)-so-loader install-so: - $(MAKE) install-so-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) install-sodebug: - $(MAKE) install-so-subtarget GENOPT='-DDEBUG' BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) install-so-subtarget GENOPT='-DDEBUG' BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) install-so-subtarget: so-subtarget -mkdir -p $(DESTDIR)$(prefix) @@ -165,22 +320,23 @@ ln -s $(GS_SONAME_MAJOR_MINOR) $(DESTDIR)$(libdir)/$(GS_SONAME_MAJOR) $(INSTALL_DATA) $(PSSRC)iapi.h $(DESTDIR)$(gsincludedir)iapi.h $(INSTALL_DATA) $(PSSRC)ierrors.h $(DESTDIR)$(gsincludedir)ierrors.h + $(INSTALL_DATA) $(GLSRC)gserrors.h $(DESTDIR)$(gsincludedir)gserrors.h $(INSTALL_DATA) $(DEVSRC)gdevdsp.h $(DESTDIR)$(gsincludedir)gdevdsp.h soinstall: - $(MAKE) soinstall-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) soinstall-subtarget BUILDDIRPREFIX=$(SODIRPREFIX) sodebuginstall: - $(MAKE) soinstall-subtarget GENOPT='-DDEBUG' BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) + $(MAKE) $(SUB_MAKE_OPTION) soinstall-subtarget GENOPT='-DDEBUG' BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) soinstall-subtarget: install-so install-scripts install-data $(INSTALL_SHARED) $(INSTALL_CONTRIB) # Clean targets soclean: - $(MAKE) BUILDDIRPREFIX=$(SODIRPREFIX) clean-so-subtarget + $(MAKE) $(SUB_MAKE_OPTION) BUILDDIRPREFIX=$(SODIRPREFIX) clean-so-subtarget clean-so-subtarget: - $(MAKE) $(SODEFS) clean-so-subsubtarget + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) clean-so-subsubtarget clean-so-subsubtarget: clean $(RM_) $(BINDIR)/$(GS_SONAME) @@ -190,9 +346,9 @@ $(RMN_) -r $(BINDIR) $(GLGENDIR) $(GLOBJDIR) $(PSGENDIR) $(PSOBJDIR) sodebugclean: - $(MAKE) BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) clean-sodebug-subtarget + $(MAKE) $(SUB_MAKE_OPTION) BUILDDIRPREFIX=$(SODEBUGDIRPREFIX) clean-sodebug-subtarget clean-sodebug-subtarget: - $(MAKE) $(SODEFS) clean-so-subsubtarget + $(MAKE) $(SUB_MAKE_OPTION) $(SODEFS) clean-so-subsubtarget # End of unix-dll.mak diff -Nru ghostscript-9.10~dfsg/base/unix-end.mak ghostscript-9.25~dfsg+1/base/unix-end.mak --- ghostscript-9.10~dfsg/base/unix-end.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unix-end.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,14 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Partial makefile common to all Unix and Desqview/X configurations. # This is the next-to-last part of the makefile for these configurations. - +UNIX_END_MAK=$(GLSRC)unix-end.mak $(TOP_MAKEFILES) # Define the rule for building standard configurations. -directories: +directories: $(UNIX_END_MAK) @if test "$(BINDIR)" != "" -a ! -d $(BINDIR); then mkdir $(BINDIR); fi @if test "$(GLGENDIR)" != "" -a ! -d $(GLGENDIR); then mkdir $(GLGENDIR); fi @if test "$(GLOBJDIR)" != "" -a ! -d $(GLOBJDIR); then mkdir $(GLOBJDIR); fi @@ -27,40 +27,195 @@ @if test "$(PSGENDIR)" != "" -a ! -d $(PSGENDIR)/cups; then mkdir $(PSGENDIR)/cups; fi @if test "$(PSOBJDIR)" != "" -a ! -d $(PSOBJDIR); then mkdir $(PSOBJDIR); fi + +gs: .gssubtarget $(UNIX_END_MAK) + $(NO_OP) + +gpcl6: .pcl6subtarget $(UNIX_END_MAK) + $(NO_OP) + +gpcl6clean: cleansub + $(NO_OP) + +gxps: .xpssubtarget $(UNIX_END_MAK) + $(NO_OP) + +gxpsclean: cleansub + $(NO_OP) + +gpdl: .gpdlsubtarget $(UNIX_END_MAK) + $(NO_OP) + +gpdlclean: .cleansub + $(NO_OP) + +libgs: $(GS_A) + $(NO_OP) + +libgsexe: $(GS_A_XE) + $(NO_OP) + +libgpcl6: $(GPCL_A) + $(NO_OP) + +libgpcl6exe: $(GPCL_A_XE) + $(NO_OP) + +libgxps: $(GXPS_A) + $(NO_OP) + +libgxpsexe: $(GXPS_A_XE) + $(NO_OP) + +libgpdl: $(GPDL_A) + $(NO_OP) + +libgpdlexe: $(GPDL_A_XE) + $(NO_OP) + # Define a rule for building profiling configurations. -PGDEFS=GENOPT='-DPROFILE' CFLAGS='$(CFLAGS_PROFILE) $(GCFLAGS) $(XCFLAGS)'\ - LDFLAGS='$(XLDFLAGS) -pg' XLIBS='Xt SM ICE Xext X11'\ - BUILDDIRPREFIX=$(PGDIRPREFIX) +PGDEFS=GENOPT='-DPROFILE' CFLAGS='-pg $(CFLAGS_PROFILE) $(GCFLAGS) $(XCFLAGS)'\ + LDFLAGS='$(XLDFLAGS) -pg' XLIBS='Xt SM ICE Xext X11' GENOPTAUX= \ + CFLAGSAUX='$(CFLAGSAUX_STANDARD) $(GCFLAGSAUX) $(XCFLAGSAUX)'\ + LDFLAGSAUX='$(XLDFLAGSAUX)' + +PROFILEMAKEOPTS=$(SUB_MAKE_OPTION) $(PGDEFS) BUILDDIRPREFIX=$(PGDIRPREFIX) pg: - $(MAKE) $(PGDEFS) default + $(MAKE) $(PROFILEMAKEOPTS) default pgclean: - $(MAKE) $(PGDEFS) clean + $(MAKE) $(PROFILEMAKEOPTS) cleansub + +gspg: + $(MAKE) $(PROFILEMAKEOPTS) .gssubtarget + +gpcl6pg: + $(MAKE) $(PROFILEMAKEOPTS) .pcl6subtarget + +gpcl6pgclean: + $(MAKE) $(PROFILEMAKEOPTS) cleansub + +gxpspg: + $(MAKE) $(PROFILEMAKEOPTS) .xpssubtarget + +gxpspgclean: + $(MAKE) $(PROFILEMAKEOPTS) cleansub + +gpdlpg: + $(MAKE) $(PROFILEMAKEOPTS) .gpdlsubtarget + +gpdlpgclean: + $(MAKE) $(PROFILEMAKEOPTS) cleansub # Define a rule for building debugging configurations. -DEBUGDEFS=GENOPT='-DDEBUG' CFLAGS='$(CFLAGS_DEBUG) $(GCFLAGS) $(XCFLAGS)'\ - BUILDDIRPREFIX=$(DEBUGDIRPREFIX) +DEBUGDEFS=GENOPT='-DDEBUG' CFLAGS='$(CFLAGS_DEBUG) $(GCFLAGS) $(XCFLAGS)' \ +GENOPTAUX='-DDEBUG_AUX' CFLAGSAUX='$(CFLAGSAUX_DEBUG) $(GCFLAGSAUX) $(XCFLAGSAUX)' + +DEBUGMAKEOPTS=$(SUB_MAKE_OPTION) $(DEBUGDEFS) BUILDDIRPREFIX=$(DEBUGDIRPREFIX) debug: - $(MAKE) $(DEBUGDEFS) default + $(MAKE) $(DEBUGMAKEOPTS) default debug-apitest: - $(MAKE) $(DEBUGDEFS) apitest + $(MAKE) $(DEBUGMAKEOPTS) apitest debugclean: - $(MAKE) $(DEBUGDEFS) clean + $(MAKE) $(DEBUGMAKEOPTS) cleansub + + +gsdebug: + $(MAKE) $(DEBUGMAKEOPTS) .gssubtarget + +gpcl6debug: + $(MAKE) $(DEBUGMAKEOPTS) .pcl6subtarget + +#gpcl6-debug-apitest: +# $(MAKE) $(DEBUGMAKEOPTS) apitest + +gpcl6debugclean: + $(MAKE) $(DEBUGMAKEOPTS) cleansub + +gxpsdebug: + $(MAKE) $(DEBUGMAKEOPTS) .xpssubtarget + +#gpcl6-debug-apitest: +# $(MAKE) $(DEBUGMAKEOPTS) apitest + +gxpsdebugclean: + $(MAKE) $(DEBUGMAKEOPTS) cleansub + +gpdldebug: + $(MAKE) $(DEBUGMAKEOPTS) .gpdlsubtarget + +#gpcl6-debug-apitest: +# $(MAKE) $(DEBUGMAKEOPTS) apitest + +gpdldebugclean: + $(MAKE) $(DEBUGMAKEOPTS) cleansub + + +libgsdebug: + $(MAKE) $(DEBUGMAKEOPTS) libgs + +libgpcl6debug: + $(MAKE) $(DEBUGMAKEOPTS) libgpcl6 + + +libgxpsdebug: + $(MAKE) $(DEBUGMAKEOPTS) libgxps + +libgpdldebug: + $(MAKE) $(DEBUGMAKEOPTS) libgpdl # Define a rule for building memento configurations. MEMENTODEFS=GENOPT='-DMEMENTO -DDEBUG' \ CFLAGS='$(CFLAGS_DEBUG) $(GCFLAGS) $(XCFLAGS)'\ - BUILDDIRPREFIX=$(MEMENTODIRPREFIX) + BUILDDIRPREFIX=$(MEMENTODIRPREFIX) GENOPTAUX='-DMEMENTO' \ + CFLAGSAUX='$(CFLAGSAUX_DEBUG) $(GCFLAGSAUX) $(XCFLAGSAUX)' + +MEMENTOMAKEOPTS=$(SUB_MAKE_OPTION) $(MEMENTODEFS) memento: - $(MAKE) $(MEMENTODEFS) default + $(MAKE) $(MEMENTOMAKEOPTS) default + +gsmemento: + $(MAKE) $(MEMENTOMAKEOPTS) .gssubtarget + +gpcl6memento: + $(MAKE) $(MEMENTOMAKEOPTS) .pcl6subtarget + +gxpsmemento: + $(MAKE) $(MEMENTOMAKEOPTS) .xpssubtarget mementoclean: - $(MAKE) $(MEMENTODEFS) clean + $(MAKE) $(MEMENTOMAKEOPTS) cleansub + +gpcl6_gxps_clean: gpcl6clean gxpsclean + $(NO_OP) + +# Define rules for building address sanitizer configurations. +SANITIZEDEFS=GENOPT='-DDEBUG' \ + CFLAGS='$(CFLAGS_DEBUG) $(CFLAGS_SANITIZE) $(GCFLAGS) $(XCFLAGS)'\ + LDFLAGS='$(LDFLAGS) $(LDFLAGS_SANITIZE)' \ + BUILDDIRPREFIX=$(SANITIZEDIRPREFIX) + +SANITIZEMAKEOPTS=$(SUB_MAKE_OPTION) $(SANITIZEDEFS) + +sanitize: + $(MAKE) $(SANITIZEMAKEOPTS) default + +gssanitize: + $(MAKE) $(SANITIZEMAKEOPTS) .gssubtarget + +gpcl6sanitize: + $(MAKE) $(SANITIZEMAKEOPTS) .pcl6subtarget + +gxpssanitize: + $(MAKE) $(SANITIZEMAKEOPTS) .xpssubtarget + +sanitizeclean: + $(MAKE) $(SANITIZEMAKEOPTS) cleansub # Emacs tags maintenance. diff -Nru ghostscript-9.10~dfsg/base/unix-gcc.mak ghostscript-9.25~dfsg+1/base/unix-gcc.mak --- ghostscript-9.10~dfsg/base/unix-gcc.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unix-gcc.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,10 +9,11 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # -# makefile for Unix/gcc/X11 configuration. +# makefile template for/from the autoconf build. +# Makefile. Generated from Makefile.in by configure. # ------------------------------- Options ------------------------------- # @@ -36,11 +37,31 @@ PSGENDIR=./$(BUILDDIRPREFIX)obj PSOBJDIR=./$(BUILDDIRPREFIX)obj +PCL5SRCDIR=./pcl/pcl +PCL5GENDIR=./$(BUILDDIRPREFIX)obj +PCL5OBJDIR=./$(BUILDDIRPREFIX)obj + +PXLSRCDIR=./pcl/pxl +PXLGENDIR=./$(BUILDDIRPREFIX)obj +PXLOBJDIR=./$(BUILDDIRPREFIX)obj + +PLSRCDIR=./pcl/pl +PLGENDIR=./$(BUILDDIRPREFIX)obj +PLOBJDIR=./$(BUILDDIRPREFIX)obj + +XPSSRCDIR=./xps +XPSGENDIR=./$(BUILDDIRPREFIX)obj +XPSOBJDIR=./$(BUILDDIRPREFIX)obj + +GPDLSRCDIR=./gpdl +GPDLGENDIR=./$(BUILDDIRPREFIX)obj +GPDLOBJDIR=./$(BUILDDIRPREFIX)obj + + +CONTRIBDIR=./contrib + # Do not edit the next group of lines. -#include $(COMMONDIR)/gccdefs.mak -#include $(COMMONDIR)/unixdefs.mak -#include $(COMMONDIR)/generic.mak include $(GLSRCDIR)/version.mak DD=$(GLGENDIR)/ GLD=$(GLGENDIR)/ @@ -56,29 +77,45 @@ INSTALL = $(GLSRCDIR)/instcopy -c INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_DATA = $(INSTALL) -m 644 +INSTALL_SHARED = prefix = /usr/local -exec_prefix = $(prefix) -bindir = $(exec_prefix)/bin +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin scriptdir = $(bindir) -includedir = $(prefix)/include -libdir = $(exec_prefix)/lib -mandir = $(prefix)/man +includedir = ${prefix}/include +libdir = ${exec_prefix}/lib +mandir = ${datarootdir}/man man1ext = 1 -datadir = $(prefix)/share -gsdir = $(datadir)/ghostscript +man1dir = $(mandir)/man$(man1ext) +datadir = ${datarootdir} +datarootdir = ${prefix}/share + +# The following must be substituted using ${datarootdir} and ${exec_prefix}/lib +# to avoid adding RPM generation paths (CUPS STR #1112) +gsdir = ${datarootdir}/ghostscript gsdatadir = $(gsdir)/$(GS_DOT_VERSION) -gssharedir = $(libdir)/ghostscript/$(GS_DOT_VERSION) -gsincludedir = $(includedir)/ghostscript/ +gssharedir = ${exec_prefix}/lib/ghostscript/$(GS_DOT_VERSION) +gsincludedir = ${prefix}/include/ghostscript/ docdir=$(gsdatadir)/doc exdir=$(gsdatadir)/examples GS_DOCDIR=$(docdir) +# Choose whether to compile the .ps initialization files into the executable. +# See gs.mak for details. + +COMPILE_INITS=1 + # Define the default directory/ies for the runtime -# initialization, resource and font files. Separate multiple directories with a :. +# initialization and font files. Separate multiple directories with a :. + +GS_LIB_DEFAULT=$(gsdatadir)/Resource/Init:$(gsdatadir)/lib:$(gsdatadir)/Resource/Font:$(gsdir)/fonts:${datarootdir}/fonts/default/ghostscript:${datarootdir}/fonts/default/Type1:${datarootdir}/fonts/default/TrueType:/usr/lib/DPS/outline/base:/usr/openwin/lib/X11/fonts/Type1:/usr/openwin/lib/X11/fonts/TrueType + +# Define the default directory for cached data files +# this must be a single path. -GS_LIB_DEFAULT=$(gsdatadir)/Resource/Init:$(gsdatadir)/lib:$(gsdatadir)/Resource/Font:$(gsdir)/fonts +GS_CACHE_DIR="~/.ghostscript/cache/" # Define whether or not searching for initialization files should always # look in the current directory first. This leads to well-known security @@ -93,6 +130,8 @@ # Choose generic configuration options. +TARGET_ARCH_FILE= + # -DDEBUG # includes debugging features (-Z switch) in the code. # Code runs substantially slower even if no debugging switches @@ -102,16 +141,44 @@ # Choose capability options. +# -DHAVE_BSWAP32 +# use bswap32 intrinsic +# -DHAVE_BYTESWAP_H +# use byteswap.h functions +# # -DHAVE_MKSTEMP -# uses mkstemp instead of mktemp -# This uses the more secure temporary file creation call -# Enable this if it is available on your platform. +# uses mkstemp instead of mktemp +# This uses the more secure temporary file creation call +# Enable this if it is available on your platform. +# -DHAVE_FILE64 +# use marked versions of the stdio FILE calls, fopen64() et al. +# +# -DHAVE_MKSTEMP64 +# use non-standard function mkstemp64() +# +# -DHAVE_LIBIDN +# use libidn to canonicalize Unicode passwords +# +# -DHAVE_SETLOCALE +# call setlocale(LC_CTYPE) when running as a standalone app +# -DHAVE_SSE2 +# use sse2 intrinsics -CAPOPT= -DHAVE_MKSTEMP +CAPOPT= -DHAVE_MKSTEMP -DHAVE_FILE64 -DHAVE_FSEEKO -DHAVE_MKSTEMP64 -DHAVE_SETLOCALE -DHAVE_SSE2 -DHAVE_BSWAP32 -DHAVE_BYTESWAP_H -DHAVE_STRERROR -DHAVE_PREAD_PWRITE=1 -DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE # Define the name of the executable file. GS=gs +GS_SO_BASE=gs + +PCL=gpcl6 +XPS=gxps +GPDL=gpdl + +XE= +XEAUX= + +PCL_XPS_TARGETS= # Define the directories for debugging and profiling binaries, relative to # the standard binaries. @@ -126,16 +193,37 @@ FT_BRIDGE=1 SHARE_FT=0 -FTSRCDIR=freetype -FT_CFLAGS=-Ifreetype/include +FTSRCDIR=./freetype +FT_CFLAGS=-I./freetype/include FT_LIBS= +FT_CONFIG_SYSTEM_ZLIB= + +# Define whether to compile in UFST. +# FAPI/UFST depends on UFST_BRIDGE being undefined - hence the construct below. +# (i.e. use "UFST_BRIDGE=1" or *not to define UFST_BRIDGE to anything*) +# As UFST is not used for fonts embedded in input files, we should still have +# Freetype enabled, above. + +UFST_ROOT= +UFST_LIB_EXT= + +UFST_ROMFS_ARGS?=-b \ + -P $(UFST_ROOT)/fontdata/mtfonts/pcl45/mt3/ -d fontdata/mtfonts/pcl45/mt3/ pcl___xj.fco plug__xi.fco wd____xh.fco \ + -P $(UFST_ROOT)/fontdata/mtfonts/pclps2/mt3/ -d fontdata/mtfonts/pclps2/mt3/ pclp2_xj.fco \ + -c -P $(PSSRCDIR)/../lib/ -d Resource/Init/ FAPIconfig-FCO + +UFSTROMFONTDIR=\"%rom%fontdata/\" +UFSTDISCFONTDIR?=\"$(UFST_ROOT)/fontdata/\" + + +UFST_CFLAGS= # Define the directory where the IJG JPEG library sources are stored, # and the major version of the library that is stored there. # You may need to change this if the IJG library version changes. # See jpeg.mak for more information. -JSRCDIR=jpeg +JSRCDIR=./jpeg # Note: if a shared library is used, it may not contain the # D_MAX_BLOCKS_IN_MCU patch, and thus may not be able to read @@ -150,70 +238,118 @@ # You may need to change this if the libpng version changes. # See png.mak for more information. -PNGSRCDIR=libpng - -# Choose whether to use a shared version of the PNG library, and if so, -# what its name is. -# See gs.mak and Make.htm for more information. - SHARE_LIBPNG=0 +PNGSRCDIR=./libpng LIBPNG_NAME=png -# Define whether to use a shared version of libtiff and where -# it is stored and what its name is. - +# libtiff SHARE_LIBTIFF=0 -TIFFSRCDIR=tiff -TIFFCONFDIR=tiff +TIFFSRCDIR= +TIFFCONFDIR= TIFFPLATFORM=unix -TIFFCONFIG_SUFFIX=.unix +TIFFCONFIG_SUFFIX= LIBTIFF_NAME=tiff -TRIOSRCDIR=trio - # Define the directory where the zlib sources are stored. # See zlib.mak for more information. -ZSRCDIR=zlib - -# Choose whether to use a shared version of the zlib library, and if so, -# what its name is (usually libz, but sometimes libgz). -# See gs.mak and Make.htm for more information. - SHARE_ZLIB=0 +ZSRCDIR=./zlib #ZLIB_NAME=gz ZLIB_NAME=z # Choose shared or compiled in libjbig2dec and source location -SHARE_JBIG2=0 +# JBIG2_LIB=jbig2dec JBIG2_LIB=jbig2dec -JBIG2SRCDIR=jbig2dec +SHARE_JBIG2=0 +JBIG2SRCDIR=./jbig2dec +JBIG2_CFLAGS=-DHAVE_STDINT_H=1 -# Define the directory where the lcms source is stored. -# See lcms.mak for more information +# uncomment the following three lines and one of the last two to +# compile in the Luratech ldf_jb2 codec +#JBIG2_LIB=luratech +#SHARE_JBIG2=0 +#JBIG2SRCDIR=ldf_jb2 +#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DLINUX +#JBIG2_CFLAGS=-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD + + +# Choose the library to use for (JPXDecode support) +# whether to link to an external build or compile in from source +# and source location and configuration flags for compiling in +JPX_LIB=openjpeg +SHARE_JPX=0 +JPXSRCDIR=./openjpeg +JPX_CFLAGS= -DUSE_JPIP -DUSE_OPENJPEG_JP2 -DOPJ_HAVE_STDINT_H=1 -DOPJ_HAVE_INTTYPES_H=1 -DOPJ_HAVE_FSEEKO=1 + +# uncomment the following three lines and one of the last two to +# compile in the Luratech lwf_jp2 codec +#JPX_LIB=luratech +#SHARE_JPX=0 +#JPXSRCDIR=lwf_jp2 +#JPX_CFLAGS=-DUSE_LWF_JP2 -DLINUX +#JPX_CFLAGS=-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD + +# Uncomment the following 4 lines to to compile in OpenJPEG codec +#JPX_LIB=openjpeg +#SHARE_JPX=0 +#JPXSRCDIR=openjpeg +#JPX_CFLAGS=-DUSE_OPENJPEG_JP2 -DOPJ_STATIC +# options for lcms color management library SHARE_LCMS=0 -LCMSSRCDIR=lcms +LCMS2SRCDIR=./lcms2mt +LCMS2_CFLAGS=-DSHARE_LCMS=$(SHARE_LCMS) -DCMS_USE_BIG_ENDIAN=0 -# Define the directory where the lcms2 source is stored. -# See lcms2.mak for more information - -LCMS2SRCDIR=lcms2 +LCMS2MTSRCDIR=./lcms2mt +LCMS2_CFLAGS=-DSHARE_LCMS=$(SHARE_LCMS) -DCMS_USE_BIG_ENDIAN=0 # Which CMS are we using? -# Options are currently lcms or lcms2 +# Options are currently lcms2mt or lcms2 +WHICH_CMS=lcms2mt -WHICH_CMS=lcms2 +EXPATSRCDIR=./expat +EXPAT_CFLAGS=-DHAVE_MEMMOVE +EXPATGENDIR=$(GLGENDIR) +EXPATOBJDIR=$(GLOBJDIR) +EXPATINCDIR = $(EXPATSRCDIR)$(D)lib +SHARE_EXPAT=0 + +JPEGXR_SRCDIR=./jpegxr +SHARE_JPEGXR=0 +JPEGXR_GENDIR=$(GLGENDIR) +JPEGXR_OBJDIR=$(GLOBJDIR) # Define the directory where the ijs source is stored, # and the process forking method to use for the server. # See ijs.mak for more information. - + SHARE_IJS=0 IJS_NAME= -IJSSRCDIR=ijs +IJSSRCDIR=./ijs IJSEXECTYPE=unix +# Define install location for 'cups' device/filter support +CUPSLIBS= +CUPSLIBDIRS= +CUPSSERVERBIN= +CUPSSERVERROOT= +CUPSDATA= +CUPSPDFTORASTER=0 + +SHARE_LCUPS=1 +LCUPS_NAME=cups +LCUPSSRCDIR=./cups +LCUPSBUILDTYPE= +CUPS_CC=$(CC) + +SHARE_LCUPSI=1 +LCUPSI_NAME=cupsimage +LCUPSISRCDIR=./cups +CUPS_CC=$(CC) + +CUPSCFLAGS= -DSHARE_LCUPS=$(SHARE_LCUPS) -DSHARE_LCUPSI=$(SHARE_LCUPSI) + # Define how to build the library archives. (These are not used in any # standard configuration.) @@ -223,28 +359,26 @@ # ------ Platform-specific options ------ # -# Define the name of the C compiler. +# Define the name of the C compiler (target and host (AUX)) CC=gcc +CCAUX=gcc # Define the name of the linker for the final link step. # Normally this is the same as the C compiler. CCLD=$(CC) +CCAUXLD=$(CCAUX) # Define the default gcc flags. -# Note that depending whether or not we are running a version of gcc with -# the 2.7.0-2.7.2 optimizer bug, either "-Dconst=" or -# "-Wcast-qual -Wwrite-strings" is automatically included. - -GCFLAGS=-Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -fno-builtin -fno-common +GCFLAGS= -Wall -Wstrict-prototypes -Wundef -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings -Wno-strict-aliasing -Werror=declaration-after-statement -fno-builtin -fno-common -Werror=return-type -DHAVE_STDINT_H=1 -DHAVE_DIRENT_H=1 -DHAVE_SYS_DIR_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_INTTYPES_H=1 -DGX_COLOR_INDEX_TYPE="unsigned long int" -D__USE_UNIX98=1 -DNOCONTRIB # Define the added flags for standard, debugging, profiling # and shared object builds. -CFLAGS_STANDARD=-O2 -CFLAGS_DEBUG=-g -O0 -CFLAGS_PROFILE=-pg -O2 +CFLAGS_STANDARD= -O2 +CFLAGS_DEBUG= -g -O0 +CFLAGS_PROFILE=-pg -O2 CFLAGS_SO=-fPIC # Define the other compilation flags. Add at most one of the following: @@ -258,9 +392,21 @@ # We don't include -ansi, because this gets in the way of the platform- # specific stuff that typically needs; nevertheless, we expect # gcc to accept ANSI-style function prototypes and function definitions. -XCFLAGS=-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\"$(gssharedir)\" +# CFLAGS from autoconf +AC_CFLAGS= -CFLAGS=$(CFLAGS_STANDARD) $(GCFLAGS) $(XCFLAGS) +# fontconfig flags, used by unix-aux.mak +FONTCONFIG_CFLAGS= +FONTCONFIG_LIBS= + +# DBus flags, used by cups.mak +DBUS_CFLAGS= +DBUS_LIBS= + +# defines from autoconf; note that we don't use all of these at present. +ACDEFS=-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_ERRNO_H=1 -DHAVE_FCNTL_H=1 -DHAVE_LIMITS_H=1 -DHAVE_MALLOC_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_SYSLOG_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DIRENT_H=1 -DHAVE_SYS_DIR_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STRUCT_STAT_ST_BLOCKS=1 -DHAVE_ST_BLOCKS=1 -DTIME_WITH_SYS_TIME=1 -DSIZEOF_UNSIGNED_LONG_INT=8 -DHAVE_LIBM=1 -DHAVE_PREAD=1 -DHAVE_PWRITE=1 -DHAVE_DECL_PWRITE=1 -DHAVE_DECL_PREAD=1 -DHAVE_LIBDL=1 -DHAVE_FSEEKO=1 -DHAVE_MEMALIGN=1 -DX_DISPLAY_MISSING=1 -DHAVE_MKSTEMP=1 -DHAVE_FOPEN64=1 -DHAVE_FSEEKO=1 -DHAVE_MKSTEMP64=1 -DHAVE_SETLOCALE=1 -DHAVE_STRERROR=1 -DHAVE_FORK=1 -DHAVE_VFORK=1 -DHAVE_WORKING_VFORK=1 -DHAVE_WORKING_FORK=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DRETSIGTYPE=void -DLSTAT_FOLLOWS_SLASHED_SYMLINK=1 -DHAVE_VPRINTF=1 -DHAVE_BZERO=1 -DHAVE_DUP2=1 -DHAVE_FLOOR=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_MEMCHR=1 -DHAVE_MEMMOVE=1 -DHAVE_MEMSET=1 -DHAVE_MKDIR=1 -DHAVE_MKFIFO=1 -DHAVE_MODF=1 -DHAVE_POW=1 -DHAVE_PUTENV=1 -DHAVE_RINT=1 -DHAVE_SETENV=1 -DHAVE_SQRT=1 -DHAVE_STRCHR=1 -DHAVE_STRRCHR=1 -DHAVE_STRSPN=1 -DHAVE_STRSTR=1 -DHAVE_STRNLEN=1 + +CFLAGS=$(CFLAGS_STANDARD) $(GCFLAGS) $(AC_CFLAGS) $(XCFLAGS) # Define platform flags for ld. # SunOS 4.n may need -Bstatic. @@ -269,9 +415,18 @@ # -R /usr/local/xxx/lib:/usr/local/lib # giving the full path names of the shared library directories. # XLDFLAGS can be set from the command line. -XLDFLAGS= +# AC_LDFLAGS from autoconf +AC_LDFLAGS= -LDFLAGS=$(XLDFLAGS) +LDFLAGS= $(AC_LDFLAGS) $(XLDFLAGS) + +GS_LDFLAGS=$(LDFLAGS) +PCL_LDFLAGS=$(LDFLAGS) +XPS_LDFLAGS=$(LDFLAGS) + +GS_LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(GS_SONAME_MAJOR) +PCL_LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(PCL_SONAME_MAJOR) +XPS_LDFLAGS_SO=-shared -Wl,$(LD_SET_DT_SONAME)$(LDFLAGS_SO_PREFIX)$(XPS_SONAME_MAJOR) # Define any extra libraries to link into the executable. # ISC Unix 2.2 wants -linet. @@ -280,7 +435,8 @@ # Solaris may need -lnsl -lsocket -lposix4. # (Libraries required by individual drivers are handled automatically.) -EXTRALIBS=-rdynamic -ldl +EXTRALIBS=$(XTRALIBS) -ldl -lm -rdynamic -ldl +AUXEXTRALIBS=$(XTRALIBS) -ldl -lm -rdynamic -ldl # Define the standard libraries to search at the end of linking. # Most platforms require -lpthread for the POSIX threads library; @@ -289,66 +445,96 @@ # All reasonable platforms require -lm, but Rhapsody and perhaps one or # two others fold libm into libc and don't require any additional library. -#STDLIBS=-lpthread -lm - -# Since the default build is for nosync, don't include pthread lib +# STDLIBS=-lpthread -lm STDLIBS=-lm # Define the include switch(es) for the X11 header files. # This can be null if handled in some other way (e.g., the files are -# in /usr/include, or the directory is supplied by an environment variable); -# in particular, SCO Xenix, Unix, and ODT just want -#XINCLUDE= -# Note that x_.h expects to find the header files in $(XINCLUDE)/X11, -# not in $(XINCLUDE). +# in /usr/include, or the directory is supplied by an environment variable) -XINCLUDE=-I/usr/X11R6/include +XINCLUDE= # Define the directory/ies and library names for the X11 library files. # XLIBDIRS is for ld and should include -L; XLIBDIR is for LD_RUN_PATH # (dynamic libraries on SVR4) and should not include -L. # Newer SVR4 systems can use -R in XLIBDIRS rather than setting XLIBDIR. -# Both can be null if these files are in the default linker search path; -# in particular, SCO Xenix, Unix, and ODT just want -#XLIBDIRS= +# Both can be null if these files are in the default linker search path. + # Solaris and other SVR4 systems with dynamic linking probably want #XLIBDIRS=-L/usr/openwin/lib -R/usr/openwin/lib # X11R6 (on any platform) may need #XLIBS=Xt SM ICE Xext X11 -#XLIBDIRS=-L/usr/local/X/lib -XLIBDIRS=-L/usr/X11R6/lib +# We use the autoconf macro AC_PATH_XTRA which defines X_LIBS with +# the -L (or whatever). It also defines X_PRE_LIBS and X_EXTRA_LIBS +# all three of which are stripped and slotted into XLIBS below. +# Usually however, all but X_LIBS are empty on modern platforms. +XLIBDIRS= XLIBDIR= -XLIBS=Xt Xext X11 +# XLIBS= Xt Xext X11 +XLIBS= # Define the .dev module that implements thread and synchronization # primitives for this platform. # If POSIX sync primitives are used, also change the STDLIBS to include -# the pthread library. +# the pthread library. Otherwise use SYNC=nosync #SYNC=posync +#SYNC=nosync +SYNC=nosync -# define the file name extension for a shared lib -DYNANIC_LIB_EXT=so +# programs we use +RM=rm -f -# Default is No sync primitives since some platforms don't have it (HP-UX) -SYNC=nosync +# ------ Dynamic loader options ------- # +SOC_CFLAGS = +SOC_LIBS = +SOC_LOADER = dxmainc.c + +# on virtually every Unix-a-like system, this is "so", +# but Apple just had to be different, so it's now set +# by configure +SO_LIB_EXT=.so +DLL_EXT= +SO_LIB_VERSION_SEPARATOR=. + +#CAIRO_CFLAGS = @CAIRO_CFLAGS@ +#CAIRO_LIBS = @CAIRO_LIBS@ -SOC_LOADER=dxmainc.c # ------ Devices and features ------ # # Choose the language feature(s) to include. See gs.mak for details. -FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)epsf.dev $(GLD)pipe.dev $(PSD)fapi.dev +# if it's included, $(PSD)gs_pdfwr.dev should always be one of the last in the list +PSI_FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)epsf.dev $(PSD)ttfont.dev \ + $(PSD)fapi_ps.dev $(PSD)jpx.dev $(PSD)jbig2.dev $(PSD)gs_pdfwr.dev + + +PCL_FEATURE_DEVS=$(PLOBJDIR)/pl.dev $(PLOBJDIR)/pjl.dev $(PXLOBJDIR)/pxl.dev $(PCL5OBJDIR)/pcl5c.dev \ + $(PCL5OBJDIR)/hpgl2c.dev + +XPS_FEATURE_DEVS=$(XPSOBJDIR)/pl.dev $(XPSOBJDIR)/xps.dev + +FEATURE_DEVS=$(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(GLD)psl3lib.dev $(GLD)psl2lib.dev \ + $(GLD)dps2lib.dev $(GLD)path1lib.dev $(GLD)patlib.dev $(GLD)psl2cs.dev $(GLD)rld.dev $(GLD)gxfapiu$(UFST_BRIDGE).dev\ + $(GLD)ttflib.dev $(GLD)cielib.dev $(GLD)pipe.dev $(GLD)htxlib.dev $(GLD)sdct.dev $(GLD)libpng.dev\ + $(GLD)seprlib.dev $(GLD)translib.dev $(GLD)cidlib.dev $(GLD)psf0lib.dev $(GLD)psf1lib.dev\ + $(GLD)psf2lib.dev $(GLD)lzwd.dev $(GLD)sicclib.dev \ + $(GLD)sjbig2.dev $(GLD)sjpx.dev $(GLD)ramfs.dev \ + $(GLD)pwgd.dev + + + + #FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev +#FEATURE_DEVS=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(GLD)pipe.dev # The following is strictly for testing. -FEATURE_DEVS_ALL=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)rasterop.dev $(PSD)double.dev $(PSD)trapping.dev $(PSD)stocht.dev $(GLD)pipe.dev +FEATURE_DEVS_ALL=$(PSD)psl3.dev $(PSD)pdf.dev $(PSD)dpsnext.dev $(PSD)ttfont.dev $(PSD)double.dev $(PSD)trapping.dev $(PSD)stocht.dev $(GLD)pipe.dev $(GLD)gsnogc.dev $(GLD)htxlib.dev $(PSD)jbig2.dev $(PSD)jpx.dev $(GLD)ramfs.dev #FEATURE_DEVS=$(FEATURE_DEVS_ALL) -# Choose whether to compile the .ps initialization files into the executable. -# See gs.mak for details. - -COMPILE_INITS=1 +# The list of resources to be included in the %rom% file system. +# This is in the top makefile since the file descriptors are platform specific +RESOURCE_LIST=Resource/CMap/ Resource/ColorSpace/ Resource/Decoding/ Resource/Font/ Resource/ProcSet/ Resource/IdiomSet/ Resource/CIDFont/ # Choose whether to store band lists on files or in memory. # The choices are 'file' or 'memory'. @@ -370,66 +556,43 @@ STDIO_IMPLEMENTATION=c -# Override the default device. This is set to 'display' by +# List of default devices, in order of priority. They need not be +# present in the actual build. +GS_DEV_DEFAULT="x11alpha bbox" + +# Fallback default device. This is set to 'display' by # unix-dll.mak when building a shared object. -DISPLAY_DEV= +DISPLAY_DEV=$(DD)bbox.dev # Choose the device(s) to include. See devs.mak for details, # devs.mak and contrib.mak for the list of available devices. - -DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11alpha.dev $(DD)x11cmyk.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev - -#DEVICE_DEVS1= -#DEVICE_DEVS2= -#DEVICE_DEVS3= -#DEVICE_DEVS4= -#DEVICE_DEVS5= -#DEVICE_DEVS6= -#DEVICE_DEVS7= -#DEVICE_DEVS8= -#DEVICE_DEVS9= -#DEVICE_DEVS10= -#DEVICE_DEVS11= -#DEVICE_DEVS12= -#DEVICE_DEVS13= -#DEVICE_DEVS14= -#DEVICE_DEVS15= -#DEVICE_DEVS16= -#DEVICE_DEVS17= -#DEVICE_DEVS18= -#DEVICE_DEVS19= -#DEVICE_DEVS20= - -DEVICE_DEVS1=$(DD)bmpmono.dev $(DD)bmpgray.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16.dev $(DD)bmp256.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)stcolor.dev -DEVICE_DEVS2=$(DD)epson.dev $(DD)eps9high.dev $(DD)eps9mid.dev $(DD)epsonc.dev $(DD)ibmpro.dev -DEVICE_DEVS3=$(DD)deskjet.dev $(DD)djet500.dev $(DD)laserjet.dev $(DD)ljetplus.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev $(DD)lj5mono.dev $(DD)lj5gray.dev -DEVICE_DEVS4=$(DD)cdeskjet.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cdj550.dev $(DD)pj.dev $(DD)pjxl.dev $(DD)pjxl300.dev -DEVICE_DEVS5=$(DD)uniprint.dev $(DD)ijs.dev -DEVICE_DEVS6=$(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev -DEVICE_DEVS7=$(DD)faxg3.dev $(DD)faxg32d.dev $(DD)faxg4.dev -DEVICE_DEVS8=$(DD)pcxmono.dev $(DD)pcxgray.dev $(DD)pcx16.dev $(DD)pcx256.dev $(DD)pcx24b.dev $(DD)pcxcmyk.dev -DEVICE_DEVS9=$(DD)pbm.dev $(DD)pbmraw.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev -DEVICE_DEVS10=$(DD)tiffcrle.dev $(DD)tiffg3.dev $(DD)tiffg32d.dev $(DD)tiffg4.dev $(DD)tifflzw.dev $(DD)tiffpack.dev -DEVICE_DEVS11=$(DD)tiff12nc.dev $(DD)tiff24nc.dev $(DD)tiff48nc.dev $(DD)tiffgray.dev $(DD)tiff32nc.dev $(DD)tiff64nc.dev $(DD)tiffsep.dev $(DD)tiffsep1.dev $(DD)tiffscaled.dev $(DD)tiffscaled8.dev $(DD)tiffscaled24.dev $(DD)tiffscaled32.dev -DEVICE_DEVS12=$(DD)bit.dev $(DD)bitrgb.dev $(DD)bitcmyk.dev -DEVICE_DEVS13=$(DD)pngmono.dev $(DD)pngmonod.dev $(DD)pnggray.dev $(DD)png16.dev $(DD)png256.dev $(DD)png16m.dev $(DD)pngalpha.dev -DEVICE_DEVS14=$(DD)jpeg.dev $(DD)jpeggray.dev $(DD)jpegcmyk.dev -DEVICE_DEVS15=$(DD)pdfwrite.dev $(DD)ps2write.dev $(DD)epswrite.dev $(DD)txtwrite.dev $(DD)pxlmono.dev $(DD)pxlcolor.dev -DEVICE_DEVS16=$(DD)bbox.dev $(DD)inkcov.dev - -DEVICE_DEVS17=$(DD)plan.dev $(DD)planm.dev $(DD)plang.dev $(DD)planc.dev $(DD)plank.dev - +# DEVICE_DEVS=$(DISPLAY_DEV) $(DD)x11.dev $(DD)x11_.dev $(DD)x11alpha.dev $(DD)x11alt_.dev $(DD)x11cmyk.dev $(DD)x11cmyk2.dev $(DD)x11cmyk4.dev $(DD)x11cmyk8.dev $(DD)x11gray2.dev $(DD)x11gray4.dev $(DD)x11mono.dev $(DD)x11rg16x.dev $(DD)x11rg32x.dev +DEVICE_DEVS=$(DISPLAY_DEV) +DEVICE_DEVS1=$(DD)bit.dev $(DD)bitcmyk.dev $(DD)bitrgb.dev $(DD)bitrgbtags.dev $(DD)bmp16.dev $(DD)bmp16m.dev $(DD)bmp256.dev $(DD)bmp32b.dev $(DD)bmpgray.dev $(DD)bmpmono.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)ccr.dev $(DD)cif.dev $(DD)devicen.dev $(DD)eps2write.dev $(DD)fpng.dev $(DD)inferno.dev $(DD)ink_cov.dev $(DD)inkcov.dev $(DD)jpeg.dev $(DD)jpegcmyk.dev $(DD)jpeggray.dev $(DD)mgr4.dev $(DD)mgr8.dev $(DD)mgrgray2.dev $(DD)mgrgray4.dev $(DD)mgrgray8.dev $(DD)mgrmono.dev $(DD)miff24.dev $(DD)pam.dev $(DD)pamcmyk32.dev $(DD)pamcmyk4.dev $(DD)pbm.dev $(DD)pbmraw.dev $(DD)pcx16.dev $(DD)pcx24b.dev $(DD)pcx256.dev $(DD)pcxcmyk.dev $(DD)pcxgray.dev $(DD)pcxmono.dev $(DD)pdfwrite.dev $(DD)pgm.dev $(DD)pgmraw.dev $(DD)pgnm.dev $(DD)pgnmraw.dev $(DD)pkm.dev $(DD)pkmraw.dev $(DD)pksm.dev $(DD)pksmraw.dev $(DD)plan.dev $(DD)plan9bm.dev $(DD)planc.dev $(DD)plang.dev $(DD)plank.dev $(DD)planm.dev $(DD)plank.dev $(DD)plib.dev $(DD)plibc.dev $(DD)plibg.dev $(DD)plibk.dev $(DD)plibm.dev $(DD)pnm.dev $(DD)pnmraw.dev $(DD)ppm.dev $(DD)ppmraw.dev $(DD)ps2write.dev $(DD)psdcmyk.dev $(DD)psdcmykog.dev $(DD)psdf.dev $(DD)psdrgb.dev $(DD)spotcmyk.dev $(DD)txtwrite.dev $(DD)xcf.dev +DEVICE_DEVS2=$(DD)ap3250.dev $(DD)atx23.dev $(DD)atx24.dev $(DD)atx38.dev $(DD)bj10e.dev $(DD)bj200.dev $(DD)bjc600.dev $(DD)bjc800.dev $(DD)cdeskjet.dev $(DD)cdj500.dev $(DD)cdj550.dev $(DD)cdjcolor.dev $(DD)cdjmono.dev $(DD)cljet5.dev $(DD)cljet5c.dev $(DD)cljet5pr.dev $(DD)coslw2p.dev $(DD)coslwxl.dev $(DD)declj250.dev $(DD)deskjet.dev $(DD)dj505j.dev $(DD)djet500.dev $(DD)djet500c.dev $(DD)dnj650c.dev $(DD)eps9high.dev $(DD)eps9mid.dev $(DD)epson.dev $(DD)epsonc.dev $(DD)escp.dev $(DD)fs600.dev $(DD)hl7x0.dev $(DD)ibmpro.dev $(DD)imagen.dev $(DD)itk24i.dev $(DD)itk38.dev $(DD)jetp3852.dev $(DD)laserjet.dev $(DD)lbp8.dev $(DD)lips3.dev $(DD)lj250.dev $(DD)lj3100sw.dev $(DD)lj4dith.dev $(DD)lj4dithp.dev $(DD)lj5gray.dev $(DD)lj5mono.dev $(DD)ljet2p.dev $(DD)ljet3.dev $(DD)ljet3d.dev $(DD)ljet4.dev $(DD)ljet4d.dev $(DD)ljet4pjl.dev $(DD)ljetplus.dev $(DD)lp2563.dev $(DD)lp8000.dev $(DD)lq850.dev $(DD)lxm5700m.dev $(DD)m8510.dev $(DD)necp6.dev $(DD)oce9050.dev $(DD)oki182.dev $(DD)okiibm.dev $(DD)paintjet.dev $(DD)photoex.dev $(DD)picty180.dev $(DD)pj.dev $(DD)pjetxl.dev $(DD)pjxl.dev $(DD)pjxl300.dev $(DD)pxlcolor.dev $(DD)pxlmono.dev $(DD)r4081.dev $(DD)rinkj.dev $(DD)sj48.dev $(DD)st800.dev $(DD)stcolor.dev $(DD)t4693d2.dev $(DD)t4693d4.dev $(DD)t4693d8.dev $(DD)tek4696.dev $(DD)uniprint.dev +DEVICE_DEVS3= +DEVICE_DEVS4=$(DD)ijs.dev +DEVICE_DEVS5= +DEVICE_DEVS6=$(DD)png16.dev $(DD)png16m.dev $(DD)png256.dev $(DD)png48.dev $(DD)pngalpha.dev $(DD)pnggray.dev $(DD)pngmono.dev +DEVICE_DEVS7= +DEVICE_DEVS8= +DEVICE_DEVS9= +DEVICE_DEVS10= +DEVICE_DEVS11= +DEVICE_DEVS12= +DEVICE_DEVS13= +DEVICE_DEVS14= +DEVICE_DEVS15= +DEVICE_DEVS16= +DEVICE_DEVS17= DEVICE_DEVS18= DEVICE_DEVS19= -DEVICE_DEVS20=$(DD)cljet5.dev $(DD)cljet5c.dev $(DD)pamcmyk32.dev $(DD)pamcmyk4.dev -DEVICE_DEVS21=$(DD)spotcmyk.dev $(DD)devicen.dev $(DD)xcf.dev $(DD)bmpsep1.dev $(DD)bmpsep8.dev $(DD)bmp16m.dev $(DD)bmp32b.dev $(DD)psdcmyk.dev $(DD)psdrgb.dev +DEVICE_DEVS20= +DEVICE_DEVS21= + # Shared library target to build. -# Note that the two vga devices are Linux specific, and requires svgalib -# We also don't do X modularized because modularization on Mac OS X doesn't work. GS_SHARED_OBJS= -#GS_SHARED_OBJS=$(GLOBJDIR)/X11.so $(GLOBJDIR)/lvga256.so $(GLOBJDIR)/vgalib.so - # ---------------------------- End of options --------------------------- # @@ -439,68 +602,109 @@ MAKEFILE=$(GLSRCDIR)/unix-gcc.mak TOP_MAKEFILES=$(MAKEFILE) $(GLSRCDIR)/unixhead.mak -# Define the auxiliary programs dependency. There aren't any, but we use -# this as a hook to detect whether we're running a version of gcc with -# the const optimization bug. +# for use in unix-dll.mak and unix-end.mak +# if you rename the Makefile, you *must* also set this to the new name +SUB_MAKE_OPTION=-f $(MAKEFILE) + +# Define the auxiliary program dependency. We don't use this. -AK=$(GLGENDIR)/cc.tr +AK= # Define the compilation rules and flags. -CCFLAGS=$(GENOPT) $(CAPOPT) $(CFLAGS) -DGX_COLOR_INDEX_TYPE='unsigned long long' -CC_=$(CC) `cat $(AK)` $(CCFLAGS) -CCAUX=$(CC) `cat $(AK)` $(CFLAGS) +CCFLAGS=$(GENOPT) $(CAPOPT) $(CFLAGS) +CC_=$(CC) $(CCFLAGS) +CCAUX_=$(CCAUX) $(CFLAGS) +CC_LEAF=$(CC_) +# note gcc can't use -fomit-frame-pointer with -pg. +CC_LEAF_PG=$(CC_) # These are the specific warnings we have to turn off to compile those # specific few files that need this. We may turn off others in the future. -CC_NO_WARN=$(CC_) -Wno-cast-qual -Wno-traditional -CC_SHARED=$(CC_) $(CFLAGS_SO) +CC_NO_WARN=$(CC_) +CCAUX_NO_WARN=$(CCAUX_) +CC_SHARED=$(CC_) -fPIC LD_SET_DT_SONAME=-soname= # MAKEDIRS = the dependency on ALL object files (must be the last one on # the line. Requires GNU make to make it an 'order only' dependency # MAKEDIRSTOP = the topmost dependency - set this if you can't set MAKEDIRS -MAKEDIRS= -MAKEDIRSTOP=directories + +MAKEDIRS=| directories +MAKEDIRSTOP= # ---------------- End of platform-specific section ---------------- # +INSTALL_CONTRIB= include $(GLSRCDIR)/unixhead.mak include $(GLSRCDIR)/gs.mak -include $(GLSRCDIR)/trio.mak -# psromfs.mak must precede lib.mak +# *romfs.mak must precede lib.mak + +# The following can be uncommented if the PCL/XPS/PDL sources +# are available +# include $(PLSRCDIR)$(D)plromfs.mak # plromfs.mak +# include $(XPSSRCDIR)$(D)xpsromfs.mak # xpsromfs.mak + include $(PSSRCDIR)/psromfs.mak include $(GLSRCDIR)/lib.mak include $(PSSRCDIR)/int.mak + +# The following can be uncommented if the PCL/XPS/PDL sources +# are available +# include $(PLSRCDIR)$(D)pl.mak # pl.mak +# include $(PCL5SRCDIR)$(D)pcl.mak # pcl.mak +# include $(PCL5SRCDIR)$(D)pcl_top.mak # pcl_top.mak +# include $(PXLSRCDIR)$(D)pxl.mak # pxl.mak + +# include $(XPSSRCDIR)$(D)xps.mak # xps.mak + +# include $(GPDLSRCDIR)$(D)gpdl.mak # gpdl.mak + include $(GLSRCDIR)/freetype.mak +include $(GLSRCDIR)$(D)stub.mak include $(GLSRCDIR)/jpeg.mak # zlib.mak must precede png.mak include $(GLSRCDIR)/zlib.mak include $(GLSRCDIR)/png.mak include $(GLSRCDIR)/tiff.mak include $(GLSRCDIR)/jbig2.mak -include $(GLSRCDIR)/lcms.mak +include $(GLSRCDIR)/ldf_jb2.mak +include $(GLSRCDIR)/lwf_jp2.mak +include $(GLSRCDIR)/openjpeg.mak + +include $(GLSRCDIR)/jpegxr.mak +include $(GLSRCDIR)/expat.mak + +include $(GLSRCDIR)/$(WHICH_CMS).mak include $(GLSRCDIR)/ijs.mak -include $(GLSRCDIR)/devs.mak -include $(GLSRCDIR)/contrib.mak + + +include $(DEVSRCDIR)/devs.mak +include $(DEVSRCDIR)/contrib.mak include $(GLSRCDIR)/unix-aux.mak include $(GLSRCDIR)/unixlink.mak include $(GLSRCDIR)/unix-dll.mak include $(GLSRCDIR)/unix-end.mak include $(GLSRCDIR)/unixinst.mak -# This has to come last so it won't be taken as the default target. -$(AK): - if ( $(CC) --version | egrep "^2\.7\.([01]|2(\.[^1-9]|$$))" >/dev/null ); then echo -Dconst= >$(AK); else echo -Wcast-qual -Wwrite-strings >$(AK); fi - -# platform-specific clean-up -# this makefile is intended to be hand edited so we don't distribute -# the (presumedly modified) version in the top level directory -distclean : clean config-clean - -$(RM) Makefile - @-rmdir $(BINDIR) $(GLOBJDIR) $(PSOBJDIR) + + +# Clean up after the autotools scripts +distclean : clean config-clean soclean pgclean debugclean mementoclean + -$(RM_) -r $(BINDIR) $(GLOBJDIR) $(PSOBJDIR) $(AUXDIR) + -$(RM_) -r autom4te.cache + -$(RM_) config.log config.status + -$(RM_) -r $(TIFFCONFDIR) + -$(RM_) Makefile + +# a debug-clean target for consistency with the ghostpdl builds +debug-clean : debugclean + +memento-clean : mementoclean maintainer-clean : distclean - # nothing special to do + -$(RM_) configure +check : default + $(NO_OP) diff -Nru ghostscript-9.10~dfsg/base/unixhead.mak ghostscript-9.25~dfsg+1/base/unixhead.mak --- ghostscript-9.10~dfsg/base/unixhead.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unixhead.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Partial makefile common to all Unix configurations. diff -Nru ghostscript-9.10~dfsg/base/unixinst.mak ghostscript-9.25~dfsg+1/base/unixinst.mak --- ghostscript-9.10~dfsg/base/unixinst.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unixinst.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,16 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Partial makefile common to all Unix and Desqview/X configurations, # containing the `install' targets. # This is the very last part of the makefile for these configurations. -install: install-exec install-scripts install-data $(INSTALL_SHARED) $(INSTALL_CONTRIB) +UNIXINST_MAK=$(GLSRC)unixinst.mak $(TOP_MAKEFILES) + +install: install-gs install-$(PCL) install-$(XPS) # The sh -c in the rules below is required because Ultrix's implementation # of sh -e terminates execution of a command if any error occurs, even if @@ -25,24 +27,45 @@ # We include mkdirs for datadir, gsdir, and gsdatadir in all 3 install # rules, just in case bindir or scriptdir is a subdirectory of any of these. -install-exec: $(GS_XE) $(MAKEDIRS) +install-exec-bindir: + -mkdir -p $(DESTDIR)$(bindir) + +install-exec: $(GS_XE) install-exec-bindir $(UNIXINST_MAK) $(MAKEDIRS) -mkdir -p $(DESTDIR)$(datadir) -mkdir -p $(DESTDIR)$(gsdir) -mkdir -p $(DESTDIR)$(gsdatadir) - -mkdir -p $(DESTDIR)$(bindir) - $(INSTALL_PROGRAM) $(GS_XE) $(DESTDIR)$(bindir)/$(GS) + $(INSTALL_PROGRAM) $(GS_XE) $(DESTDIR)$(bindir)/$(GS)$(XE) + +install-gs: install-exec install-scripts install-data $(INSTALL_SHARED) $(INSTALL_CONTRIB) + $(NO_OP) + +install-gpcl6: $(GPCL_XE) install-exec-bindir $(UNIXINST_MAK) $(MAKEDIRS) + $(INSTALL_PROGRAM) $(GPCL_XE) $(DESTDIR)$(bindir)/$(PCL)$(XE) + +install-gxps: $(GXPS_XE) install-exec-bindir $(UNIXINST_MAK) $(MAKEDIRS) + $(INSTALL_PROGRAM) $(GXPS_XE) $(DESTDIR)$(bindir)/$(XPS)$(XE) + +# dummy install taget if we don't have pcl and xps available +install-: + $(NO_OP) + +install-no_gpcl6: + $(NO_OP) + +install-no_gxps: + $(NO_OP) -install-scripts: $(PSLIBDIR)/gsnd +install-scripts: $(PSLIBDIR)/gsnd $(UNIXINST_MAK) $(MAKEDIRS) -mkdir -p $(DESTDIR)$(datadir) -mkdir -p $(DESTDIR)$(gsdir) -mkdir -p $(DESTDIR)$(gsdatadir) -mkdir -p $(DESTDIR)$(scriptdir) $(SH) -c 'for f in \ gsbj gsdj gsdj500 gslj gslp gsnd \ -bdftops dvipdf eps2eps font2c \ +bdftops dvipdf eps2eps \ pdf2dsc pdf2ps pf2afm pfbtopfa pphs printafm \ ps2ascii ps2epsi ps2pdf ps2pdf12 ps2pdf13 ps2pdf14 ps2pdfwr ps2ps ps2ps2 \ -wftopfa fixmswrd.pl lprsetup.sh pj-gs.sh pv.sh sysvlp.sh unix-lpr.sh ;\ +fixmswrd.pl lprsetup.sh pj-gs.sh pv.sh sysvlp.sh unix-lpr.sh ;\ do if ( test -f $(PSLIBDIR)/$$f ); then \ (cat $(PSLIBDIR)/$$f | sed -e "s/GS_EXECUTABLE=gs/GS_EXECUTABLE=$(GS)/" > $(PSOBJDIR)/$$f); \ $(INSTALL_PROGRAM) $(PSOBJDIR)/$$f $(DESTDIR)$(scriptdir)/$$f; \ @@ -55,7 +78,7 @@ PSEXDIR=$(PSLIBDIR)/../examples PSMANDIR=$(PSLIBDIR)/../man -install-data: install-libdata install-resdata$(COMPILE_INITS) install-iccdata$(COMPILE_INITS) install-doc install-man install-examples +install-data: install-libdata install-resdata$(COMPILE_INITS) install-iccdata$(COMPILE_INITS) install-doc install-man # There's no point in providing a complete dependency list: we include # one file from each subdirectory just as a sanity check. @@ -68,20 +91,20 @@ $(SH) -c 'for f in \ $(EXTRA_INIT_FILES) Fontmap.GS \ ht_ccsto.ps \ -acctest.ps addxchar.ps align.ps bdftops.ps \ -caption.ps cid2code.ps decrypt.ps docie.ps \ -errpage.ps font2c.ps font2pcl.ps gslp.ps gsnup.ps image-qa.ps impath.ps \ -jispaper.ps landscap.ps level1.ps lines.ps markhint.ps markpath.ps \ +acctest.ps align.ps bdftops.ps \ +caption.ps cid2code.ps docie.ps \ +errpage.ps font2pcl.ps gslp.ps gsnup.ps image-qa.ps \ +jispaper.ps landscap.ps lines.ps \ mkcidfm.ps PDFA_def.ps PDFX_def.ps \ -packfile.ps pcharstr.ps pf2afm.ps pfbtopfa.ps ppath.ps \ +pf2afm.ps pfbtopfa.ps ppath.ps \ pphs.ps \ prfont.ps printafm.ps \ -ps2ai.ps ps2ascii.ps ps2epsi.ps quit.ps rollconv.ps \ -showchar.ps showpage.ps stcinfo.ps stcolor.ps stocht.ps \ -traceimg.ps traceop.ps type1enc.ps type1ops.ps uninfo.ps unprot.ps \ +ps2ai.ps ps2ascii.ps ps2epsi.ps rollconv.ps \ +stcinfo.ps stcolor.ps stocht.ps \ +traceimg.ps traceop.ps uninfo.ps \ viewcmyk.ps viewgif.ps viewjpeg.ps viewmiff.ps \ viewpcx.ps viewpbm.ps viewps2a.ps \ -winmaps.ps wftopfa.ps wrfont.ps zeroline.ps \ +winmaps.ps zeroline.ps \ pdf2dsc.ps ;\ do if ( test -f $(PSLIBDIR)/$$f ); then $(INSTALL_DATA) $(PSLIBDIR)/$$f $(DESTDIR)$(gsdatadir)/lib; fi;\ done' @@ -129,10 +152,12 @@ Hershey.htm History5.htm index.html Make.htm Ps2ps2.htm Release.htm \ WhatIsGS.htm Changes.htm Details8.htm DLL.htm gs.css History1.htm \ History6.htm Install.htm News.htm pscet_status.txt Source.htm \ - Xfonts.htm Commprod.htm Details9.htm Drivers.htm gsdoc.el History2.htm \ + Commprod.htm Details9.htm Drivers.htm gsdoc.el History2.htm \ History7.htm Issues.htm Projects.htm Psfiles.htm thirdparty.htm \ COPYING Details.htm Fonts.htm gs-vms.hlp History3.htm History8.htm\ - Language.htm Ps2epsi.htm Ps-style.htm Unix-lpr.htm + Language.htm Ps2epsi.htm Ps-style.htm Unix-lpr.htm \ + sample_downscale_device.htm SavedPages.htm subclass.htm\ + VectorDevices.htm gdevds32.c install-doc: $(PSDOCDIR)/News.htm @@ -178,7 +203,7 @@ install-examples: -mkdir -p $(DESTDIR)$(exdir) for f in \ - alphabet.ps chess.ps colorcir.ps escher.ps grayalph.ps snowflak.ps \ + alphabet.ps colorcir.ps escher.ps grayalph.ps snowflak.ps \ text_graph_image_cmyk_rgb.pdf transparency_example.ps waterfal.ps \ annots.pdf doretree.ps golfer.eps ridt91.eps text_graphic_image.pdf \ tiger.eps vasarely.ps;\ diff -Nru ghostscript-9.10~dfsg/base/unixlink.mak ghostscript-9.25~dfsg+1/base/unixlink.mak --- ghostscript-9.10~dfsg/base/unixlink.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/unixlink.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,14 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Partial makefile common to all Unix configurations. # This part of the makefile contains the linking steps. # Define the name of this makefile. -UNIXLINK_MAK=$(GLSRC)unixlink.mak +UNIXLINK_MAK=$(GLSRC)unixlink.mak $(TOP_MAKEFILES) # The following prevents GNU make from constructing argument lists that # include all environment variables, which can easily be longer than @@ -28,36 +28,141 @@ ### Interpreter main program -INT_ARCHIVE_ALL=$(PSOBJ)imainarg.$(OBJ) $(PSOBJ)imain.$(OBJ) \ - $(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ) +INT_ARCHIVE_SOME=$(GLOBJ)gconfig.$(OBJ) $(GLOBJ)gscdefs.$(OBJ) + +PSINT_ARCHIVE_ALL=$(PSOBJ)imainarg.$(OBJ) $(PSOBJ)imain.$(OBJ) $(GLOBJ)iconfig.$(OBJ) + +INT_ARCHIVE_ALL=$(PSINT_ARCHIVE_ALL) $(INT_ARCHIVE_SOME) + XE_ALL=$(PSOBJ)gs.$(OBJ) $(INT_ARCHIVE_ALL) $(INT_ALL) $(DEVS_ALL) +GS_DOT_O=$(PSOBJ)gs.$(OBJ) + # Build a library archive for the entire interpreter. # This is not used in a standard build. -liar_tr=$(GLOBJ)liar.tr -GS_A=$(GS).a -$(GS_A): $(obj_tr) $(ECHOGS_XE) $(INT_ARCHIVE_ALL) $(INT_ALL) $(DEVS_ALL) + +# options for genconf, to *just* output the libs to link +# and search paths for them +CONFLIBSTR=-pl "&-l%s&s&&" -pL "&-L%s&s&&" -l + +libgs_a_tr=$(GLOBJ)libgs_a.tr +GS_A=$(BINDIR)$(D)$(GS).a +$(GS_A): $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) \ + $(obj_tr) $(ECHOGS_XE) $(INT_ARCHIVE_ALL) $(INT_ALL) $(DEVS_ALL) \ + $(UNIXLINK_MAK) rm -f $(GS_A) - $(ECHOGS_XE) -w $(liar_tr) -n - $(AR) $(ARFLAGS) $(GS_A) - $(ECHOGS_XE) -a $(liar_tr) -n -s $(INT_ARCHIVE_ALL) -s - cat $(obj_tr) >>$(liar_tr) - $(ECHOGS_XE) -a $(liar_tr) -s - - $(SH) <$(liar_tr) + $(ECHOGS_XE) -w $(libgs_a_tr) -n - $(AR) $(ARFLAGS) $(GS_A) + $(ECHOGS_XE) -a $(libgs_a_tr) -n -s $(INT_ARCHIVE_ALL) -s + $(ECHOGS_XE) -a $(libgs_a_tr) -n -s $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) -s + cat $(obj_tr) >>$(libgs_a_tr) + $(ECHOGS_XE) -a $(libgs_a_tr) -s - + $(SH) <$(libgs_a_tr) $(RANLIB) $(GS_A) +GS_A_XE=$(BINDIR)$(D)$(GS)_aexe$(XE) +gs_a_xeld_tr=$(GLOBJ)$(D)$(GS)_aexeld.tr +gs_a_xeldt_tr=$(GLOBJ)$(D)$(GS)_aexeldt.tr +$(GS_A_XE): $(GS_A) $(GS_DOT_O) + $(EXP)$(GENCONF_XE) $(gs_tr) -h $(GLGENDIR)$(D)unused.h $(CONFLIBSTR) $(gs_a_xeld_tr) + $(ECHOGS_XE) -w $(gs_a_xeldt_tr) -n - $(CCLD) $(GS_LDFLAGS) -o $(GS_A_XE) + $(ECHOGS_XE) -a $(gs_a_xeldt_tr) -n -s $(GS_DOT_O) -s + $(ECHOGS_XE) -a $(gs_a_xeldt_tr) -n -s - $(GS_A) $(EXTRALIBS) $(STDLIBS) -s + $(ECHOGS_XE) -a $(gs_a_xeldt_tr) -n -s -R $(gs_a_xeld_tr) + $(SH) < $(gs_a_xeldt_tr) + +libgpcl6_a_tr=$(GLOBJ)libgpcl6_a.tr +GPCL_A=$(BINDIR)$(D)$(PCL).a +$(GPCL_A): $(MAIN_OBJ) $(TOP_OBJ) $(XOBJS) \ + $(GLOBJDIR)/pclromfs$(COMPILE_INITS).$(OBJ) $(PCL_DEVS_ALL) \ + $(INT_ARCHIVE_SOME) $(pclobj_tr) $(ECHOGS_XE) $(DEVS_ALL) $(UNIXLINK_MAK) + rm -f $(GPCL_A) + $(ECHOGS_XE) -w $(libgpcl6_a_tr) -n - $(AR) $(ARFLAGS) $(GPCL_A) + $(ECHOGS_XE) -a $(libgpcl6_a_tr) -n -s $(TOP_OBJ) $(INT_ARCHIVE_SOME) $(XOBJS) -s + $(ECHOGS_XE) -a $(libgpcl6_a_tr) -n -s $(PSOBJ)pclromfs$(COMPILE_INITS).$(OBJ) $(MAIN_OBJ) -s + cat $(pclobj_tr) >>$(libgpcl6_a_tr) + $(ECHOGS_XE) -a $(libgpcl6_a_tr) -s - + $(SH) <$(libgpcl6_a_tr) + $(RANLIB) $(GPCL_A) + +GPCL_A_XE=$(BINDIR)$(D)$(PCL)_aexe$(XE) +gpcl_a_xeld_tr=$(GLOBJ)$(D)$(PCL)_aexeld.tr +gpcl_a_xeldt_tr=$(GLOBJ)$(D)$(PCL)_aexeldt.tr +$(GPCL_A_XE): $(GPCL_A) $(REALMAIN_OBJ) + $(EXP)$(GENCONF_XE) $(pcl_tr) -h $(GLGENDIR)$(D)unused.h $(CONFLIBSTR) $(gpcl_a_xeld_tr) + $(ECHOGS_XE) -w $(gpcl_a_xeldt_tr) -n - $(CCLD) $(GS_LDFLAGS) -o $(GPCL_A_XE) + $(ECHOGS_XE) -a $(gpcl_a_xeldt_tr) -n -s $(REALMAIN_OBJ) -s + $(ECHOGS_XE) -a $(gpcl_a_xeldt_tr) -n -s - $(GPCL_A) $(EXTRALIBS) $(STDLIBS) -s + $(ECHOGS_XE) -a $(gpcl_a_xeldt_tr) -n -s -R $(gpcl_a_xeld_tr) + $(SH) < $(gpcl_a_xeldt_tr) + +libgxps_a_tr=$(GLOBJ)libgxps_a.tr +GXPS_A=$(BINDIR)$(D)$(XPS).a +$(GXPS_A): $(MAIN_OBJ) $(XPS_TOP_OBJS) $(XOBJS) \ + $(GLOBJDIR)/xpsromfs$(COMPILE_INITS).$(OBJ) $(XPS_DEVS_ALL) \ + $(INT_ARCHIVE_SOME) $(xpsobj_tr) $(ECHOGS_XE) $(DEVS_ALL) $(UNIXLINK_MAK) + rm -f $(GXPS_A) + $(ECHOGS_XE) -w $(libgxps_a_tr) -n - $(AR) $(ARFLAGS) $(GXPS_A) + $(ECHOGS_XE) -a $(libgxps_a_tr) -n -s $(XPS_TOP_OBJS) $(INT_ARCHIVE_SOME) $(XOBJS) -s + $(ECHOGS_XE) -a $(libgxps_a_tr) -n -s $(PSOBJ)xpsromfs$(COMPILE_INITS).$(OBJ) $(MAIN_OBJ) -s + cat $(xpsobj_tr) >> $(libgxps_a_tr) + $(ECHOGS_XE) -a $(libgxps_a_tr) -s - + $(SH) <$(libgxps_a_tr) + $(RANLIB) $(GXPS_A) + +GXPS_A_XE=$(BINDIR)$(D)$(XPS)_aexe$(XE) +gxps_a_xeld_tr=$(GLOBJ)$(D)$(XPS)_aexeld.tr +gxps_a_xeldt_tr=$(GLOBJ)$(D)$(XPS)_aexeldt.tr +$(GXPS_A_XE): $(GXPS_A) $(REALMAIN_OBJ) + $(EXP)$(GENCONF_XE) $(xps_tr) -h $(GLGENDIR)$(D)unused.h $(CONFLIBSTR) $(gxps_a_xeld_tr) + $(ECHOGS_XE) -w $(gxps_a_xeldt_tr) -n - $(CCLD) $(GS_LDFLAGS) -o $(GXPS_A_XE) + $(ECHOGS_XE) -a $(gxps_a_xeldt_tr) -n -s $(REALMAIN_OBJ) -s + $(ECHOGS_XE) -a $(gxps_a_xeldt_tr) -n -s - $(GXPS_A) $(EXTRALIBS) $(STDLIBS) -s + $(ECHOGS_XE) -a $(gxps_a_xeldt_tr) -n -s -R $(gxps_a_xeld_tr) + $(SH) < $(gxps_a_xeldt_tr) + +libgpdl_tr=$(GLOBJ)libgpdl.tr +GPDL_A=$(BINDIR)$(D)$(GPDL).a +$(GPDL_A): $(GPDL_PSI_TOP_OBJS) $(PCL_PXL_TOP_OBJS) $(PSI_TOP_OBJ) $(XPS_TOP_OBJ) $(MAIN_OBJ) \ + $(XOBJS) $(GLOBJDIR)/pdlromfs$(COMPILE_INITS).$(OBJ) \ + $(PSINT_ARCHIVE_ALL) \ + $(pdlobj_tr) $(ECHOGS_XE) $(INT_ARCHIVE_ALL) $(INT_ALL) $(DEVS_ALL) \ + $(UNIXLINK_MAK) + rm -f $(GPDL_A) + $(ECHOGS_XE) -w $(libgpdl_tr) -n - $(AR) $(ARFLAGS) $(GPDL_A) + $(ECHOGS_XE) -a $(libgpdl_tr) -n -s $(GPDL_PSI_TOP_OBJS) $(PCL_PXL_TOP_OBJS) $(PSI_TOP_OBJ) $(XPS_TOP_OBJ) $(XOBJS) -s + $(ECHOGS_XE) -a $(libgpdl_tr) -n -s $(GLOBJDIR)/pdlromfs$(COMPILE_INITS).$(OBJ) $(MAIN_OBJ) -s + cat $(pdlobj_tr) >>$(libgpdl_tr) + $(ECHOGS_XE) -a $(libgpdl_tr) -s - + $(SH) <$(libgpdl_tr) + $(RANLIB) $(GPDL_A) + +GPDL_A_XE=$(BINDIR)$(D)$(GPDL)_aexe$(XE) +gpdl_a_xeld_tr=$(GLOBJ)$(D)$(GPDL)_aexeld.tr +gpdl_a_xeldt_tr=$(GLOBJ)$(D)$(GPDL)_aexeldt.tr +$(GPDL_A_XE): $(GPDL_A) $(REALMAIN_OBJ) + $(EXP)$(GENCONF_XE) $(gpdl_tr) -h $(GLGENDIR)$(D)unused.h $(CONFLIBSTR) $(gpdl_a_xeld_tr) + $(ECHOGS_XE) -w $(gpdl_a_xeldt_tr) -n - $(CCLD) $(GS_LDFLAGS) -o $(GPDL_A_XE) + $(ECHOGS_XE) -a $(gpdl_a_xeldt_tr) -n -s $(REALMAIN_OBJ) -s + $(ECHOGS_XE) -a $(gpdl_a_xeldt_tr) -n -s - $(GPDL_A) $(EXTRALIBS) $(STDLIBS) -s + $(ECHOGS_XE) -a $(gpdl_a_xeldt_tr) -n -s -R $(gpdl_a_xeld_tr) + $(SH) < $(gpdl_a_xeldt_tr) + + # Here is the final link step. The stuff with LD_RUN_PATH is for SVR4 # systems with dynamic library loading; I believe it's harmless elsewhere. # The resetting of the environment variables to empty strings is for SCO Unix, # which has limited environment space. ldt_tr=$(PSOBJ)ldt.tr -$(GS_XE): $(ld_tr) $(ECHOGS_XE) $(XE_ALL) $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) - $(ECHOGS_XE) -w $(ldt_tr) -n - $(CCLD) $(LDFLAGS) -o $(GS_XE) - $(ECHOGS_XE) -a $(ldt_tr) -n -s $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) $(PSOBJ)gs.$(OBJ) -s - cat $(ld_tr) >>$(ldt_tr) + +$(GS_XE): $(ld_tr) $(gs_tr) $(ECHOGS_XE) $(XE_ALL) $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) \ + $(UNIXLINK_MAK) + $(ECHOGS_XE) -w $(ldt_tr) -n - $(CCLD) $(GS_LDFLAGS) -o $(GS_XE) + $(ECHOGS_XE) -a $(ldt_tr) -n -s $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) $(GS_DOT_O) -s + cat $(gsld_tr) >> $(ldt_tr) $(ECHOGS_XE) -a $(ldt_tr) -s - $(EXTRALIBS) $(STDLIBS) if [ x$(XLIBDIR) != x ]; then LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; fi; \ XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \ - FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \ + PSI_FEATURE_DEVS= FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \ DEVICE_DEVS4= DEVICE_DEVS5= DEVICE_DEVS6= DEVICE_DEVS7= DEVICE_DEVS8= \ DEVICE_DEVS9= DEVICE_DEVS10= DEVICE_DEVS11= DEVICE_DEVS12= \ DEVICE_DEVS13= DEVICE_DEVS14= DEVICE_DEVS15= DEVICE_DEVS16= \ @@ -65,11 +170,83 @@ DEVICE_DEVS_EXTRA= \ $(SH) <$(ldt_tr) +.gssubtarget: $(GS_XE) + $(NO_OP) + + +pclldt_tr=$(PSOBJ)pclldt.tr +$(GPCL_XE): $(ld_tr) $(pcl_tr) $(REALMAIN_OBJ) $(MAIN_OBJ) $(TOP_OBJ) $(XOBJS) \ + $(GLOBJDIR)/pclromfs$(COMPILE_INITS).$(OBJ) \ + $(INT_ARCHIVE_SOME) $(UNIXLINK_MAK) + $(ECHOGS_XE) -w $(pclldt_tr) -n - $(CCLD) $(PCL_LDFLAGS) $(XLIBDIRS) -o $(GPCL_XE) + $(ECHOGS_XE) -a $(pclldt_tr) -n -x 20 + $(ECHOGS_XE) -a $(pclldt_tr) -n -s $(TOP_OBJ) $(INT_ARCHIVE_SOME) $(XOBJS) -s + cat $(pclld_tr) >> $(pclldt_tr) + $(ECHOGS_XE) -a $(pclldt_tr) -n -s - $(GLOBJDIR)/pclromfs$(COMPILE_INITS).$(OBJ) $(REALMAIN_OBJ) $(MAIN_OBJ) + $(ECHOGS_XE) -a $(pclldt_tr) -s - $(EXTRALIBS) $(STDLIBS) + if [ x$(XLIBDIR) != x ]; then LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; fi; \ + XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \ + PCL_FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \ + DEVICE_DEVS4= DEVICE_DEVS5= DEVICE_DEVS6= DEVICE_DEVS7= DEVICE_DEVS8= \ + DEVICE_DEVS9= DEVICE_DEVS10= DEVICE_DEVS11= DEVICE_DEVS12= \ + DEVICE_DEVS13= DEVICE_DEVS14= DEVICE_DEVS15= DEVICE_DEVS16= \ + DEVICE_DEVS17= DEVICE_DEVS18= DEVICE_DEVS19= DEVICE_DEVS20= \ + DEVICE_DEVS_XETRA= \ + sh <$(pclldt_tr) + +.pcl6subtarget: $(GPCL_XE) + $(NO_OP) + +xpsldt_tr=$(PSOBJ)xpsldt.tr +$(GXPS_XE): $(ld_tr) $(xps_tr) $(REALMAIN_OBJ) $(MAIN_OBJ) $(XPS_TOP_OBJS) \ + $(XOBJS) $(GLOBJDIR)/xpsromfs$(COMPILE_INITS).$(OBJ) \ + $(INT_ARCHIVE_SOME) $(UNIXLINK_MAK) + $(ECHOGS_XE) -w $(xpsldt_tr) -n - $(CCLD) $(XPS_LDFLAGS) $(XLIBDIRS) -o $(GXPS_XE) + $(ECHOGS_XE) -a $(xpsldt_tr) -n -s $(XPS_TOP_OBJS) $(INT_ARCHIVE_SOME) $(XOBJS) -s + cat $(xpsld_tr) >> $(xpsldt_tr) + $(ECHOGS_XE) -a $(xpsldt_tr) -s - $(GLOBJDIR)/xpsromfs$(COMPILE_INITS).$(OBJ) $(REALMAIN_OBJ) $(MAIN_OBJ) $(EXTRALIBS) $(STDLIBS) + if [ x$(XLIBDIR) != x ]; then LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; fi; \ + XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \ + PCL_FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \ + DEVICE_DEVS4= DEVICE_DEVS5= DEVICE_DEVS6= DEVICE_DEVS7= DEVICE_DEVS8= \ + DEVICE_DEVS9= DEVICE_DEVS10= DEVICE_DEVS11= DEVICE_DEVS12= \ + DEVICE_DEVS13= DEVICE_DEVS14= DEVICE_DEVS15= DEVICE_DEVS16= \ + DEVICE_DEVS17= DEVICE_DEVS18= DEVICE_DEVS19= DEVICE_DEVS20= \ + DEVICE_DEVS_EXTRA= \ + sh <$(xpsldt_tr) + +.xpssubtarget: $(GXPS_XE) + $(NO_OP) + +gpdlldt_tr=$(PSOBJ)gpdlldt.tr +$(GPDL_XE): $(ld_tr) $(gpdl_tr) $(INT_ARCHIVE_ALL) $(REALMAIN_OBJ) $(MAIN_OBJ) \ + $(GPDL_PSI_TOP_OBJS) $(PCL_PXL_TOP_OBJS) $(PSI_TOP_OBJ) $(XPS_TOP_OBJ) \ + $(XOBJS) $(GLOBJDIR)/pdlromfs$(COMPILE_INITS).$(OBJ) \ + $(PSINT_ARCHIVE_ALL) $(UNIXLINK_MAK) + $(ECHOGS_XE) -w $(gpdlldt_tr) -n - $(CCLD) $(PDL_LDFLAGS) $(XLIBDIRS) -o $(GPDL_XE) + $(ECHOGS_XE) -a $(gpdlldt_tr) -n -s $(GPDL_PSI_TOP_OBJS) $(PCL_PXL_TOP_OBJS) $(PSI_TOP_OBJ) $(XPS_TOP_OBJ) $(XOBJS) -s + cat $(gpdlld_tr) >> $(gpdlldt_tr) + $(ECHOGS_XE) -a $(gpdlldt_tr) -s - $(GLOBJDIR)/pdlromfs$(COMPILE_INITS).$(OBJ) $(REALMAIN_OBJ) $(MAIN_OBJ) $(EXTRALIBS) $(STDLIBS) + if [ x$(XLIBDIR) != x ]; then LD_RUN_PATH=$(XLIBDIR); export LD_RUN_PATH; fi; \ + XCFLAGS= XINCLUDE= XLDFLAGS= XLIBDIRS= XLIBS= \ + PCL_FEATURE_DEVS= DEVICE_DEVS= DEVICE_DEVS1= DEVICE_DEVS2= DEVICE_DEVS3= \ + DEVICE_DEVS4= DEVICE_DEVS5= DEVICE_DEVS6= DEVICE_DEVS7= DEVICE_DEVS8= \ + DEVICE_DEVS9= DEVICE_DEVS10= DEVICE_DEVS11= DEVICE_DEVS12= \ + DEVICE_DEVS13= DEVICE_DEVS14= DEVICE_DEVS15= DEVICE_DEVS16= \ + DEVICE_DEVS17= DEVICE_DEVS18= DEVICE_DEVS19= DEVICE_DEVS20= \ + DEVICE_DEVS_EXTRA= \ + sh <$(gpdlldt_tr) + +.gpdlsubtarget: $(GPDL_XE) + $(NO_OP) + + APITEST_XE=$(BINDIR)$(D)apitest$(XE) apitest: $(APITEST_XE) -$(APITEST_XE): $(ld_tr) $(ECHOGS_XE) $(XE_ALL) $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) $(PSOBJ)apitest.$(OBJ) +$(APITEST_XE): $(ld_tr) $(ECHOGS_XE) $(XE_ALL) $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) $(PSOBJ)apitest.$(OBJ) \ + $(UNIXLINK_MAK) $(ECHOGS_XE) -w $(ldt_tr) -n - $(CCLD) $(LDFLAGS) -o $(APITEST_XE) $(ECHOGS_XE) -a $(ldt_tr) -n -s $(PSOBJ)gsromfs$(COMPILE_INITS).$(OBJ) $(PSOBJ)apitest.$(OBJ) -s cat $(ld_tr) >>$(ldt_tr) diff -Nru ghostscript-9.10~dfsg/base/valgrind.h ghostscript-9.25~dfsg+1/base/valgrind.h --- ghostscript-9.10~dfsg/base/valgrind.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/valgrind.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/vdtrace.c ghostscript-9.25~dfsg+1/base/vdtrace.c --- ghostscript-9.10~dfsg/base/vdtrace.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/vdtrace.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Visual tracer service */ - -#include "math_.h" -#include "gxfixed.h" -#include "vdtrace.h" - -/* Global data for all instances : */ -vd_trace_interface * vd_trace0 = NULL, * vd_trace1 = NULL; -char vd_flags[128] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0""\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; - -static double px, py; - -#define NullRET if(vd_trace1 == NULL) return - -static inline double scale_x(vd_trace_interface *I, double x) -{ return (x - I->orig_x) * I->scale_x + I->shift_x; -} - -static inline double scale_y(vd_trace_interface *I, double y) -{ return (y - I->orig_y) * I->scale_y + I->shift_y; -} - -#define SX(x) scale_x(vd_trace1, x) -#define SY(y) scale_y(vd_trace1, y) - -static inline double bezier_point(double p0, double p1, double p2, double p3, double t) -{ double s = 1-t; - return p0*s*s*s + 3*p1*s*s*t + 3*p2*s*t*t + p3*t*t*t; -} - -static void vd_flatten(double p0x, double p0y, double p1x, double p1y, double p2x, double p2y, double p3x, double p3y) -{ -#ifdef DEBUG - double flat = 0.5; - double d2x0 = (p0x - 2 * p1x + p2x), d2y0 = (p0y - 2 * p1y + p2y); - double d2x1 = (p1x - 2 * p2x + p3x), d2y1 = (p1y - 2 * p2y + p3y); - double d2norm0 = hypot(d2x0, d2y0); - double d2norm1 = hypot(d2x1, d2y1); - double D = max(d2norm0, d2norm1); /* This is half of maximum norm of 2nd derivative of the curve by parameter t. */ - int NN = (int)ceil(sqrt(D * 3 / 4 / flat)); /* Number of output segments. */ - int i; - int N = max(NN, 1); /* safety (if the curve degenerates to line) */ - double e = 0.5 / N; - - for (i = 0; i < N; i++) { - double t = (double)i / N + e; - double px = bezier_point(p0x, p1x, p2x, p3x, t); - double py = bezier_point(p0y, p1y, p2y, p3y, t); - - vd_lineto(px, py); - } - vd_lineto(p3x, p3y); -#endif -} - -void vd_impl_moveto(double x, double y) -{ NullRET; - px = SX(x), py = SY(y); - vd_trace1->moveto(vd_trace1, px, py); -} - -void vd_impl_lineto(double x, double y) -{ NullRET; - px = SX(x), py = SY(y); - vd_trace1->lineto(vd_trace1, px, py); -} - -void vd_impl_lineto_multi(const struct gs_fixed_point_s *p, int n) -{ int i; - NullRET; - for (i = 0; i < n; i++) { - px = SX(p[i].x), py = SY(p[i].y); - vd_trace1->lineto(vd_trace1, px, py); - } -} - -void vd_impl_curveto(double x1, double y1, double x2, double y2, double x3, double y3) -{ double p1x, p1y, p2x, p2y, p3x, p3y; - - NullRET; - p1x = SX(x1), p1y = SY(y1); - p2x = SX(x2), p2y = SY(y2); - p3x = SX(x3), p3y = SY(y3); - if (vd_trace1->curveto != NULL) - vd_trace1->curveto(vd_trace1, p1x, p1y, p2x, p2y, p3x, p3y); - else - vd_flatten(px, py, p1x, p1y, p2x, p2y, p3x, p3y); - px = p3x, py = p3y; -} - -void vd_impl_bar(double x0, double y0, double x1, double y1, int w, unsigned long c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->setlinewidth(vd_trace1, w); - vd_trace1->beg_path(vd_trace1); - vd_trace1->moveto(vd_trace1, SX(x0), SY(y0)); - vd_trace1->lineto(vd_trace1, SX(x1), SY(y1)); - vd_trace1->end_path(vd_trace1); - vd_trace1->stroke(vd_trace1); -} - -void vd_impl_square(double x, double y, int w, unsigned int c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->setlinewidth(vd_trace1, 1); - vd_trace1->beg_path(vd_trace1); - vd_trace1->moveto(vd_trace1, SX(x) - w, SY(y) - w); - vd_trace1->lineto(vd_trace1, SX(x) + w, SY(y) - w); - vd_trace1->lineto(vd_trace1, SX(x) + w, SY(y) + w); - vd_trace1->lineto(vd_trace1, SX(x) - w, SY(y) + w); - vd_trace1->lineto(vd_trace1, SX(x) - w, SY(y) - w); - vd_trace1->end_path(vd_trace1); - vd_trace1->stroke(vd_trace1); -} - -void vd_impl_rect(double x0, double y0, double x1, double y1, int w, unsigned int c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->setlinewidth(vd_trace1, w); - vd_trace1->beg_path(vd_trace1); - vd_trace1->moveto(vd_trace1, SX(x0), SY(y0)); - vd_trace1->lineto(vd_trace1, SX(x0), SY(y1)); - vd_trace1->lineto(vd_trace1, SX(x1), SY(y1)); - vd_trace1->lineto(vd_trace1, SX(x1), SY(y0)); - vd_trace1->lineto(vd_trace1, SX(x0), SY(y0)); - vd_trace1->end_path(vd_trace1); - vd_trace1->stroke(vd_trace1); -} - -void vd_impl_quad(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int w, unsigned int c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->setlinewidth(vd_trace1, w); - vd_trace1->beg_path(vd_trace1); - vd_trace1->moveto(vd_trace1, SX(x0), SY(y0)); - vd_trace1->lineto(vd_trace1, SX(x1), SY(y1)); - vd_trace1->lineto(vd_trace1, SX(x2), SY(y2)); - vd_trace1->lineto(vd_trace1, SX(x3), SY(y3)); - vd_trace1->lineto(vd_trace1, SX(x0), SY(y0)); - vd_trace1->end_path(vd_trace1); - vd_trace1->stroke(vd_trace1); -} - -void vd_impl_curve(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int w, unsigned long c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->setlinewidth(vd_trace1, w); - vd_trace1->beg_path(vd_trace1); - vd_trace1->moveto(vd_trace1, SX(x0), SY(y0)); - vd_impl_curveto(x1, y1, x2, y2, x3, y3); - vd_trace1->end_path(vd_trace1); - vd_trace1->stroke(vd_trace1); -} - -void vd_impl_circle(double x, double y, int r, unsigned long c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->setlinewidth(vd_trace1, 1); - vd_trace1->circle(vd_trace1, SX(x), SY(y), r); -} - -void vd_impl_round(double x, double y, int r, unsigned long c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->setlinewidth(vd_trace1, 1); - vd_trace1->round(vd_trace1, SX(x), SY(y), r); -} - -void vd_impl_pixel(double x, double y, unsigned long c) -{ NullRET; - vd_trace1->pixel(vd_trace1, SX(x), SY(y), c); -} - -void vd_impl_text(double x, double y, char *s, unsigned long c) -{ NullRET; - vd_trace1->setcolor(vd_trace1, c); - vd_trace1->text(vd_trace1, SX(x), SY(y), s); -} - -void vd_setflag(char f, char v) -{ vd_flags[f & 127] = v; -} diff -Nru ghostscript-9.10~dfsg/base/vdtrace.h ghostscript-9.25~dfsg+1/base/vdtrace.h --- ghostscript-9.10~dfsg/base/vdtrace.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/vdtrace.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,192 +0,0 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. - All Rights Reserved. - - This software is provided AS-IS with no warranty, either express or - implied. - - This software is distributed under license and may not be copied, - modified or distributed except as expressly authorized under the terms - of the license contained in the file LICENSE in this distribution. - - Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. -*/ - - -/* Visual tracer service interface */ - -#ifndef vdtrace_INCLUDED -# define vdtrace_INCLUDED - -/* Painting contract : - - First use vd_get_dc. - Then paint with vd_* functionns. - When completed, use vd_release_dc. - - The following functions paint immediately, without vd_beg_path, vd_end_path, vd_fill, vd_stroke : - vd_circle, vd_round, vd_bar, vd_bar_w, vd_curve, vd_curve_w - - The following functions require vd_fill or vd_stroke only if enclosed with vd_beg_path, vd_end_path : - vd_moveto, vd_lineto, vd_curveto, vd_closepath. - Otherwise they paint directly (this is useful for step-by-step execution). -*/ - -#if !defined(VD_TRACE) -# if defined(DEBUG) -# define VD_TRACE 1 -# else -# define VD_TRACE 0 -# endif -#endif - -typedef struct vd_trace_host_s vd_trace_host; -typedef struct vd_trace_interface_s vd_trace_interface; -struct gs_fixed_point_s; - -struct vd_trace_interface_s { - vd_trace_host *host; - double scale_x, scale_y; - double orig_x, orig_y; - double shift_x, shift_y; - double (*get_size_x)(vd_trace_interface *I); - double (*get_size_y)(vd_trace_interface *I); - void (*get_dc)(vd_trace_interface *I, vd_trace_interface **I1); - void (*release_dc)(vd_trace_interface *I, vd_trace_interface **I1); - void (*erase)(vd_trace_interface *I, unsigned long rgbcolor); - void (*beg_path)(vd_trace_interface *I); - void (*end_path)(vd_trace_interface *I); - void (*moveto)(vd_trace_interface *I, double x, double y); - void (*lineto)(vd_trace_interface *I, double x, double y); - void (*curveto)(vd_trace_interface *I, double x0, double y0, double x1, double y1, double x2, double y2); - void (*closepath)(vd_trace_interface *I); - void (*circle)(vd_trace_interface *I, double x, double y, int r); /* Radius doesn't scale. */ - void (*round)(vd_trace_interface *I, double x, double y, int r); /* Radius doesn't scale. */ - void (*pixel)(vd_trace_interface *I, double x, double y, unsigned long rgbcolor); - void (*fill)(vd_trace_interface *I); - void (*stroke)(vd_trace_interface *I); - void (*setcolor)(vd_trace_interface *I, unsigned long rgbcolor); - void (*setlinewidth)(vd_trace_interface *I, unsigned int width); /* Width doesn't scale. */ - void (*text)(vd_trace_interface *I, double x, double y, char *ASCIIZ); /* Font doesn't scale. */ - void (*wait)(vd_trace_interface *I); - void (*set_scale)(vd_trace_interface *I); - void (*set_shift)(vd_trace_interface *I); - void (*set_origin)(vd_trace_interface *I); -}; - -extern vd_trace_interface * vd_trace0; /* Pointer to trace interface. */ -extern vd_trace_interface * vd_trace1; /* A copy of vd_trace0, or NULL if trace is disabled. */ -extern char vd_flags[]; - -void vd_impl_moveto(double x, double y); -void vd_impl_lineto(double x, double y); -void vd_impl_lineto_multi(const struct gs_fixed_point_s *p, int n); -void vd_impl_curveto(double x0, double y0, double x1, double y1, double x2, double y2); -void vd_impl_bar(double x0, double y0, double x1, double y1, int w, unsigned long c); /* unscaled width */ -void vd_impl_square(double x0, double y0, int w, unsigned int c); /* unscaled width */ -void vd_impl_rect(double x0, double y0, double x1, double y1, int w, unsigned int c); /* unscaled width */ -void vd_impl_quad(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int w, unsigned int c); /* unscaled width */ -void vd_impl_curve(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int w, unsigned long c); /* unscaled width */ -void vd_impl_circle(double x, double y, int r, unsigned long c); /* unscaled radius */ -void vd_impl_round(double x, double y, int r, unsigned long c); /* unscaled radius */ -void vd_impl_pixel(double x, double y, unsigned long c); -void vd_impl_text(double x, double y, char *s, unsigned long c); /* unscaled font */ -void vd_setflag(char f, char v); - -#ifndef RGB -# define RGB(r,g,b) ((unsigned long)(r) * 65536L + (unsigned long)(g) * 256L + (unsigned long)(b)) -#endif - -#if VD_TRACE && defined(DEBUG) -# define vd_allowed(f) (vd_flags[(f) & 127]) -# define vd_get_dc(f) while (vd_trace0 && vd_allowed(f)) { vd_trace0->get_dc(vd_trace0, &vd_trace1); break; } -# define vd_release_dc BEGIN if (vd_trace1) vd_trace1->release_dc(vd_trace1, &vd_trace1); END -# define vd_enabled (vd_trace1 != 0) -# define vd_get_size_unscaled_x (vd_trace1 ? vd_trace1->get_size_x(vd_trace1) : 100) -# define vd_get_size_unscaled_y (vd_trace1 ? vd_trace1->get_size_y(vd_trace1) : 100) -# define vd_get_size_scaled_x (vd_trace1 ? vd_trace1->get_size_x(vd_trace1) / vd_trace1->scale_x : 100) -# define vd_get_size_scaled_y (vd_trace1 ? vd_trace1->get_size_y(vd_trace1) / vd_trace1->scale_y : 100) -# define vd_get_scale_x (vd_trace1 ? vd_trace1->scale_x : 100) -# define vd_get_scale_y (vd_trace1 ? vd_trace1->scale_y : 100) -# define vd_get_origin_x (vd_trace1 ? vd_trace1->orig_x : 0) -# define vd_get_origin_y (vd_trace1 ? vd_trace1->orig_y : 0) -# define vd_set_scale(s) BEGIN if (vd_trace1) { vd_trace1->scale_x = vd_trace1->scale_y = s; vd_trace1->set_scale(vd_trace1); } END -# define vd_set_scaleXY(sx,sy) BEGIN if (vd_trace1) { vd_trace1->scale_x = sx, vd_trace1->scale_y = sy; vd_trace1->set_scale(vd_trace1); } END -# define vd_set_origin(x,y) BEGIN if (vd_trace1) { vd_trace1->orig_x = x, vd_trace1->orig_y = y; vd_trace1->set_origin(vd_trace1); } END -# define vd_set_shift(x,y) BEGIN if (vd_trace1) { vd_trace1->shift_x = x, vd_trace1->shift_y = y; vd_trace1->set_shift(vd_trace1); } END -# define vd_set_central_shift BEGIN if (vd_trace1) vd_trace1->shift_x = vd_trace1->get_size_x(vd_trace1)/2, vd_trace1->shift_y = vd_trace1->get_size_y(vd_trace1)/2; END -# define vd_erase(c) BEGIN if (vd_trace1) vd_trace1->erase(vd_trace1,c); END -# define vd_beg_path BEGIN if (vd_trace1) vd_trace1->beg_path(vd_trace1); END -# define vd_end_path BEGIN if (vd_trace1) vd_trace1->end_path(vd_trace1); END -# define vd_moveto(x,y) BEGIN if (vd_trace1) vd_impl_moveto(x,y); END -# define vd_lineto(x,y) BEGIN if (vd_trace1) vd_impl_lineto(x,y); END -# define vd_lineto_multi(p,n) BEGIN if (vd_trace1) vd_impl_lineto_multi(p,n); END -# define vd_curveto(x0,y0,x1,y1,x2,y2) BEGIN if (vd_trace1) vd_impl_curveto(x0,y0,x1,y1,x2,y2); END -# define vd_closepath BEGIN if (vd_trace1) vd_trace1->closepath(vd_trace1); END -# define vd_bar(x0,y0,x1,y1,w,c) BEGIN if (vd_trace1) vd_impl_bar(x0,y0,x1,y1,w,c); END -# define vd_square(x0,y0,w,c) BEGIN if (vd_trace1) vd_impl_square(x0,y0,w,c); END -# define vd_rect(x0,y0,x1,y1,w,c) BEGIN if (vd_trace1) vd_impl_rect(x0,y0,x1,y1,w,c); END -# define vd_quad(x0,y0,x1,y1,x2,y2,x3,y3,w,c) BEGIN if (vd_trace1) vd_impl_quad(x0,y0,x1,y1,x2,y2,x3,y3,w,c); END -# define vd_curve(x0,y0,x1,y1,x2,y2,x3,y3,w,c) BEGIN if (vd_trace1) vd_impl_curve(x0,y0,x1,y1,x2,y2,x3,y3,w,c); END -# define vd_circle(x,y,r,c) BEGIN if (vd_trace1) vd_impl_circle(x,y,r,c); END -# define vd_round(x,y,r,c) BEGIN if (vd_trace1) vd_impl_round(x,y,r,c); END -# define vd_pixel(x,y,c) BEGIN if (vd_trace1) vd_impl_pixel(x,y,c); END -# define vd_fill BEGIN if (vd_trace1) vd_trace1->fill(vd_trace1); END -# define vd_stroke BEGIN if (vd_trace1) vd_trace1->stroke(vd_trace1); END -# define vd_setcolor(c) BEGIN if (vd_trace1) vd_trace1->setcolor(vd_trace1,c); END -# define vd_setlinewidth(w) BEGIN if (vd_trace1) vd_trace1->setlinewidth(vd_trace1,w); END -# define vd_text(x,y,s,c) BEGIN if (vd_trace1) vd_impl_text(x,y,s,c); END -# define vd_wait BEGIN if (vd_trace1) vd_trace1->wait(vd_trace1); END -# define vd_save vd_trace_interface * vd_trace_save; vd_trace_save = vd_trace1; /* NOTE : - Use vd_save at end of the definition group of a block, - because in release build it compiles to the empty operator. - We intentionally defined an operator here for a compatible syntax check. */ -# define vd_restore vd_trace1 = vd_trace_save -# define vd_disable vd_trace1 = NULL -#else -# define vd_allowed(f) false -# define vd_get_dc(f) DO_NOTHING -# define vd_release_dc DO_NOTHING -# define vd_enabled 0 -# define vd_get_size_unscaled_x 100 -# define vd_get_size_unscaled_y 100 -# define vd_get_size_scaled_x 100 -# define vd_get_size_scaled_y 100 -# define vd_get_scale_x 100 -# define vd_get_scale_y 100 -# define vd_get_origin_x 0 -# define vd_get_origin_y 0 -# define vd_set_scale(sx) DO_NOTHING -# define vd_set_scaleXY(sx,sy) DO_NOTHING -# define vd_set_origin(x,y) DO_NOTHING -# define vd_set_shift(x,y) DO_NOTHING -# define vd_set_central_shift DO_NOTHING -# define vd_erase(c) DO_NOTHING -# define vd_beg_path DO_NOTHING -# define vd_end_path DO_NOTHING -# define vd_moveto(x,y) DO_NOTHING -# define vd_lineto(x,y) DO_NOTHING -# define vd_lineto_multi(p,n) DO_NOTHING -# define vd_curveto(x0,y0,x1,y1,x2,y2) DO_NOTHING -# define vd_closepath DO_NOTHING -# define vd_bar(x0,y0,x1,y1,w,c) DO_NOTHING -# define vd_square(x0,y0,w,c) DO_NOTHING -# define vd_rect(x0,y0,x1,y1,w,c) DO_NOTHING -# define vd_quad(x0,y0,x1,y1,x2,y2,x3,y3,w,c) DO_NOTHING -# define vd_curve(x0,y0,x1,y1,x2,y2,x3,y3,w,c) DO_NOTHING -# define vd_circle(x,y,r,c) DO_NOTHING -# define vd_round(x,y,r,c) DO_NOTHING -# define vd_pixel(x,y,c) DO_NOTHING -# define vd_fill DO_NOTHING -# define vd_stroke DO_NOTHING -# define vd_setcolor(c) DO_NOTHING -# define vd_setlinewidth(w) DO_NOTHING -# define vd_text(x,y,s,c) DO_NOTHING -# define vd_wait DO_NOTHING -# define vd_save DO_NOTHING -# define vd_restore DO_NOTHING -# define vd_disable DO_NOTHING -#endif - -#endif /* vdtrace_INCLUDED */ diff -Nru ghostscript-9.10~dfsg/base/version.mak ghostscript-9.25~dfsg+1/base/version.mak --- ghostscript-9.10~dfsg/base/version.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/version.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2010 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -7,18 +7,18 @@ # This software is distributed under license and may not be copied, modified # or distributed except as expressly authorized under the terms of that # license. Refer to licensing information at http://www.artifex.com/ -# or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, -# San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +# or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200, +# Novato, CA 94945, U.S.A., +1(415)492-9861, for further information. # # Makefile fragment containing the current revision identification. # Major and minor version numbers. # MINOR0 is different from MINOR only if MINOR is a single digit. GS_VERSION_MAJOR=9 -GS_VERSION_MINOR=10 -GS_VERSION_MINOR0=10 +GS_VERSION_MINOR=25 +GS_VERSION_MINOR0=25 # Revision date: year x 10000 + month x 100 + day. -GS_REVISIONDATE=20130830 +GS_REVISIONDATE=20180913 # Derived values GS_VERSION=$(GS_VERSION_MAJOR)$(GS_VERSION_MINOR0) GS_DOT_VERSION=$(GS_VERSION_MAJOR).$(GS_VERSION_MINOR0) diff -Nru ghostscript-9.10~dfsg/base/vmsmath.h ghostscript-9.25~dfsg+1/base/vmsmath.h --- ghostscript-9.10~dfsg/base/vmsmath.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/vmsmath.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/vms_x_fix.h ghostscript-9.25~dfsg+1/base/vms_x_fix.h --- ghostscript-9.10~dfsg/base/vms_x_fix.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/vms_x_fix.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/windows_.h ghostscript-9.25~dfsg+1/base/windows_.h --- ghostscript-9.10~dfsg/base/windows_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/windows_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -19,8 +19,6 @@ #ifndef windows__INCLUDED # define windows__INCLUDED -/* This is a good place to define GS_NO_UTF8 */ - #define STRICT #ifdef METRO #include @@ -28,12 +26,16 @@ #include #include +/* After including windows.h, we have to undef bool for VS 2014 and later */ +#if defined(_MSC_VER) && _MSC_VER>=1900 +# undef bool + typedef int bool; +#endif + /* Unicode/UTF-8 wrappers that we provide */ BOOL gp_OpenPrinter(char *device, LPHANDLE printer); -#ifndef GS_NO_UTF8 int utf8_to_wchar(wchar_t *out, const char *in); int wchar_to_utf8(char *out, const wchar_t *in); -#endif #ifdef __WATCOMC__ typedef RGBQUAD FAR * LPRGBQUAD; diff -Nru ghostscript-9.10~dfsg/base/winlib.mak ghostscript-9.25~dfsg+1/base/winlib.mak --- ghostscript-9.10~dfsg/base/winlib.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/winlib.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,15 +9,15 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Common makefile section for 32-bit MS Windows. # This makefile must be acceptable to Microsoft Visual C++, Watcom C++, # and Borland C++. For this reason, the only conditional directives # allowed are !if[n]def, !else, and !endif. - +WINLIB_MAK=$(GLSRC)winlib.mak $(TOP_MAKEFILES) # Note that built-in third-party libraries aren't available. @@ -87,6 +87,8 @@ Q= XE=.exe XEAUX=.exe +PERCENTESCAPE=% +GENCONFLINECONT= # Define generic commands. @@ -115,7 +117,7 @@ # Which CMS are we using? !ifndef WHICH_CMS -WHICH_CMS=lcms2 +WHICH_CMS=lcms2mt !endif # Define the files to be removed by `make clean'. @@ -133,7 +135,6 @@ #!include $(COMMONDIR)/pcdefs.mak #!include $(COMMONDIR)/generic.mak !include $(GLSRCDIR)\gs.mak -!include $(GLSRCDIR)\trio.mak !include $(GLSRCDIR)\lib.mak !include $(GLSRCDIR)\freetype.mak !if "$(UFST_BRIDGE)"=="1" @@ -148,6 +149,10 @@ !include $(GLSRCDIR)\ldf_jb2.mak !include $(GLSRCDIR)\lwf_jp2.mak !include $(GLSRCDIR)\openjpeg.mak + +!include $(GLSRCDIR)\expat.mak +!include $(GLSRCDIR)\jpegxr.mak + !include $(GLSRCDIR)\$(WHICH_CMS).mak !include $(GLSRCDIR)\ijs.mak !include $(GLSRCDIR)\lcups.mak @@ -182,37 +187,38 @@ $(GLOBJ)gp_stdia.$(OBJ) $(GLOBJ)gp_wutf8.$(OBJ) mswin32_inc=$(GLD)nosync.dev $(GLD)winplat.dev -$(GLGEN)mswin32_.dev: $(mswin32__) $(ECHOGS_XE) $(mswin32_inc) +$(GLGEN)mswin32_.dev: $(mswin32__) $(ECHOGS_XE) $(mswin32_inc) $(WINLIB_MAK) $(SETMOD) $(GLGEN)mswin32_ $(mswin32__) $(ADDMOD) $(GLGEN)mswin32_ -include $(mswin32_inc) $(GLOBJ)gp_mswin.$(OBJ): $(GLSRC)gp_mswin.c $(AK) $(gp_mswin_h) \ $(ctype__h) $(dos__h) $(malloc__h) $(memory__h) $(pipe__h) \ $(stdio__h) $(string__h) $(windows__h) \ - $(gx_h) $(gp_h) $(gpcheck_h) $(gpmisc_h) $(gserrors_h) $(gsexit_h) + $(gx_h) $(gp_h) $(gpcheck_h) $(gpmisc_h) $(gserrors_h) $(gsexit_h) \ + $(WINLIB_MAK) $(GLCCWIN) $(GLO_)gp_mswin.$(OBJ) $(C_) $(GLSRC)gp_mswin.c -$(GLOBJ)gp_wutf8.$(OBJ): $(GLSRC)gp_wutf8.c $(windows__h) +$(GLOBJ)gp_wutf8.$(OBJ): $(GLSRC)gp_wutf8.c $(windows__h) $(WINLIB_MAK) $(GLCCWIN) $(GLO_)gp_wutf8.$(OBJ) $(C_) $(GLSRC)gp_wutf8.c -$(AUX)gp_wutf8.$(OBJ): $(GLSRC)gp_wutf8.c $(windows__h) +$(AUX)gp_wutf8.$(OBJ): $(GLSRC)gp_wutf8.c $(windows__h) $(WINLIB_MAK) $(GLCCAUX) $(AUXO_)gp_wutf8.$(OBJ) $(C_) $(GLSRC)gp_wutf8.c -$(GLOBJ)gp_wgetv.$(OBJ): $(GLSRC)gp_wgetv.c $(AK) $(gscdefs_h) +$(GLOBJ)gp_wgetv.$(OBJ): $(GLSRC)gp_wgetv.c $(AK) $(gscdefs_h) $(WINLIB_MAK) $(GLCCWIN) $(GLO_)gp_wgetv.$(OBJ) $(C_) $(GLSRC)gp_wgetv.c -$(GLOBJ)gp_wpapr.$(OBJ): $(GLSRC)gp_wpapr.c $(AK) $(gp_h) +$(GLOBJ)gp_wpapr.$(OBJ): $(GLSRC)gp_wpapr.c $(AK) $(gp_h) $(WINLIB_MAK) $(GLCCWIN) $(GLO_)gp_wpapr.$(OBJ) $(C_) $(GLSRC)gp_wpapr.c $(GLOBJ)gp_stdia.$(OBJ): $(GLSRC)gp_stdia.c $(AK)\ - $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h) + $(stdio__h) $(time__h) $(unistd__h) $(gx_h) $(gp_h) $(WINLIB_MAK) $(GLCCWIN) $(GLO_)gp_stdia.$(OBJ) $(C_) $(GLSRC)gp_stdia.c # The Metro platform !ifdef METRO METRO_OBJS=$(GLOBJ)winrtsup.$(OBJ) $(GLOBJ)gp_wutf8.$(OBJ) -$(GLOBJ)winrtsup.$(OBJ): $(GLSRCDIR)/winrtsup.cpp +$(GLOBJ)winrtsup.$(OBJ): $(GLSRCDIR)/winrtsup.cpp $(WINLIB_MAK) $(GLCCWIN) /EHsc $(GLO_)winrtsup.$(OBJ) $(C_) $(GLSRCDIR)/winrtsup.cpp !else METRO_OBJS= @@ -224,7 +230,7 @@ #$(GLOBJ)gp_wutf8.$(OBJ) metro_inc=$(GLD)nosync.dev $(GLD)winplat.dev -$(GLGEN)metro_.dev: $(metro__) $(ECHOGS_XE) $(metro_inc) +$(GLGEN)metro_.dev: $(metro__) $(ECHOGS_XE) $(metro_inc) $(WINLIB_MAK) $(SETMOD) $(GLGEN)metro_ $(metro__) $(ADDMOD) $(GLGEN)metro_ -include $(metro_inc) @@ -232,35 +238,36 @@ # Define MS-Windows handles (file system) as a separable feature. mshandle_=$(GLOBJ)gp_mshdl.$(OBJ) -$(GLD)mshandle.dev: $(ECHOGS_XE) $(mshandle_) +$(GLD)mshandle.dev: $(ECHOGS_XE) $(mshandle_) $(WINLIB_MAK) $(SETMOD) $(GLD)mshandle $(mshandle_) $(ADDMOD) $(GLD)mshandle -iodev handle $(GLOBJ)gp_mshdl.$(OBJ): $(GLSRC)gp_mshdl.c $(AK)\ $(ctype__h) $(errno__h) $(stdio__h) $(string__h)\ - $(gsmemory_h) $(gstypes_h) $(gxiodev_h) $(gserrors_h) + $(gsmemory_h) $(gstypes_h) $(gxiodev_h) $(gserrors_h) $(WINLIB_MAK) $(GLCC) $(GLO_)gp_mshdl.$(OBJ) $(C_) $(GLSRC)gp_mshdl.c # Define MS-Windows printer (file system) as a separable feature. msprinter_=$(GLOBJ)gp_msprn.$(OBJ) -$(GLD)msprinter.dev: $(ECHOGS_XE) $(msprinter_) + +$(GLD)msprinter.dev: $(msprinter_) $(WINLIB_MAK) $(SETMOD) $(GLD)msprinter $(msprinter_) $(ADDMOD) $(GLD)msprinter -iodev printer $(GLOBJ)gp_msprn.$(OBJ): $(GLSRC)gp_msprn.c $(AK)\ $(ctype__h) $(errno__h) $(stdio__h) $(string__h)\ - $(gsmemory_h) $(gstypes_h) $(gxiodev_h) + $(gsmemory_h) $(gstypes_h) $(gxiodev_h) $(WINLIB_MAK) $(GLCCWIN) $(GLO_)gp_msprn.$(OBJ) $(C_) $(GLSRC)gp_msprn.c # Define MS-Windows polling as a separable feature # because it is not needed by the gslib. mspoll_=$(GLOBJ)gp_mspol.$(OBJ) -$(GLD)mspoll.dev: $(ECHOGS_XE) $(mspoll_) +$(GLD)mspoll.dev: $(ECHOGS_XE) $(mspoll_) $(WINLIB_MAK) $(SETMOD) $(GLD)mspoll $(mspoll_) $(GLOBJ)gp_mspol.$(OBJ): $(GLSRC)gp_mspol.c $(AK)\ - $(gx_h) $(gp_h) $(gpcheck_h) + $(gx_h) $(gp_h) $(gpcheck_h) $(WINLIB_MAK) $(GLCCWIN) $(GLO_)gp_mspol.$(OBJ) $(C_) $(GLSRC)gp_mspol.c # end of winlib.mak diff -Nru ghostscript-9.10~dfsg/base/winplat.mak ghostscript-9.25~dfsg+1/base/winplat.mak --- ghostscript-9.10~dfsg/base/winplat.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/winplat.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,49 +9,69 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # Common makefile section for builds on 32-bit MS Windows, including the # Watcom MS-DOS build. # Define the name of this makefile. -WINPLAT_MAK=$(GLSRC)winplat.mak +WINPLAT_MAK=$(GLSRC)winplat.mak $(TOP_MAKEFILES) + +GLCCWINXPSPRINT=$(CC_WX) $(XPSPRINTCFLAGS) $(CCWINFLAGS) $(I_)$(GLI_)$(_I) $(GLF_) # Define generic Windows-specific modules. -winplat_=$(GLOBJ)gp_ntfs.$(OBJ) $(GLOBJ)gp_win32.$(OBJ) -$(GLD)winplat.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winplat_) - $(SETMOD) $(GLD)winplat $(winplat_) +winplatcommon_=$(GLOBJ)gp_ntfs.$(OBJ) $(GLOBJ)gp_win32.$(OBJ) + +winplat_=$(winplatcommon_) $(GLOBJ)gp_nxpsprn.$(OBJ) +winplatxpsprint_=$(winplatcommon_) $(GLOBJ)gp_wxpsprn.$(OBJ) + +$(GLD)winplat0.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winplat_) $(WINPLAT_MAK) + $(SETMOD) $(GLD)winplat0 $(winplat_) + +$(GLD)winplat1.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winplatxpsprint_) $(WINPLAT_MAK) + $(SETMOD) $(GLD)winplat1 $(winplatxpsprint_) + +$(GLD)winplat.dev : $(GLD)winplat$(XPSPRINT).dev + $(CP_) $(GLD)winplat$(XPSPRINT).dev $(GLD)winplat.dev $(GLOBJ)gp_ntfs.$(OBJ): $(GLSRC)gp_ntfs.c $(AK)\ $(dos__h) $(memory__h) $(stdio__h) $(string__h) $(windows__h)\ - $(gp_h) $(gpmisc_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h) + $(gp_h) $(gpmisc_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h) \ + $(WINPLAT_MAK) $(GLCCWIN) $(GLO_)gp_ntfs.$(OBJ) $(C_) $(GLSRC)gp_ntfs.c $(AUX)gp_ntfs.$(OBJ): $(GLSRC)gp_ntfs.c $(AK)\ $(dos__h) $(memory__h) $(stdio__h) $(string__h) $(windows__h)\ - $(gp_h) $(gpmisc_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h) + $(gp_h) $(gpmisc_h) $(gsmemory_h) $(gsstruct_h) $(gstypes_h) $(gsutil_h) \ + $(WINPLAT_MAK) $(GLCCAUX) $(AUXO_)gp_ntfs.$(OBJ) $(C_) $(GLSRC)gp_ntfs.c $(GLOBJ)gp_win32.$(OBJ): $(GLSRC)gp_win32.c $(AK)\ $(dos__h) $(malloc__h) $(stdio__h) $(string__h) $(windows__h)\ - $(gp_h) $(gsmemory_h) $(gstypes_h) + $(gp_h) $(gsmemory_h) $(gstypes_h) $(WINPLAT_MAK) $(GLCCWIN) $(GLO_)gp_win32.$(OBJ) $(C_) $(GLSRC)gp_win32.c $(AUX)gp_win32.$(OBJ): $(GLSRC)gp_win32.c $(AK)\ $(dos__h) $(malloc__h) $(stdio__h) $(string__h) $(windows__h)\ - $(gp_h) $(gsmemory_h) $(gstypes_h) + $(gp_h) $(gsmemory_h) $(gstypes_h) $(WINPLAT_MAK) $(GLCCAUX) $(AUXO_)gp_win32.$(OBJ) $(C_) $(GLSRC)gp_win32.c # Define the Windows thread / synchronization module. winsync_=$(GLOBJ)gp_wsync.$(OBJ) -$(GLD)winsync.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winsync_) +$(GLD)winsync.dev : $(WINPLAT_MAK) $(ECHOGS_XE) $(winsync_) $(WINPLAT_MAK) $(SETMOD) $(GLD)winsync $(winsync_) $(ADDMOD) $(GLD)winsync -replace $(GLD)nosync $(GLOBJ)gp_wsync.$(OBJ): $(GLSRC)gp_wsync.c $(AK)\ $(dos__h) $(malloc__h) $(stdio__h) $(string__h) $(windows__h)\ - $(gp_h) $(gsmemory_h) $(gstypes_h) + $(gp_h) $(gsmemory_h) $(gstypes_h) $(WINPLAT_MAK) $(GLCCWIN) $(GLO_)gp_wsync.$(OBJ) $(C_) $(GLSRC)gp_wsync.c + +# The XPS printer +$(GLOBJ)gp_wxpsprn.$(OBJ): $(GLSRC)gp_wxpsprn.cpp $(windows__h) $(string__h) \ + $(gx_h) $(gserrors_h) $(WINLIB_MAK) + $(GLCCWINXPSPRINT) $(GLO_)gp_wxpsprn.$(OBJ) $(C_) $(GLSRC)gp_wxpsprn.cpp + diff -Nru ghostscript-9.10~dfsg/base/winrtsup.cpp ghostscript-9.25~dfsg+1/base/winrtsup.cpp --- ghostscript-9.10~dfsg/base/winrtsup.cpp 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/winrtsup.cpp 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2013 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ #include "windows_.h" @@ -20,7 +20,7 @@ #include #include -extern "C" DWORD GetTempPathWRT(DWORD nBufferLength, LPSTR lpBuffer) +extern "C" DWORD GetTempPathWRT(DWORD nBufferLength, LPWSTR lpBuffer) { try { @@ -55,11 +55,10 @@ UINT32 length; PCWSTR value = WindowsGetStringRawBuffer(folderName, &length); std::wstring ws(value); - std::string s; - s.assign(ws.begin(), ws.end()); - strncpy(lpBuffer, s.c_str(), nBufferLength); + wcsncpy(lpBuffer, ws.c_str(), nBufferLength); + lpBuffer[nBufferLength-1] = 0; WindowsDeleteString(folderName); - return s.length(); + return ws.length(); } catch(...) { @@ -67,13 +66,13 @@ } } -extern "C" UINT GetTempFileNameWRT(LPCSTR lpPathName, LPCSTR lpPrefixString, LPSTR lpTempFileName) +extern "C" UINT GetTempFileNameWRT(LPCWSTR lpPathName, LPCWSTR lpPrefixString, LPWSTR lpTempFileName) { try { - std::string path(lpPathName); - std::string prefix(lpPrefixString); - LPFILETIME lpSystemTimeAsFileTime; + std::wstring path(lpPathName); + std::wstring prefix(lpPrefixString); + FILETIME systemTimeAsFileTime; if (!path.empty() && path.back() != '\\') path.push_back('\\'); @@ -81,31 +80,28 @@ if (path.length() > _MAX_PATH - 14) return ERROR_BUFFER_OVERFLOW; - GetSystemTimeAsFileTime(lpSystemTimeAsFileTime); + GetSystemTimeAsFileTime(&systemTimeAsFileTime); - DWORD time = lpSystemTimeAsFileTime->dwLowDateTime; + DWORD time = systemTimeAsFileTime.dwLowDateTime; while(true) { // Create file name of at most 13 characters, using at most 10 // digits of time, and as many of the prefix characters as can fit - std::stringstream str; - str << (UINT)time; - std::string num(str.str()); + std::wstring num(std::to_wstring((UINT)time)); if (num.length() > 10) num = num.substr(num.length() - 10); - std::string pf(prefix); + std::wstring pf(prefix); if (num.length() + pf.length() > 13) pf.resize(13 - num.length()); - std::string fullpath = path+pf+num; + std::wstring fullpath = path+pf+num; // Test that the file doesn't already exist - std::wstring wfullpath(fullpath.begin(), fullpath.end()); LPWIN32_FIND_DATA find_data; - HANDLE h = FindFirstFileExW(wfullpath.c_str(), FindExInfoStandard, &find_data, FindExSearchNameMatch, NULL, 0); + HANDLE h = FindFirstFileExW(fullpath.c_str(), FindExInfoStandard, &find_data, FindExSearchNameMatch, NULL, 0); if (h == INVALID_HANDLE_VALUE) { // File doesn't exist - strcpy(lpTempFileName, fullpath.c_str()); + wcscpy(lpTempFileName, fullpath.c_str()); return fullpath.length(); } diff -Nru ghostscript-9.10~dfsg/base/winrtsup.h ghostscript-9.25~dfsg+1/base/winrtsup.h --- ghostscript-9.10~dfsg/base/winrtsup.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/winrtsup.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2013 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,14 +9,14 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ #include "windows_.h" -DWORD GetTempPathWRT(DWORD nBufferLength, LPSTR lpBuffer); +DWORD GetTempPathWRT(DWORD nBufferLength, LPWSTR lpBuffer); -UINT GetTempFileNameWRT(LPCSTR lpPathName, LPCSTR lpPrefixString, LPSTR lpTempFileName); +UINT GetTempFileNameWRT(LPCWSTR lpPathName, LPCWSTR lpPrefixString, LPWSTR lpTempFileName); void OutputDebugStringWRT(LPCSTR str, DWORD len); diff -Nru ghostscript-9.10~dfsg/base/wrfont.c ghostscript-9.25~dfsg+1/base/wrfont.c --- ghostscript-9.10~dfsg/base/wrfont.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/wrfont.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* @@ -21,6 +21,7 @@ #include "wrfont.h" #include "stdio_.h" +#include "assert_.h" #define EEXEC_KEY 55665 #define EEXEC_FACTOR 52845 @@ -37,9 +38,9 @@ } void -WRF_wbyte(WRF_output * a_output, unsigned char a_byte) +WRF_wbyte(const gs_memory_t *memory, WRF_output * a_output, unsigned char a_byte) { - if (a_output->m_count < a_output->m_limit) { + if (a_output->m_count < a_output->m_limit && a_output->m_pos != NULL) { if (a_output->m_encrypt) { a_byte ^= (a_output->m_key >> 8); a_output->m_key = @@ -52,35 +53,43 @@ } void -WRF_wtext(WRF_output * a_output, const unsigned char *a_string, long a_length) +WRF_wtext(const gs_memory_t *memory, WRF_output * a_output, const unsigned char *a_string, long a_length) { while (a_length > 0) { - WRF_wbyte(a_output, *a_string++); + WRF_wbyte(memory, a_output, *a_string++); a_length--; } } void -WRF_wstring(WRF_output * a_output, const char *a_string) +WRF_wstring(const gs_memory_t *memory, WRF_output * a_output, const char *a_string) { while (*a_string) - WRF_wbyte(a_output, *a_string++); + WRF_wbyte(memory, a_output, *a_string++); } void -WRF_wfloat(WRF_output * a_output, double a_float) +WRF_wfloat(const gs_memory_t *memory, WRF_output * a_output, double a_float) { char buffer[32]; + int l; - gs_sprintf(buffer, "%f", a_float); - WRF_wstring(a_output, buffer); + l = gs_snprintf(buffer, sizeof (buffer), "%f", a_float); + if (l > sizeof (buffer)) { + emprintf(memory, "Warning: Font real number value truncated\n"); + } + WRF_wstring(memory, a_output, buffer); } void -WRF_wint(WRF_output * a_output, long a_int) +WRF_wint(const gs_memory_t *memory, WRF_output * a_output, long a_int) { char buffer[32]; + int l; - gs_sprintf(buffer, "%ld", a_int); - WRF_wstring(a_output, buffer); + l = gs_snprintf(buffer, sizeof(buffer), "%ld", a_int); + if (l > sizeof (buffer)) { + emprintf(memory, "Warning: Font integer number value truncated\n"); + } + WRF_wstring(memory, a_output, buffer); } diff -Nru ghostscript-9.10~dfsg/base/wrfont.h ghostscript-9.25~dfsg+1/base/wrfont.h --- ghostscript-9.10~dfsg/base/wrfont.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/wrfont.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ @@ -24,6 +24,7 @@ #define wrfont_INCLUDED #include "stdpre.h" +#include "std.h" typedef struct WRF_output_ { @@ -36,11 +37,11 @@ void WRF_init(WRF_output * a_output, unsigned char *a_buffer, long a_buffer_size); -void WRF_wbyte(WRF_output * a_output, unsigned char a_byte); -void WRF_wtext(WRF_output * a_output, const unsigned char *a_string, +void WRF_wbyte(const gs_memory_t *memory, WRF_output * a_output, unsigned char a_byte); +void WRF_wtext(const gs_memory_t *memory, WRF_output * a_output, const unsigned char *a_string, long a_length); -void WRF_wstring(WRF_output * a_output, const char *a_string); -void WRF_wfloat(WRF_output * a_output, double a_float); -void WRF_wint(WRF_output * a_output, long a_int); +void WRF_wstring(const gs_memory_t *memory, WRF_output * a_output, const char *a_string); +void WRF_wfloat(const gs_memory_t *memory, WRF_output * a_output, double a_float); +void WRF_wint(const gs_memory_t *memory, WRF_output * a_output, long a_int); #endif diff -Nru ghostscript-9.10~dfsg/base/write_t1.c ghostscript-9.25~dfsg+1/base/write_t1.c --- ghostscript-9.10~dfsg/base/write_t1.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/write_t1.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* @@ -34,15 +34,15 @@ { short x; - WRF_wbyte(a_output, '/'); - WRF_wstring(a_output, a_name); - WRF_wbyte(a_output, ' '); + WRF_wbyte(a_fapi_font->memory, a_output, '/'); + WRF_wstring(a_fapi_font->memory, a_output, a_name); + WRF_wbyte(a_fapi_font->memory, a_output, ' '); /* Get the value and convert it from unsigned to signed by assigning it to a short. */ x = a_fapi_font->get_word(a_fapi_font, a_index, 0); /* Divide by the divisor to bring it back to font units. */ x = (short)(x / a_divisor); - WRF_wint(a_output, x); - WRF_wstring(a_output, " def\n"); + WRF_wint(a_fapi_font->memory, a_output, x); + WRF_wstring(a_fapi_font->memory, a_output, " def\n"); } static void @@ -55,19 +55,19 @@ if (a_count <= 0) return; - WRF_wbyte(a_output, '/'); - WRF_wstring(a_output, a_name); - WRF_wstring(a_output, " ["); + WRF_wbyte(a_fapi_font->memory, a_output, '/'); + WRF_wstring(a_fapi_font->memory, a_output, a_name); + WRF_wstring(a_fapi_font->memory, a_output, " ["); for (i = 0; i < a_count; i++) { /* Get the value and convert it from unsigned to signed by assigning it to a short. */ short x = a_fapi_font->get_word(a_fapi_font, a_index, i); /* Divide by the divisor to bring it back to font units. */ x = (short)(x / a_divisor); - WRF_wint(a_output, x); - WRF_wbyte(a_output, (byte) (i == a_count - 1 ? ']' : ' ')); + WRF_wint(a_fapi_font->memory, a_output, x); + WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == a_count - 1 ? ']' : ' ')); } - WRF_wstring(a_output, " def\n"); + WRF_wstring(a_fapi_font->memory, a_output, " def\n"); } static void @@ -91,9 +91,9 @@ if (count <= 0) return; - WRF_wstring(a_output, "/Subrs "); - WRF_wint(a_output, count); - WRF_wstring(a_output, " array\n"); + WRF_wstring(a_fapi_font->memory, a_output, "/Subrs "); + WRF_wint(a_fapi_font->memory, a_output, count); + WRF_wstring(a_fapi_font->memory, a_output, " array\n"); for (i = 0; i < count; i++) { long length; @@ -103,11 +103,11 @@ length = a_fapi_font->get_raw_subr(a_fapi_font, i, 0, 0); else length = a_fapi_font->get_subr(a_fapi_font, i, 0, 0); - WRF_wstring(a_output, "dup "); - WRF_wint(a_output, i); - WRF_wbyte(a_output, ' '); - WRF_wint(a_output, length); - WRF_wstring(a_output, " RD "); + WRF_wstring(a_fapi_font->memory, a_output, "dup "); + WRF_wint(a_fapi_font->memory, a_output, i); + WRF_wbyte(a_fapi_font->memory, a_output, ' '); + WRF_wint(a_fapi_font->memory, a_output, length); + WRF_wstring(a_fapi_font->memory, a_output, " RD "); /* Get the subroutine into the buffer and encrypt it in place. */ buffer_size = a_output->m_limit - a_output->m_count; @@ -118,14 +118,14 @@ else a_fapi_font->get_subr(a_fapi_font, i, a_output->m_pos, (ushort) length); - WRF_wtext(a_output, a_output->m_pos, length); + WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length); } else a_output->m_count += length; - WRF_wstring(a_output, " NP\n"); + WRF_wstring(a_fapi_font->memory, a_output, " NP\n"); } - WRF_wstring(a_output, "ND\n"); + WRF_wstring(a_fapi_font->memory, a_output, "ND\n"); } static void @@ -141,9 +141,9 @@ if (count <= 0) return; - WRF_wstring(a_output, "2 index /CharStrings "); - WRF_wint(a_output, count); - WRF_wstring(a_output, " dict dup begin\n"); + WRF_wstring(a_fapi_font->memory, a_output, "2 index /CharStrings "); + WRF_wint(a_fapi_font->memory, a_output, count); + WRF_wstring(a_fapi_font->memory, a_output, " dict dup begin\n"); for (i = 0; i < count; i++) { length = a_fapi_font->get_charstring_name(a_fapi_font, i, @@ -151,24 +151,24 @@ if (length > 0) { length = a_fapi_font->get_charstring(a_fapi_font, i, 0, 0); - WRF_wbyte(a_output, '/'); - WRF_wstring(a_output, (const char *)&NameBuf); - WRF_wbyte(a_output, ' '); - WRF_wint(a_output, length); - WRF_wstring(a_output, " RD "); + WRF_wbyte(a_fapi_font->memory, a_output, '/'); + WRF_wstring(a_fapi_font->memory, a_output, (const char *)&NameBuf); + WRF_wbyte(a_fapi_font->memory, a_output, ' '); + WRF_wint(a_fapi_font->memory, a_output, length); + WRF_wstring(a_fapi_font->memory, a_output, " RD "); /* Get the CharString into the buffer and encrypt it in place. */ buffer_size = a_output->m_limit - a_output->m_count; if (buffer_size >= length) { a_fapi_font->get_charstring(a_fapi_font, i, a_output->m_pos, (ushort) length); - WRF_wtext(a_output, a_output->m_pos, length); + WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length); } else a_output->m_count += length; - WRF_wstring(a_output, " ND\n"); + WRF_wstring(a_fapi_font->memory, a_output, " ND\n"); } } - WRF_wstring(a_output, " end"); + WRF_wstring(a_fapi_font->memory, a_output, " end"); } static int @@ -179,33 +179,216 @@ } static void +write_private_blend_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output) +{ + short x, x1, x2, i, j, acc; + if (is_MM_font(a_fapi_font)) { + + WRF_wstring(a_fapi_font->memory, a_output, "3 index /Blend get /Private get begin\n"); + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueValues_length, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/BlueValues ["); + acc = 0; + for (i = 0; i < x; i++) { + WRF_wstring(a_fapi_font->memory, a_output, " ["); + x1 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueValues_count, i); + for (j = 0; j < x1; j++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueValues, acc++); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]"); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendOtherBlues_length, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/OtherBlues ["); + acc = 0; + for (i = 0; i < x; i++) { + WRF_wstring(a_fapi_font->memory, a_output, " ["); + x1 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendOtherBlues_count, i); + for (j = 0; j < x1; j++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendOtherBlues, acc++); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]"); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueScale_count, 0); + if (x > 0) { + float v; + WRF_wstring(a_fapi_font->memory, a_output, "/BlueScale ["); + for (i =0; i < x; i++) { + v = a_fapi_font->get_float(a_fapi_font, + gs_fapi_font_feature_BlendBlueScale, i); + WRF_wfloat(a_fapi_font->memory, a_output, v); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueShift_count, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/BlueShift ["); + for (i =0; i < x; i++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueShift, i); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueFuzz_count, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/BlueFuzz ["); + for (i =0; i < x; i++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendBlueFuzz, i); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendForceBold_count, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/ForceBold ["); + for (i =0; i < x; i++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendForceBold, i); + WRF_wstring(a_fapi_font->memory, a_output, x2 ? "/true" : "/false"); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStdHW_length, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/StdHW ["); + acc = 0; + for (i = 0; i < x; i++) { + WRF_wstring(a_fapi_font->memory, a_output, " ["); + x1 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStdHW_count, i); + for (j = 0; j < x1; j++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStdHW, acc++); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]"); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStdVW_length, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/StdVW ["); + acc = 0; + for (i = 0; i < x; i++) { + WRF_wstring(a_fapi_font->memory, a_output, " ["); + x1 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStdVW_count, i); + for (j = 0; j < x1; j++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStdVW, acc++); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]"); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStemSnapH_length, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/StemSnapH ["); + acc = 0; + for (i = 0; i < x; i++) { + WRF_wstring(a_fapi_font->memory, a_output, " ["); + x1 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStemSnapH_count, i); + for (j = 0; j < x1; j++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStemSnapH, acc++); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]"); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStemSnapV_length, 0); + if (x > 0) { + WRF_wstring(a_fapi_font->memory, a_output, "/StemSnapV ["); + acc = 0; + for (i = 0; i < x; i++) { + WRF_wstring(a_fapi_font->memory, a_output, " ["); + x1 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStemSnapV_count, i); + for (j = 0; j < x1; j++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendStemSnapV, acc++); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]"); + } + WRF_wstring(a_fapi_font->memory, a_output, " ]\n"); + } + + WRF_wstring(a_fapi_font->memory, a_output, "end\n"); + } +} + +static void write_private_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output, int Write_CharStrings) { a_output->m_encrypt = true; /* Write 4 bytes that must encrypt to at least one character that cannot be a valid hexadecimal character. */ - WRF_wstring(a_output, "XXXX"); + WRF_wstring(a_fapi_font->memory, a_output, "XXXX"); /*+ to do: correct size of dictionary from 8. */ - WRF_wstring(a_output, "dup /Private 8 dict dup begin\n"); + WRF_wstring(a_fapi_font->memory, a_output, "dup /Private 8 dict dup begin\n"); - WRF_wstring(a_output, "/MinFeature {16 16} def\n"); - WRF_wstring(a_output, "/password 5839 def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "/MinFeature {16 16} def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "/password 5839 def\n"); if (Write_CharStrings) write_word_entry(a_fapi_font, a_output, "lenIV", gs_fapi_font_feature_lenIV, 1); else - WRF_wstring(a_output, "/lenIV -1 def\n"); /* indicate that /subrs are not encoded. */ + WRF_wstring(a_fapi_font->memory, a_output, "/lenIV -1 def\n"); /* indicate that /subrs are not encoded. */ write_word_entry(a_fapi_font, a_output, "BlueFuzz", gs_fapi_font_feature_BlueFuzz, 16); - WRF_wstring(a_output, "/BlueScale "); - WRF_wfloat(a_output, + WRF_wstring(a_fapi_font->memory, a_output, "/BlueScale "); + WRF_wfloat(a_fapi_font->memory, a_output, a_fapi_font->get_long(a_fapi_font, gs_fapi_font_feature_BlueScale, 0) / 65536.0); - WRF_wstring(a_output, " def\n"); + WRF_wstring(a_fapi_font->memory, a_output, " def\n"); write_word_entry(a_fapi_font, a_output, "BlueShift", gs_fapi_font_feature_BlueShift, 16); @@ -228,10 +411,8 @@ write_array_entry(a_fapi_font, a_output, "StemSnapV", gs_fapi_font_feature_StemSnapV, 16); - if (is_MM_font(a_fapi_font)) { - WRF_wstring(a_output, "3 index /Blend get /Private get begin\n"); - WRF_wstring(a_output, "|-\n"); - } + write_private_blend_dictionary(a_fapi_font, a_output); + if (Write_CharStrings) write_subrs(a_fapi_font, a_output, 1); else @@ -241,42 +422,36 @@ } static void -write_blend_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output) -{ -} - -static void write_main_dictionary(gs_fapi_font * a_fapi_font, WRF_output * a_output, int Write_CharStrings) { int i; - WRF_wstring(a_output, "5 dict begin\n"); + WRF_wstring(a_fapi_font->memory, a_output, "5 dict begin\n"); - WRF_wstring(a_output, "/FontType 1 def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "/FontType 1 def\n"); - WRF_wstring(a_output, "/FontMatrix ["); + WRF_wstring(a_fapi_font->memory, a_output, "/FontMatrix ["); for (i = 0; i < 6; i++) { - WRF_wfloat(a_output, + WRF_wfloat(a_fapi_font->memory, a_output, a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_FontMatrix, i)); - WRF_wbyte(a_output, (byte) (i == 5 ? ']' : ' ')); + WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 5 ? ']' : ' ')); } - WRF_wbyte(a_output, '\n'); - + WRF_wbyte(a_fapi_font->memory, a_output, '\n'); /* For now, specify standard encoding - I think GS will pass glyph indices so doesn't matter. */ - WRF_wstring(a_output, "/Encoding StandardEncoding def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "/Encoding StandardEncoding def\n"); - WRF_wstring(a_output, "/FontBBox {"); + WRF_wstring(a_fapi_font->memory, a_output, "/FontBBox {"); for (i = 0; i < 4; i++) { short x = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_FontBBox, i); - WRF_wint(a_output, x); - WRF_wbyte(a_output, (byte) (i == 3 ? '}' : ' ')); + WRF_wint(a_fapi_font->memory, a_output, x); + WRF_wbyte(a_fapi_font->memory, a_output, (byte) (i == 3 ? '}' : ' ')); } - WRF_wbyte(a_output, '\n'); + WRF_wbyte(a_fapi_font->memory, a_output, '\n'); if (is_MM_font(a_fapi_font)) { short x, x2; float x1; @@ -301,71 +476,71 @@ entries++; gs_sprintf(Buffer, "/FontInfo %d dict dup begin\n", entries); - WRF_wstring(a_output, Buffer); + WRF_wstring(a_fapi_font->memory, a_output, Buffer); x = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_BlendAxisTypes_count, 0); if (x) { - WRF_wstring(a_output, "/BlendAxisTypes ["); + WRF_wstring(a_fapi_font->memory, a_output, "/BlendAxisTypes ["); for (i = 0; i < x; i++) { - WRF_wstring(a_output, " /"); + WRF_wstring(a_fapi_font->memory, a_output, " /"); a_fapi_font->get_name(a_fapi_font, gs_fapi_font_feature_BlendAxisTypes, i, (char *)&Buffer, 255); - WRF_wstring(a_output, Buffer); + WRF_wstring(a_fapi_font->memory, a_output, Buffer); } - WRF_wstring(a_output, "] def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "] def\n"); } x = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_BlendDesignPositionsArrays_count, 0); if (x) { - WRF_wstring(a_output, "/BlendDesignPositions ["); + WRF_wstring(a_fapi_font->memory, a_output, "/BlendDesignPositions ["); x2 = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_BlendAxisTypes_count, 0); for (i = 0; i < x; i++) { - WRF_wstring(a_output, "["); + WRF_wstring(a_fapi_font->memory, a_output, "["); for (j = 0; j < x2; j++) { x1 = a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_BlendDesignPositionsArrayValue, i * 8 + j); gs_sprintf(Buffer, "%f ", x1); - WRF_wstring(a_output, Buffer); + WRF_wstring(a_fapi_font->memory, a_output, Buffer); } - WRF_wstring(a_output, "]"); + WRF_wstring(a_fapi_font->memory, a_output, "]"); } - WRF_wstring(a_output, "] def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "] def\n"); } x = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_BlendDesignMapArrays_count, 0); if (x) { - WRF_wstring(a_output, "/BlendDesignMap ["); + WRF_wstring(a_fapi_font->memory, a_output, "/BlendDesignMap ["); for (i = 0; i < x; i++) { x2 = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_BlendDesignMapSubArrays_count, i); - WRF_wstring(a_output, "["); + WRF_wstring(a_fapi_font->memory, a_output, "["); for (j = 0; j < x2; j++) { - WRF_wstring(a_output, "["); + WRF_wstring(a_fapi_font->memory, a_output, "["); x1 = a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_BlendDesignPositionsArrayValue, i * 64 + j * 64); gs_sprintf(Buffer, "%f ", x1); - WRF_wstring(a_output, Buffer); + WRF_wstring(a_fapi_font->memory, a_output, Buffer); x1 = a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_BlendDesignPositionsArrayValue, i * 64 + j * 64 + 1); gs_sprintf(Buffer, "%f ", x1); - WRF_wstring(a_output, Buffer); - WRF_wstring(a_output, "]"); + WRF_wstring(a_fapi_font->memory, a_output, Buffer); + WRF_wstring(a_fapi_font->memory, a_output, "]"); } - WRF_wstring(a_output, "]"); + WRF_wstring(a_fapi_font->memory, a_output, "]"); } - WRF_wstring(a_output, "] def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "] def\n"); } - WRF_wstring(a_output, "end readonly def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "end readonly def\n"); /* Previously we tried to write $Blend twice - the "real" one from the font, * and the boiler plate one below. @@ -377,7 +552,7 @@ a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_DollarBlend_length, 0)) > 0) { - WRF_wstring(a_output, "/$Blend {"); + WRF_wstring(a_fapi_font->memory, a_output, "/$Blend {"); if (a_output->m_count) a_output->m_count += x; @@ -386,27 +561,46 @@ (char *)a_output->m_pos); if (a_output->m_pos) a_output->m_pos += x; - WRF_wstring(a_output, "} def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "} def\n"); } else { - WRF_wstring(a_output, + WRF_wstring(a_fapi_font->memory, a_output, "/$Blend {0.1 mul exch 0.45 mul add exch 0.17 mul add add} def\n"); } - WRF_wstring(a_output, "/WeightVector ["); +#if 1 + WRF_wstring(a_fapi_font->memory, a_output, "/WeightVector ["); x = a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_WeightVector_count, 0); for (i = 0; i < x; i++) { x1 = a_fapi_font->get_float(a_fapi_font, gs_fapi_font_feature_WeightVector, i); gs_sprintf(Buffer, "%f ", x1); - WRF_wstring(a_output, Buffer); + WRF_wstring(a_fapi_font->memory, a_output, Buffer); } - WRF_wstring(a_output, "] def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "] def\n"); +#endif + + WRF_wstring(a_fapi_font->memory, a_output, "/Blend 3 dict dup begin\n"); + WRF_wstring(a_fapi_font->memory, a_output, "/FontBBox {"); + x = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendFontBBox_length , 0); + for (i = 0; i < x; i++) { + int j; + WRF_wstring(a_fapi_font->memory, a_output, " {"); + for (j = 0; j < 4; j++) { + x2 = a_fapi_font->get_word(a_fapi_font, + gs_fapi_font_feature_BlendFontBBox, + j + (i * 4)); + WRF_wint(a_fapi_font->memory, a_output, x2); + WRF_wbyte(a_fapi_font->memory, a_output, (byte)' '); + } + WRF_wstring(a_fapi_font->memory, a_output, "}"); + } + WRF_wstring(a_fapi_font->memory, a_output, " } def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "/Private 14 dict def\n"); + WRF_wstring(a_fapi_font->memory, a_output, "end def\n"); } - WRF_wstring(a_output, "currentdict end\ncurrentfile eexec\n"); + WRF_wstring(a_fapi_font->memory, a_output, "currentdict end\ncurrentfile eexec\n"); write_private_dictionary(a_fapi_font, a_output, Write_CharStrings); - if (is_MM_font(a_fapi_font)) { - write_blend_dictionary(a_fapi_font, a_output); - } } /** @@ -427,9 +621,17 @@ WRF_init(&output, a_buffer, a_buffer_size); /* Leading comment identifying a Type 1 font. */ - WRF_wstring(&output, "%!PS-AdobeFont-1\n"); + WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n"); write_main_dictionary(a_fapi_font, &output, 0); +#if 0 + { + extern FILE *stdout; + if (is_MM_font(a_fapi_font) && a_buffer && a_buffer_size >= output.m_count) { + fwrite(a_buffer, 1, output.m_count, stdout); + } + } +#endif return output.m_count; } @@ -443,7 +645,7 @@ WRF_init(&output, a_buffer, a_buffer_size); /* Leading comment identifying a Type 1 font. */ - WRF_wstring(&output, "%!PS-AdobeFont-1\n"); + WRF_wstring(a_fapi_font->memory, &output, "%!PS-AdobeFont-1\n"); write_main_dictionary(a_fapi_font, &output, 1); return output.m_count; diff -Nru ghostscript-9.10~dfsg/base/write_t1.h ghostscript-9.25~dfsg+1/base/write_t1.h --- ghostscript-9.10~dfsg/base/write_t1.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/write_t1.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/write_t2.c ghostscript-9.25~dfsg+1/base/write_t2.c --- ghostscript-9.10~dfsg/base/write_t2.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/write_t2.c 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ /* @@ -40,30 +40,30 @@ } static void -write_type2_int(WRF_output * a_output, long a_int) +write_type2_int(gs_fapi_font * a_fapi_font, WRF_output * a_output, long a_int) { if (a_int >= -107 && a_int <= 107) - WRF_wbyte(a_output, (unsigned char)(a_int + 139)); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int + 139)); else if (a_int >= -32768 && a_int <= 32767) { if (a_int >= 108 && a_int <= 1131) a_int += 63124; else if (a_int >= -1131 && a_int <= -108) a_int = -a_int + 64148; else - WRF_wbyte(a_output, 28); - WRF_wbyte(a_output, (unsigned char)(a_int >> 8)); - WRF_wbyte(a_output, (unsigned char)(a_int & 0xFF)); + WRF_wbyte(a_fapi_font->memory, a_output, 28); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int >> 8)); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_int & 0xFF)); } else { unsigned char buffer[4]; - WRF_wbyte(a_output, 29); + WRF_wbyte(a_fapi_font->memory, a_output, 29); write_4_byte_int(buffer, a_int); - WRF_wtext(a_output, buffer, 4); + WRF_wtext(a_fapi_font->memory, a_output, buffer, 4); } } static void -write_type2_float(WRF_output * a_output, double a_float) +write_type2_float(gs_fapi_font * a_fapi_font, WRF_output * a_output, double a_float) { char buffer[32]; const char *p = buffer; @@ -71,7 +71,7 @@ char c = 0; gs_sprintf(buffer, "%f", a_float); - WRF_wbyte(a_output, 30); + WRF_wbyte(a_fapi_font->memory, a_output, 30); for (;;) { char n = 0; @@ -91,12 +91,12 @@ n = 0xF; if (high) { if (*p == 0) - WRF_wbyte(a_output, 0xFF); + WRF_wbyte(a_fapi_font->memory, a_output, 0xFF); else c = (char)(n << 4); } else { c |= n; - WRF_wbyte(a_output, c); + WRF_wbyte(a_fapi_font->memory, a_output, c); } if (*p == 0) @@ -108,16 +108,16 @@ } static void -write_header(WRF_output * a_output) +write_header(gs_fapi_font * a_fapi_font, WRF_output * a_output) { - WRF_wtext(a_output, (const unsigned char *)"\x1\x0\x4\x1", 4); + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1\x0\x4\x1", 4); } static void -write_name_index(WRF_output * a_output) +write_name_index(gs_fapi_font * a_fapi_font, WRF_output * a_output) { /* Write a dummy name of 'x'. */ - WRF_wtext(a_output, (const unsigned char *)"\x0\x1\x1\x1\x2" "x", 6); + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x1\x1\x1\x2" "x", 6); } static void @@ -134,11 +134,11 @@ /* Divide by the divisor to bring it back to font units. */ x = (short)(x / a_divisor); - write_type2_int(a_output, x); + write_type2_int(a_fapi_font, a_output, x); } if (a_two_byte_op) - WRF_wbyte(a_output, 12); - WRF_wbyte(a_output, (unsigned char)a_op); + WRF_wbyte(a_fapi_font->memory, a_output, 12); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op); } } @@ -161,12 +161,12 @@ /* Divide by the divisor to bring it back to font units. */ value = (short)(value / a_divisor); - write_type2_int(a_output, value - prev_value); + write_type2_int(a_fapi_font, a_output, value - prev_value); prev_value = value; } if (a_two_byte_op) - WRF_wbyte(a_output, 12); - WRF_wbyte(a_output, (unsigned char)a_op); + WRF_wbyte(a_fapi_font->memory, a_output, 12); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op); } } @@ -181,11 +181,11 @@ for (i = 0; i < a_feature_count; i++) { double x = a_fapi_font->get_float(a_fapi_font, a_feature_id, i); - write_type2_float(a_output, x); + write_type2_float(a_fapi_font, a_output, x); } if (a_two_byte_op) - WRF_wbyte(a_output, 12); - WRF_wbyte(a_output, (unsigned char)a_op); + WRF_wbyte(a_fapi_font->memory, a_output, 12); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)a_op); } } @@ -197,24 +197,24 @@ { unsigned char *data_start = 0; - WRF_wtext(a_output, (const unsigned char *)"\x0\x1\x2\x0\x1\x0\x0", 7); /* count = 1, offset size = 2, first offset = 1, last offset = 0 (to be filled in later). */ + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x1\x2\x0\x1\x0\x0", 7); /* count = 1, offset size = 2, first offset = 1, last offset = 0 (to be filled in later). */ if (a_output->m_pos) data_start = a_output->m_pos; write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontBBox, 4, false, 5, 1); write_float_entry(a_fapi_font, a_output, gs_fapi_font_feature_FontMatrix, 6, true, 7); - write_type2_int(a_output, 0); /* 0 = Standard Encoding. */ - WRF_wbyte(a_output, 16); /* 16 = opcode for 'encoding'. */ + write_type2_int(a_fapi_font, a_output, 0); /* 0 = Standard Encoding. */ + WRF_wbyte(a_fapi_font->memory, a_output, 16); /* 16 = opcode for 'encoding'. */ *a_charset_offset_ptr = a_output->m_pos; - WRF_wtext(a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */ - WRF_wbyte(a_output, 15); /* opcode for 'charset' */ + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the charset, which will be a 5-byte integer. */ + WRF_wbyte(a_fapi_font->memory, a_output, 15); /* opcode for 'charset' */ *a_charstrings_offset_ptr = a_output->m_pos; - WRF_wtext(a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */ - WRF_wbyte(a_output, 17); /* opcode for 'Charstrings' */ + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx", 5); /* placeholder for the offset to the Charstrings index, which will be a 5-byte integer. */ + WRF_wbyte(a_fapi_font->memory, a_output, 17); /* opcode for 'Charstrings' */ *a_private_dict_length_ptr = a_output->m_pos; - WRF_wtext(a_output, (const unsigned char *)"\x1d" "xxxx\x1d" "yyyy", 10); /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */ - WRF_wbyte(a_output, 18); /* opcode for 'Private' */ + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x1d" "xxxx\x1d" "yyyy", 10); /* placeholder for size and offset of Private dictionary, which will be 5-byte integers. */ + WRF_wbyte(a_fapi_font->memory, a_output, 18); /* opcode for 'Private' */ if (a_output->m_pos) { int last_offset = a_output->m_pos - data_start + 1; @@ -230,9 +230,9 @@ than the fact that there is at least one character. */ static int -write_charset(WRF_output * a_output, unsigned char *a_charset_offset_ptr) +write_charset(gs_fapi_font * a_fapi_font, WRF_output * a_output, unsigned char *a_charset_offset_ptr) { - const int characters = 1; + const int characters = 2; /* .notdef + one other */ int i = 0; /* Write the offset to the start of the charset to the top dictionary. */ @@ -245,10 +245,10 @@ write all the others as .notdef (SID = 0) because we don't actually need the charset at the moment. */ - WRF_wbyte(a_output, 0); /* format = 0 */ + WRF_wbyte(a_fapi_font->memory, a_output, 0); /* format = 0 */ for (i = 1; i < characters; i++) { - WRF_wbyte(a_output, 0); - WRF_wbyte(a_output, 0); + WRF_wbyte(a_fapi_font->memory, a_output, 0); + WRF_wbyte(a_fapi_font->memory, a_output, 0); } return characters; @@ -259,7 +259,7 @@ FreeType how many glyphs there are. */ static void -write_charstrings_index(WRF_output * a_output, int a_characters, +write_charstrings_index(gs_fapi_font * a_fapi_font, WRF_output * a_output, int a_characters, unsigned char *a_charstrings_offset_ptr) { /* Write the offset to the charstrings index to the top dictionary. */ @@ -267,11 +267,11 @@ write_4_byte_int(a_charstrings_offset_ptr + 1, a_output->m_count); /* Write the index. */ - WRF_wbyte(a_output, (unsigned char)(a_characters >> 8)); - WRF_wbyte(a_output, (unsigned char)(a_characters & 0xFF)); - WRF_wbyte(a_output, 1); /* offset size = 1. */ + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters >> 8)); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(a_characters & 0xFF)); + WRF_wbyte(a_fapi_font->memory, a_output, 1); /* offset size = 1. */ while (a_characters-- >= 0) - WRF_wbyte(a_output, 1); /* offset = 1 */ + WRF_wbyte(a_fapi_font->memory, a_output, 1); /* offset = 1 */ } static void @@ -284,32 +284,32 @@ gs_fapi_font_feature_GlobalSubrs_count, 0); - WRF_wbyte(a_output, (unsigned char)(count >> 8)); - WRF_wbyte(a_output, (unsigned char)(count & 0xFF)); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8)); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF)); if (count <= 0) return; - WRF_wbyte(a_output, 4); /* offset size = 4 bytes */ - WRF_wtext(a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */ + WRF_wbyte(a_fapi_font->memory, a_output, 4); /* offset size = 4 bytes */ + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */ if (a_output->m_pos) cur_offset = a_output->m_pos; /* Write dummy bytes for the offsets at the end of each data item. */ for (i = 0; i < count; i++) - WRF_wtext(a_output, (const unsigned char *)"xxxx", 4); + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4); if (a_output->m_pos) data_start = a_output->m_pos; for (i = 0; i < count; i++) { - long buffer_size = a_output->m_limit - a_output->m_count; + long buffer_size = a_output->m_limit - a_output->m_count < 0 ? 0 : a_output->m_limit - a_output->m_count; long length = a_fapi_font->get_gsubr(a_fapi_font, i, a_output->m_pos, - (ushort) buffer_size); + (ushort) (buffer_size > 65535 ? 65535 : buffer_size)); if (a_output->m_pos) - WRF_wtext(a_output, a_output->m_pos, length); + WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length); else a_output->m_count += length; if (cur_offset) { @@ -331,21 +331,21 @@ a_fapi_font->get_word(a_fapi_font, gs_fapi_font_feature_Subrs_count, 0); - WRF_wbyte(a_output, (unsigned char)(count >> 8)); - WRF_wbyte(a_output, (unsigned char)(count & 0xFF)); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count >> 8)); + WRF_wbyte(a_fapi_font->memory, a_output, (unsigned char)(count & 0xFF)); if (count <= 0) return; - WRF_wbyte(a_output, 4); /* offset size = 4 bytes */ - WRF_wtext(a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */ + WRF_wbyte(a_fapi_font->memory, a_output, 4); /* offset size = 4 bytes */ + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"\x0\x0\x0\x1", 4); /* first offset = 1 */ if (a_output->m_pos) cur_offset = a_output->m_pos; /* Write dummy bytes for the offsets at the end of each data item. */ for (i = 0; i < count; i++) - WRF_wtext(a_output, (const unsigned char *)"xxxx", 4); + WRF_wtext(a_fapi_font->memory, a_output, (const unsigned char *)"xxxx", 4); if (a_output->m_pos) data_start = a_output->m_pos; @@ -356,7 +356,7 @@ (ushort) buffer_size); if (a_output->m_pos) - WRF_wtext(a_output, a_output->m_pos, length); + WRF_wtext(a_fapi_font->memory, a_output, a_output->m_pos, length); else a_output->m_count += length; if (cur_offset) { @@ -383,12 +383,12 @@ write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueFuzz, 1, true, 11, 16); - write_type2_float(a_output, + write_type2_float(a_fapi_font, a_output, a_fapi_font->get_long(a_fapi_font, gs_fapi_font_feature_BlueScale, 0) / 65536.0); - WRF_wbyte(a_output, 12); - WRF_wbyte(a_output, 9); + WRF_wbyte(a_fapi_font->memory, a_output, 12); + WRF_wbyte(a_fapi_font->memory, a_output, 9); write_word_entry(a_fapi_font, a_output, gs_fapi_font_feature_BlueShift, 1, true, 10, 16); @@ -420,10 +420,10 @@ { gs_font_type1 *t1 = (gs_font_type1 *) a_fapi_font->client_font_data; - write_type2_float(a_output, fixed2float(t1->data.defaultWidthX)); - WRF_wbyte(a_output, 20); - write_type2_float(a_output, fixed2float(t1->data.nominalWidthX)); - WRF_wbyte(a_output, 21); + write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.defaultWidthX)); + WRF_wbyte(a_fapi_font->memory, a_output, 20); + write_type2_float(a_fapi_font, a_output, fixed2float(t1->data.nominalWidthX)); + WRF_wbyte(a_fapi_font->memory, a_output, 21); } count = @@ -443,34 +443,34 @@ switch (n) { case 1: if (n1 >= -107 && n1 <= 107) { - write_type2_int(a_output, n1); + write_type2_int(a_fapi_font, a_output, n1); n = 5; } break; case 2: if ((n1 >= 108 && n1 <= 1131) || (n1 >= -1131 && n1 <= -108)) { - write_type2_int(a_output, n1); + write_type2_int(a_fapi_font, a_output, n1); n = 5; } break; case 3: if (n1 >= -32768 && n1 <= 32767) { - write_type2_int(a_output, n1); + write_type2_int(a_fapi_font, a_output, n1); n = 5; } break; case 4: break; case 5: - write_type2_int(a_output, n1); + write_type2_int(a_fapi_font, a_output, n1); break; } n++; } while (n < 5); - WRF_wbyte(a_output, 19); + WRF_wbyte(a_fapi_font->memory, a_output, 19); } /* Write the length in bytes of the private dictionary to the top dictionary. */ @@ -497,17 +497,17 @@ WRF_init(&output, a_buffer, a_buffer_size); - write_header(&output); - write_name_index(&output); + write_header(a_fapi_font, &output); + write_name_index(a_fapi_font, &output); write_font_dict_index(a_fapi_font, &output, &charset_offset_ptr, &charstrings_offset_ptr, &private_dict_length_ptr); /* Write an empty string index. */ - WRF_wtext(&output, (const unsigned char *)"\x0\x0", 2); + WRF_wtext(a_fapi_font->memory, &output, (const unsigned char *)"\x0\x0", 2); write_gsubrs_index(a_fapi_font, &output); - characters = write_charset(&output, charset_offset_ptr); - write_charstrings_index(&output, characters, charstrings_offset_ptr); + characters = write_charset(a_fapi_font, &output, charset_offset_ptr); + write_charstrings_index(a_fapi_font, &output, characters, charstrings_offset_ptr); write_private_dict(a_fapi_font, &output, private_dict_length_ptr); write_subrs_index(a_fapi_font, &output); diff -Nru ghostscript-9.10~dfsg/base/write_t2.h ghostscript-9.25~dfsg+1/base/write_t2.h --- ghostscript-9.10~dfsg/base/write_t2.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/write_t2.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/x_.h ghostscript-9.25~dfsg+1/base/x_.h --- ghostscript-9.10~dfsg/base/x_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/x_.h 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2012 Artifex Software, Inc. +/* Copyright (C) 2001-2018 Artifex Software, Inc. All Rights Reserved. This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ of the license contained in the file LICENSE in this distribution. Refer to licensing information at http://www.artifex.com or contact - Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, - CA 94903, U.S.A., +1(415)492-9861, for further information. + Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, + CA 94945, U.S.A., +1(415)492-9861, for further information. */ diff -Nru ghostscript-9.10~dfsg/base/zlib.mak ghostscript-9.25~dfsg+1/base/zlib.mak --- ghostscript-9.10~dfsg/base/zlib.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/base/zlib.mak 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2012 Artifex Software, Inc. +# Copyright (C) 2001-2018 Artifex Software, Inc. # All Rights Reserved. # # This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ # of the license contained in the file LICENSE in this distribution. # # Refer to licensing information at http://www.artifex.com or contact -# Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -# CA 94903, U.S.A., +1(415)492-9861, for further information. +# Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +# CA 94945, U.S.A., +1(415)492-9861, for further information. # # makefile for zlib library code. # Users of this makefile must define the following: @@ -52,13 +52,13 @@ # We need D_, _D_, and _D because the OpenVMS compiler uses different # syntax from other compilers. # ZI_ and ZF_ are defined in gs.mak. -ZCCFLAGS=$(I_)$(ZI_)$(_I) $(ZF_) $(D_)verbose$(_D_)-1$(_D) +ZCCFLAGS=$(ZLIB_CFLAGS) $(I_)$(ZI_)$(_I) $(ZF_) $(D_)verbose$(_D_)-1$(_D) ZCC=$(CC_) $(ZCCFLAGS) -ZCCAUXFLAGS=$(I_)$(ZI_)$(_I) $(ZF_) $(D_)verbose$(_D_)-1$(_D) +ZCCAUXFLAGS=$(ZLIB_CFLAGS) $(I_)$(ZI_)$(_I) $(ZF_) $(D_)verbose$(_D_)-1$(_D) ZCCAUX=$(CCAUX_) $(ZCCAUXFLAGS) # Define the name of this makefile. -ZLIB_MAK=$(GLSRC)zlib.mak +ZLIB_MAK=$(GLSRC)zlib.mak $(TOP_MAKEFILES) z.clean : z.config-clean z.clean-not-config-clean @@ -69,7 +69,7 @@ z.config-clean : $(RMN_) $(ZGEN)zlib*.dev $(ZGEN)crc32*.dev -ZDEP=$(AK) +ZDEP=$(AK) $(ZLIB_MAK) $(MAKEDIRS) # Code common to compression and decompression. @@ -82,15 +82,18 @@ # Encoding (compression) code. -$(ZGEN)zlibe.dev : $(TOP_MAKEFILES) $(ZGEN)zlibe_$(SHARE_ZLIB).dev +$(ZGEN)zlibe.dev : $(ZLIB_MAK) $(ZGEN)zlibe_$(SHARE_ZLIB).dev \ + $(MAKEDIRS) $(CP_) $(ZGEN)zlibe_$(SHARE_ZLIB).dev $(ZGEN)zlibe.dev -$(ZGEN)zlibe_1.dev : $(TOP_MAKEFILES) $(ZLIB_MAK) $(ECHOGS_XE) +$(ZGEN)zlibe_1.dev : $(ZLIB_MAK) $(ZLIB_MAK) $(ECHOGS_XE) \ + $(MAKEDIRS) $(SETMOD) $(ZGEN)zlibe_1 -lib $(ZLIB_NAME) zlibe_=$(ZOBJ)adler32.$(OBJ) $(ZOBJ)deflate.$(OBJ) \ $(ZOBJ)compress.$(OBJ) $(ZOBJ)trees.$(OBJ) $(ZOBJ)crc32.$(OBJ) -$(ZGEN)zlibe_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibe_) +$(ZGEN)zlibe_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibe_) \ + $(MAKEDIRS) $(SETMOD) $(ZGEN)zlibe_0 $(zlibe_) $(ADDMOD) $(ZGEN)zlibe_0 -include $(ZGEN)zlibc.dev @@ -110,13 +113,16 @@ # The zlib filters per se don't need crc32, but libpng versions starting # with 0.90 do. -$(ZGEN)crc32.dev : $(TOP_MAKEFILES) $(ZGEN)crc32_$(SHARE_ZLIB).dev +$(ZGEN)crc32.dev : $(ZLIB_MAK) $(ZGEN)crc32_$(SHARE_ZLIB).dev \ + $(MAKEDIRS) $(CP_) $(ZGEN)crc32_$(SHARE_ZLIB).dev $(ZGEN)crc32.dev -$(ZGEN)crc32_1.dev : $(TOP_MAKEFILES) $(ZLIB_MAK) $(ECHOGS_XE) +$(ZGEN)crc32_1.dev : $(ZLIB_MAK) $(ZLIB_MAK) $(ECHOGS_XE) \ + $(MAKEDIRS) $(SETMOD) $(ZGEN)crc32_1 -lib $(ZLIB_NAME) -$(ZGEN)crc32_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZOBJ)crc32.$(OBJ) +$(ZGEN)crc32_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZOBJ)crc32.$(OBJ) \ + $(MAKEDIRS) $(SETMOD) $(ZGEN)crc32_0 $(ZOBJ)crc32.$(OBJ) # We have to compile crc32 without warnings, because it defines 32-bit @@ -126,10 +132,11 @@ # Decoding (decompression) code. -$(ZGEN)zlibd.dev : $(TOP_MAKEFILES) $(ZGEN)zlibd_$(SHARE_ZLIB).dev +$(ZGEN)zlibd.dev : $(ZLIB_MAK) $(ZGEN)zlibd_$(SHARE_ZLIB).dev $(MAKEDIRS) $(CP_) $(ZGEN)zlibd_$(SHARE_ZLIB).dev $(ZGEN)zlibd.dev -$(ZGEN)zlibd_1.dev : $(TOP_MAKEFILES) $(ZLIB_MAK) $(ECHOGS_XE) +$(ZGEN)zlibd_1.dev : $(ZLIB_MAK) $(ZLIB_MAK) $(ECHOGS_XE) \ + $(MAKEDIRS) $(SETMOD) $(ZGEN)zlibd_1 -lib $(ZLIB_NAME) # zlibd[12]_ list the decompression source files for zlib 1.4.x @@ -140,7 +147,7 @@ zlibd_=$(ZOBJ)inffast.$(OBJ) $(ZOBJ)inflate.$(OBJ) $(ZOBJ)inftrees.$(OBJ) $(ZOBJ)uncompr.$(OBJ) -$(ZGEN)zlibd_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibd_) +$(ZGEN)zlibd_0.dev : $(ZLIB_MAK) $(ECHOGS_XE) $(ZGEN)zlibc.dev $(zlibd_) $(MAKEDIRS) $(SETMOD) $(ZGEN)zlibd_0 $(zlibd_) $(ADDMOD) $(ZGEN)zlibd_0 -include $(ZGEN)zlibc.dev diff -Nru ghostscript-9.10~dfsg/configure ghostscript-9.25~dfsg+1/configure --- ghostscript-9.10~dfsg/configure 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/configure 2018-09-13 10:02:46.000000000 +0000 @@ -620,16 +620,55 @@ #endif" ac_subst_vars='LTLIBOBJS +AUXEXTRALIBS +LDFLAGSAUX +CFLAGSAUX_PROFILE +CFLAGSAUX_DEBUG +CFLAGSAUX_STANDARD +CAPOPTAUX +GCFLAGSAUX +CCAUX +JPX_SSE_CFLAGS +CFLAGS_SANITIZE GCFLAGS DBG_CFLAGS OPT_CFLAGS +SRCDIR +ARCH_ARITH_RSHIFT +ARCH_DIV_NEG_POS_TRUNCATES +ARCH_PTRS_ARE_SIGNED +ARCH_IS_BIG_ENDIAN +ARCH_LOG2_SIZEOF_DOUBLE +ARCH_SIZEOF_DOUBLE +ARCH_LOG2_SIZEOF_FLOAT +ARCH_SIZEOF_FLOAT +ARCH_LOG2_SIZEOF_PTR +ARCH_SIZEOF_PTR +ARCH_LOG2_SIZEOF_LONG_LONG +ARCH_LOG2_SIZEOF_LONG +ARCH_LOG2_SIZEOF_INT +ARCH_LOG2_SIZEOF_SHORT +ARCH_LOG2_SIZEOF_CHAR +ARCH_ALIGN_DOUBLE_MOD +ARCH_ALIGN_FLOAT_MOD +ARCH_ALIGN_PTR_MOD +ARCH_ALIGN_LONG_MOD +ARCH_ALIGN_INT_MOD +ARCH_ALIGN_SHORT_MOD +CLUSTER_CFLAGS +VERSIONED_PATH AUXDIRPOSTFIX +SUB_MAKE_OPTION ORDER_ONLY HAVE_BYTESWAP_H HAVE_BSWAP32 SQRTF_SUBST +LCMS2_PTR_ALIGNMENT LCMS2_ENDIAN LCMS_ENDIAN +HAVE_FPCLASSIFY +HAVE_ISINF +HAVE_ISNAN HAVE_STRERROR HAVE_SETLOCALE HAVE_MKSTEMP64 @@ -643,7 +682,10 @@ X11_DEVS INSTALL_SHARED DYNAMIC_LIBS -DYNAMIC_LDFLAGS +PDL_DYNAMIC_LDFLAGS +XPS_DYNAMIC_LDFLAGS +PCL_DYNAMIC_LDFLAGS +GS_DYNAMIC_LDFLAGS DYNAMIC_FLAGS DYNAMIC_DEVS DYNAMIC_CFLAGS @@ -651,11 +693,24 @@ IJS_DEVS JBIG2_DEVS XPS_DEVS -SVG_DEVS CUPS_DEVS F_DEVS P_DEVS COMPILE_INITS +GPDL_MAK +GPDL_TARGET +GPDL +XPSROMFS_MAK +XPS_MAK +XPS_TARGET +XPS +PXL_MAK +PCL_TOP_MAK +PCL_MAK +PL_MAK +PLROMFS_MAK +PCL_TARGET +PCL GS XLIBS X_LDFLAGS @@ -664,13 +719,13 @@ X_PRE_LIBS X_CFLAGS XMKMF -OMNIDEVS SOC_LOADER SOC_LIBS SOC_CFLAGS JPXDEVS SHARE_JPX JPXDIR +JPX_AUTOCONF_LIBS JPX_AUTOCONF_CFLAGS JPX_DECODER JBIG2_AUTOCONF_CFLAGS @@ -696,18 +751,25 @@ CUPSLIBDIRS CUPSLIBS CUPSCFLAGS +BUILD_CUPSCONFIG CUPSCONFIG +EXPAT_LIBS +EXPAT_CFLAGS +EXPATDIR +SHARE_EXPAT +TIFFCFLAGS LIBTIFFCONFDIR LIBTIFFDIR SHARE_LIBTIFF +LCMS2MTDIR LCMS2DIR -LCMSDIR WHICHLCMS SHARELCMS LIBPNGDIR SHARE_LIBPNG FT_SYS_ZLIB ZLIBDIR +ZLIBCFLAGS AUX_SHARED_ZLIB SHARE_ZLIB LIBJPEGDIR @@ -730,17 +792,24 @@ HAVE_FONTCONFIG UTF8DEVS HAVE_LIBIDN +RECURSIVE_MUTEXATTR PTHREAD_LIBS SYNC +HAVE_POPEN_PROTO +HAVE_PREAD_PWRITE +ARCH_SIZEOF_GX_COLOR_INDEX LIBOBJS OBJDIR_BSDMAKE_WORKAROUND +HAVE_SSE2 EGREP GREP -HAVE_SSE2 ARCH_CONF_HEADER SET_DT_SONAME INSTALL_CONTRIB CONTRIBINCLUDE +BUILD_STRIP_XE +STRIP_XE +BUILD_PKGCONFIG PKGCONFIG RANLIB SED_EXTENDED_REGEX_OPT @@ -772,6 +841,7 @@ docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -794,11 +864,13 @@ ac_subst_files='' ac_user_opts=' enable_option_checking +enable_save_confaux enable_contrib -enable_big_endian -enable_little_endian +with_arch_h enable_sse2 enable_threadsafe +with_large_color_index +enable_threading with_libiconv with_libidn with_libpaper @@ -807,7 +879,7 @@ enable_freetype enable_fapi with_ufst -with_lcms +with_libtiff with_system_libtiff enable_cups with_pdftoraster @@ -820,17 +892,23 @@ with_jbig2dec enable_openjpeg enable_gtk -with_omni with_x with_gs +with_pcl +with_xps +with_gpdl enable_compile_inits with_drivers with_driversfile enable_dynamic with_fontpath +with_memory_alignment enable_bswap32 enable_byteswap_h with_gnu_make +with_exe_ext +with_versioned_path +enable_cluster ' ac_precious_vars='build_alias host_alias @@ -880,6 +958,7 @@ sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1132,6 +1211,15 @@ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1269,7 +1357,7 @@ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1422,6 +1510,7 @@ --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1453,12 +1542,12 @@ --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-contrib Do not include contributed drivers - --enable-big-endian Force big endian - --enable-little-endian Force little endian --disable-sse2 Do not use sse2 instrinsics --enable-threadsafe enable a thread safe build - NOTE: this will exclude non-threadsafe devices + --disable-threading disable support for multithreaded rendering --disable-fontconfig Do not use fontconfig to list system fonts --disable-dbus Do not use dbus to communicate with external services @@ -1476,14 +1565,16 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-arch_h= + Use a custom arch.h (must be an absolute path) + --with-libiconv=[no/gnu/native] use the libiconv library --without-libidn Do not use libidn to support Unicode passwords --without-libpaper disable libpaper support --with-ufst=UFST_ROOT_DIR Use UFST - --with-lcms try to use LittleCMS 1.x instead of the default of - LittleCMS 2.x + --without-libtiff disable use of libtiff --with-system-libtiff Force using the systems libtiff --without-pdftoraster Do not include CUPS' pdftoraster filter --with-local-cups Force using the GS supplied cups code - only useful @@ -1495,9 +1586,14 @@ --without-luratech do not try to use the Luratech library for JBIG2 nor JPX decoding --without-jbig2dec disable JBIG2 decode support - --with-omni enable the omni driver --with-x use the X Window System --with-gs=NAME name of the Ghostscript executible [[gs]] + --with-pcl=NAME name of the GhostPCL executible (if the source is + available, ignored otherwise) [[gpcl6]] + --with-xps=NAME name of the GhostXPS executible (if the source is + available, ignored otherwise) [[gxps]] + --with-gpdl=NAME name of the GhostPDL executible (if the source is + available, ignored otherwise) [[gpdl]] --with-drivers=LIST Drivers to support, separated by commas. Either list the drivers or use aliases: ALL = all drivers @@ -1531,7 +1627,16 @@ Default: ALL --with-driversfile=FILE Drivers to support from file, separated by newlines. --with-fontpath set font search path for gs + --with-memory-alignment Allows setting minimum alignment for the memory + manager (4 or 8 bytes) --without-gnu-make disable GNU make features + --with-exe-ext=EXT set the file name executable extension (must include + any separator e.g. the period in ".exe") + --without-versioned-path + Do not use file paths containing the version of GS. + + WARNING: This option is dangerous & unsupported, and + you take full responsibility for using it! Some influential environment variables: CC C compiler command @@ -1699,6 +1804,52 @@ } # ac_fn_c_try_cpp +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes @@ -1741,51 +1892,36 @@ } # ac_fn_c_try_run -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval -} # ac_fn_c_try_link +} # ac_fn_c_check_header_compile # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- @@ -1874,37 +2010,6 @@ } # ac_fn_c_check_header_mongrel -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -2265,6 +2370,52 @@ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -2631,6 +2782,20 @@ CXXFLAGS="${CXXFLAGS:=}" LDFLAGS="${LDFLAGS:=}" +if test x"$cross_compiling" = x"yes"; then + CFLAGSAUX="${CFLAGSAUX:=}" + LDFLAGSAUX="${LDFLAGSAUX:=}" +else + CFLAGSAUX="${CFLAGSAUX:-$CFLAGS}" + LDFLAGSAUX="${LDFLAGSAUX:-$LDFLAGS}" +fi + +THEMAKEFILE="${MAKEFILE:-Makefile}" +AUXFLAGS_MAK=auxflags.mak + +ARCH_AUTOCONF_HEADER=arch-config/arch_autoconf.h +ARCH_AUTOCONF_HEADER_PROTO=arch/arch_autoconf.h.in + NTS_DEVS='opvp oprp' NTS_DEVS="$NTS_DEVS uniprint" @@ -2648,7 +2813,7 @@ -save_cflags=$CFLAGS +save_cflags="$CFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3575,7 +3740,88 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -CFLAGS=$save_cflags +CFLAGS="$save_cflags" + +AUXFLAGS_MAK_LINE00="CCAUX=@CC@" +AUXFLAGS_MAK_LINE01="GCFLAGSAUX=@CPPFLAGS@ @GCFLAGS@ @CFLAGS@" +AUXFLAGS_MAK_LINE02="CAPOPTAUX=" +AUXFLAGS_MAK_LINE03="CFLAGSAUX_STANDARD=@OPT_CFLAGS@" +AUXFLAGS_MAK_LINE04="CFLAGSAUX_DEBUG=@DBG_CFLAGS@" +AUXFLAGS_MAK_LINE05="CFLAGSAUX_PROFILE=-pg @OPT_CFLAGS@" +AUXFLAGS_MAK_LINE06="LDFLAGSAUX=@LDFLAGS@" +AUXFLAGS_MAK_LINE07="AUXEXTRALIBS=@LIBS@" + +GCFLAGSAUXTMP="\$(GCFLAGS)" +CAPOPTAUXTMP="\$(CAPOPT)" +CFLAGSAUX_STANDARDTMP="\$(CFLAGS_STANDARD)" +CFLAGSAUX_DEBUGTMP="\$(CFLAGS_DEBUG)" +CFLAGSAUX_PROFILETMP="\$(CFLAGS_PROFILE)" +LDFLAGSAUXTMP="\$(LDFLAGS)" +AUXEXTRALIBSTMP="\$(EXTRALIBS)" + + +# purposefully do not include "help" output for this +# Check whether --enable-save_confaux was given. +if test "${enable_save_confaux+set}" = set; then : + enableval=$enable_save_confaux; +fi + + +if test x"$CCAUX" != x"" ; then + # rerun configure for the AUX tools, disabling a load of tests not relevant for CCAUX + olddir=`pwd` + if test x"$enable_save_confaux" = x"yes"; then + CONFAUXDIR=auxtmp + else + CONFAUXDIR=auxtmp$RANDOM$RANDOM + fi + mkdir $CONFAUXDIR + cd $CONFAUXDIR + echo -e $AUXFLAGS_MAK_CONTENTS > $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE00 > $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE01 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE02 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE03 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE04 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE05 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE06 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE07 >> $AUXFLAGS_MAK.in + + ../$0 CC="$CCAUX" CFLAGS="$CFLAGSAUX" LDFLAGS="$LDFLAGSAUX" CCAUX= CFLAGSAUX= CFLAGSAUX= MAKEFILE=$AUXFLAGS_MAK --host= --build= --without-libtiff --disable-contrib --disable-fontconfig --disable-dbus --disable-freetype --disable-fapi --disable-cups --disable-openjpeg --disable-gtk --with-libiconv=no --without-libidn --without-libpaper --without-pdftoraster --without-ijs --without-luratech --without-jbig2dec --without-x --with-drivers="" + status=$? + cp config.log ../configaux.log + if test $status -eq 0 ; then + CCAUX=$(grep CCAUX $AUXFLAGS_MAK | sed "s/CCAUX=//g") + GCFLAGSAUXTMP=$(grep GCFLAGSAUX $AUXFLAGS_MAK | sed "s/GCFLAGSAUX=//g") + CAPOPTAUXTMP=$(grep CAPOPTAUX $AUXFLAGS_MAK | sed "s/CAPOPTAUX=//g") + CFLAGSAUX_STANDARDTMP=$(grep CFLAGSAUX_STANDARD $AUXFLAGS_MAK | sed "s/CFLAGSAUX_STANDARD=//g") + CFLAGSAUX_DEBUGTMP=$(grep CFLAGSAUX_DEBUG $AUXFLAGS_MAK | sed "s/CFLAGSAUX_DEBUG=//g") + CFLAGS_PROFILETMP=$(grep CFLAGS_PROFILE $AUXFLAGS_MAK | sed "s/CFLAGS_PROFILE=//g") + LDFLAGSAUXTMP=$(grep LDFLAGSAUX $AUXFLAGS_MAK | sed "s/LDFLAGSAUX=//g") + AUXEXTRALIBSTMP=$(grep AUXEXTRALIBS$ $AUXFLAGS_MAK | sed "s/AUXEXTRALIBS$=//g") + fi + cd $olddir + + if test x"$enable_save_confaux" != x"yes"; then + rm -rf $CONFAUXDIR + fi + + if test $status -ne 0 ; then + as_fn_error $status "Recursive call to configure (for auxiliary tools) script failed" "$LINENO" 5 + fi +fi + +GCFLAGSAUX=$GCFLAGSAUXTMP +CAPOPTAUX=$CAPOPTAUXTMP +CFLAGSAUX_STANDARD=$CFLAGSAUX_STANDARDTMP +CFLAGSAUX_DEBUG=$CFLAGSAUX_DEBUGTMP +CFLAGS_PROFILE=$CFLAGS_PROFILETMP +LDFLAGSAUX=$LDFLAGSAUXTMP +AUXEXTRALIBS=$AUXEXTRALIBSTMP + +# we have to do this here in case it took +# AC_PROG_CC to set CC (as it usually does) +CCAUX="${CCAUX:-$CC}" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } @@ -3748,8 +3994,10 @@ #AC_PROG_INSTALL -# Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-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_path_PKGCONFIG+:} false; then : @@ -3788,34 +4036,302 @@ fi - - -# Check whether --enable-contrib was given. -if test "${enable_contrib+set}" = set; then : - enableval=$enable_contrib; fi +if test -z "$ac_cv_path_PKGCONFIG"; then + ac_pt_PKGCONFIG=$PKGCONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-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_path_ac_pt_PKGCONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKGCONFIG="$ac_pt_PKGCONFIG" # Let the user override the test with a path. + ;; + *) + 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_path_ac_pt_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 -CONTRIBINCLUDE="include $srcdir/contrib/contrib.mak" -INSTALL_CONTRIB="install-contrib-extras" - -case `uname` in - MINGW*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling contrib devices" >&5 -$as_echo "$as_me: WARNING: disabling contrib devices" >&2;} - enable_contrib=no - ;; - *) -# This is just an arbitrary file in contrib to check - if ! test -f $srcdir/contrib/gdevbjc_.c; then - enable_contrib=no - fi - ;; + ;; esac - -if test x$enable_contrib = xno; then - CONTRIBINCLUDE="" - INSTALL_CONTRIB="" - CFLAGS="$CFLAGS -DNOCONTRIB" +fi +ac_pt_PKGCONFIG=$ac_cv_path_ac_pt_PKGCONFIG +if test -n "$ac_pt_PKGCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 +$as_echo "$ac_pt_PKGCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKGCONFIG" = x; then + PKGCONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKGCONFIG=$ac_pt_PKGCONFIG + fi +else + PKGCONFIG="$ac_cv_path_PKGCONFIG" +fi + + +# this is an unpleasant hack +# but if we are cross compiling, and there isn't a matching +# pkconfig for the --host setting, then don't use the 'local' +# pkconfig at all +if test x"$cross_compiling" = x"yes"; then + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-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_path_BUILD_PKGCONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_PKGCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_PKGCONFIG="$BUILD_PKGCONFIG" # Let the user override the test with a path. + ;; + *) + 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_path_BUILD_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +BUILD_PKGCONFIG=$ac_cv_path_BUILD_PKGCONFIG +if test -n "$BUILD_PKGCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_PKGCONFIG" >&5 +$as_echo "$BUILD_PKGCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$BUILD_PKGCONFIG" = x"$PKGCONFIG" ; then + PKGCONFIG= + fi +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; 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_path_STRIP_XE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $STRIP_XE in + [\\/]* | ?:[\\/]*) + ac_cv_path_STRIP_XE="$STRIP_XE" # Let the user override the test with a path. + ;; + *) + 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_path_STRIP_XE="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +STRIP_XE=$ac_cv_path_STRIP_XE +if test -n "$STRIP_XE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP_XE" >&5 +$as_echo "$STRIP_XE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_STRIP_XE"; then + ac_pt_STRIP_XE=$STRIP_XE + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; 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_path_ac_pt_STRIP_XE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_STRIP_XE in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_STRIP_XE="$ac_pt_STRIP_XE" # Let the user override the test with a path. + ;; + *) + 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_path_ac_pt_STRIP_XE="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +ac_pt_STRIP_XE=$ac_cv_path_ac_pt_STRIP_XE +if test -n "$ac_pt_STRIP_XE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_STRIP_XE" >&5 +$as_echo "$ac_pt_STRIP_XE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_STRIP_XE" = x; then + STRIP_XE="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP_XE=$ac_pt_STRIP_XE + fi +else + STRIP_XE="$ac_cv_path_STRIP_XE" +fi + + +# this is an unpleasant hack +# but if we are cross compiling, and there isn't a matching +# pkconfig for the --host setting, then don't use the 'local' +# pkconfig at all +if test x"$cross_compiling" = x"yes"; then + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; 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_path_BUILD_STRIP_XE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_STRIP_XE in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_STRIP_XE="$BUILD_STRIP_XE" # Let the user override the test with a path. + ;; + *) + 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_path_BUILD_STRIP_XE="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +BUILD_STRIP_XE=$ac_cv_path_BUILD_STRIP_XE +if test -n "$BUILD_STRIP_XE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_STRIP_XE" >&5 +$as_echo "$BUILD_STRIP_XE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$BUILD_STRIP_XE" = x"$STRIP_XE" ; then + STRIP_XE= + fi +fi + + +# Check whether --enable-contrib was given. +if test "${enable_contrib+set}" = set; then : + enableval=$enable_contrib; +fi + + +CONTRIBINCLUDE="include $srcdir/contrib/contrib.mak" +INSTALL_CONTRIB="install-contrib-extras" + +if test x"$enable_contrib" = x; then + if test x"$cross_compiling" = x"yes"; then + enable_contrib= + else + case `uname` in + MINGW*|MSYS*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling contrib devices" >&5 +$as_echo "$as_me: WARNING: disabling contrib devices" >&2;} + enable_contrib=no + ;; + *) + ;; + esac + fi +fi + +if test x"$enable_contrib" != x"no"; then +# This is just an arbitrary file in contrib to check + if test -f $srcdir/contrib/gdevbjc_.c; then + enable_contrib=yes + else + enable_contrib=no + fi +fi + +if test x$enable_contrib = xno; then + CONTRIBINCLUDE="" + INSTALL_CONTRIB="" + CFLAGS="$CFLAGS -DNOCONTRIB" fi @@ -3826,7 +4342,13 @@ CC_OPT_FLAGS_TO_TRY="-O" SET_DT_SONAME="-soname=" -case `uname` in +if test x"$cross_compiling" = x"yes"; then + if test $ac_cv_c_compiler_gnu = yes; then + CC_OPT_FLAGS_TO_TRY="-O2" + CC_DBG_FLAGS_TO_TRY="-gdwarf-2 -g3 -O0" + fi +else + case `uname` in Linux*|GNU*) if test $ac_cv_c_compiler_gnu = yes; then CC_OPT_FLAGS_TO_TRY="-O2" @@ -3859,7 +4381,15 @@ CC_DBG_FLAGS_TO_TRY="-g -O0" fi ;; -esac + AIX) + if test $ac_cv_c_compiler_gnu = yes; then + CC_OPT_FLAGS_TO_TRY="-O2" + CC_DBG_FLAGS_TO_TRY="-gdwarf-2 -g3 -O0" + SET_DT_SONAME="so" + fi + ;; + esac +fi @@ -3867,8 +4397,8 @@ if test $ac_cv_c_compiler_gnu = yes; then cflags_to_try="-Wall -Wstrict-prototypes -Wundef \ -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings \ --Wno-strict-aliasing -Wdeclaration-after-statement \ --fno-builtin -fno-common" +-fno-strict-aliasing -Werror=declaration-after-statement \ +-fno-builtin -fno-common -Werror=return-type" optflags_to_try="$CC_OPT_FLAGS_TO_TRY" dbgflags_to_try="$CC_DBG_FLAGS_TO_TRY" else @@ -3877,16 +4407,76 @@ dbgflags_to_try="$CC_DBG_FLAGS_TO_TRY" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports restrict" >&5 +$as_echo_n "checking if compiler supports restrict... " >&6; } + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ == 199901L +void test (char * restrict p){} +#else +void test (char * __restrict p){} +#endif + +int +main () +{ + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ == 199901L + char *restrict t; +#else + char * __restrict t; +#endif + test(t); + return 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + CFLAGS="$CFLAGS -DHAVE_RESTRICT=1" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + + CFLAGS="$CFLAGS -DHAVE_RESTRICT=0" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + + + +# Check whether --with-arch_h was given. +if test "${with_arch_h+set}" = set; then : + withval=$with_arch_h; +else + with_arch_h= +fi + + ARCH_CONF_HEADER= -case `uname` in - Darwin*) - ARCH_CONF_HEADER="\$(GLSRCDIR)/../arch/osx-x86-x86_64-ppc-gcc.h" - ;; - *) - ARCH_CONF_HEADER= - ;; -esac +if test x"$with_arch_h" = x""; then + if test x"$cross_compiling" = x"yes"; then + ARCH_CONF_HEADER="\$(GLSRCDIR)/../$ARCH_AUTOCONF_HEADER" + else + case `uname` in + Darwin*) + ARCH_CONF_HEADER="\$(GLSRCDIR)/../arch/osx-x86-x86_64-ppc-gcc.h" + ;; + *) + ARCH_CONF_HEADER= + ;; + esac + fi +else + ARCH_CONF_HEADER=$with_arch_h +fi @@ -3898,14 +4488,15 @@ # CFLAGS="-DDEBUG $CFLAGS" #fi +# NOTE: To correctly disable GCC's strict aliasing with '-fno-strict-aliasing' +# option, the 'cflags_to_try' have to checked after 'optflags_to_try'. { $as_echo "$as_me:${as_lineno-$LINENO}: checking supported compiler flags" >&5 $as_echo_n "checking supported compiler flags... " >&6; } old_cflags=$CFLAGS -echo + for flag in $optflags_to_try; do CFLAGS="$CFLAGS $flag" - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -3948,7 +4539,7 @@ CFLAGS=$old_cflags done old_cflags=$CFLAGS -echo + for flag in $dbgflags_to_try; do CFLAGS="$CFLAGS $flag" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3975,287 +4566,40 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ...done." >&5 $as_echo " ...done." >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler/linker address santizer support" >&5 +$as_echo_n "checking compiler/linker address santizer support... " >&6; } -BIGENDIAN= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for big endian" >&5 -$as_echo_n "checking for big endian... " >&6; } - -# Check whether --enable-big-endian was given. -if test "${enable_big_endian+set}" = set; then : - enableval=$enable_big_endian; BIGENDIAN=1 -fi - - -if test x$BIGENDIAN = x; then - # Check whether --enable-little-endian was given. -if test "${enable_little_endian+set}" = set; then : - enableval=$enable_little_endian; BIGENDIAN=0 -fi +CFLAGS_SANITIZE="" +CFLAGS_SANITIZE_TRY="-fsanitize=address -fno-omit-frame-pointer" +CFLAGS_SAVED="$CFLAGS" +CFLAGS="$CFLAGS_SANITIZE_TRY" -fi -if test x$BIGENDIAN = x ; then - if test "$cross_compiling" = yes; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run test program while cross compiling -See \`config.log' for more details" "$LINENO" 5; } -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { - static const int one = 1; - return (*(char*)&one == 0 ? 0 : 1); + return(0); ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - BIGENDIAN=1;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: big" >&5 -$as_echo "big" >&6; } +if ac_fn_c_try_link "$LINENO"; then : + CFLAGS_SANITIZE="$CFLAGS" else - BIGENDIAN=0;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: little" >&5 -$as_echo "little" >&6; } -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -else - if test x$BIGENDIAN = x1 ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: big" >&5 -$as_echo "big" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: little" >&5 -$as_echo "little" >&6; } - fi -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sse2 support" >&5 -$as_echo_n "checking sse2 support... " >&6; } -save_cflags=$CFLAGS -CFLAGS="$CFLAGS $OPT_CFLAGS" - -HAVE_SSE2="" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ - - __m128i input1; - unsigned char buf1[128]; - input1 = _mm_loadu_si128((const __m128i *)buf1); - return(0); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - HAVE_SSE2="-DHAVE_SSE2" -else - HAVE_SSE2="" + CFLAGS_SANITIZE="****************ADDRESS_SANITIZER_NOT_SUPPORTED*********************" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext -# Check whether --enable-sse2 was given. -if test "${enable_sse2+set}" = set; then : - enableval=$enable_sse2; - if test "x$enable_sse2" = xno; then - HAVE_SSE2="" - fi -fi - - -if test "x$HAVE_SSE2" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -CFLAGS=$save_cflags - - -# Check whether --enable-threadsafe was given. -if test "${enable_threadsafe+set}" = set; then : - enableval=$enable_threadsafe; -fi - -if test x$enable_threadsafe = xyes ; then - CFLAGS="-DGS_THREADSAFE" -fi - - -ac_header_dirent=no -for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do - as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 -$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } -if eval \${$as_ac_Header+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include <$ac_hdr> - -int -main () -{ -if ((DIR *) 0) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$as_ac_Header=yes" -else - eval "$as_ac_Header=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$as_ac_Header - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 -_ACEOF - -ac_header_dirent=$ac_hdr; break -fi - -done -# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. -if test $ac_header_dirent = dirent.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if ${ac_cv_search_opendir+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$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 opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dir; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_opendir+:} false; then : - break -fi -done -if ${ac_cv_search_opendir+:} false; then : - -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if ${ac_cv_search_opendir+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$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 opendir (); -int -main () -{ -return opendir (); - ; - return 0; -} -_ACEOF -for ac_lib in '' x; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_opendir=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_opendir+:} false; then : - break -fi -done -if ${ac_cv_search_opendir+:} false; then : - -else - ac_cv_search_opendir=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } -ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi +CFLAGS="$CFLAGS_SAVED" -fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ...done." >&5 +$as_echo " ...done." >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 @@ -4517,681 +4861,951 @@ done -for ac_header in errno.h fcntl.h limits.h malloc.h memory.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/time.h sys/times.h syslog.h unistd.h dirent.h ndir.h sys/dir.h sys/ndir.h inttypes.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + _ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include -done +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif -OBJDIR_BSDMAKE_WORKAROUND=obj - -case `uname` in - *BSD) - OBJDIR_BSDMAKEWORKAOROUND="notobj" - ;; -esac - - -# for gdev3b1.c (AT&T terminal interface) -ac_fn_c_check_header_mongrel "$LINENO" "sys/window.h" "ac_cv_header_sys_window_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_window_h" = xyes; then : - -fi - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include int main () { +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif -#ifndef __cplusplus - /* Ultrix mips cc rejects this sort of thing. */ - typedef int charset[2]; - const charset cs = { 0, 0 }; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this sort of thing. */ - char tx; - char *t = &tx; - char const *s = 0 ? (char *) 0 : (char const *) 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; } bx; - struct s *b = &bx; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes + ac_cv_c_bigendian=yes else - ac_cv_c_const=no + ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 -$as_echo_n "checking for inline... " >&6; } -if ${ac_cv_c_inline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_inline=$ac_kw + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 -$as_echo "$ac_cv_c_inline" >&6; } + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif + ; + return 0; +} _ACEOF - ;; -esac +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi -ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" -if test "x$ac_cv_type_mode_t" = xyes; then : + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + BIGENDIAN=1;; #( + no) + BIGENDIAN=0 ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac -else -cat >>confdefs.h <<_ACEOF -#define mode_t int -_ACEOF -fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking sse2 support" >&5 +$as_echo_n "checking sse2 support... " >&6; } +save_cflags=$CFLAGS +CFLAGS="$CFLAGS $OPT_CFLAGS" -ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" -if test "x$ac_cv_type_off_t" = xyes; then : +HAVE_SSE2="" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ -else + __m128i input1; + unsigned char buf1[128]; + input1 = _mm_loadu_si128((const __m128i *)buf1); + return(0); -cat >>confdefs.h <<_ACEOF -#define off_t long int + ; + return 0; +} _ACEOF +if ac_fn_c_try_link "$LINENO"; then : + HAVE_SSE2="-DHAVE_SSE2" +else + HAVE_SSE2="" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +# Check whether --enable-sse2 was given. +if test "${enable_sse2+set}" = set; then : + enableval=$enable_sse2; + if test "x$enable_sse2" = xno; then + HAVE_SSE2="" + fi fi -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : +if test "x$HAVE_SSE2" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi -ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLOCKS 1 -_ACEOF +CFLAGS=$save_cflags -$as_echo "#define HAVE_ST_BLOCKS 1" >>confdefs.h -else - case " $LIBOBJS " in - *" fileblocks.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fileblocks.$ac_objext" - ;; -esac +# Check whether --enable-threadsafe was given. +if test "${enable_threadsafe+set}" = set; then : + enableval=$enable_threadsafe; +fi +if test x$enable_threadsafe = xyes ; then + CFLAGS="-DGS_THREADSAFE" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if ${ac_cv_header_time+:} false; then : +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include -#include -#include +#include <$ac_hdr> int main () { -if ((struct tm *) 0) +if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time=yes + eval "$as_ac_Header=yes" else - ac_cv_header_time=no + eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF +ac_header_dirent=$ac_hdr; break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 -$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } -if ${ac_cv_struct_tm+:} false; then : +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include +/* 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 opendir (); int main () { -struct tm tm; - int *p = &tm.tm_sec; - return !p; +return opendir (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_tm=time.h -else - ac_cv_struct_tm=sys/time.h +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 -$as_echo "$ac_cv_struct_tm" >&6; } -if test $ac_cv_struct_tm = sys/time.h; then - -$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h +done +if ${ac_cv_search_opendir+:} false; then : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" +fi -if test "x$ac_cv_header_stdint_h" != xyes; then - ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "#include -" -if test "x$ac_cv_type_int8_t" = xyes; then : +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -cat >>confdefs.h <<_ACEOF -#define HAVE_INT8_T 1 +/* 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 opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} _ACEOF - - +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res fi -ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "#include -" -if test "x$ac_cv_type_int16_t" = xyes; then : +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_INT16_T 1 -_ACEOF +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" +fi fi -ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "#include -" -if test "x$ac_cv_type_int32_t" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_INT32_T 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +int +main () +{ + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no fi -ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "#include -" -if test "x$ac_cv_type_uint8_t" = xyes; then : +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT8_T 1 _ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : +else + ac_cv_header_stdc=no +fi +rm -f conftest* fi -ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "#include -" -if test "x$ac_cv_type_uint16_t" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT16_T 1 +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + _ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : +else + ac_cv_header_stdc=no +fi +rm -f conftest* fi -ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include -" -if test "x$ac_cv_type_uint32_t" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT32_T 1 -_ACEOF +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : +else + ac_cv_header_stdc=no fi - - if test "$ac_cv_type_uint8_t" = yes; then - $as_echo "#define SYS_TYPES_HAS_STDINT_TYPES 1" >>confdefs.h - - GCFLAGS="$GCFLAGS -DSYS_TYPES_HAS_STDINT_TYPES" - fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -if test "$ac_cv_c_const" != yes; then - GCFLAGS="$GCFLAGS -Dconst=" fi -if test "x$ac_cv_header_stdint_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_STDINT_H=1" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then -if test "x$ac_cv_header_dirent_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_DIRENT_H=1" -fi +$as_echo "#define STDC_HEADERS 1" >>confdefs.h -if test "x$ac_cv_header_ndir_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_NDIR_H=1" fi -if test "x$ac_cv_header_sys_dir_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_SYS_DIR_H=1" -fi +for ac_header in errno.h fcntl.h limits.h malloc.h memory.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/time.h sys/times.h syslog.h unistd.h dirent.h ndir.h sys/dir.h sys/ndir.h inttypes.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF -if test "x$ac_cv_header_sys_ndir_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_SYS_NDIR_H=1" fi -if test "x$ac_cv_header_sys_time_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_SYS_TIME_H=1" -fi +done -if test "x$ac_cv_header_sys_times_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_SYS_TIMES_H=1" -fi -if test "x$ac_cv_header_inttypes_h" = xyes; then - GCFLAGS="$GCFLAGS -DHAVE_INTTYPES_H=1" -fi -uint64_type="none" - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long int" >&5 -$as_echo_n "checking size of unsigned long int... " >&6; } -if ${ac_cv_sizeof_unsigned_long_int+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long int))" "ac_cv_sizeof_unsigned_long_int" "$ac_includes_default"; then : +OBJDIR_BSDMAKE_WORKAROUND=obj -else - if test "$ac_cv_type_unsigned_long_int" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (unsigned long int) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_unsigned_long_int=0 - fi -fi +case `uname` in + *BSD) + OBJDIR_BSDMAKEWORKAOROUND="notobj" + ;; +esac -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_int" >&5 -$as_echo "$ac_cv_sizeof_unsigned_long_int" >&6; } +ac_fn_c_check_header_mongrel "$LINENO" "sys/window.h" "ac_cv_header_sys_window_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_window_h" = xyes; then : +fi -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED_LONG_INT $ac_cv_sizeof_unsigned_long_int -_ACEOF - if test $ac_cv_sizeof_unsigned_long_int = 8; then - uint64_type="unsigned long int" - else - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5 -$as_echo_n "checking size of unsigned long long... " >&6; } -if ${ac_cv_sizeof_unsigned_long_long+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_unsigned_long_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (unsigned long long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_unsigned_long_long=0 - fi -fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5 -$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; } +int +main () +{ +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long + ; + return 0; +} _ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then +$as_echo "#define const /**/" >>confdefs.h - if test $ac_cv_sizeof_unsigned_long_long = 8; then - uint64_type="unsigned long long" - else - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned __int64" >&5 -$as_echo_n "checking size of unsigned __int64... " >&6; } -if ${ac_cv_sizeof_unsigned___int64+:} false; then : +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned __int64))" "ac_cv_sizeof_unsigned___int64" "$ac_includes_default"; then : + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif -else - if test "$ac_cv_type_unsigned___int64" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (unsigned __int64) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_unsigned___int64=0 - fi +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned___int64" >&5 -$as_echo "$ac_cv_sizeof_unsigned___int64" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac +ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" +if test "x$ac_cv_type_mode_t" = xyes; then : +else cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED___INT64 $ac_cv_sizeof_unsigned___int64 +#define mode_t int _ACEOF +fi - if test $ac_cv_sizeof_unsigned___int64 = 8; then - uint64_type="unsigned __int64" - else - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of u_int64_t" >&5 -$as_echo_n "checking size of u_int64_t... " >&6; } -if ${ac_cv_sizeof_u_int64_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (u_int64_t))" "ac_cv_sizeof_u_int64_t" "$ac_includes_default"; then : +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = xyes; then : else - if test "$ac_cv_type_u_int64_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (u_int64_t) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_u_int64_t=0 - fi -fi + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_u_int64_t" >&5 -$as_echo "$ac_cv_sizeof_u_int64_t" >&6; } +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : +else cat >>confdefs.h <<_ACEOF -#define SIZEOF_U_INT64_T $ac_cv_sizeof_u_int64_t +#define size_t unsigned int _ACEOF - - if test $ac_cv_sizeof_u_int64_t = 8; then - uint64_type="u_int64_t" - fi - fi - fi - fi -if test "$uint64_type" != "none"; then - GCFLAGS="$GCFLAGS -DGX_COLOR_INDEX_TYPE=\"$uint64_type\"" fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : -SUBCONFIG_OPTS="" - -if test x$build_alias != x; then -SUBCONFIG_OPTS="$SUBCONFIG_OPTS --build=$build_alias" -fi +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 +_ACEOF +$as_echo "#define HAVE_ST_BLOCKS 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 -$as_echo_n "checking for cos in -lm... " >&6; } -if ${ac_cv_lib_m_cos+:} false; then : +else + case " $LIBOBJS " in + *" fileblocks.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS fileblocks.$ac_objext" + ;; +esac + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include +#include +#include -/* 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 cos (); int main () { -return cos (); +if ((struct tm *) 0) +return 0; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_m_cos=yes +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes else - ac_cv_lib_m_cos=no + ac_cv_header_time=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 -$as_echo "$ac_cv_lib_m_cos" >&6; } -if test "x$ac_cv_lib_m_cos" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBM 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then - LIBS="-lm $LIBS" +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi - -SYNC="nosync" -PTHREAD_LIBS="" - -case `uname` in - MINGW*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling support for pthreads......" >&5 -$as_echo "$as_me: WARNING: disabling support for pthreads......" >&2;} - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 -$as_echo_n "checking for pthread_create in -lpthread... " >&6; } -if ${ac_cv_lib_pthread_pthread_create+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if ${ac_cv_struct_tm+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include +#include -/* 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_create (); int main () { -return pthread_create (); +struct tm tm; + int *p = &tm.tm_sec; + return !p; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pthread_pthread_create=yes +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h else - ac_cv_lib_pthread_pthread_create=no + ac_cv_struct_tm=sys/time.h fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 -$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } -if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then - SYNC=posync; - PTHREAD_LIBS="-lpthread" +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h fi - ;; -esac +if test "x$ac_cv_header_stdint_h" != xyes; then + ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "#include +" +if test "x$ac_cv_type_int8_t" = xyes; then : +cat >>confdefs.h <<_ACEOF +#define HAVE_INT8_T 1 +_ACEOF +fi +ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "#include +" +if test "x$ac_cv_type_int16_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT16_T 1 +_ACEOF + -# Check whether --with-libiconv was given. -if test "${with_libiconv+set}" = set; then : - withval=$with_libiconv; -else - with_libiconv=maybe fi +ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "#include +" +if test "x$ac_cv_type_int32_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT32_T 1 +_ACEOF + -found_iconv=no -case $with_libiconv in - maybe) - # Check in the C library first - ac_fn_c_check_func "$LINENO" "iconv_open" "ac_cv_func_iconv_open" -if test "x$ac_cv_func_iconv_open" = xyes; then : - with_libiconv=no; found_iconv=yes fi +ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "#include +" +if test "x$ac_cv_type_uint8_t" = xyes; then : - # Check if we have GNU libiconv - if test $found_iconv = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libiconv_open in -liconv" >&5 -$as_echo_n "checking for libiconv_open in -liconv... " >&6; } -if ${ac_cv_lib_iconv_libiconv_open+:} false; then : +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT8_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "#include +" +if test "x$ac_cv_type_uint16_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT16_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include +" +if test "x$ac_cv_type_uint32_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT32_T 1 +_ACEOF + + +fi + + if test "$ac_cv_type_uint8_t" = yes; then + $as_echo "#define SYS_TYPES_HAS_STDINT_TYPES 1" >>confdefs.h + + GCFLAGS="$GCFLAGS -DSYS_TYPES_HAS_STDINT_TYPES" + fi +fi + +if test "$ac_cv_c_const" != yes; then + GCFLAGS="$GCFLAGS -Dconst=" +fi +if test "x$ac_cv_header_stdint_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_STDINT_H=1" +fi + +if test "x$ac_cv_header_dirent_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_DIRENT_H=1" +fi + +if test "x$ac_cv_header_ndir_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_NDIR_H=1" +fi + +if test "x$ac_cv_header_sys_dir_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_SYS_DIR_H=1" +fi + +if test "x$ac_cv_header_sys_ndir_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_SYS_NDIR_H=1" +fi + +if test "x$ac_cv_header_sys_time_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_SYS_TIME_H=1" +fi + +if test "x$ac_cv_header_sys_times_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_SYS_TIMES_H=1" +fi + +if test "x$ac_cv_header_inttypes_h" = xyes; then + GCFLAGS="$GCFLAGS -DHAVE_INTTYPES_H=1" +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-liconv $LIBS" +LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5201,370 +5815,382 @@ #ifdef __cplusplus extern "C" #endif -char libiconv_open (); +char dlopen (); int main () { -return libiconv_open (); +return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_iconv_libiconv_open=yes + ac_cv_lib_dl_dlopen=yes else - ac_cv_lib_iconv_libiconv_open=no + ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_libiconv_open" >&5 -$as_echo "$ac_cv_lib_iconv_libiconv_open" >&6; } -if test "x$ac_cv_lib_iconv_libiconv_open" = xyes; then : - with_libiconv=gnu; found_iconv=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + GCFLAGS="$GCFLAGS -DHAVE_LIBDL=1";LIBS="-ldl $LIBS" fi - fi - # Check if we have a iconv in -liconv, possibly from vendor - if test $found_iconv = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv_open in -liconv" >&5 -$as_echo_n "checking for iconv_open in -liconv... " >&6; } -if ${ac_cv_lib_iconv_iconv_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-liconv $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 iconv_open (); -int -main () -{ -return iconv_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_iconv_iconv_open=yes -else - ac_cv_lib_iconv_iconv_open=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_iconv_open" >&5 -$as_echo "$ac_cv_lib_iconv_iconv_open" >&6; } -if test "x$ac_cv_lib_iconv_iconv_open" = xyes; then : - with_libiconv=native; found_iconv=yes + fi - fi - ;; - no) - found_iconv=no - ;; - gnu|yes) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libiconv_open in -liconv" >&5 -$as_echo_n "checking for libiconv_open in -liconv... " >&6; } -if ${ac_cv_lib_iconv_libiconv_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-liconv $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 libiconv_open (); -int -main () -{ -return libiconv_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_iconv_libiconv_open=yes -else - ac_cv_lib_iconv_libiconv_open=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_libiconv_open" >&5 -$as_echo "$ac_cv_lib_iconv_libiconv_open" >&6; } -if test "x$ac_cv_lib_iconv_libiconv_open" = xyes; then : - with_libiconv=gnu; found_iconv=yes +large_color_index=1 + + +# Check whether --with-large_color_index was given. +if test "${with_large_color_index+set}" = set; then : + withval=$with_large_color_index; large_color_index="$with_large_color_index" fi - ;; - native) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv_open in -liconv" >&5 -$as_echo_n "checking for iconv_open in -liconv... " >&6; } -if ${ac_cv_lib_iconv_iconv_open+:} false; then : + +if test x"$large_color_index" != "x0"; then + color_ind_type="none" + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5 +$as_echo_n "checking size of unsigned long long... " >&6; } +if ${ac_cv_sizeof_unsigned_long_long+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-liconv $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then : -/* 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 iconv_open (); -int -main () -{ -return iconv_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_iconv_iconv_open=yes else - ac_cv_lib_iconv_iconv_open=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_iconv_open" >&5 -$as_echo "$ac_cv_lib_iconv_iconv_open" >&6; } -if test "x$ac_cv_lib_iconv_iconv_open" = xyes; then : - with_libiconv=native; found_iconv=yes + if test "$ac_cv_type_unsigned_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned long long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_long_long=0 + fi fi - ;; -esac -if test x$found_iconv != xno -a x$with_libiconv != xno ; then - LIBS="$LIBS -liconv" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; } -case $with_libiconv in - gnu) - -$as_echo "#define USE_LIBICONV_GNU 1" >>confdefs.h - - CFLAGS="$CFLAGS -DUSE_LIBICONV_GNU" - ;; - native) - -$as_echo "#define USE_LIBICONV_NATIVE 1" >>confdefs.h - ;; -esac +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long +_ACEOF -# Check whether --with-libidn was given. -if test "${with_libidn+set}" = set; then : - withval=$with_libidn; -else - with_libidn=maybe -fi -if test x$with_libidn != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stringprep in -lidn" >&5 -$as_echo_n "checking for stringprep in -lidn... " >&6; } -if ${ac_cv_lib_idn_stringprep+:} false; then : + if test $ac_cv_sizeof_unsigned_long_long = 8; then + color_ind_type="unsigned long long" + color_ind_size=$ac_cv_sizeof_unsigned_long_long + else + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long int" >&5 +$as_echo_n "checking size of unsigned long int... " >&6; } +if ${ac_cv_sizeof_unsigned_long_int+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lidn $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long int))" "ac_cv_sizeof_unsigned_long_int" "$ac_includes_default"; then : -/* 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 stringprep (); -int -main () -{ -return stringprep (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_idn_stringprep=yes else - ac_cv_lib_idn_stringprep=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + if test "$ac_cv_type_unsigned_long_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned long int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_long_int=0 + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_idn_stringprep" >&5 -$as_echo "$ac_cv_lib_idn_stringprep" >&6; } -if test "x$ac_cv_lib_idn_stringprep" = xyes; then : - with_libidn=no - ac_fn_c_check_header_mongrel "$LINENO" "stringprep.h" "ac_cv_header_stringprep_h" "$ac_includes_default" -if test "x$ac_cv_header_stringprep_h" = xyes; then : - with_libidn=yes fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_int" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long_int" >&6; } -else +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG_INT $ac_cv_sizeof_unsigned_long_int +_ACEOF - if test x$with_libidn != xmaybe; then - as_fn_error $? "libidn not found" "$LINENO" 5 - fi - with_libidn=no -fi + if test $ac_cv_sizeof_unsigned_long_int = 8; then + color_ind_type="unsigned long int" + color_ind_size=$ac_cv_sizeof_unsigned_long_int + else + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned __int64" >&5 +$as_echo_n "checking size of unsigned __int64... " >&6; } +if ${ac_cv_sizeof_unsigned___int64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned __int64))" "ac_cv_sizeof_unsigned___int64" "$ac_includes_default"; then : +else + if test "$ac_cv_type_unsigned___int64" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned __int64) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned___int64=0 + fi fi -HAVE_LIBIDN='' -UTF8DEVS='' -if test x$with_libidn != xno; then - HAVE_LIBIDN=-DHAVE_LIBIDN - LIBS="$LIBS -lidn" - if test x$found_iconv != xno; then - UTF8DEVS='$(PSD)utf8.dev' - fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned___int64" >&5 +$as_echo "$ac_cv_sizeof_unsigned___int64" >&6; } +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED___INT64 $ac_cv_sizeof_unsigned___int64 +_ACEOF -# Check whether --with-libpaper was given. -if test "${with_libpaper+set}" = set; then : - withval=$with_libpaper; -fi -if test x$with_libpaper != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for systempapername in -lpaper" >&5 -$as_echo_n "checking for systempapername in -lpaper... " >&6; } -if ${ac_cv_lib_paper_systempapername+:} false; then : + if test $ac_cv_sizeof_unsigned___int64 = 8; then + color_ind_type="unsigned __int64" + color_ind_size=$ac_cv_sizeof_unsigned___int64 + else + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of u_int64_t" >&5 +$as_echo_n "checking size of u_int64_t... " >&6; } +if ${ac_cv_sizeof_u_int64_t+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpaper $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (u_int64_t))" "ac_cv_sizeof_u_int64_t" "$ac_includes_default"; then : -/* 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 systempapername (); -int -main () -{ -return systempapername (); - ; - return 0; -} +else + if test "$ac_cv_type_u_int64_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (u_int64_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_u_int64_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_u_int64_t" >&5 +$as_echo "$ac_cv_sizeof_u_int64_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_U_INT64_T $ac_cv_sizeof_u_int64_t _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_paper_systempapername=yes + + + if test $ac_cv_sizeof_u_int64_t = 8; then + color_ind_type="u_int64_t" + color_ind_size=$ac_cv_sizeof_u_int64_t + fi + fi + fi + fi else - ac_cv_lib_paper_systempapername=no + color_ind_type="none" + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long int" >&5 +$as_echo_n "checking size of unsigned long int... " >&6; } +if ${ac_cv_sizeof_unsigned_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long int))" "ac_cv_sizeof_unsigned_long_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_unsigned_long_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned long int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_long_int=0 + fi fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_paper_systempapername" >&5 -$as_echo "$ac_cv_lib_paper_systempapername" >&6; } -if test "x$ac_cv_lib_paper_systempapername" = xyes; then : - with_libpaper=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_int" >&5 +$as_echo "$ac_cv_sizeof_unsigned_long_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_LONG_INT $ac_cv_sizeof_unsigned_long_int +_ACEOF + + + if test $ac_cv_sizeof_unsigned_long_int = 4; then + color_ind_type="unsigned long int" + color_ind_size=$ac_cv_sizeof_unsigned_long_int + else + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5 +$as_echo_n "checking size of unsigned int... " >&6; } +if ${ac_cv_sizeof_unsigned_int+:} false; then : + $as_echo_n "(cached) " >&6 else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling support for libpaper" >&5 -$as_echo "$as_me: WARNING: disabling support for libpaper" >&2;} - with_libpaper=no +else + if test "$ac_cv_type_unsigned_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5 +$as_echo "$ac_cv_sizeof_unsigned_int" >&6; } + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int +_ACEOF + + + if test $ac_cv_sizeof_unsigned_int = 4; then + color_ind_type="unsigned int" + color_ind_size=$ac_cv_sizeof_unsigned_int + else + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned __int32" >&5 +$as_echo_n "checking size of unsigned __int32... " >&6; } +if ${ac_cv_sizeof_unsigned___int32+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned __int32))" "ac_cv_sizeof_unsigned___int32" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_unsigned___int32" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (unsigned __int32) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_unsigned___int32=0 + fi fi fi -if test x$with_libpaper != xno; then - ac_fn_c_check_header_mongrel "$LINENO" "paper.h" "ac_cv_header_paper_h" "$ac_includes_default" -if test "x$ac_cv_header_paper_h" = xyes; then : - with_libpaper=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned___int32" >&5 +$as_echo "$ac_cv_sizeof_unsigned___int32" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_UNSIGNED___INT32 $ac_cv_sizeof_unsigned___int32 +_ACEOF + + + if test $ac_cv_sizeof_unsigned___int32 = 4; then + color_ind_type="unsigned __int32" + color_in_size=$ac_cv_sizeof_unsigned___int32 + else + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of u_int32_t" >&5 +$as_echo_n "checking size of u_int32_t... " >&6; } +if ${ac_cv_sizeof_u_int32_t+:} false; then : + $as_echo_n "(cached) " >&6 else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (u_int32_t))" "ac_cv_sizeof_u_int32_t" "$ac_includes_default"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling support for libpaper" >&5 -$as_echo "$as_me: WARNING: disabling support for libpaper" >&2;} - with_libpaper=no +else + if test "$ac_cv_type_u_int32_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (u_int32_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_u_int32_t=0 + fi +fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_u_int32_t" >&5 +$as_echo "$ac_cv_sizeof_u_int32_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_U_INT32_T $ac_cv_sizeof_u_int32_t +_ACEOF + if test $ac_cv_sizeof_u_int32_t = 4; then + color_ind_type="u_int32_t" + color_ind_size=$ac_cv_sizeof_u_int32_t + fi + fi + fi + fi fi -if test x$with_libpaper != xno; then - LIBS="$LIBS -lpaper" +if test "$color_ind_type" != "none"; then + GCFLAGS="$GCFLAGS -DGX_COLOR_INDEX_TYPE=\"$color_ind_type\"" + ARCH_SIZEOF_GX_COLOR_INDEX=$color_ind_size +fi -$as_echo "#define USE_LIBPAPER 1" >>confdefs.h - CFLAGS="$CFLAGS -DUSE_LIBPAPER" + + + + +SUBCONFIG_OPTS="" + +if test x"$build_alias" != x""; then + SUBCONFIG_OPTS="$SUBCONFIG_OPTS --build=$build_alias" fi -HAVE_FONTCONFIG="" -FONTCONFIG_CFLAGS="" -FONTCONFIG_LIBS="" -# Check whether --enable-fontconfig was given. -if test "${enable_fontconfig+set}" = set; then : - enableval=$enable_fontconfig; +if test x"$host_alias" != x""; then + SUBCONFIG_OPTS="$SUBCONFIG_OPTS --host=$host_alias" fi -if test "$enable_fontconfig" != "no"; then - # We MUST NOT use PKG_CHECK_MODULES since it is a) not a standard - # autoconf macro and b) requires pkg-config on the system, which is - # NOT standard on ANY OS, including Linux! - if test "x$PKGCONFIG" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fontconfig with pkg-config" >&5 -$as_echo_n "checking for fontconfig with pkg-config... " >&6; } - if $PKGCONFIG --exists fontconfig; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - FONTCONFIG_CFLAGS="$CFLAGS `$PKGCONFIG --cflags fontconfig`" - FONTCONFIG_LIBS="`$PKGCONFIG --libs fontconfig`" - HAVE_FONTCONFIG=-DHAVE_FONTCONFIG - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - fi - if test -z "$HAVE_FONTCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FcInitLoadConfigAndFonts in -lfontconfig" >&5 -$as_echo_n "checking for FcInitLoadConfigAndFonts in -lfontconfig... " >&6; } -if ${ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts+:} false; then : + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 +$as_echo_n "checking for cos in -lm... " >&6; } +if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lfontconfig $LIBS" +LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5574,77 +6200,122 @@ #ifdef __cplusplus extern "C" #endif -char FcInitLoadConfigAndFonts (); +char cos (); int main () { -return FcInitLoadConfigAndFonts (); +return cos (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts=yes + ac_cv_lib_m_cos=yes else - ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts=no + ac_cv_lib_m_cos=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts" >&5 -$as_echo "$ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts" >&6; } -if test "x$ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts" = xyes; then : - - ac_fn_c_check_header_mongrel "$LINENO" "fontconfig/fontconfig.h" "ac_cv_header_fontconfig_fontconfig_h" "$ac_includes_default" -if test "x$ac_cv_header_fontconfig_fontconfig_h" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 +$as_echo "$ac_cv_lib_m_cos" >&6; } +if test "x$ac_cv_lib_m_cos" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF - FONTCONFIG_LIBS="-lfontconfig" - HAVE_FONTCONFIG="-DHAVE_FONTCONFIG" + LIBS="-lm $LIBS" fi - +for ac_func in pread pwrite +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + HAVE_PREAD_PWRITE="-DHAVE_PREAD_PWRITE=1" +else + HAVE_PREAD_PWRITE= fi +done - fi + +if test "x$HAVE_PREAD_PWRITE" != "x"; then + save_cflags=$CFLAGS + CFLAGS="$CFLAGS -D__USE_UNIX98=1 -D_XOPEN_SOURCE=500" + ac_fn_c_check_decl "$LINENO" "pwrite" "ac_cv_have_decl_pwrite" "$ac_includes_default" +if test "x$ac_cv_have_decl_pwrite" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 fi +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PWRITE $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : +else + HAVE_PREAD_PWRITE= +fi +ac_fn_c_check_decl "$LINENO" "pread" "ac_cv_have_decl_pread" "$ac_includes_default" +if test "x$ac_cv_have_decl_pread" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PREAD $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : -HAVE_DBUS="" -DBUS_CFLAGS="" -DBUS_LIBS="" -# Check whether --enable-dbus was given. -if test "${enable_dbus+set}" = set; then : - enableval=$enable_dbus; +else + HAVE_PREAD_PWRITE= fi -if test "$enable_dbus" != "no"; then - if test "x$PKGCONFIG" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbus with pkg-config" >&5 -$as_echo_n "checking for dbus with pkg-config... " >&6; } - if $PKGCONFIG --exists dbus-1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - DBUS_CFLAGS="$CFLAGS `$PKGCONFIG --cflags dbus-1`" - DBUS_LIBS="`$PKGCONFIG --libs dbus-1`" - HAVE_DBUS=-DHAVE_DBUS - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - fi - if test -z "$HAVE_DBUS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbus_message_iter_get_basic in -ldbus" >&5 -$as_echo_n "checking for dbus_message_iter_get_basic in -ldbus... " >&6; } -if ${ac_cv_lib_dbus_dbus_message_iter_get_basic+:} false; then : + CFLAGS=$save_cflags + if test "x$HAVE_PREAD_PWRITE" != "x"; then + GCFLAGS="$GCFLAGS -D__USE_UNIX98=1" + fi +fi + + + +ac_fn_c_check_decl "$LINENO" "popen" "ac_cv_have_decl_popen" "$ac_includes_default" +if test "x$ac_cv_have_decl_popen" = xyes; then : + HAVE_POPEN_PROTO="-DHAVE_POPEN_PROTO=1" +else + AVE_POPEN_PROTO= +fi + + + +SYNC="nosync" +PTHREAD_LIBS="" +RECURSIVE_MUTEXATTR="" + +# Check whether --enable-threading was given. +if test "${enable_threading+set}" = set; then : + enableval=$enable_threading; +fi + + +# if you haven't got pread/pwrite, we can't use multithreading +if test "x$HAVE_PREAD_PWRITE" != "x"; then + if test "$enable_threading" != "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +$as_echo_n "checking for pthread_create in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-ldbus $LIBS" +LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5654,53 +6325,121 @@ #ifdef __cplusplus extern "C" #endif -char dbus_message_iter_get_basic (); +char pthread_create (); int main () { -return dbus_message_iter_get_basic (); +return pthread_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dbus_dbus_message_iter_get_basic=yes + ac_cv_lib_pthread_pthread_create=yes else - ac_cv_lib_dbus_dbus_message_iter_get_basic=no + ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dbus_dbus_message_iter_get_basic" >&5 -$as_echo "$ac_cv_lib_dbus_dbus_message_iter_get_basic" >&6; } -if test "x$ac_cv_lib_dbus_dbus_message_iter_get_basic" = xyes; then : - - ac_fn_c_check_header_mongrel "$LINENO" "dbus-1.0/dbus/dbus.h" "ac_cv_header_dbus_1_0_dbus_dbus_h" "$ac_includes_default" -if test "x$ac_cv_header_dbus_1_0_dbus_dbus_h" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : - DBUS_LIBS="-ldbus-1 -lpthread -lrt" - HAVE_DBUS="-DHAVE_DBUS" + SYNC=posync; + PTHREAD_LIBS="-lpthread" fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking recursive mutexes......." >&5 +$as_echo_n "checking recursive mutexes.......... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + static int k = PTHREAD_MUTEX_RECURSIVE; + #ifndef pthread_mutexattr_settype + #ifdef __cplusplus + (void) pthread_mutexattr_settype; + #else + (void) pthread_mutexattr_settype; + #endif + #endif + ; + return 0; -fi + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ - fi + static int k = PTHREAD_MUTEX_RECURSIVE_NP; + #ifndef pthread_mutexattr_settype + #ifdef __cplusplus + (void) pthread_mutexattr_settype; + #else + (void) pthread_mutexattr_settype; + #endif + #endif + ; + return 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE_NP" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : + + +# Check whether --with-libiconv was given. +if test "${with_libiconv+set}" = set; then : + withval=$with_libiconv; +else + with_libiconv=maybe +fi + +found_iconv=no +case $with_libiconv in + maybe) + # Check in the C library first + ac_fn_c_check_func "$LINENO" "iconv_open" "ac_cv_func_iconv_open" +if test "x$ac_cv_func_iconv_open" = xyes; then : + with_libiconv=no; found_iconv=yes +fi + + # Check if we have GNU libiconv + if test $found_iconv = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libiconv_open in -liconv" >&5 +$as_echo_n "checking for libiconv_open in -liconv... " >&6; } +if ${ac_cv_lib_iconv_libiconv_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" +LIBS="-liconv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5710,194 +6449,88 @@ #ifdef __cplusplus extern "C" #endif -char dlopen (); +char libiconv_open (); int main () { -return dlopen (); +return libiconv_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes + ac_cv_lib_iconv_libiconv_open=yes else - ac_cv_lib_dl_dlopen=no + ac_cv_lib_iconv_libiconv_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDL 1 -_ACEOF - - LIBS="-ldl $LIBS" - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_libiconv_open" >&5 +$as_echo "$ac_cv_lib_iconv_libiconv_open" >&6; } +if test "x$ac_cv_lib_iconv_libiconv_open" = xyes; then : + with_libiconv=gnu; found_iconv=yes fi + fi + # Check if we have a iconv in -liconv, possibly from vendor + if test $found_iconv = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv_open in -liconv" >&5 +$as_echo_n "checking for iconv_open in -liconv... " >&6; } +if ${ac_cv_lib_iconv_iconv_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-liconv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -# Check whether --enable-freetype was given. -if test "${enable_freetype+set}" = set; then : - enableval=$enable_freetype; +/* 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 iconv_open (); +int +main () +{ +return iconv_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_iconv_iconv_open=yes +else + ac_cv_lib_iconv_iconv_open=no fi - - -FT_BRIDGE=0 -SHARE_FT=0 -FTSRCDIR= -FT_CFLAGS= -FT_LIBS= - -INSERT_UFST_BRIDGE_EQUAL_ONE= -UFST_ROOT= -UFST_CFLAGS= -UFST_LIB_EXT= -FAPIUFST_MAK="\$(GLSRCDIR)/stub.mak" - -# Check whether --enable-fapi was given. -if test "${enable_fapi+set}" = set; then : - enableval=$enable_fapi; +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi - - -if test x"$enable_fapi" != xno; then - - -# Check whether --with-ufst was given. -if test "${with_ufst+set}" = set; then : - withval=$with_ufst; -else - with_ufst=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_iconv_open" >&5 +$as_echo "$ac_cv_lib_iconv_iconv_open" >&6; } +if test "x$ac_cv_lib_iconv_iconv_open" = xyes; then : + with_libiconv=native; found_iconv=yes fi - - if test x"$with_ufst" != xno; then - if test -d $with_ufst; then - INSERT_UFST_BRIDGE_EQUAL_ONE="UFST_BRIDGE=1" - case $with_ufst in - /*) UFST_ROOT=$with_ufst ;; - *) UFST_ROOT=`pwd`/$with_ufst ;; - esac - - FAPIUFST_MAK="\$(UFST_ROOT)/fapiufst.mak" - - if ! test -f $UFST_ROOT/fapiufst.mak ; then - echo $UFST_ROOT/fapiufst.mak - as_fn_error $? "UFST: fapiufst.mak not found" "$LINENO" 5 - fi - - # Check pointer size - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char*" >&5 -$as_echo_n "checking size of char*... " >&6; } -if ${ac_cv_sizeof_charp+:} false; then : + fi + ;; + no) + found_iconv=no + ;; + gnu|yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libiconv_open in -liconv" >&5 +$as_echo_n "checking for libiconv_open in -liconv... " >&6; } +if ${ac_cv_lib_iconv_libiconv_open+:} false; then : $as_echo_n "(cached) " >&6 else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char*))" "ac_cv_sizeof_charp" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_charp" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (char*) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_charp=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_charp" >&5 -$as_echo "$ac_cv_sizeof_charp" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_CHARP $ac_cv_sizeof_charp -_ACEOF - - - - # UFST 5.x uses strcmpi() but on GNU systems the equivalent is - # strcasecmp() - if test "x$ac_cv_sizeof_charp" = "x8"; then - UFST_CFLAGS="-DGCCx86_64 -DO_BINARY=0 -Dstrcmpi=strcasecmp" - else - if test "x$ac_cv_sizeof_charp" = "x4"; then - UFST_CFLAGS="-DGCCx86 -DO_BINARY=0 -Dstrcmpi=strcasecmp" - fi - fi - - UFST_LIB_EXT=.a - else - as_fn_error $? "UFST source directory not found" "$LINENO" 5 - fi - fi - - if test x"$enable_freetype" != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local freetype library source" >&5 -$as_echo_n "checking for local freetype library source... " >&6; } - for dir in $srccdir/freetype2 $srcdir/freetype; do - if test -f $dir/src/base/ftbbox.c; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SHARE_FT=0 - FTSRCDIR="$dir" - FT_CFLAGS="-I$dir/include" - FT_BRIDGE=1 - break; - fi - done - - if test -z $FTSRCDIR; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - if test "x$PKGCONFIG" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system freetype2 >= 2.4.2 with pkg-config" >&5 -$as_echo_n "checking for system freetype2 >= 2.4.2 with pkg-config... " >&6; } - # pkg-config needs the libtool version, which != the freetype2 version - # There is a table of corresponding ft2<->libtool numbers in freetype/docs/VERSION.DLL - if $PKGCONFIG --atleast-version=12.0.6 freetype2; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - FT_CFLAGS="$CFLAGS `$PKGCONFIG --cflags freetype2`" - FT_LIBS="`$PKGCONFIG --libs freetype2`" - FT_BRIDGE=1 - SHARE_FT=1 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: freetype library source not found...using native rasterizer" >&5 -$as_echo "$as_me: WARNING: freetype library source not found...using native rasterizer" >&2;} - AFS=1 - fi - else - ac_fn_c_check_header_mongrel "$LINENO" "ft2build.h" "ac_cv_header_ft2build_h" "$ac_includes_default" -if test "x$ac_cv_header_ft2build_h" = xyes; then : - FT_BRIDGE=1 -else - AFS=1 -fi - - - - if test "x$FT_BRIDGE" = x1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 -$as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } -if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lfreetype $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + ac_check_lib_save_LIBS=$LIBS +LIBS="-liconv $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 @@ -5905,110 +6538,108 @@ #ifdef __cplusplus extern "C" #endif -char FT_Init_FreeType (); +char libiconv_open (); int main () { -return FT_Init_FreeType (); +return libiconv_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_freetype_FT_Init_FreeType=yes + ac_cv_lib_iconv_libiconv_open=yes else - ac_cv_lib_freetype_FT_Init_FreeType=no + ac_cv_lib_iconv_libiconv_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 -$as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } -if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : - FT_BRIDGE=1 -else - FT_BRIDGE=0; AFS=1 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_libiconv_open" >&5 +$as_echo "$ac_cv_lib_iconv_libiconv_open" >&6; } +if test "x$ac_cv_lib_iconv_libiconv_open" = xyes; then : + with_libiconv=gnu; found_iconv=yes fi - - if test "x$FT_BRIDGE" = x1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system freetype2 library >= 2.4.2" >&5 -$as_echo_n "checking for system freetype2 library >= 2.4.2... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ;; + native) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv_open in -liconv" >&5 +$as_echo_n "checking for iconv_open in -liconv... " >&6; } +if ${ac_cv_lib_iconv_iconv_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-liconv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include "ft2build.h" - #include FT_FREETYPE_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 iconv_open (); int main () { - - #if FREETYPE_MAJOR < 2 - FAIL - #endif - #if FREETYPE_MINOR < 4 - FAIL - #endif - #if FREETYPE_PATCH < 2 - FAIL - #endif - return(0); - +return iconv_open (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - FT_BRIDGE=1;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_iconv_iconv_open=yes else - FT_BRIDGE=0; AFS=1;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + ac_cv_lib_iconv_iconv_open=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - fi - - fi - fi - fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_iconv_open" >&5 +$as_echo "$ac_cv_lib_iconv_iconv_open" >&6; } +if test "x$ac_cv_lib_iconv_iconv_open" = xyes; then : + with_libiconv=native; found_iconv=yes fi + ;; +esac +if test x$found_iconv != xno -a x$with_libiconv != xno ; then + LIBS="$LIBS -liconv" +fi +case $with_libiconv in + gnu) +$as_echo "#define USE_LIBICONV_GNU 1" >>confdefs.h + CFLAGS="$CFLAGS -DUSE_LIBICONV_GNU" + ;; + native) +$as_echo "#define USE_LIBICONV_NATIVE 1" >>confdefs.h + ;; +esac - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for local jpeg library source" >&5 -$as_echo_n "checking for local jpeg library source... " >&6; } -LIBJPEGDIR=src -if test -f $srcdir/jpeg/jpeglib.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: jpeg" >&5 -$as_echo "jpeg" >&6; } - SHARE_LIBJPEG=0 - LIBJPEGDIR=$srcdir/jpeg -elif test -f $srcdir/jpeg-6b/jpeglib.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: jpeg-6b" >&5 -$as_echo "jpeg-6b" >&6; } - SHARE_LIBJPEG=0 - LIBJPEGDIR=$srcdir/jpeg-6b +# Check whether --with-libidn was given. +if test "${with_libidn+set}" = set; then : + withval=$with_libidn; else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_set_defaults in -ljpeg" >&5 -$as_echo_n "checking for jpeg_set_defaults in -ljpeg... " >&6; } -if ${ac_cv_lib_jpeg_jpeg_set_defaults+:} false; then : + with_libidn=maybe +fi + +if test x$with_libidn != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stringprep in -lidn" >&5 +$as_echo_n "checking for stringprep in -lidn... " >&6; } +if ${ac_cv_lib_idn_stringprep+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-ljpeg $LIBS" +LIBS="-lidn $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6018,90 +6649,73 @@ #ifdef __cplusplus extern "C" #endif -char jpeg_set_defaults (); +char stringprep (); int main () { -return jpeg_set_defaults (); +return stringprep (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_jpeg_jpeg_set_defaults=yes + ac_cv_lib_idn_stringprep=yes else - ac_cv_lib_jpeg_jpeg_set_defaults=no + ac_cv_lib_idn_stringprep=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_set_defaults" >&5 -$as_echo "$ac_cv_lib_jpeg_jpeg_set_defaults" >&6; } -if test "x$ac_cv_lib_jpeg_jpeg_set_defaults" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_idn_stringprep" >&5 +$as_echo "$ac_cv_lib_idn_stringprep" >&6; } +if test "x$ac_cv_lib_idn_stringprep" = xyes; then : - for ac_header in jpeglib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" -if test "x$ac_cv_header_jpeglib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_JPEGLIB_H 1 -_ACEOF - SHARE_LIBJPEG=1 + with_libidn=no + ac_fn_c_check_header_mongrel "$LINENO" "stringprep.h" "ac_cv_header_stringprep_h" "$ac_includes_default" +if test "x$ac_cv_header_stringprep_h" = xyes; then : + with_libidn=yes fi -done -fi +else -fi -if test -z "$SHARE_LIBJPEG"; then - as_fn_error $? "I wasn't able to find a copy - of the jpeg library. This is required for compiling - ghostscript. Please download a copy of the source, - e.g. from http://www.ijg.org/, unpack it at the - top level of the gs source tree, and rename - the directory to 'jpeg'. - " "$LINENO" 5 -fi + if test x$with_libidn != xmaybe; then + as_fn_error $? "libidn not found" "$LINENO" 5 + fi + with_libidn=no +fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for jmemsys.h" >&5 -$as_echo_n "checking for jmemsys.h... " >&6; } -if test -r $LIBJPEGDIR/jmemsys.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -$as_echo "#define DONT_HAVE_JMEMSYS_H 1" >>confdefs.h +fi +HAVE_LIBIDN='' +UTF8DEVS='' +if test x$with_libidn != xno; then + HAVE_LIBIDN=-DHAVE_LIBIDN + LIBS="$LIBS -lidn" + if test x$found_iconv != xno; then + UTF8DEVS='$(PSD)utf8.dev' + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for local zlib source" >&5 -$as_echo_n "checking for local zlib source... " >&6; } -# we must define ZLIBDIR regardless because png.mak does a -I$(ZLIBDIR) -# this seems a harmless default -ZLIBDIR=src -AUX_SHARED_ZLIB= -if test -d $srcdir/zlib; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SHARE_ZLIB=0 - ZLIBDIR=$srcdir/zlib -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5 -$as_echo_n "checking for deflate in -lz... " >&6; } -if ${ac_cv_lib_z_deflate+:} false; then : + + +# Check whether --with-libpaper was given. +if test "${with_libpaper+set}" = set; then : + withval=$with_libpaper; +fi + +if test x$with_libpaper != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for systempapername in -lpaper" >&5 +$as_echo_n "checking for systempapername in -lpaper... " >&6; } +if ${ac_cv_lib_paper_systempapername+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" +LIBS="-lpaper $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6111,87 +6725,94 @@ #ifdef __cplusplus extern "C" #endif -char deflate (); +char systempapername (); int main () { -return deflate (); +return systempapername (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_z_deflate=yes + ac_cv_lib_paper_systempapername=yes else - ac_cv_lib_z_deflate=no + ac_cv_lib_paper_systempapername=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5 -$as_echo "$ac_cv_lib_z_deflate" >&6; } -if test "x$ac_cv_lib_z_deflate" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_paper_systempapername" >&5 +$as_echo "$ac_cv_lib_paper_systempapername" >&6; } +if test "x$ac_cv_lib_paper_systempapername" = xyes; then : + with_libpaper=yes +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling support for libpaper" >&5 +$as_echo "$as_me: WARNING: disabling support for libpaper" >&2;} + with_libpaper=no - for ac_header in zlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ZLIB_H 1 -_ACEOF - SHARE_ZLIB=1; AUX_SHARED_ZLIB="-l\$(ZLIB_NAME)" fi -done +fi +if test x$with_libpaper != xno; then + ac_fn_c_check_header_mongrel "$LINENO" "paper.h" "ac_cv_header_paper_h" "$ac_includes_default" +if test "x$ac_cv_header_paper_h" = xyes; then : + with_libpaper=yes +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling support for libpaper" >&5 +$as_echo "$as_me: WARNING: disabling support for libpaper" >&2;} + with_libpaper=no fi -fi -if test -z "$SHARE_ZLIB"; then - as_fn_error $? "I did not find a copy of zlib on your system. - Please either install it, or unpack a copy of the source in a - local directory named 'zlib'. See http://www.gzip.org/zlib/ - for more information. - " "$LINENO" 5 -fi -FT_SYS_ZLIB="" -if test x$FT_BRIDGE != x0; then - if test xx$SHARE_FT != x1; then - if test x$SHARE_ZLIB != x0; then - FT_SYS_ZLIB="-DFT_CONFIG_OPTION_SYSTEM_ZLIB" - fi - fi fi +if test x$with_libpaper != xno; then + LIBS="$LIBS -lpaper" +$as_echo "#define USE_LIBPAPER 1" >>confdefs.h + CFLAGS="$CFLAGS -DUSE_LIBPAPER" +fi +HAVE_FONTCONFIG="" +FONTCONFIG_CFLAGS="" +FONTCONFIG_LIBS="" +# Check whether --enable-fontconfig was given. +if test "${enable_fontconfig+set}" = set; then : + enableval=$enable_fontconfig; +fi - -LIBPNGDIR=src -PNGDEVS='' -PNGDEVS_ALL='png48 png16m pnggray pngmono png256 png16 pngalpha' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for local png library source" >&5 -$as_echo_n "checking for local png library source... " >&6; } -if test -f $srcdir/libpng/pngread.c; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +if test "$enable_fontconfig" != "no"; then + # We MUST NOT use PKG_CHECK_MODULES since it is a) not a standard + # autoconf macro and b) requires pkg-config on the system, which is + # NOT standard on ANY OS, including Linux! + if test "x$PKGCONFIG" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fontconfig with pkg-config" >&5 +$as_echo_n "checking for fontconfig with pkg-config... " >&6; } + if $PKGCONFIG --exists fontconfig; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - SHARE_LIBPNG=0 - LIBPNGDIR=$srcdir/libpng - PNGDEVS="$PNGDEVS_ALL" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + FONTCONFIG_CFLAGS="$CFLAGS `$PKGCONFIG --cflags fontconfig`" + FONTCONFIG_LIBS="`$PKGCONFIG --libs fontconfig`" + HAVE_FONTCONFIG=-DHAVE_FONTCONFIG + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_create_write_struct in -lpng" >&5 -$as_echo_n "checking for png_create_write_struct in -lpng... " >&6; } -if ${ac_cv_lib_png_png_create_write_struct+:} false; then : + fi + fi + if test -z "$HAVE_FONTCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FcInitLoadConfigAndFonts in -lfontconfig" >&5 +$as_echo_n "checking for FcInitLoadConfigAndFonts in -lfontconfig... " >&6; } +if ${ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lpng -lz $LIBS" +LIBS="-lfontconfig $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6201,89 +6822,77 @@ #ifdef __cplusplus extern "C" #endif -char png_create_write_struct (); +char FcInitLoadConfigAndFonts (); int main () { -return png_create_write_struct (); +return FcInitLoadConfigAndFonts (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_png_png_create_write_struct=yes + ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts=yes else - ac_cv_lib_png_png_create_write_struct=no + ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_create_write_struct" >&5 -$as_echo "$ac_cv_lib_png_png_create_write_struct" >&6; } -if test "x$ac_cv_lib_png_png_create_write_struct" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts" >&5 +$as_echo "$ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts" >&6; } +if test "x$ac_cv_lib_fontconfig_FcInitLoadConfigAndFonts" = xyes; then : - for ac_header in png.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default" -if test "x$ac_cv_header_png_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_PNG_H 1 -_ACEOF + ac_fn_c_check_header_mongrel "$LINENO" "fontconfig/fontconfig.h" "ac_cv_header_fontconfig_fontconfig_h" "$ac_includes_default" +if test "x$ac_cv_header_fontconfig_fontconfig_h" = xyes; then : - SHARE_LIBPNG=1 - PNGDEVS="$PNGDEVS_ALL" + FONTCONFIG_LIBS="-lfontconfig" + HAVE_FONTCONFIG="-DHAVE_FONTCONFIG" -else - SHARE_LIBPNG=0 fi -done -else - SHARE_LIBPNG=0 fi + fi fi -if test -z "$PNGDEVS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: disabling png output devices" >&5 -$as_echo "$as_me: disabling png output devices" >&6;} -fi - -#AC_SUBST(PNGDEVS) -WHICHLCMS= -# Check whether --with-lcms was given. -if test "${with_lcms+set}" = set; then : - withval=$with_lcms; +HAVE_DBUS="" +DBUS_CFLAGS="" +DBUS_LIBS="" +# Check whether --enable-dbus was given. +if test "${enable_dbus+set}" = set; then : + enableval=$enable_dbus; fi - -if test x$with_lcms != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local lcms2 library source" >&5 -$as_echo_n "checking for local lcms2 library source... " >&6; } - LCMS2DIR=$srcdir/lcms2 - if test -f $LCMS2DIR/include/lcms2.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +if test "$enable_dbus" != "no"; then + if test "x$PKGCONFIG" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbus with pkg-config" >&5 +$as_echo_n "checking for dbus with pkg-config... " >&6; } + if $PKGCONFIG --exists dbus-1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - SHARELCMS=0 - WHICHLCMS=lcms2 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + DBUS_CFLAGS="$CFLAGS `$PKGCONFIG --cflags dbus-1`" + DBUS_LIBS="`$PKGCONFIG --libs dbus-1`" + HAVE_DBUS=-DHAVE_DBUS + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system lcms2 library" >&5 -$as_echo_n "checking for system lcms2 library... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cmsGetTransformOutputFormat in -llcms2" >&5 -$as_echo_n "checking for cmsGetTransformOutputFormat in -llcms2... " >&6; } -if ${ac_cv_lib_lcms2_cmsGetTransformOutputFormat+:} false; then : + fi + fi + if test -z "$HAVE_DBUS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbus_message_iter_get_basic in -ldbus" >&5 +$as_echo_n "checking for dbus_message_iter_get_basic in -ldbus... " >&6; } +if ${ac_cv_lib_dbus_dbus_message_iter_get_basic+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-llcms2 $LIBS" +LIBS="-ldbus $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6293,199 +6902,212 @@ #ifdef __cplusplus extern "C" #endif -char cmsGetTransformOutputFormat (); +char dbus_message_iter_get_basic (); int main () { -return cmsGetTransformOutputFormat (); +return dbus_message_iter_get_basic (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lcms2_cmsGetTransformOutputFormat=yes + ac_cv_lib_dbus_dbus_message_iter_get_basic=yes else - ac_cv_lib_lcms2_cmsGetTransformOutputFormat=no + ac_cv_lib_dbus_dbus_message_iter_get_basic=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lcms2_cmsGetTransformOutputFormat" >&5 -$as_echo "$ac_cv_lib_lcms2_cmsGetTransformOutputFormat" >&6; } -if test "x$ac_cv_lib_lcms2_cmsGetTransformOutputFormat" = xyes; then : - - for ac_header in lcms2.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "lcms2.h" "ac_cv_header_lcms2_h" "$ac_includes_default" -if test "x$ac_cv_header_lcms2_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LCMS2_H 1 -_ACEOF - LCMS2DIR="";SHARELCMS=1;WHICHLCMS=lcms2 -fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dbus_dbus_message_iter_get_basic" >&5 +$as_echo "$ac_cv_lib_dbus_dbus_message_iter_get_basic" >&6; } +if test "x$ac_cv_lib_dbus_dbus_message_iter_get_basic" = xyes; then : -done + ac_fn_c_check_header_mongrel "$LINENO" "dbus-1.0/dbus/dbus.h" "ac_cv_header_dbus_1_0_dbus_dbus_h" "$ac_includes_default" +if test "x$ac_cv_header_dbus_1_0_dbus_dbus_h" = xyes; then : + DBUS_LIBS="-ldbus-1 -lpthread -lrt" + HAVE_DBUS="-DHAVE_DBUS" fi - if test x$WHICHLCMS = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: lcms2 not found, or too old" >&5 -$as_echo "$as_me: WARNING: lcms2 not found, or too old" >&2;} - fi - fi -fi -if test x$WHICHLCMS = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local lcms library source" >&5 -$as_echo_n "checking for local lcms library source... " >&6; } - LCMSDIR=$srcdir/lcms - SHARELCMS=0 - if test -f $LCMSDIR/include/lcms.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SHARELCMS=0 - WHICHLCMS=lcms - else - as_fn_error $? "LittleCMS source not found!" "$LINENO" 5 - #AC_CHECK_LIB(lcms, cmsCreateXYZProfile, [ - # AC_CHECK_HEADERS([lcms.h], [SHARELCMS=1;LCMSDIR=""]) - # ]) - fi fi + fi +fi +# Check whether --enable-freetype was given. +if test "${enable_freetype+set}" = set; then : + enableval=$enable_freetype; +fi -# Check whether --with-system-libtiff was given. -if test "${with_system_libtiff+set}" = set; then : - withval=$with_system_libtiff; + +FT_BRIDGE=0 +SHARE_FT=0 +FTSRCDIR=src +FT_CFLAGS= +FT_LIBS= + +INSERT_UFST_BRIDGE_EQUAL_ONE= +UFST_ROOT= +UFST_CFLAGS= +UFST_LIB_EXT= +FAPIUFST_MAK="\$(GLSRCDIR)\$(D)stub.mak" + +# Check whether --enable-fapi was given. +if test "${enable_fapi+set}" = set; then : + enableval=$enable_fapi; +fi + + +if test x"$enable_fapi" != xno; then + + +# Check whether --with-ufst was given. +if test "${with_ufst+set}" = set; then : + withval=$with_ufst; else - with_system_libtiff=check + with_ufst=no fi -TIFFDEVS='' -FAX_DEVS='' -LIBTIFFDIR='' -LIBTIFFCONFDIR='' + if test x"$with_ufst" != xno; then + if test -d $with_ufst; then + INSERT_UFST_BRIDGE_EQUAL_ONE="UFST_BRIDGE=1" + case $with_ufst in + /*) UFST_ROOT=$with_ufst ;; + *) UFST_ROOT=`pwd`/$with_ufst ;; + esac -TIFFDEVS_ALL='tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled' -FAX_DEVS_ALL='cfax dfaxlow dfaxhigh fax faxg3 faxg32d faxg4 tiffg3 tiffg32d tiffg4 tfax' -case "x$with_system_libtiff" in - xcheck) - if test -d $srcdir/tiff; then - LIBTIFFDIR=$srcdir/tiff - LIBTIFFCONFDIR=tiff-config - HAVE_LOCAL_LIBTIFF=1 - SHARE_LIBTIFF=0 - else - # We MUST NOT use PKG_CHECK_MODULES since it is a) not a standard - # autoconf macro and b) requires pkg-config on the system, which is - # NOT standard on ANY OS, including Linux! - if test "x$PKGCONFIG" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtiff with pkg-config" >&5 -$as_echo_n "checking for libtiff with pkg-config... " >&6; } - if $PKGCONFIG --exists libtiff-4; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - CFLAGS="$CFLAGS `$PKGCONFIG --cflags libtiff-4`" - LIBS="$LIBS `$PKGCONFIG --libs libtiff-4`" - HAVE_SYSTEM_LIBTIFF=1 - fi - fi - if test "x$HAVE_SYSTEM_LIBTIFF" = "x1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFOpen in -ltiff" >&5 -$as_echo_n "checking for TIFFOpen in -ltiff... " >&6; } -if ${ac_cv_lib_tiff_TIFFOpen+:} false; then : + # Various versions of UFST fail to build with -Werror=return-type so + # strip that off our GCFLAGS if it's there. + tmp_cflags="" + for tmp_cflag in $GCFLAGS ; do + echo $tmp_cflag + tmp_cflags="$tmp_cflags $(echo $tmp_cflag | grep -v "Werror=return-type")" + done + GCFLAGS="$tmp_cflags" + + FAPIUFST_MAK="\$(UFST_ROOT)\$(D)fapiufst.mak" + + if ! test -f $UFST_ROOT/fapiufst.mak ; then + echo $UFST_ROOT/fapiufst.mak + as_fn_error $? "UFST: fapiufst.mak not found" "$LINENO" 5 + fi + + # Check pointer size + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char*" >&5 +$as_echo_n "checking size of char*... " >&6; } +if ${ac_cv_sizeof_charp+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ltiff -ljpeg $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char*))" "ac_cv_sizeof_charp" "$ac_includes_default"; then : -/* 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 TIFFOpen (); -int -main () -{ -return TIFFOpen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_tiff_TIFFOpen=yes else - ac_cv_lib_tiff_TIFFOpen=no + if test "$ac_cv_type_charp" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char*) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_charp=0 + fi fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFOpen" >&5 -$as_echo "$ac_cv_lib_tiff_TIFFOpen" >&6; } -if test "x$ac_cv_lib_tiff_TIFFOpen" = xyes; then : - for ac_header in tiff.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default" -if test "x$ac_cv_header_tiff_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_TIFF_H 1 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_charp" >&5 +$as_echo "$ac_cv_sizeof_charp" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHARP $ac_cv_sizeof_charp _ACEOF - HAVE_SYSTEM_LIBTIFF=1;SHARE_LIBTIFF=1 -fi -done -fi - fi - fi - if test "x$HAVE_LOCAL_LIBTIFF" = x && test "x$HAVE_SYSTEM_LIBTIFF" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find a copy of libtiff on your system. -Disabling tiff output devices." >&5 -$as_echo "$as_me: Could not find a copy of libtiff on your system. -Disabling tiff output devices." >&6;} - else - TIFFDEVS="$TIFFDEVS_ALL" - FAX_DEVS="$FAX_DEVS_ALL" + # UFST 5.x uses strcmpi() but on GNU systems the equivalent is + # strcasecmp() + if test "x$ac_cv_sizeof_charp" = "x8"; then + UFST_CFLAGS="-DGCCx86_64 -DO_BINARY=0 -Dstrcmpi=strcasecmp" + else + if test "x$ac_cv_sizeof_charp" = "x4"; then + UFST_CFLAGS="-DGCCx86 -DO_BINARY=0 -Dstrcmpi=strcasecmp" fi - ;; - xyes) - # We MUST NOT use PKG_CHECK_MODULES since it is a) not a standard - # autoconf macro and b) requires pkg-config on the system, which is - # NOT standard on ANY OS, including Linux! - if test "x$PKGCONFIG" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtiff with pkg-config" >&5 -$as_echo_n "checking for libtiff with pkg-config... " >&6; } - if $PKGCONFIG --exists libtiff-4; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + fi + + UFST_LIB_EXT=.a + else + as_fn_error $? "UFST source directory not found" "$LINENO" 5 + fi + fi + + if test x"$enable_freetype" != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local freetype library source" >&5 +$as_echo_n "checking for local freetype library source... " >&6; } + for dir in $srccdir/freetype2 $srcdir/freetype; do + if test -f $dir/src/base/ftbbox.c; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - CFLAGS="$CFLAGS `$PKGCONFIG --cflags libtiff-4`" - LIBS="$LIBS `$PKGCONFIG --libs libtiff-4`" - HAVE_SYSTEM_LIBTIFF=1 - fi - fi - if test -z "$HAVE_SYSTEM_LIBTIFF"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFOpen in -ltiff" >&5 -$as_echo_n "checking for TIFFOpen in -ltiff... " >&6; } -if ${ac_cv_lib_tiff_TIFFOpen+:} false; then : + SHARE_FT=0 + FTSRCDIR="$dir" + FT_CFLAGS="-I$dir/include" + FT_BRIDGE=1 + break; + fi + done + + if test x"$FTSRCDIR" = x"src"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if test "x$PKGCONFIG" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system freetype2 >= 2.4.2 with pkg-config" >&5 +$as_echo_n "checking for system freetype2 >= 2.4.2 with pkg-config... " >&6; } + # pkg-config needs the libtool version, which != the freetype2 version + # There is a table of corresponding ft2<->libtool numbers in freetype/docs/VERSION.DLL + if $PKGCONFIG --atleast-version=12.0.6 freetype2; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + FT_CFLAGS="$CFLAGS `$PKGCONFIG --cflags freetype2`" + FT_LIBS="`$PKGCONFIG --libs freetype2`" + FT_BRIDGE=1 + SHARE_FT=1 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: freetype library source not found...using native rasterizer" >&5 +$as_echo "$as_me: WARNING: freetype library source not found...using native rasterizer" >&2;} + AFS=1 + fi + else + ac_fn_c_check_header_mongrel "$LINENO" "ft2build.h" "ac_cv_header_ft2build_h" "$ac_includes_default" +if test "x$ac_cv_header_ft2build_h" = xyes; then : + FT_BRIDGE=1 +else + AFS=1 +fi + + + + if test "x$FT_BRIDGE" = x1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FT_Init_FreeType in -lfreetype" >&5 +$as_echo_n "checking for FT_Init_FreeType in -lfreetype... " >&6; } +if ${ac_cv_lib_freetype_FT_Init_FreeType+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-ltiff -ljpeg $LIBS" +LIBS="-lfreetype $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6495,90 +7117,72 @@ #ifdef __cplusplus extern "C" #endif -char TIFFOpen (); +char FT_Init_FreeType (); int main () { -return TIFFOpen (); +return FT_Init_FreeType (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_tiff_TIFFOpen=yes + ac_cv_lib_freetype_FT_Init_FreeType=yes else - ac_cv_lib_tiff_TIFFOpen=no + ac_cv_lib_freetype_FT_Init_FreeType=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFOpen" >&5 -$as_echo "$ac_cv_lib_tiff_TIFFOpen" >&6; } -if test "x$ac_cv_lib_tiff_TIFFOpen" = xyes; then : - for ac_header in tiff.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default" -if test "x$ac_cv_header_tiff_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_TIFF_H 1 -_ACEOF - HAVE_SYSTEM_LIBTIFF=1;SHARE_LIBTIFF=1 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5 +$as_echo "$ac_cv_lib_freetype_FT_Init_FreeType" >&6; } +if test "x$ac_cv_lib_freetype_FT_Init_FreeType" = xyes; then : + FT_BRIDGE=1 +else + FT_BRIDGE=0; AFS=1 fi -done - -fi - fi - if test "x$HAVE_SYSTEM_LIBTIFF" != x; then - SHARE_LIBTIFF=1 - TIFFDEVS="$TIFFDEVS_ALL" - FAX_DEVS="$FAX_DEVS_ALL" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find a copy of libtiff on your system. -Disabling tiff output devices." >&5 -$as_echo "$as_me: Could not find a copy of libtiff on your system. -Disabling tiff output devices." >&6;} - fi - ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local libtiff source" >&5 -$as_echo_n "checking for local libtiff source... " >&6; } - if test -d $srcdir/tiff; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + if test "x$FT_BRIDGE" = x1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system freetype2 library >= 2.4.2" >&5 +$as_echo_n "checking for system freetype2 library >= 2.4.2... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "ft2build.h" + #include FT_FREETYPE_H +int +main () +{ + + #if FREETYPE_MAJOR < 2 + FAIL + #endif + #if FREETYPE_MINOR < 4 + FAIL + #endif + #if FREETYPE_PATCH < 2 + FAIL + #endif + return(0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + FT_BRIDGE=1;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - LIBTIFFDIR=$srcdir/tiff - LIBTIFFCONFDIR=tiff-config - SHARE_LIBTIFF=0 - TIFFDEVS="$TIFFDEVS_ALL" - FAX_DEVS="$FAX_DEVS_ALL" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else + FT_BRIDGE=0; AFS=1;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find local copy of libtiff. -Disabling tiff output devices." >&5 -$as_echo "$as_me: Could not find local copy of libtiff. -Disabling tiff output devices." >&6;} +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi fi - ;; -esac - -if test $SHARE_LIBTIFF -eq 0; then - echo - echo "Running libtiff configure script..." - olddir=`pwd` - if ! test -d $LIBTIFFCONFDIR ; then - mkdir $LIBTIFFCONFDIR fi - cd "$LIBTIFFCONFDIR" && $olddir/$LIBTIFFDIR/configure --disable-jbig --disable-lzma $SUBCONFIG_OPTS - status=$? - if test "$status" -ne 0 ; then - as_fn_error $status "libtiff configure script failed" "$LINENO" 5 - fi - cd "$olddir" - echo - echo "Continuing with Ghostscript configuration..." + fi + fi fi @@ -6586,196 +7190,197 @@ -# Check whether --enable-cups was given. -if test "${enable_cups+set}" = set; then : - enableval=$enable_cups; -fi -# Check whether --with-pdftoraster was given. -if test "${with_pdftoraster+set}" = set; then : - withval=$with_pdftoraster; -fi - - -# Check whether --with-local-cups was given. -if test "${with_local_cups+set}" = set; then : - withval=$with_local_cups; with_local_cups=yes -else - with_local_cups=no -fi -# Check whether --with-cups-serverbin was given. -if test "${with_cups_serverbin+set}" = set; then : - withval=$with_cups_serverbin; CUPS_SERVERBIN="$withval" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for local jpeg library source" >&5 +$as_echo_n "checking for local jpeg library source... " >&6; } +LIBJPEGDIR=src +if test -f $srcdir/jpeg/jpeglib.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: jpeg" >&5 +$as_echo "jpeg" >&6; } + SHARE_LIBJPEG=0 + LIBJPEGDIR=$srcdir/jpeg +elif test -f $srcdir/jpeg-6b/jpeglib.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: jpeg-6b" >&5 +$as_echo "jpeg-6b" >&6; } + SHARE_LIBJPEG=0 + LIBJPEGDIR=$srcdir/jpeg-6b else - CUPS_SERVERBIN="" -fi - - + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_set_defaults in -ljpeg" >&5 +$as_echo_n "checking for jpeg_set_defaults in -ljpeg... " >&6; } +if ${ac_cv_lib_jpeg_jpeg_set_defaults+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ljpeg $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -# Check whether --with-cups-serverroot was given. -if test "${with_cups_serverroot+set}" = set; then : - withval=$with_cups_serverroot; CUPS_SERVERROOT="$withval" +/* 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 jpeg_set_defaults (); +int +main () +{ +return jpeg_set_defaults (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_jpeg_jpeg_set_defaults=yes else - CUPS_SERVERROOT="" + ac_cv_lib_jpeg_jpeg_set_defaults=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_set_defaults" >&5 +$as_echo "$ac_cv_lib_jpeg_jpeg_set_defaults" >&6; } +if test "x$ac_cv_lib_jpeg_jpeg_set_defaults" = xyes; then : + for ac_header in jpeglib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "jpeglib.h" "ac_cv_header_jpeglib_h" "$ac_includes_default" +if test "x$ac_cv_header_jpeglib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_JPEGLIB_H 1 +_ACEOF + SHARE_LIBJPEG=1 +fi +done -# Check whether --with-cups-datadir was given. -if test "${with_cups_datadir+set}" = set; then : - withval=$with_cups_datadir; CUPS_DATADIR="$withval" -else - CUPS_DATADIR="" fi +fi +if test -z "$SHARE_LIBJPEG"; then + as_fn_error $? "I wasn't able to find a copy + of the jpeg library. This is required for compiling + ghostscript. Please download a copy of the source, + e.g. from http://www.ijg.org/, unpack it at the + top level of the gs source tree, and rename + the directory to 'jpeg'. + " "$LINENO" 5 +fi -CUPSDEV="" -CUPSINCLUDE="" -CUPSCFLAGS="" -CUPSLIBS="" -CUPSLIBDIRS="" -CUPSCONFIG="${CUPSCONFIG:=}" -CUPSSERVERBIN="" -CUPSSERVERROOT="" -CUPSDATA="" -CUPSVERSION="0" -CUPSPDFTORASTER="0" -CUPS_DIR="" - -SHARELCUPS=1 -SHARELCUPSI=1 - -if ( test -d $srcdir/cups ); then - CUPS_DIR="$srcdir/cups" - if test x$enable_cups != xno; then - if test x$with_local_cups != xyes; then - # Extract the first word of "cups-config", so it can be a program name with args. -set dummy cups-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_path_CUPSCONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $CUPSCONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_CUPSCONFIG="$CUPSCONFIG" # Let the user override the test with a path. - ;; - *) - 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_path_CUPSCONFIG="$as_dir/$ac_word$ac_exec_ext" - $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 - ;; -esac -fi -CUPSCONFIG=$ac_cv_path_CUPSCONFIG -if test -n "$CUPSCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPSCONFIG" >&5 -$as_echo "$CUPSCONFIG" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for jmemsys.h" >&5 +$as_echo_n "checking for jmemsys.h... " >&6; } +if test -r $LIBJPEGDIR/jmemsys.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } -fi +$as_echo "#define DONT_HAVE_JMEMSYS_H 1" >>confdefs.h - ac_fn_c_check_header_mongrel "$LINENO" "cups/raster.h" "ac_cv_header_cups_raster_h" "$ac_includes_default" -if test "x$ac_cv_header_cups_raster_h" = xyes; then : - -else - CUPSCONFIG="" fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for local zlib source" >&5 +$as_echo_n "checking for local zlib source... " >&6; } +# we must define ZLIBDIR regardless because png.mak does a -I$(ZLIBDIR) +# this seems a harmless default +ZLIBDIR=src +AUX_SHARED_ZLIB= +ZLIBCFLAGS="" - if test "x$CUPSCONFIG" != x; then - CUPSCFLAGS="`$CUPSCONFIG --cflags` $CFLAGS" -# CUPSLINK="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --static --image --libs | sed -e '1,$s/-lssl//'` $LIBS" - CUPSLINK="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --image --libs`" - -# the makefile wants a list of just the library names -for gs_item in $CUPSLINK; do - gs_stripped_item=`echo "$gs_item" | sed -e 's/^-l//'` - if test "x$gs_stripped_item" != "x$gs_item"; then - CUPSLIBS="$CUPSLIBS $gs_stripped_item" - fi -done - +if test -d $srcdir/zlib; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SHARE_ZLIB=0 + ZLIBDIR=$srcdir/zlib -for gs_item in $CUPSLINK; do - gs_stripped_item=`echo "$gs_item" | sed -e 's/-L//'` - if test "x$gs_stripped_item" != "x$gs_item"; then - CUPSLIBDIRS="$CUPSLIBDIRS $gs_stripped_item" - fi -done - - - if test "x$CUPS_SERVERROOT" != "x"; then - CUPSSERVERROOT="$CUPS_SERVERROOT" - else - CUPSSERVERROOT="`$CUPSCONFIG --serverroot`" - fi - - if test "x$CUPS_SERVERBIN" != "x"; then - CUPSSERVERBIN="$CUPS_SERVERBIN" - else - CUPSSERVERBIN="`$CUPSCONFIG --serverbin`" - fi - - if test "x$CUPS_DATADIR" != "x"; then - CUPSDATA="$CUPS_DATADIR" - else - CUPSDATA="`$CUPSCONFIG --datadir`" - fi - - CUPSINCLUDE="include $srcdir/cups/cups.mak" - CUPSDEV="cups" - CUPSVERSION="`$CUPSCONFIG --version`" - LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" - LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" - if ( test x$with_pdftoraster != xno ); then - if test "$CUPSVERSION" ">" "1.2"; then - CUPSPDFTORASTER="1" - fi - fi - fi - else - if test "$(uname)" = "Linux"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: * USING LOCAL CUPS SOURCE *" >&5 -$as_echo "$as_me: WARNING: * USING LOCAL CUPS SOURCE *" >&2;} - SHARELCUPS=0 - SHARELCUPSI=0 - LCUPSBUILDTYPE=linux - LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" - LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" - CUPSDEV="cups" - fi + if test x"$ac_cv_c_compiler_gnu" = x"yes"; then + ZLIBCFLAGS="-Wno-write-strings" fi - fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5 +$as_echo_n "checking for deflate in -lz... " >&6; } +if ${ac_cv_lib_z_deflate+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $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 deflate (); +int +main () +{ +return deflate (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_deflate=yes +else + ac_cv_lib_z_deflate=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5 +$as_echo "$ac_cv_lib_z_deflate" >&6; } +if test "x$ac_cv_lib_z_deflate" = xyes; then : -#AC_SUBST(CUPSDEV) + for ac_header in zlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ZLIB_H 1 +_ACEOF + SHARE_ZLIB=1; AUX_SHARED_ZLIB="-l\$(ZLIB_NAME)" +fi +done +fi +fi +if test -z "$SHARE_ZLIB"; then + as_fn_error $? "I did not find a copy of zlib on your system. + Please either install it, or unpack a copy of the source in a + local directory named 'zlib'. See http://www.gzip.org/zlib/ + for more information. + " "$LINENO" 5 +fi +FT_SYS_ZLIB="" +if test x$FT_BRIDGE != x0; then + if test xx$SHARE_FT != x1; then + if test x$SHARE_ZLIB != x0; then + FT_SYS_ZLIB="-DFT_CONFIG_OPTION_SYSTEM_ZLIB" + fi + fi +fi @@ -6783,52 +7388,130 @@ +LIBPNGDIR=src +PNGDEVS='' +PNGDEVS_ALL='png48 png16m pnggray pngmono pngmonod png256 png16 pngalpha' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for local png library source" >&5 +$as_echo_n "checking for local png library source... " >&6; } +if test -f $srcdir/libpng/pngread.c; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SHARE_LIBPNG=0 + LIBPNGDIR=$srcdir/libpng + PNGDEVS="$PNGDEVS_ALL" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_create_write_struct in -lpng" >&5 +$as_echo_n "checking for png_create_write_struct in -lpng... " >&6; } +if ${ac_cv_lib_png_png_create_write_struct+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpng -lz $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 png_create_write_struct (); +int +main () +{ +return png_create_write_struct (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_png_png_create_write_struct=yes +else + ac_cv_lib_png_png_create_write_struct=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_create_write_struct" >&5 +$as_echo "$ac_cv_lib_png_png_create_write_struct" >&6; } +if test "x$ac_cv_lib_png_png_create_write_struct" = xyes; then : + for ac_header in png.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default" +if test "x$ac_cv_header_png_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PNG_H 1 +_ACEOF + SHARE_LIBPNG=1 + PNGDEVS="$PNGDEVS_ALL" +else + SHARE_LIBPNG=0 +fi +done +else + SHARE_LIBPNG=0 +fi -# Check whether --with-ijs was given. -if test "${with_ijs+set}" = set; then : - withval=$with_ijs; +fi +if test -z "$PNGDEVS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: disabling png output devices" >&5 +$as_echo "$as_me: disabling png output devices" >&6;} fi -case `uname` in - MINGW*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling the ijs device" >&5 -$as_echo "$as_me: WARNING: disabling the ijs device" >&2;} - with_ijs=no - ;; - *) - ;; -esac +#AC_SUBST(PNGDEVS) +WHICHLCMS= - IJSDIR=src - IJSDEVS='' - SHAREIJS=0 -if test x$with_ijs != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local ijs library source" >&5 -$as_echo_n "checking for local ijs library source... " >&6; } - if test -d $srcdir/ijs; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for local lcms2mt library source" >&5 +$as_echo_n "checking for local lcms2mt library source... " >&6; } +LCMS2DIR=src +LCMS2MTDIR=src + +# First check for Artifex version +LCMS2MTSRC=$srcdir/lcms2mt +if test -f $LCMS2MTSRC/include/lcms2mt.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - IJSDIR=$srcdir/ijs - IJSDEVS='ijs' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + SHARELCMS=0 + WHICHLCMS=lcms2mt + LCMS2MTDIR=$LCMS2MTSRC +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ijs_server_init in -lijs" >&5 -$as_echo_n "checking for ijs_server_init in -lijs... " >&6; } -if ${ac_cv_lib_ijs_ijs_server_init+:} false; then : + # Now check for local lcms2 (non-Artifex) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local lcms2 library source" >&5 +$as_echo_n "checking for local lcms2 library source... " >&6; } + LCMS2SRC=$srcdir/lcms2 + if test -f $LCMS2SRC/include/lcms2.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SHARELCMS=0 + WHICHLCMS=lcms2 + LCMS2DIR=$LCMS2SRC + else + # See if we have system library of lcms2 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for system lcms2 library" >&5 +$as_echo_n "checking for system lcms2 library... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _cmsCreateMutex in -llcms2" >&5 +$as_echo_n "checking for _cmsCreateMutex in -llcms2... " >&6; } +if ${ac_cv_lib_lcms2__cmsCreateMutex+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lijs $LIBS" +LIBS="-llcms2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6838,36 +7521,36 @@ #ifdef __cplusplus extern "C" #endif -char ijs_server_init (); +char _cmsCreateMutex (); int main () { -return ijs_server_init (); +return _cmsCreateMutex (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ijs_ijs_server_init=yes + ac_cv_lib_lcms2__cmsCreateMutex=yes else - ac_cv_lib_ijs_ijs_server_init=no + ac_cv_lib_lcms2__cmsCreateMutex=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ijs_ijs_server_init" >&5 -$as_echo "$ac_cv_lib_ijs_ijs_server_init" >&6; } -if test "x$ac_cv_lib_ijs_ijs_server_init" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lcms2__cmsCreateMutex" >&5 +$as_echo "$ac_cv_lib_lcms2__cmsCreateMutex" >&6; } +if test "x$ac_cv_lib_lcms2__cmsCreateMutex" = xyes; then : - for ac_header in ijs/ijs.h + for ac_header in lcms2.h do : - ac_fn_c_check_header_mongrel "$LINENO" "ijs/ijs.h" "ac_cv_header_ijs_ijs_h" "$ac_includes_default" -if test "x$ac_cv_header_ijs_ijs_h" = xyes; then : + ac_fn_c_check_header_mongrel "$LINENO" "lcms2.h" "ac_cv_header_lcms2_h" "$ac_includes_default" +if test "x$ac_cv_header_lcms2_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_IJS_IJS_H 1 +#define HAVE_LCMS2_H 1 _ACEOF - SHAREIJS=1 + SHARELCMS=1;WHICHLCMS=lcms2 fi done @@ -6875,159 +7558,157 @@ fi - if test $SHAREIJS -eq 1 ; then - IJSLIB=ijs - # This is for safety - it prevents our header search path going outside the GS source tree - IJSDIR='$(GLOBJDIR)' - IJSDEVS='ijs' - fi - fi + if test x$WHICHLCMS = x; then + as_fn_error $? "lcms2 not found, or too old" "$LINENO" 5 + fi + fi fi -#AC_SUBST(IJSDEVS) - -JBIG2_DECODER= -JBIG2DIR=src -SHARE_JBIG2=0 -JBIG2DEVS='' -JBIG2_AUTOCONF_CFLAGS= -LURATECHDIR=luratech -# Check whether --with-luratech was given. -if test "${with_luratech+set}" = set; then : - withval=$with_luratech; +# Check whether --with-libtiff was given. +if test "${with_libtiff+set}" = set; then : + withval=$with_libtiff; with_libtiff=no fi -if test x$with_luratech != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local Luratech JBIG2 library source" >&5 -$as_echo_n "checking for local Luratech JBIG2 library source... " >&6; } - if test -d $srcdir/luratech/ldf_jb2; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - JBIG2_DECODER=luratech - SHARE_JBIG2=0 - JBIG2DIR=$srcdir/luratech/ldf_jb2 +# Check whether --with-system-libtiff was given. +if test "${with_system_libtiff+set}" = set; then : + withval=$with_system_libtiff; +else + with_system_libtiff=check +fi - case `uname` in - Darwin*) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD" - ;; - AIX) - if test $ac_cv_c_compiler_gnu = yes; then - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX" - else - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -qchars=signed -DLINUX" - fi - ;; - *) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DLINUX" - ;; - esac - JBIG2FILEDEVS='$(DD)gdevjbig2.dev' - JBIG2DEVS='$(PSD)jbig2.dev' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi +if test x"$with_libtiff" = x"no" ; then + with_system_libtiff=none fi -JB2_STDINT_TYPES_IN= +TIFFDEVS='' +FAX_DEVS='' +XPSWRITEDEVICE='' -if test "x$JBIG2_DECODER" = x; then -# Check whether --with-jbig2dec was given. -if test "${with_jbig2dec+set}" = set; then : - withval=$with_jbig2dec; -fi +LIBTIFFDIR='src' +LIBTIFFCONFDIR='' +TIFFCFLAGS='' - if test x$with_jbig2dec != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local jbig2dec library source" >&5 -$as_echo_n "checking for local jbig2dec library source... " >&6; } - for d in $srcdir/jbig2dec $srcdir/jbig2dec-0.2 $srcdir/jbig2dec-0.3; do - test -d "$d" && JBIG2DIR=$d && break - done - if test "x$JBIG2DIR" != xsrc; then - JBIG2_DECODER=jbig2dec - if test x$ac_cv_header_stdint_h = xyes ; then - JBIG2_AUTOCONF_CFLAGS="-DHAVE_STDINT_H=1" - else +TIFFDEVS_ALL='tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled tiffscaled4 tiffscaled8 tiffscaled24 tiffscaled32' +FAX_DEVS_ALL='cfax dfaxlow dfaxhigh fax faxg3 faxg32d faxg4 tiffg3 tiffg32d tiffg4 tfax' - for include in sys/types.h inttypes.h sys/inttypes.h sys/int_types.h ; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint32_t in $include" >&5 -$as_echo_n "checking for uint32_t in $include... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +case "x$with_system_libtiff" in + xcheck) + if test -d $srcdir/tiff; then + LIBTIFFDIR=$srcdir/tiff + LIBTIFFCONFDIR=tiff-config + HAVE_LOCAL_LIBTIFF=1 + SHARE_LIBTIFF=0 + else + # We MUST NOT use PKG_CHECK_MODULES since it is a) not a standard + # autoconf macro and b) requires pkg-config on the system, which is + # NOT standard on ANY OS, including Linux! + if test "x$PKGCONFIG" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtiff with pkg-config" >&5 +$as_echo_n "checking for libtiff with pkg-config... " >&6; } + if $PKGCONFIG --exists libtiff-4; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$CFLAGS `$PKGCONFIG --cflags libtiff-4`" + LIBS="$LIBS `$PKGCONFIG --libs libtiff-4`" + HAVE_SYSTEM_LIBTIFF=1 + fi + fi + if test "x$HAVE_SYSTEM_LIBTIFF" = "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFOpen in -ltiff" >&5 +$as_echo_n "checking for TIFFOpen in -ltiff... " >&6; } +if ${ac_cv_lib_tiff_TIFFOpen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltiff -ljpeg $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <$include> + +/* 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 TIFFOpen (); int main () { -uint32_t canary; +return TIFFOpen (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - stdint_types_in="$include" - break; - +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_tiff_TIFFOpen=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + ac_cv_lib_tiff_TIFFOpen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFOpen" >&5 +$as_echo "$ac_cv_lib_tiff_TIFFOpen" >&6; } +if test "x$ac_cv_lib_tiff_TIFFOpen" = xyes; then : + for ac_header in tiff.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default" +if test "x$ac_cv_header_tiff_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TIFF_H 1 +_ACEOF + HAVE_SYSTEM_LIBTIFF=1;SHARE_LIBTIFF=1 +fi + +done fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done - case "$stdint_types_in" in - "sys/types.h") - JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_SYS_TYPES_H" - ;; - "inttypes.h") - JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_INTTYPES_H" - ;; - "sys/inttypes.h") - JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_SYS_INTTYPES_H" - ;; - "sys/int_types.h") - JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_SYS_INT_TYPES_H" - ;; - *) - as_fn_error $? " - Unable to find suitable definitions of the stdint.h types (uint32_t and friends). - These are required by jbig2dec. - " "$LINENO" 5 - esac + fi fi - - if test "x$BIGENDIAN" != "x0"; then - JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DWORDS_BIGENDIAN" + if test "x$HAVE_LOCAL_LIBTIFF" = x && test "x$HAVE_SYSTEM_LIBTIFF" = x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find a copy of libtiff on your system. Disabling tiff and xps output devices." >&5 +$as_echo "$as_me: Could not find a copy of libtiff on your system. Disabling tiff and xps output devices." >&6;} + else + TIFFDEVS="$TIFFDEVS_ALL" + FAX_DEVS="$FAX_DEVS_ALL" + XPSWRITEDEVICE='xpswrite' fi - - echo - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JBIG2DIR" >&5 -$as_echo "$JBIG2DIR" >&6; } - echo "Continuing with Ghostscript configuration..." - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jbig2_page_out in -ljbig2dec" >&5 -$as_echo_n "checking for jbig2_page_out in -ljbig2dec... " >&6; } -if ${ac_cv_lib_jbig2dec_jbig2_page_out+:} false; then : + ;; + xyes) + # We MUST NOT use PKG_CHECK_MODULES since it is a) not a standard + # autoconf macro and b) requires pkg-config on the system, which is + # NOT standard on ANY OS, including Linux! + if test "x$PKGCONFIG" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtiff with pkg-config" >&5 +$as_echo_n "checking for libtiff with pkg-config... " >&6; } + if $PKGCONFIG --exists libtiff-4; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS="$CFLAGS `$PKGCONFIG --cflags libtiff-4`" + LIBS="$LIBS `$PKGCONFIG --libs libtiff-4`" + HAVE_SYSTEM_LIBTIFF=1 + fi + fi + if test -z "$HAVE_SYSTEM_LIBTIFF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFOpen in -ltiff" >&5 +$as_echo_n "checking for TIFFOpen in -ltiff... " >&6; } +if ${ac_cv_lib_tiff_TIFFOpen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-ljbig2dec $LIBS" +LIBS="-ltiff -ljpeg $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7037,146 +7718,225 @@ #ifdef __cplusplus extern "C" #endif -char jbig2_page_out (); +char TIFFOpen (); int main () { -return jbig2_page_out (); +return TIFFOpen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_jbig2dec_jbig2_page_out=yes + ac_cv_lib_tiff_TIFFOpen=yes else - ac_cv_lib_jbig2dec_jbig2_page_out=no + ac_cv_lib_tiff_TIFFOpen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jbig2dec_jbig2_page_out" >&5 -$as_echo "$ac_cv_lib_jbig2dec_jbig2_page_out" >&6; } -if test "x$ac_cv_lib_jbig2dec_jbig2_page_out" = xyes; then : - - SHARE_JBIG2=1 - -else +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tiff_TIFFOpen" >&5 +$as_echo "$ac_cv_lib_tiff_TIFFOpen" >&6; } +if test "x$ac_cv_lib_tiff_TIFFOpen" = xyes; then : + for ac_header in tiff.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "tiff.h" "ac_cv_header_tiff_h" "$ac_includes_default" +if test "x$ac_cv_header_tiff_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TIFF_H 1 +_ACEOF + HAVE_SYSTEM_LIBTIFF=1;SHARE_LIBTIFF=1 +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling support for JBIG2 files" >&5 -$as_echo "$as_me: WARNING: disabling support for JBIG2 files" >&2;} - with_jbig2dec=no +done fi - if test x$with_jbig2dec != xno; then - JBIG2_DECODER=jbig2dec - fi - fi - fi - if test x$with_jbig2dec != xno; then -# I *think* jbig2dec handles these being missing gracefully -# if test x$ac_cv_header_stdint_h != xyes && test x$ac_cv_header_inttypes_h != xyes; then -# AC_MSG_WARN([JBIG2 support requires stdint types which do not seem to be available.]) -# else - JBIG2DEVS='$(PSD)jbig2.dev' -# fi - fi -fi - - + fi + if test "x$HAVE_SYSTEM_LIBTIFF" != x; then + SHARE_LIBTIFF=1 + TIFFDEVS="$TIFFDEVS_ALL" + FAX_DEVS="$FAX_DEVS_ALL" + XPSWRITEDEVICE='xpswrite' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find a copy of libtiff on your system. Disabling tiff and xps output devices." >&5 +$as_echo "$as_me: Could not find a copy of libtiff on your system. Disabling tiff and xps output devices." >&6;} + fi + ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local libtiff source" >&5 +$as_echo_n "checking for local libtiff source... " >&6; } + if test -d $srcdir/tiff; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LIBTIFFDIR=$srcdir/tiff + LIBTIFFCONFDIR=tiff-config + SHARE_LIBTIFF=0 + TIFFDEVS="$TIFFDEVS_ALL" + FAX_DEVS="$FAX_DEVS_ALL" + XPSWRITEDEVICE='xpswrite' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: Could not find local copy of libtiff. Disabling tiff and xps output devices." >&5 +$as_echo "$as_me: Could not find local copy of libtiff. Disabling tiff and xps output devices." >&6;} + fi + ;; + xnone) + ;; +esac +CGLAGS_STORE=$CFLAGS +CFLAGS=-Wno-misleading-indentation +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + CFLAGS_NMI="-Wno-misleading-indentation" +else + CFLAGS_NMI="" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS=-Wno-undef +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + CFLAGS_NUD="-Wno-undef" +else + CFLAGS_NUD="" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -JPXDIR=src -SHARE_JPX=0 -JPXDEVS='' -JPX_DECODER= -JPX_AUTOCONF_CFLAGS= +CFLAGS=$CGLAGS_STORE -if test x$with_luratech != xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local Luratech JPEG2K library source" >&5 -$as_echo_n "checking for local Luratech JPEG2K library source... " >&6; } - if test -d $srcdir/luratech/lwf_jp2; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - JPX_DECODER=luratech - SHARE_JPX=0 - JPXDIR=$srcdir/luratech/lwf_jp2 +if test x"$SHARE_LIBTIFF" = x"0" ; then + echo "Running libtiff configure script..." + olddir=`pwd` + if ! test -d "$LIBTIFFCONFDIR" ; then + mkdir "$LIBTIFFCONFDIR" + fi + cd "$LIBTIFFCONFDIR" && ../"$LIBTIFFDIR"/configure --disable-jbig --disable-lzma $SUBCONFIG_OPTS + status=$? + if test $status -ne 0 ; then + as_fn_error $status "libtiff configure script failed" "$LINENO" 5 + fi + cd "$olddir" - case `uname` in - Darwin*) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD" - ;; - AIX) - if test $ac_cv_c_compiler_gnu = yes; then - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -fsigned-char -DLINUX" - else - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -qchars=signed -DLINUX" - fi - ;; - *) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX" - ;; - esac + if test x"$ac_cv_c_compiler_gnu" = x"yes"; then + TIFFCFLAGS="-Wno-write-strings $CFLAGS_NMI $CFLAGS_NUD -DJPEG_LIB_MK1_OR_12BIT=0" + fi - JPXDEVS='$(PSD)jpx.dev' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi + echo + echo "Continuing with Ghostscript configuration..." fi -OPENJPEGDIR=$srcdir/openjpeg -JPX_SSE_CFLAGS="" -if test "x$HAVE_SSE2" = "x" ; then - if test $ac_cv_c_compiler_gnu = yes; then - JPX_SSE_CFLAGS="-U__SSE__" - fi -fi -# Check whether --enable-openjpeg was given. -if test "${enable_openjpeg+set}" = set; then : - enableval=$enable_openjpeg; -fi -if test "x$JPX_DECODER" = "x"; then - if test "x$enable_openjpeg" != "xno"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local OpenJPEG library source" >&5 -$as_echo_n "checking for local OpenJPEG library source... " >&6; } - if test -e $OPENJPEGDIR/libopenjpeg/openjpeg.h; then +SHARE_EXPAT=0 +EXPATDIR=src +EXPAT_CFLAGS= +EXPAT_LIBS= + +if test x"$with_xps" != x"no" ; then + if test -f $srcdir/xps/xps.mak; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local expat library source" >&5 +$as_echo_n "checking for local expat library source... " >&6; } + if test -f $srcdir/expat/lib/expat.h ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - JPXDIR="$OPENJPEGDIR" - JPX_DECODER=openjpeg - SHARE_JPX=0 - for ac_func in memalign -do : - ac_fn_c_check_func "$LINENO" "memalign" "ac_cv_func_memalign" -if test "x$ac_cv_func_memalign" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_MEMALIGN 1 + SHARE_EXPAT=0 + EXPATDIR=$srcdir/expat + EXPAT_CFLAGS="-DHAVE_MEMMOVE" + if test x"$BIGENDIAN" != x"0"; then + EXPAT_CFLAGS="$EXPAT_CFLAGS -DBYTEORDER=4321" + else + EXPAT_CFLAGS="$EXPAT_CFLAGS -DBYTEORDER=1234" + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML_ParserCreateNS in -lexpat" >&5 +$as_echo_n "checking for XML_ParserCreateNS in -lexpat... " >&6; } +if ${ac_cv_lib_expat_XML_ParserCreateNS+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lexpat $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 XML_ParserCreateNS (); +int +main () +{ +return XML_ParserCreateNS (); + ; + return 0; +} _ACEOF - have_memalign=1 +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_expat_XML_ParserCreateNS=yes +else + ac_cv_lib_expat_XML_ParserCreateNS=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_ParserCreateNS" >&5 +$as_echo "$ac_cv_lib_expat_XML_ParserCreateNS" >&6; } +if test "x$ac_cv_lib_expat_XML_ParserCreateNS" = xyes; then : + + ac_fn_c_check_header_mongrel "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default" +if test "x$ac_cv_header_expat_h" = xyes; then : + SHARE_EXPAT=1 fi -done - if test "x$have_memalign" = "x1"; then - JPX_AUTOCONF_CFLAGS="-DUSE_OPENJPEG_JP2 $JPX_SSE_CFLAGS" - else - JPX_AUTOCONF_CFLAGS="-DUSE_OPENJPEG_JP2 $JPX_SSE_CFLAGS -D\"memalign(a,b)=malloc(b)\"" - fi - JPXDEVS='$(PSD)jpx.dev' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +else + + as_fn_error $? "expat lib not found" "$LINENO" 5 + +fi + + if test $SHARE_EXPAT = 1; then + if test "x$PKGCONFIG" != x; then + if $PKGCONFIG --exists expat; then + EXPAT_LIBS="`$PKGCONFIG --libs expat`" + CFLAGS="$CFLAGS `$PKGCONFIG --cflags expat`" + fi + fi + if test x"$XPS_LDFLAGS" = x ; then + EXPAT_LIBS="-lexpat" + fi + fi fi fi fi @@ -7187,413 +7947,375 @@ -# Check whether --enable-gtk was given. -if test "${enable_gtk+set}" = set; then : - enableval=$enable_gtk; +# Check whether --enable-cups was given. +if test "${enable_cups+set}" = set; then : + enableval=$enable_cups; fi -SOC_CFLAGS="" -SOC_LIBS="" -SOC_LOADER="" -if test "x$enable_gtk" != "xno"; then - # Try GTK+ 3.x first... - if test "x$PKGCONFIG" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK+ 3.x" >&5 -$as_echo_n "checking for GTK+ 3.x... " >&6; } - if $PKGCONFIG --exists gtk+-3.0; then - SOC_LOADER="dxmain.c" - SOC_CFLAGS="`$PKGCONFIG gtk+-3.0 --cflags`" - SOC_LIBS="`$PKGCONFIG gtk+-3.0 --libs`" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - # Or resort to GTK+ 2.x - if test "x$SOC_LOADER" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK+ 2.x" >&5 -$as_echo_n "checking for GTK+ 2.x... " >&6; } - if $PKGCONFIG --exists gtk+-2.0; then - SOC_LOADER="dxmain.c" - SOC_CFLAGS="`$PKGCONFIG gtk+-2.0 --cflags`" - SOC_LIBS="`$PKGCONFIG gtk+-2.0 --libs`" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - fi - fi -fi -if test "x$SOC_LOADER" = "x"; then - SOC_LOADER="dxmainc.c" +# Check whether --with-pdftoraster was given. +if test "${with_pdftoraster+set}" = set; then : + withval=$with_pdftoraster; fi +# Check whether --with-local-cups was given. +if test "${with_local_cups+set}" = set; then : + withval=$with_local_cups; with_local_cups=yes +else + with_local_cups=no +fi -# Check whether --with-omni was given. -if test "${with_omni+set}" = set; then : - withval=$with_omni; +# Check whether --with-cups-serverbin was given. +if test "${with_cups_serverbin+set}" = set; then : + withval=$with_cups_serverbin; CUPS_SERVERBIN="$withval" +else + CUPS_SERVERBIN="" fi -OMNIDEVS='' -INCLUDEOMNI=no -if ( ! test -z "$CONTRIBINCLUDE" ) && ( test x$with_omni = xyes ); then - INCLUDEOMNI=yes - OMNIDEVS='$(DD)omni.dev' - if test -n "$GCC"; then - LIBS="$LIBS -lstdc++" - fi + +# Check whether --with-cups-serverroot was given. +if test "${with_cups_serverroot+set}" = set; then : + withval=$with_cups_serverroot; CUPS_SERVERROOT="$withval" +else + CUPS_SERVERROOT="" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 -$as_echo_n "checking for X... " >&6; } -# Check whether --with-x was given. -if test "${with_x+set}" = set; then : - withval=$with_x; +# Check whether --with-cups-datadir was given. +if test "${with_cups_datadir+set}" = set; then : + withval=$with_cups_datadir; CUPS_DATADIR="$withval" +else + CUPS_DATADIR="" fi -# $have_x is `yes', `no', `disabled', or empty when we do not yet know. -if test "x$with_x" = xno; then - # The user explicitly disabled X. - have_x=disabled -else - case $x_includes,$x_libraries in #( - *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + +CUPSDEV="" +CUPSINCLUDE="" +CUPSCFLAGS="" +CUPSLIBS="" +CUPSLIBDIRS="" +CUPSCONFIG="${CUPSCONFIG:=}" +CUPSSERVERBIN="" +CUPSSERVERROOT="" +CUPSDATA="" +CUPSVERSION="0" +CUPSPDFTORASTER="0" +CUPS_DIR="" + +SHARELCUPS=1 +SHARELCUPSI=1 + +if ( test -f $srcdir/cups/gdevcups.c ); then + CUPS_DIR="$srcdir/cups" + if test x$enable_cups != xno; then + if test x$with_local_cups != xyes; then + if test x"$CUPSCONFIG" = x""; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cups-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}cups-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_path_CUPSCONFIG+:} false; then : $as_echo_n "(cached) " >&6 else - # One or both of the vars are not set, and there is no cached value. -ac_x_includes=no ac_x_libraries=no -rm -f -r conftest.dir -if mkdir conftest.dir; then - cd conftest.dir - cat >Imakefile <<'_ACEOF' -incroot: - @echo incroot='${INCROOT}' -usrlibdir: - @echo usrlibdir='${USRLIBDIR}' -libdir: - @echo libdir='${LIBDIR}' -_ACEOF - if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then - # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. - for ac_var in incroot usrlibdir libdir; do - eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" - done - # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. - for ac_extension in a so sl dylib la dll; do - if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && - test -f "$ac_im_libdir/libX11.$ac_extension"; then - ac_im_usrlibdir=$ac_im_libdir; break - fi - done - # Screen out bogus values from the imake configuration. They are - # bogus both because they are the default anyway, and because - # using them would break gcc on systems where it needs fixed includes. - case $ac_im_incroot in - /usr/include) ac_x_includes= ;; - *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; - esac - case $ac_im_usrlibdir in - /usr/lib | /usr/lib64 | /lib | /lib64) ;; - *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; - esac + case $CUPSCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_CUPSCONFIG="$CUPSCONFIG" # Let the user override the test with a path. + ;; + *) + 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_path_CUPSCONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 fi - cd .. - rm -f -r conftest.dir -fi - -# Standard set of common directories for X headers. -# Check X11 before X11Rn because it is often a symlink to the current release. -ac_x_header_dirs=' -/usr/X11/include -/usr/X11R7/include -/usr/X11R6/include -/usr/X11R5/include -/usr/X11R4/include - -/usr/include/X11 -/usr/include/X11R7 -/usr/include/X11R6 -/usr/include/X11R5 -/usr/include/X11R4 - -/usr/local/X11/include -/usr/local/X11R7/include -/usr/local/X11R6/include -/usr/local/X11R5/include -/usr/local/X11R4/include - -/usr/local/include/X11 -/usr/local/include/X11R7 -/usr/local/include/X11R6 -/usr/local/include/X11R5 -/usr/local/include/X11R4 - -/usr/X386/include -/usr/x386/include -/usr/XFree86/include/X11 +done + done +IFS=$as_save_IFS -/usr/include -/usr/local/include -/usr/unsupported/include -/usr/athena/include -/usr/local/x11r5/include -/usr/lpp/Xamples/include + ;; +esac +fi +CUPSCONFIG=$ac_cv_path_CUPSCONFIG +if test -n "$CUPSCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CUPSCONFIG" >&5 +$as_echo "$CUPSCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi -/usr/openwin/include -/usr/openwin/share/include' -if test "$ac_x_includes" = no; then - # Guess where to find include files, by looking for Xlib.h. - # First, try using that file with no special directory specified. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # We can compile using X headers with no special include directory. -ac_x_includes= +fi +if test -z "$ac_cv_path_CUPSCONFIG"; then + ac_pt_CUPSCONFIG=$CUPSCONFIG + # Extract the first word of "cups-config", so it can be a program name with args. +set dummy cups-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_path_ac_pt_CUPSCONFIG+:} false; then : + $as_echo_n "(cached) " >&6 else - for ac_dir in $ac_x_header_dirs; do - if test -r "$ac_dir/X11/Xlib.h"; then - ac_x_includes=$ac_dir - break + case $ac_pt_CUPSCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_CUPSCONFIG="$ac_pt_CUPSCONFIG" # Let the user override the test with a path. + ;; + *) + 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_path_ac_pt_CUPSCONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +ac_pt_CUPSCONFIG=$ac_cv_path_ac_pt_CUPSCONFIG +if test -n "$ac_pt_CUPSCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CUPSCONFIG" >&5 +$as_echo "$ac_pt_CUPSCONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi -rm -f conftest.err conftest.i conftest.$ac_ext -fi # $ac_x_includes = no -if test "$ac_x_libraries" = no; then - # Check for the libraries. - # See if we find them without any special options. - # Don't add to $LIBS permanently. - ac_save_LIBS=$LIBS - LIBS="-lX11 $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -XrmInitialize () - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - LIBS=$ac_save_LIBS -# We can link X programs with no special library path. -ac_x_libraries= + if test "x$ac_pt_CUPSCONFIG" = x; then + CUPSCONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CUPSCONFIG=$ac_pt_CUPSCONFIG + fi else - LIBS=$ac_save_LIBS -for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` -do - # Don't even attempt the hair of trying to link an X program! - for ac_extension in a so sl dylib la dll; do - if test -r "$ac_dir/libX11.$ac_extension"; then - ac_x_libraries=$ac_dir - break 2 - fi - done -done + CUPSCONFIG="$ac_cv_path_CUPSCONFIG" fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi # $ac_x_libraries = no -case $ac_x_includes,$ac_x_libraries in #( - no,* | *,no | *\'*) - # Didn't find X, or a directory has "'" in its name. - ac_cv_have_x="have_x=no";; #( + if test x"$cross_compiling" = x"yes"; then + # Extract the first word of "cups-config", so it can be a program name with args. +set dummy cups-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_path_BUILD_CUPSCONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $BUILD_CUPSCONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_BUILD_CUPSCONFIG="$BUILD_CUPSCONFIG" # Let the user override the test with a path. + ;; *) - # Record where we found X for the cache. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$ac_x_includes'\ - ac_x_libraries='$ac_x_libraries'" + 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_path_BUILD_CUPSCONFIG="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; esac fi -;; #( - *) have_x=yes;; - esac - eval "$ac_cv_have_x" -fi # $with_x != no - -if test "$have_x" != yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 -$as_echo "$have_x" >&6; } - no_x=yes +BUILD_CUPSCONFIG=$ac_cv_path_BUILD_CUPSCONFIG +if test -n "$BUILD_CUPSCONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_CUPSCONFIG" >&5 +$as_echo "$BUILD_CUPSCONFIG" >&6; } else - # If each of the values was on the command line, it overrides each guess. - test "x$x_includes" = xNONE && x_includes=$ac_x_includes - test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries - # Update the cache value to reflect the command line values. - ac_cv_have_x="have_x=yes\ - ac_x_includes='$x_includes'\ - ac_x_libraries='$x_libraries'" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 -$as_echo "libraries $x_libraries, headers $x_includes" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi -if test "$no_x" = yes; then - # Not all programs may use this symbol, but it does not hurt to define it. -$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h + if test x"$BUILD_CUPSCONFIG" = x"$CUPSCONFIG" ; then + CUPSCONFIG= + fi + fi + fi + # check for a libcups header + ac_fn_c_check_header_mongrel "$LINENO" "cups/cups.h" "ac_cv_header_cups_cups_h" "$ac_includes_default" +if test "x$ac_cv_header_cups_cups_h" = xyes; then : - X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else - if test -n "$x_includes"; then - X_CFLAGS="$X_CFLAGS -I$x_includes" - fi + CUPSCONFIG="" +fi - # It would also be nice to do this for all -L options, not just this one. - if test -n "$x_libraries"; then - X_LIBS="$X_LIBS -L$x_libraries" - # For Solaris; some versions of Sun CC require a space after -R and - # others require no space. Words are not sufficient . . . . - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 -$as_echo_n "checking whether -R must be followed by a space... " >&6; } - ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" - ac_xsave_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int -main () -{ + # And check for a libcupsimage header + if test "x$CUPSCONFIG" != x; then + ac_fn_c_check_header_mongrel "$LINENO" "cups/raster.h" "ac_cv_header_cups_raster_h" "$ac_includes_default" +if test "x$ac_cv_header_cups_raster_h" = xyes; then : - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - X_LIBS="$X_LIBS -R$x_libraries" else - LIBS="$ac_xsave_LIBS -R $x_libraries" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + CUPSCONFIG="" +fi -int -main () -{ - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - X_LIBS="$X_LIBS -R $x_libraries" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 -$as_echo "neither works" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_c_werror_flag=$ac_xsave_c_werror_flag - LIBS=$ac_xsave_LIBS + fi + + if test "x$CUPSCONFIG" != x; then + CUPSCFLAGS="`$CUPSCONFIG --cflags` $CFLAGS" +# CUPSLINK="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --static --image --libs | sed -e '1,$s/-lssl//'` $LIBS" + CUPSLINK="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --image --libs`" + CUPSAPIVERSION="`$CUPSCONFIG --api-version`" + + +# the makefile wants a list of just the library names +for gs_item in $CUPSLINK; do + gs_stripped_item=`echo "$gs_item" | sed -e 's/^-l//'` + if test "x$gs_stripped_item" != "x$gs_item"; then + CUPSLIBS="$CUPSLIBS $gs_stripped_item" fi +done - # Check for system-dependent libraries X programs must link with. - # Do this before checking for the system-independent R6 libraries - # (-lICE), since we may need -lsocket or whatever for X linking. - if test "$ISC" = yes; then - X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" - else - # Martyn Johnson says this is needed for Ultrix, if the X - # libraries were built with DECnet support. And Karl Berry says - # the Alpha needs dnet_stub (dnet does not exist). - ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +for gs_item in $CUPSLINK; do + gs_stripped_item=`echo "$gs_item" | sed -e 's/-L//'` + if test "x$gs_stripped_item" != "x$gs_item"; then + CUPSLIBDIRS="$CUPSLIBDIRS $gs_stripped_item" + fi +done -/* 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 XOpenDisplay (); -int -main () -{ -return XOpenDisplay (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 -$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldnet $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + if test "x$CUPS_SERVERROOT" != "x"; then + CUPSSERVERROOT="$CUPS_SERVERROOT" + else + CUPSSERVERROOT="`$CUPSCONFIG --serverroot`" + fi -/* 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 dnet_ntoa (); -int -main () -{ -return dnet_ntoa (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dnet_dnet_ntoa=yes -else - ac_cv_lib_dnet_dnet_ntoa=no + if test "x$CUPS_SERVERBIN" != "x"; then + CUPSSERVERBIN="$CUPS_SERVERBIN" + else + CUPSSERVERBIN="`$CUPSCONFIG --serverbin`" + fi + + if test "x$CUPS_DATADIR" != "x"; then + CUPSDATA="$CUPS_DATADIR" + else + CUPSDATA="`$CUPSCONFIG --datadir`" + fi + + CUPSINCLUDE="include $srcdir/cups/cups.mak" + CUPSDEV="cups" + + # pwgraster support arrived in cups 1.5.x + if test "$CUPSAPIVERSION" ">" "1.4" ; then + CUPSDEV="$CUPSDEV pwgraster" + fi + + CUPSVERSION="`$CUPSCONFIG --version`" + + LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" + LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" + if ( test x$with_pdftoraster != xno ); then + if test "$CUPSVERSION" ">" "1.2"; then + CUPSPDFTORASTER="1" + fi + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: USING LOCAL CUPS SOURCE" >&5 +$as_echo "$as_me: WARNING: USING LOCAL CUPS SOURCE" >&2;} + SHARELCUPS=0 + SHARELCUPSI=0 + LCUPSBUILDTYPE=linux + LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" + LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" + CUPSDEV="cups pwgraster" + fi + fi fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + +#AC_SUBST(CUPSDEV) + + + + + + + + + + + + + + + + + + + + +# Check whether --with-ijs was given. +if test "${with_ijs+set}" = set; then : + withval=$with_ijs; fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 -$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" + + +if test x"$cross_compiling" != x"yes"; then + case `uname` in + MINGW*|MSYS*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling the ijs device" >&5 +$as_echo "$as_me: WARNING: disabling the ijs device" >&2;} + with_ijs=no + ;; + *) + ;; + esac fi - if test $ac_cv_lib_dnet_dnet_ntoa = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 -$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : + IJSDIR=src + IJSDEVS='' + SHAREIJS=0 +if test x$with_ijs != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local ijs library source" >&5 +$as_echo_n "checking for local ijs library source... " >&6; } + if test -d $srcdir/ijs; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + IJSDIR=$srcdir/ijs + IJSDEVS='ijs' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ijs_server_init in -lijs" >&5 +$as_echo_n "checking for ijs_server_init in -lijs... " >&6; } +if ${ac_cv_lib_ijs_ijs_server_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-ldnet_stub $LIBS" +LIBS="-lijs $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7603,154 +8325,203 @@ #ifdef __cplusplus extern "C" #endif -char dnet_ntoa (); +char ijs_server_init (); int main () { -return dnet_ntoa (); +return ijs_server_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dnet_stub_dnet_ntoa=yes + ac_cv_lib_ijs_ijs_server_init=yes else - ac_cv_lib_dnet_stub_dnet_ntoa=no + ac_cv_lib_ijs_ijs_server_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 -$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" -fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ijs_ijs_server_init" >&5 +$as_echo "$ac_cv_lib_ijs_ijs_server_init" >&6; } +if test "x$ac_cv_lib_ijs_ijs_server_init" = xyes; then : - fi + for ac_header in ijs/ijs.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "ijs/ijs.h" "ac_cv_header_ijs_ijs_h" "$ac_includes_default" +if test "x$ac_cv_header_ijs_ijs_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_IJS_IJS_H 1 +_ACEOF + SHAREIJS=1 fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$ac_xsave_LIBS" - # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, - # to get the SysV transport functions. - # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) - # needs -lnsl. - # The nsl library prevents programs from opening the X display - # on Irix 5.2, according to T.E. Dickey. - # The functions gethostbyname, getservbyname, and inet_addr are - # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. - ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : +done + fi - if test $ac_cv_func_gethostbyname = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 -$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + if test $SHAREIJS -eq 1 ; then + IJSLIB=ijs + # This is for safety - it prevents our header search path going outside the GS source tree + IJSDIR='$(GLOBJDIR)' + IJSDEVS='ijs' + fi + fi +fi -/* 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 gethostbyname (); -int -main () -{ -return gethostbyname (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nsl_gethostbyname=yes -else - ac_cv_lib_nsl_gethostbyname=no + + +#AC_SUBST(IJSDEVS) + + +JBIG2_DECODER= +JBIG2DIR=src +SHARE_JBIG2=0 +JBIG2DEVS='' +JBIG2_AUTOCONF_CFLAGS= + +LURATECHDIR=luratech + + +# Check whether --with-luratech was given. +if test "${with_luratech+set}" = set; then : + withval=$with_luratech; fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + + + +if test x$with_luratech != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local Luratech JBIG2 library source" >&5 +$as_echo_n "checking for local Luratech JBIG2 library source... " >&6; } + if test -d $srcdir/luratech/ldf_jb2; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + JBIG2_DECODER=luratech + SHARE_JBIG2=0 + JBIG2DIR=$srcdir/luratech/ldf_jb2 + + if test x"$cross_compiling" = x"yes"; then + if test x"$JBIG2_CFLAGS" != x""; then + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char $JBIG2_CFLAGS" + else + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" + fi + else + case `uname` in + Darwin*) + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD -fsigned-char" + ;; + AIX) + if test $ac_cv_c_compiler_gnu = yes; then + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" + else + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -qchars=signed -DLINUX=1 -DFORTE" + fi + ;; + *) + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" + ;; + esac + fi + + JBIG2FILEDEVS='$(DD)gdevjbig2.dev' + JBIG2DEVS='$(PSD)jbig2.dev' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 -$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" + +JB2_STDINT_TYPES_IN= + +if test "x$JBIG2_DECODER" = x; then + +# Check whether --with-jbig2dec was given. +if test "${with_jbig2dec+set}" = set; then : + withval=$with_jbig2dec; fi - if test $ac_cv_lib_nsl_gethostbyname = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 -$as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbsd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + if test x$with_jbig2dec != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local jbig2dec library source" >&5 +$as_echo_n "checking for local jbig2dec library source... " >&6; } + for d in $srcdir/jbig2dec $srcdir/jbig2dec-0.2 $srcdir/jbig2dec-0.3; do + test -d "$d" && JBIG2DIR=$d && break + done + if test "x$JBIG2DIR" != xsrc; then + JBIG2_DECODER=jbig2dec + if test x$ac_cv_header_stdint_h = xyes ; then + JBIG2_AUTOCONF_CFLAGS="-DHAVE_STDINT_H=1" + else -/* 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 gethostbyname (); + for include in sys/types.h inttypes.h sys/inttypes.h sys/int_types.h ; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint32_t in $include" >&5 +$as_echo_n "checking for uint32_t in $include... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$include> int main () { -return gethostbyname (); +uint32_t canary; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bsd_gethostbyname=yes -else - ac_cv_lib_bsd_gethostbyname=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 -$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" -fi +if ac_fn_c_try_compile "$LINENO"; then : - fi - fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + stdint_types_in="$include" + break; - # lieder@skyler.mavd.honeywell.com says without -lsocket, - # socket/setsockopt and other routines are undefined under SCO ODT - # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary - # on later versions), says Simon Leinen: it contains gethostby* - # variants that don't use the name server (or something). -lsocket - # must be given before -lnsl if both are needed. We assume that - # if connect needs -lnsl, so does gethostbyname. - ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done - if test $ac_cv_func_connect = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 -$as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : + case "$stdint_types_in" in + "sys/types.h") + JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_SYS_TYPES_H" + ;; + "inttypes.h") + JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_INTTYPES_H" + ;; + "sys/inttypes.h") + JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_SYS_INTTYPES_H" + ;; + "sys/int_types.h") + JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DSTD_INT_USE_SYS_INT_TYPES_H" + ;; + *) + as_fn_error $? " + Unable to find suitable definitions of the stdint.h types (uint32_t and friends). + These are required by jbig2dec. + " "$LINENO" 5 + esac + fi + + if test "x$BIGENDIAN" != "x0"; then + JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DWORDS_BIGENDIAN" + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JBIG2DIR" >&5 +$as_echo "$JBIG2DIR" >&6; } + echo "Continuing with Ghostscript configuration..." + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jbig2_page_out in -ljbig2dec" >&5 +$as_echo_n "checking for jbig2_page_out in -ljbig2dec... " >&6; } +if ${ac_cv_lib_jbig2dec_jbig2_page_out+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $X_EXTRA_LIBS $LIBS" +LIBS="-ljbig2dec $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7760,221 +8531,220 @@ #ifdef __cplusplus extern "C" #endif -char connect (); +char jbig2_page_out (); int main () { -return connect (); +return jbig2_page_out (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_connect=yes + ac_cv_lib_jbig2dec_jbig2_page_out=yes else - ac_cv_lib_socket_connect=no + ac_cv_lib_jbig2dec_jbig2_page_out=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 -$as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : - X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jbig2dec_jbig2_page_out" >&5 +$as_echo "$ac_cv_lib_jbig2dec_jbig2_page_out" >&6; } +if test "x$ac_cv_lib_jbig2dec_jbig2_page_out" = xyes; then : + + SHARE_JBIG2=1 + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: disabling support for JBIG2 files" >&5 +$as_echo "$as_me: WARNING: disabling support for JBIG2 files" >&2;} + with_jbig2dec=no + fi + if test x$with_jbig2dec != xno; then + JBIG2_DECODER=jbig2dec + fi fi + fi + if test x$with_jbig2dec != xno; then +# I *think* jbig2dec handles these being missing gracefully +# if test x$ac_cv_header_stdint_h != xyes && test x$ac_cv_header_inttypes_h != xyes; then +# AC_MSG_WARN([JBIG2 support requires stdint types which do not seem to be available.]) +# else + JBIG2DEVS='$(PSD)jbig2.dev' +# fi + fi +fi - # Guillermo Gomez says -lposix is necessary on A/UX. - ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = xyes; then : -fi - if test $ac_cv_func_remove = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 -$as_echo_n "checking for remove in -lposix... " >&6; } -if ${ac_cv_lib_posix_remove+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lposix $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 remove (); -int -main () -{ -return remove (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_posix_remove=yes -else - ac_cv_lib_posix_remove=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 -$as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" -fi - fi - # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. - ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = xyes; then : +JPXDIR=src +SHARE_JPX=0 +JPXDEVS='' +JPX_DECODER= +JPX_AUTOCONF_CFLAGS= +JPX_LRINTF_SUBST= + +if test x$with_luratech != xno; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local Luratech JPEG2K library source" >&5 +$as_echo_n "checking for local Luratech JPEG2K library source... " >&6; } + if test -d $srcdir/luratech/lwf_jp2; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + JPX_DECODER=luratech + SHARE_JPX=0 + JPXDIR=$srcdir/luratech/lwf_jp2 + + if test x"$cross_compiling" = x"yes"; then + if test x"$JPX_CFLAGS" != x""; then + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 $JPX_CFLAGS" + else + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX=1 -DFORTE" + fi + else + case `uname` in + Darwin*) + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD" + ;; + AIX) + if test $ac_cv_c_compiler_gnu = yes; then + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -fsigned-char -DLINUX=1 -DFORTE" + else + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -qchars=signed -DLINUX=1 -DFORTE" + fi + ;; + *) + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX=1 -DFORTE" + ;; + esac + fi + JPXDEVS='$(PSD)jpx.dev' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi fi - if test $ac_cv_func_shmat = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 -$as_echo_n "checking for shmat in -lipc... " >&6; } -if ${ac_cv_lib_ipc_shmat+:} false; then : - $as_echo_n "(cached) " >&6 +if test "x$ac_cv_header_stdint_h" = "xyes"; then + CFLAGS_OPJ_HAVE_STDINT_H="-DOPJ_HAVE_STDINT_H=1" else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lipc $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + CFLAGS_OPJ_HAVE_STDINT_H= +fi -/* 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 shmat (); -int -main () -{ -return shmat (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ipc_shmat=yes + +if test "x$ac_cv_header_inttypes_h" = "xyes"; then + CFLAGS_OPJ_HAVE_INTTYPES_H="-DOPJ_HAVE_INTTYPES_H=1" else - ac_cv_lib_ipc_shmat=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 -$as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = xyes; then : - X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" + CFLAGS_OPJ_HAVE_INTTYPES_H= fi - fi - fi - - # Check for libraries that X11R6 Xt/Xaw programs need. - ac_save_LDFLAGS=$LDFLAGS - test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" - # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to - # check for ICE first), but we must link in the order -lSM -lICE or - # we get undefined symbols. So assume we have SM if we have ICE. - # These have to be linked with before -lX11, unlike the other - # libraries we check for below, so use a different variable. - # John Interrante, Karl Berry - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 -$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : - $as_echo_n "(cached) " >&6 +if test "x$BIGENDIAN" != "x0"; then + CFLAGS_OPJ_BIGENDIAN="-DOPJ_BIG_ENDIAN" else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lICE $X_EXTRA_LIBS $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + CFLAGS_OPJ_BIGENDIAN= +fi -/* 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 IceConnectionNumber (); -int -main () -{ -return IceConnectionNumber (); - ; - return 0; -} +for ac_func in fseeko +do : + ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" +if test "x$ac_cv_func_fseeko" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FSEEKO 1 _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ICE_IceConnectionNumber=yes + CFLAGS_OPJ_HAVE_FSEEKO="-DOPJ_HAVE_FSEEKO=1" else - ac_cv_lib_ICE_IceConnectionNumber=no + CFLAGS_OPJ_HAVE_STDINT_H= fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +done + + +JPX_SSE_CFLAGS="" + +if test "x$HAVE_SSE2" = "x" ; then + if test $ac_cv_c_compiler_gnu = yes; then + JPX_SSE_CFLAGS="-U__SSE__" + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 -$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : - X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" + +ac_fn_c_check_decl "$LINENO" "lrintf" "ac_cv_have_decl_lrintf" "#include +" +if test "x$ac_cv_have_decl_lrintf" = xyes; then : + +else + OPJ_LRINTF_SUBST="-D\"lrintf(a)\"=\"((long)(a+0.5))\"" fi - LDFLAGS=$ac_save_LDFLAGS +# Check whether --enable-openjpeg was given. +if test "${enable_openjpeg+set}" = set; then : + enableval=$enable_openjpeg; fi -X_LDFLAGS="" -X_CFLAGS="" -X_DEVS="" -X_LIBS="" +OPENJPEGDIR=$srcdir/openjpeg -if test x$no_x != xyes; then - if test "$x_libraries" = "/usr/lib"; then - echo "Ignoring X library directory \"$x_libraries\" requested by configure." - x_libraries="NONE" - fi - if test ! "$x_libraries" = "NONE" -a ! "$x_libraries" = ""; then - X_LDFLAGS="-L$x_libraries" - if test "$uname" = "SunOS"; then - X_LDFLAGS="$X_LDFLAGS -R$x_libraries" - fi - fi +if test "x$JPX_DECODER" = "x"; then + if test "x$enable_openjpeg" != "xno"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for local OpenJPEG library source" >&5 +$as_echo_n "checking for local OpenJPEG library source... " >&6; } + if test -e $OPENJPEGDIR/src/lib/openjp2/openjpeg.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + JPXDIR="$OPENJPEGDIR" + JPX_DECODER=openjpeg + SHARE_JPX=0 + for ac_func in memalign +do : + ac_fn_c_check_func "$LINENO" "memalign" "ac_cv_func_memalign" +if test "x$ac_cv_func_memalign" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MEMALIGN 1 +_ACEOF + have_memalign=1 +fi +done - if test "$x_includes" = "/usr/include"; then - echo "Ignoring X include directory \"$x_includes\" requested by configure." - x_includes="NONE" - fi - if test ! "$x_includes" = "NONE" -a ! "$x_includes" = ""; then - X_CFLAGS="-I$x_includes" - fi - SAVELIBS="$LIBS" - SAVELDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $X_LDFLAGS" + if test "x$have_memalign" = "x1"; then + JPX_AUTOCONF_CFLAGS="" + else + JPX_AUTOCONF_CFLAGS="-D\"memalign(a,b)=malloc(b)\"" + fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDisplay in -lX11" >&5 -$as_echo_n "checking for XOpenDisplay in -lX11... " >&6; } -if ${ac_cv_lib_X11_XOpenDisplay+:} false; then : + JPX_AUTOCONF_CFLAGS="$JPX_AUTOCONF_CFLAGS -DMUTEX_pthread=0 $OPJ_LRINTF_SUBST -DUSE_JPIP -DUSE_OPENJPEG_JP2 $CFLAGS_OPJ_HAVE_STDINT_H $CFLAGS_OPJ_HAVE_INTTYPES_H $CFLAGS_OPJ_BIGENDIAN $CFLAGS_OPJ_HAVE_FSEEKO" + + JPXDEVS='$(PSD)jpx.dev' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + if test x"$PKGCONFIG" != x""; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenJPEG2" >&5 +$as_echo_n "checking for OpenJPEG2... " >&6; } + if $PKGCONFIG --exists libopenjp2; then + JPX_AUTOCONF_CFLAGS="`$PKGCONFIG libopenjp2 --cflags` -DUSE_OPENJPEG_JP2" + JPX_AUTOCONF_LIBS="`$PKGCONFIG libopenjp2 --libs`" + SHARE_JPX=1 + JPX_DECODER=openjpeg + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_stream_set_user_data in -lopenjp2" >&5 +$as_echo_n "checking for opj_stream_set_user_data in -lopenjp2... " >&6; } +if ${ac_cv_lib_openjp2_opj_stream_set_user_data+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lX11 $LIBS" +LIBS="-lopenjp2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7984,1432 +8754,3332 @@ #ifdef __cplusplus extern "C" #endif -char XOpenDisplay (); +char opj_stream_set_user_data (); int main () { -return XOpenDisplay (); +return opj_stream_set_user_data (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_X11_XOpenDisplay=yes + ac_cv_lib_openjp2_opj_stream_set_user_data=yes else - ac_cv_lib_X11_XOpenDisplay=no + ac_cv_lib_openjp2_opj_stream_set_user_data=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XOpenDisplay" >&5 -$as_echo "$ac_cv_lib_X11_XOpenDisplay" >&6; } -if test "x$ac_cv_lib_X11_XOpenDisplay" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBX11 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openjp2_opj_stream_set_user_data" >&5 +$as_echo "$ac_cv_lib_openjp2_opj_stream_set_user_data" >&6; } +if test "x$ac_cv_lib_openjp2_opj_stream_set_user_data" = xyes; then : + JPX_AUTOCONF_CFLAGS="$JPX_AUTOCONF_CFLAGS $OPJ_LRINTF_SUBST -DUSE_JPIP -DUSE_OPENJPEG_JP2 $CFLAGS_OPJ_HAVE_STDINT_H $CFLAGS_OPJ_HAVE_INTTYPES_H $CFLAGS_OPJ_BIGENDIAN $CFLAGS_OPJ_HAVE_FSEEKO"; + JPX_AUTOCONF_LIBS="-lopenjp2"; + SHARE_JPX=1 - LIBS="-lX11 $LIBS" +fi + fi + fi + fi fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XdbeQueryExtension in -lXext" >&5 -$as_echo_n "checking for XdbeQueryExtension in -lXext... " >&6; } -if ${ac_cv_lib_Xext_XdbeQueryExtension+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXext $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 XdbeQueryExtension (); -int -main () -{ -return XdbeQueryExtension (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xext_XdbeQueryExtension=yes -else - ac_cv_lib_Xext_XdbeQueryExtension=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XdbeQueryExtension" >&5 -$as_echo "$ac_cv_lib_Xext_XdbeQueryExtension" >&6; } -if test "x$ac_cv_lib_Xext_XdbeQueryExtension" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBXEXT 1 -_ACEOF - LIBS="-lXext $LIBS" -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XtAppCreateShell in -lXt" >&5 -$as_echo_n "checking for XtAppCreateShell in -lXt... " >&6; } -if ${ac_cv_lib_Xt_XtAppCreateShell+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXt $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 XtAppCreateShell (); -int -main () -{ -return XtAppCreateShell (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xt_XtAppCreateShell=yes -else - ac_cv_lib_Xt_XtAppCreateShell=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xt_XtAppCreateShell" >&5 -$as_echo "$ac_cv_lib_Xt_XtAppCreateShell" >&6; } -if test "x$ac_cv_lib_Xt_XtAppCreateShell" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBXT 1 -_ACEOF - LIBS="-lXt $LIBS" +# Check whether --enable-gtk was given. +if test "${enable_gtk+set}" = set; then : + enableval=$enable_gtk; fi +SOC_CFLAGS="" +SOC_LIBS="" +SOC_LOADER="" +if test "x$enable_gtk" != "xno"; then + # Try GTK+ 3.x first... + if test "x$PKGCONFIG" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK+ 3.x" >&5 +$as_echo_n "checking for GTK+ 3.x... " >&6; } + if $PKGCONFIG --exists gtk+-3.0; then + SOC_LOADER="dxmain" + SOC_CFLAGS="`$PKGCONFIG gtk+-3.0 --cflags`" + SOC_LIBS="`$PKGCONFIG gtk+-3.0 --libs`" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi - LDFLAGS="$SAVELDFLAGS" - LIBS="$SAVELIBS" - - if test "$ac_cv_lib_Xt_XtAppCreateShell" = yes; then - X11DEVS="x11 x11alpha x11cmyk x11mono x11_ x11alt_ x11cmyk2 x11cmyk4 x11cmyk8 x11rg16x x11rg32x x11gray2 x11gray4" - X_DEVS=$X11DEVS - # the makefile wants a list of just the library names in X_LIBS - -# the makefile wants a list of just the library names -for gs_item in -lXt $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS; do - gs_stripped_item=`echo "$gs_item" | sed -e 's/^-l//'` - if test "x$gs_stripped_item" != "x$gs_item"; then - X_LIBS="$X_LIBS $gs_stripped_item" - fi -done - + # Or resort to GTK+ 2.x + if test "x$SOC_LOADER" = "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK+ 2.x" >&5 +$as_echo_n "checking for GTK+ 2.x... " >&6; } + if $PKGCONFIG --exists gtk+-2.0; then + SOC_LOADER="dxmain" + SOC_CFLAGS="`$PKGCONFIG gtk+-2.0 --cflags`" + SOC_LIBS="`$PKGCONFIG gtk+-2.0 --libs`" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi fi + fi fi - - - -#AC_SUBST(X_DEVS) -#AC_SUBST(X11DEVS) - - - -# Check whether --with-gs was given. -if test "${with_gs+set}" = set; then : - withval=$with_gs; GS="$with_gs" -else - GS='gs' +if test "x$SOC_LOADER" = "x"; then + SOC_LOADER="dxmainc" fi -COMPILE_INITS="1" -# Check whether --enable-compile-inits was given. -if test "${enable_compile_inits+set}" = set; then : - enableval=$enable_compile_inits; - if test "x$enable_compile_inits" = xno; then - COMPILE_INITS="0" - fi -fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 +$as_echo_n "checking for X... " >&6; } -# Check whether --with-drivers was given. -if test "${with_drivers+set}" = set; then : - withval=$with_drivers; drivers="$withval" -else - drivers="ALL" +# Check whether --with-x was given. +if test "${with_x+set}" = set; then : + withval=$with_x; fi - - -# Check whether --with-driversfile was given. -if test "${with_driversfile+set}" = set; then : - withval=$with_driversfile; driversfile="$withval" +# $have_x is `yes', `no', `disabled', or empty when we do not yet know. +if test "x$with_x" = xno; then + # The user explicitly disabled X. + have_x=disabled else - driversfile="" + case $x_includes,$x_libraries in #( + *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( + *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : + $as_echo_n "(cached) " >&6 +else + # One or both of the vars are not set, and there is no cached value. +ac_x_includes=no ac_x_libraries=no +rm -f -r conftest.dir +if mkdir conftest.dir; then + cd conftest.dir + cat >Imakefile <<'_ACEOF' +incroot: + @echo incroot='${INCROOT}' +usrlibdir: + @echo usrlibdir='${USRLIBDIR}' +libdir: + @echo libdir='${LIBDIR}' +_ACEOF + if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then + # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. + for ac_var in incroot usrlibdir libdir; do + eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" + done + # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. + for ac_extension in a so sl dylib la dll; do + if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && + test -f "$ac_im_libdir/libX11.$ac_extension"; then + ac_im_usrlibdir=$ac_im_libdir; break + fi + done + # Screen out bogus values from the imake configuration. They are + # bogus both because they are the default anyway, and because + # using them would break gcc on systems where it needs fixed includes. + case $ac_im_incroot in + /usr/include) ac_x_includes= ;; + *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; + esac + case $ac_im_usrlibdir in + /usr/lib | /usr/lib64 | /lib | /lib64) ;; + *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; + esac + fi + cd .. + rm -f -r conftest.dir fi +# Standard set of common directories for X headers. +# Check X11 before X11Rn because it is often a symlink to the current release. +ac_x_header_dirs=' +/usr/X11/include +/usr/X11R7/include +/usr/X11R6/include +/usr/X11R5/include +/usr/X11R4/include -if test "x$driversfile" != x; then - # Add drivers from file... - drivers="`tr '\n' ',' <$driversfile`" -fi +/usr/include/X11 +/usr/include/X11R7 +/usr/include/X11R6 +/usr/include/X11R5 +/usr/include/X11R4 -P_DEVS0="" -F_DEVS0="" -CUPS_DEVS0="" -SVG_DEVS0="" -XPS_DEVS0="" -JBIG2_DEVS="" -IJS_DEVS0="" -PNG_DEVS0="" -X11_DEVS0="" +/usr/local/X11/include +/usr/local/X11R7/include +/usr/local/X11R6/include +/usr/local/X11R5/include +/usr/local/X11R4/include +/usr/local/include/X11 +/usr/local/include/X11R7 +/usr/local/include/X11R6 +/usr/local/include/X11R5 +/usr/local/include/X11R4 -HP_DEVS='cdj500 djet500 djet500c dnj650c cljet5pr deskjet laserjet ljetplus ljet2p ljet3 ljet3d ljet4 ljet4d lj4dith lj5mono lj5gray cdeskjet cdjcolor cdjmono cdj550 pj pjxl pjxl300 lp2563 paintjet pjetxl cljet5 cljet5c pxlmono pxlcolor cdj670 cdj850 cdj880 cdj890 cdj970 cdj1600 cdnj500 chp2200 pcl3 hpdjplus hpdjportable hpdj310 hpdj320 hpdj340 hpdj400 hpdj500 hpdj500c hpdj510 hpdj520 hpdj540 hpdj550c hpdj560c hpdj600 hpdj660c hpdj670c hpdj680c hpdj690c hpdj850c hpdj855c hpdj870c hpdj890c hpdj1120c lj3100sw' -PCLXL_DEVS='pxlmono pxlcolor' -EPSON_DEVS='eps9high eps9mid epson epsonc escp lp8000 lq850 photoex st800 stcolor alc1900 alc2000 alc4000 alc4100 alc8500 alc8600 alc9100 lp3000c lp8000c lp8200c lp8300c lp8500c lp8800c lp9000c lp9200c lp9500c lp9800c lps6500 epl2050 epl2050p epl2120 epl2500 epl2750 epl5800 epl5900 epl6100 epl6200 lp1800 lp1900 lp2200 lp2400 lp2500 lp7500 lp7700 lp7900 lp8100 lp8300f lp8400f lp8600 lp8600f lp8700 lp8900 lp9000b lp9100 lp9200b lp9300 lp9400 lp9600 lp9600s lps4500 eplcolor eplmono' -CANON_DEVS='bj10e bj200 bjc600 bjc800 lbp8 lips3 bjcmono bjcgray bjccmyk bjccolor' -LEXMARK_DEVS='lxm5700m lxm3200 lex2050 lex3200 lex5700 lex7000' -BROTHER_DEVS='hl7x0 hl1240 hl1250' -APPLE_DEVS='appledmp iwhi iwlo iwlq' -IBM_DEVS='ibmpro jetp3852' +/usr/X386/include +/usr/x386/include +/usr/XFree86/include/X11 + +/usr/include +/usr/local/include +/usr/unsupported/include +/usr/athena/include +/usr/local/x11r5/include +/usr/lpp/Xamples/include + +/usr/openwin/include +/usr/openwin/share/include' + +if test "$ac_x_includes" = no; then + # Guess where to find include files, by looking for Xlib.h. + # First, try using that file with no special directory specified. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # We can compile using X headers with no special include directory. +ac_x_includes= +else + for ac_dir in $ac_x_header_dirs; do + if test -r "$ac_dir/X11/Xlib.h"; then + ac_x_includes=$ac_dir + break + fi +done +fi +rm -f conftest.err conftest.i conftest.$ac_ext +fi # $ac_x_includes = no + +if test "$ac_x_libraries" = no; then + # Check for the libraries. + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS=$LIBS + LIBS="-lX11 $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +XrmInitialize () + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + LIBS=$ac_save_LIBS +# We can link X programs with no special library path. +ac_x_libraries= +else + LIBS=$ac_save_LIBS +for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +do + # Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl dylib la dll; do + if test -r "$ac_dir/libX11.$ac_extension"; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi # $ac_x_libraries = no + +case $ac_x_includes,$ac_x_libraries in #( + no,* | *,no | *\'*) + # Didn't find X, or a directory has "'" in its name. + ac_cv_have_x="have_x=no";; #( + *) + # Record where we found X for the cache. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$ac_x_includes'\ + ac_x_libraries='$ac_x_libraries'" +esac +fi +;; #( + *) have_x=yes;; + esac + eval "$ac_cv_have_x" +fi # $with_x != no + +if test "$have_x" != yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 +$as_echo "$have_x" >&6; } + no_x=yes +else + # If each of the values was on the command line, it overrides each guess. + test "x$x_includes" = xNONE && x_includes=$ac_x_includes + test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries + # Update the cache value to reflect the command line values. + ac_cv_have_x="have_x=yes\ + ac_x_includes='$x_includes'\ + ac_x_libraries='$x_libraries'" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 +$as_echo "libraries $x_libraries, headers $x_includes" >&6; } +fi + +if test "$no_x" = yes; then + # Not all programs may use this symbol, but it does not hurt to define it. + +$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h + + X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= +else + if test -n "$x_includes"; then + X_CFLAGS="$X_CFLAGS -I$x_includes" + fi + + # It would also be nice to do this for all -L options, not just this one. + if test -n "$x_libraries"; then + X_LIBS="$X_LIBS -L$x_libraries" + # For Solaris; some versions of Sun CC require a space after -R and + # others require no space. Words are not sufficient . . . . + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 +$as_echo_n "checking whether -R must be followed by a space... " >&6; } + ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" + ac_xsave_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + X_LIBS="$X_LIBS -R$x_libraries" +else + LIBS="$ac_xsave_LIBS -R $x_libraries" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + X_LIBS="$X_LIBS -R $x_libraries" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 +$as_echo "neither works" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_c_werror_flag=$ac_xsave_c_werror_flag + LIBS=$ac_xsave_LIBS + fi + + # Check for system-dependent libraries X programs must link with. + # Do this before checking for the system-independent R6 libraries + # (-lICE), since we may need -lsocket or whatever for X linking. + + if test "$ISC" = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" + else + # Martyn Johnson says this is needed for Ultrix, if the X + # libraries were built with DECnet support. And Karl Berry says + # the Alpha needs dnet_stub (dnet does not exist). + ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" + 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 XOpenDisplay (); +int +main () +{ +return XOpenDisplay (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 +$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } +if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet $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 dnet_ntoa (); +int +main () +{ +return dnet_ntoa (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dnet_dnet_ntoa=yes +else + ac_cv_lib_dnet_dnet_ntoa=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 +$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } +if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 +$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } +if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldnet_stub $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 dnet_ntoa (); +int +main () +{ +return dnet_ntoa (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dnet_stub_dnet_ntoa=yes +else + ac_cv_lib_dnet_stub_dnet_ntoa=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 +$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +fi + + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$ac_xsave_LIBS" + + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to T.E. Dickey. + # The functions gethostbyname, getservbyname, and inet_addr are + # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. + ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes; then : + +fi + + if test $ac_cv_func_gethostbyname = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $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 gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +fi + + if test $ac_cv_lib_nsl_gethostbyname = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 +$as_echo_n "checking for gethostbyname in -lbsd... " >&6; } +if ${ac_cv_lib_bsd_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $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 gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_bsd_gethostbyname=yes +else + ac_cv_lib_bsd_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 +$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } +if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" +fi + + fi + fi + + # lieder@skyler.mavd.honeywell.com says without -lsocket, + # socket/setsockopt and other routines are undefined under SCO ODT + # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary + # on later versions), says Simon Leinen: it contains gethostby* + # variants that don't use the name server (or something). -lsocket + # must be given before -lnsl if both are needed. We assume that + # if connect needs -lnsl, so does gethostbyname. + ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" +if test "x$ac_cv_func_connect" = xyes; then : + +fi + + if test $ac_cv_func_connect = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 +$as_echo_n "checking for connect in -lsocket... " >&6; } +if ${ac_cv_lib_socket_connect+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $X_EXTRA_LIBS $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 connect (); +int +main () +{ +return connect (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_connect=yes +else + ac_cv_lib_socket_connect=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 +$as_echo "$ac_cv_lib_socket_connect" >&6; } +if test "x$ac_cv_lib_socket_connect" = xyes; then : + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +fi + + fi + + # Guillermo Gomez says -lposix is necessary on A/UX. + ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" +if test "x$ac_cv_func_remove" = xyes; then : + +fi + + if test $ac_cv_func_remove = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 +$as_echo_n "checking for remove in -lposix... " >&6; } +if ${ac_cv_lib_posix_remove+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lposix $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 remove (); +int +main () +{ +return remove (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_posix_remove=yes +else + ac_cv_lib_posix_remove=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 +$as_echo "$ac_cv_lib_posix_remove" >&6; } +if test "x$ac_cv_lib_posix_remove" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" +if test "x$ac_cv_func_shmat" = xyes; then : + +fi + + if test $ac_cv_func_shmat = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 +$as_echo_n "checking for shmat in -lipc... " >&6; } +if ${ac_cv_lib_ipc_shmat+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lipc $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 shmat (); +int +main () +{ +return shmat (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ipc_shmat=yes +else + ac_cv_lib_ipc_shmat=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 +$as_echo "$ac_cv_lib_ipc_shmat" >&6; } +if test "x$ac_cv_lib_ipc_shmat" = xyes; then : + X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" +fi + + fi + fi + + # Check for libraries that X11R6 Xt/Xaw programs need. + ac_save_LDFLAGS=$LDFLAGS + test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" + # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to + # check for ICE first), but we must link in the order -lSM -lICE or + # we get undefined symbols. So assume we have SM if we have ICE. + # These have to be linked with before -lX11, unlike the other + # libraries we check for below, so use a different variable. + # John Interrante, Karl Berry + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 +$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } +if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lICE $X_EXTRA_LIBS $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 IceConnectionNumber (); +int +main () +{ +return IceConnectionNumber (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ICE_IceConnectionNumber=yes +else + ac_cv_lib_ICE_IceConnectionNumber=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 +$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +fi + + LDFLAGS=$ac_save_LDFLAGS + +fi + + +X_LDFLAGS="" +X_CFLAGS="" +X_DEVS="" +X_LIBS="" + +if test x$no_x != xyes; then + if test "$x_libraries" = "/usr/lib"; then + echo "Ignoring X library directory \"$x_libraries\" requested by configure." + x_libraries="NONE" + fi + if test ! "$x_libraries" = "NONE" -a ! "$x_libraries" = ""; then + X_LDFLAGS="-L$x_libraries" + if test "$uname" = "SunOS"; then + X_LDFLAGS="$X_LDFLAGS -R$x_libraries" + fi + fi + + if test "$x_includes" = "/usr/include"; then + echo "Ignoring X include directory \"$x_includes\" requested by configure." + x_includes="NONE" + fi + if test ! "$x_includes" = "NONE" -a ! "$x_includes" = ""; then + X_CFLAGS="-I$x_includes" + fi + + SAVELIBS="$LIBS" + SAVELDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $X_LDFLAGS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDisplay in -lX11" >&5 +$as_echo_n "checking for XOpenDisplay in -lX11... " >&6; } +if ${ac_cv_lib_X11_XOpenDisplay+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lX11 $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 XOpenDisplay (); +int +main () +{ +return XOpenDisplay (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_X11_XOpenDisplay=yes +else + ac_cv_lib_X11_XOpenDisplay=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XOpenDisplay" >&5 +$as_echo "$ac_cv_lib_X11_XOpenDisplay" >&6; } +if test "x$ac_cv_lib_X11_XOpenDisplay" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBX11 1 +_ACEOF + + LIBS="-lX11 $LIBS" + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XdbeQueryExtension in -lXext" >&5 +$as_echo_n "checking for XdbeQueryExtension in -lXext... " >&6; } +if ${ac_cv_lib_Xext_XdbeQueryExtension+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXext $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 XdbeQueryExtension (); +int +main () +{ +return XdbeQueryExtension (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xext_XdbeQueryExtension=yes +else + ac_cv_lib_Xext_XdbeQueryExtension=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xext_XdbeQueryExtension" >&5 +$as_echo "$ac_cv_lib_Xext_XdbeQueryExtension" >&6; } +if test "x$ac_cv_lib_Xext_XdbeQueryExtension" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBXEXT 1 +_ACEOF + + LIBS="-lXext $LIBS" + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XtAppCreateShell in -lXt" >&5 +$as_echo_n "checking for XtAppCreateShell in -lXt... " >&6; } +if ${ac_cv_lib_Xt_XtAppCreateShell+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXt $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 XtAppCreateShell (); +int +main () +{ +return XtAppCreateShell (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_Xt_XtAppCreateShell=yes +else + ac_cv_lib_Xt_XtAppCreateShell=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xt_XtAppCreateShell" >&5 +$as_echo "$ac_cv_lib_Xt_XtAppCreateShell" >&6; } +if test "x$ac_cv_lib_Xt_XtAppCreateShell" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBXT 1 +_ACEOF + + LIBS="-lXt $LIBS" + +fi + + + LDFLAGS="$SAVELDFLAGS" + LIBS="$SAVELIBS" + + if test "$ac_cv_lib_Xt_XtAppCreateShell" = yes; then + X11DEVS="x11 x11alpha x11cmyk x11mono x11_ x11alt_ x11cmyk2 x11cmyk4 x11cmyk8 x11rg16x x11rg32x x11gray2 x11gray4" + X_DEVS=$X11DEVS + # the makefile wants a list of just the library names in X_LIBS + +# the makefile wants a list of just the library names +for gs_item in -lXt $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS; do + gs_stripped_item=`echo "$gs_item" | sed -e 's/^-l//'` + if test "x$gs_stripped_item" != "x$gs_item"; then + X_LIBS="$X_LIBS $gs_stripped_item" + fi +done + + fi +fi + + + + +#AC_SUBST(X_DEVS) +#AC_SUBST(X11DEVS) + + + +# Check whether --with-gs was given. +if test "${with_gs+set}" = set; then : + withval=$with_gs; GS="$with_gs" +else + GS='gs' +fi + + + +PCL=no_gpcl6 +PCL_TARGET= + +PLROMFS_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PL_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PCL_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PCL_TOP_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PXL_MAK="\$(GLSRCDIR)\$(D)stub.mak" + +if test x"$with_pcl" != x"no" ; then + if test -f $srcdir/pcl/pl/pl.mak; then + +# Check whether --with-pcl was given. +if test "${with_pcl+set}" = set; then : + withval=$with_pcl; PCL="$with_pcl" +else + PCL='gpcl6' +fi + + + PCL_TARGET=gpcl6 + + PLROMFS_MAK="\$(PLSRCDIR)\$(D)plromfs.mak" + PL_MAK="\$(PLSRCDIR)\$(D)pl.mak" + PCL_MAK="\$(PCL5SRCDIR)\$(D)pcl.mak" + PCL_TOP_MAK="\$(PCL5SRCDIR)\$(D)pcl_top.mak" + PXL_MAK="\$(PXLSRCDIR)\$(D)pxl.mak" + fi +fi + + + + + + + + + + +XPS=no_gxps +XPS_TARGET= + +XPS_MAK="\$(GLSRCDIR)\$(D)stub.mak" +XPSROMFS_MAK="\$(GLSRCDIR)\$(D)stub.mak" +# gxps currently depends on code in pl +if test x"$with_xps" != x"no" ; then + if test x"$PCL_TARGET" != x ; then + if test -f $srcdir/xps/xps.mak; then + +# Check whether --with-xps was given. +if test "${with_xps+set}" = set; then : + withval=$with_xps; XPS="$with_xps" +else + XPS='gxps' +fi + + + XPS_TARGET=gxps + XPS_MAK="\$(XPSSRCDIR)\$(D)xps.mak" + XPSROMFS_MAK="\$(XPSSRCDIR)\$(D)xpsromfs.mak" + fi + fi +fi + + + + + + +GPDL=no_gpdl +GPDL_TARGET= + +GPDL_MAK="\$(GLSRCDIR)\$(D)stub.mak" +# in order to build gpdl we need the pdls available + +if test "x$XPS_TARGET" != "x" && test "x$PCL_TARGET" != "x" ; then + if test -f $srcdir/gpdl/gpdl.mak; then + +# Check whether --with-gpdl was given. +if test "${with_gpdl+set}" = set; then : + withval=$with_gpdl; GPDL="$with_gpdl" +else + GPDL='gpdl' +fi + + +# GPDL_TARGET=gpdl + GPDL_MAK="\$(GPDLSRCDIR)\$(D)gpdl.mak" + fi +fi + + + + +COMPILE_INITS="1" +# Check whether --enable-compile-inits was given. +if test "${enable_compile_inits+set}" = set; then : + enableval=$enable_compile_inits; + if test "x$enable_compile_inits" = xno; then + COMPILE_INITS="0" + fi +fi + + + + +# Check whether --with-drivers was given. +if test "${with_drivers+set}" = set; then : + withval=$with_drivers; drivers="$withval" +else + drivers="ALL" +fi + + + +# Check whether --with-driversfile was given. +if test "${with_driversfile+set}" = set; then : + withval=$with_driversfile; driversfile="$withval" +else + driversfile="" +fi + + +if test "x$driversfile" != x; then + # Add drivers from file... + drivers="`tr '\n' ',' <$driversfile`" +fi + +P_DEVS0="" +F_DEVS0="" +CUPS_DEVS0="" +XPS_DEVS0="" +JBIG2_DEVS="" +IJS_DEVS0="" +PNG_DEVS0="" +X11_DEVS0="" + + +HP_DEVS='cdj500 djet500 djet500c dnj650c cljet5pr deskjet laserjet ljetplus ljet2p ljet3 ljet3d ljet4 ljet4d lj4dith lj5mono lj5gray cdeskjet cdjcolor cdjmono cdj550 pj pjxl pjxl300 lp2563 paintjet pjetxl cljet5 cljet5c pxlmono pxlcolor cdj670 cdj850 cdj880 cdj890 cdj970 cdj1600 cdnj500 chp2200 pcl3 hpdjplus hpdjportable hpdj310 hpdj320 hpdj340 hpdj400 hpdj500 hpdj500c hpdj510 hpdj520 hpdj540 hpdj550c hpdj560c hpdj600 hpdj660c hpdj670c hpdj680c hpdj690c hpdj850c hpdj855c hpdj870c hpdj890c hpdj1120c lj3100sw' +PCLXL_DEVS='pxlmono pxlcolor' +EPSON_DEVS='eps9high eps9mid epson epsonc escp lp8000 lq850 photoex st800 stcolor alc1900 alc2000 alc4000 alc4100 alc8500 alc8600 alc9100 lp3000c lp8000c lp8200c lp8300c lp8500c lp8800c lp9000c lp9200c lp9500c lp9800c lps6500 epl2050 epl2050p epl2120 epl2500 epl2750 epl5800 epl5900 epl6100 epl6200 lp1800 lp1900 lp2200 lp2400 lp2500 lp7500 lp7700 lp7900 lp8100 lp8300f lp8400f lp8600 lp8600f lp8700 lp8900 lp9000b lp9100 lp9200b lp9300 lp9400 lp9600 lp9600s lps4500 eplcolor eplmono' +CANON_DEVS='bj10e bj200 bjc600 bjc800 lbp8 lips3 bjcmono bjcgray bjccmyk bjccolor' +LEXMARK_DEVS='lxm5700m lxm3200 lex2050 lex3200 lex5700 lex7000' +BROTHER_DEVS='hl7x0 hl1240 hl1250' +IBM_DEVS='ibmpro jetp3852' OKI_DEVS='oki182 okiibm oki4w' JAPAN_DEVS='lips4 lips4v ljet4pjl lj4dithp dj505j picty180 lips2p bjc880j pr201 pr150 pr1000 pr1000_4 jj100 bj10v bj10vh mj700v2c mj500c mj6000c mj8000c fmpr fmlbp ml600 lbp310 lbp320 md50Mono md50Eco md1xMono escpage lp2000 npdl rpdl' -MISC_PDEVS='uniprint ap3250 atx23 atx24 atx38 coslw2p coslwxl cp50 declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696 t4693d2 t4693d4 t4693d8 dl2100 la50 la70 la75 la75plus ln03 xes md2k md5k gdi samsunggdi' +MISC_PDEVS='uniprint ap3250 atx23 atx24 atx38 itk24i itk38 coslw2p coslwxl declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696 t4693d2 t4693d4 t4693d8 dl2100 la50 la70 la75 la75plus ln03 xes md2k md5k gdi samsunggdi' OPVP_DEVS='opvp oprp' -ETS_HALFTONING_DEVS='rinkj' +ETS_HALFTONING_DEVS='rinkj' + +BMP_DEVS='bmpmono bmpgray bmpsep1 bmpsep8 bmp16 bmp256 bmp16m bmp32b' + +JPEG_DEVS='jpeg jpeggray jpegcmyk' +# PNG_DEVS='png16 png16m png256 pngalpha pnggray pngmono' + +PCX_DEVS='pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk' +PBM_DEVS='pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw pam pamcmyk4 pamcmyk32 plan plang planm planc plank' +PS_DEVS='psdf psdcmyk psdrgb pdfwrite ps2write eps2write bbox txtwrite inkcov ink_cov psdcmykog fpng pdfimage8 pdfimage24 pdfimage32 PCLm' + +# the "display" device isn't an ideal fit in the list below, but it saves adding a "list" for just that one entry +MISC_FDEVS='ccr cif inferno mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm bit bitrgb bitrgbtags bitcmyk devicen spotcmyk xcf plib plibg plibm plibc plibk gprf display' + +XPSDEV=$XPSWRITEDEVICE + +while test -n "$drivers"; do + if echo $drivers |grep "," >/dev/null; then + THIS="`echo $drivers |sed -e 's/,.*//'`" + SEDCMD="s/$THIS,//" + drivers="`echo $drivers |sed -e $SEDCMD`" + else + THIS=$drivers + drivers="" + fi + case "$THIS" in + ALL) + # ALL = PRINTERS + FILES... + if test -z "$drivers"; then + drivers="PRINTERS,FILES,X11" + else + drivers="$drivers,PRINTERS,FILES,X11" + fi + ;; + PRINTERS) + P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS" + IJS_DEVS0="$IJSDEVS" + if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then + P_DEVS0="$P_DEVS0 $OPVP_DEVS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&5 +$as_echo "$as_me: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&2;} + fi + ;; + FILES) + F_DEVS0="$F_DEVS0 $BMP_DEVS $FAX_DEVS $JPEG_DEVS $TIFFDEVS $PCX_DEVS $PBM_DEVS $PS_DEVS $MISC_FDEVS $XPSDEV" + CUPS_DEVS0="$CUPSDEV" + JBIG2_DEVS="$JBIG2FILEDEVS" + PNG_DEVS0="$PNGDEVS" + ;; + BMP) + # BMP file format + F_DEVS0="$F_DEVS0 $BMP_DEVS" + ;; + CANON) + # All Canon printers + P_DEVS0="$P_DEVS0 $CANON_DEVS" + ;; + EPSON) + # All Epson printers + P_DEVS0="$P_DEVS0 $EPSON_DEVS" + ;; + FAX) + # Fax file formats + F_DEVS0="$F_DEVS0 $FAX_DEVS" + ;; + JPEG) + # Jpeg file formats + F_DEVS0="$F_DEVS0 $JPEG_DEVS" + ;; + JBIG2) + # JBIG file formats + JBIG2_DEVS="$JBIG2DEVS" + ;; + PNG) + # PNG file formats + PNG_DEVS0="$PNGDEVS" + ;; + TIFF) + # TIFF file formats + F_DEVS0="$F_DEVS0 $TIFFDEVS" + ;; + PCLXL) + # PCL XL/PCL 6 drivers + F_DEVS0="$F_DEVS0 $PCLXL_DEVS" + ;; + PCX) + # PCX file formats + F_DEVS0="$F_DEVS0 $PCX_DEVS" + ;; + PBM) + # PBM file formats + F_DEVS0="$F_DEVS0 $PBM_DEVS" + ;; + CUPS) + # CUPS file format + CUPS_DEVS0="$CUPSDEV" + ;; + HP) + # All HP printers + P_DEVS0="$P_DEVS0 $HP_DEVS" + ;; + LEXMARK) + # All Lexmark printers + P_DEVS0="$P_DEVS0 $LEXMARK_DEVS" + ;; + BROTHER) + # All Brother printers + P_DEVS0="$P_DEVS0 $BROTHER_DEVS" + ;; + OKI) + # All OKI printers + P_DEVS0="$P_DEVS0 $OKI_DEVS" + ;; + IBM) + # All IBM printers + P_DEVS0="$P_DEVS0 $IBM_DEVS" + ;; + IJS) + # IJS printers + IJS_DEVS0="$IJSDEVS" + ;; + JAPAN) + # All old japanese printers + P_DEVS0="$P_DEVS0 $JAPAN_DEVS" + ;; + PS) + # PostScript/PDF writing + F_DEVS0="$F_DEVS0 $PS_DEVS" + ;; + XPS) + # XPS writing + XPS_DEVS0="$XPSDEV" + ;; + + ETS) + # ETS Halftoning devices + F_DEVS0="$F_DEVS0 $ETS_HALFTONING_DEVS" + ;; + X11) + # X11 display devices + X11_DEVS0="$X_DEVS" + ;; + opvp) + # Open Vector Printing driver... + if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then + P_DEVS0="$P_DEVS0 $OPVP_DEVS" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&5 +$as_echo "$as_me: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&2;} + fi + ;; + *) + # It's a driver name (or a user messup) + P_DEVS0="$P_DEVS0 `echo $THIS |sed -e 's,\.dev$,,'`" + ;; + esac +done + +if test x$enable_threadsafe = xyes; then + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$P_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + P_DEVS0=`echo $P_DEVS0 | sed "s/\b$ntsdev\b//g"` + done + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$F_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + F_DEVS0=`echo $F_DEVS0 | sed "s/\b$ntsdev\b//g"` + done + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$CUPS_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + CUPS_DEVS0=`echo $CUPS_DEVS0 | sed "s/\b$ntsdev\b//g"` + done + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$XPS_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + XPS_DEVS0=`echo $XPS_DEVS0 | sed "s/\b$ntsdev\b//g"` + done + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$IJS_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + IJS_DEVS0=`echo $IJS_DEVS0 | sed "s/\b$ntsdev\b//g"` + done + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$PNG_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + PNG_DEVS0=`echo $PNG_DEVS0 | sed "s/\b$ntsdev\b//g"` + done + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$X11_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + X11_DEVS0=`echo $X11_DEVS0 | sed "s/\b$ntsdev\b//g"` + done + + for ntsdev in $NTS_DEVS ; do + NTS_EXCLUDES="$(echo \"$JBIG2_DEVS{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" + JBIG2_DEVS=`echo $JBIG2_DEVS | sed "s/\b$ntsdev\b//g"` + done + + NTS_EXCLUDES=`echo "$NTS_EXCLUDES" | tr " " "\n" | sort | uniq | tr "\n" " "` +fi # x$enable_threadsafe = xyes + +noncontribmakefiles=`find $srcdir -name '*.mak' -print | grep -v '/contrib/'` + +# No need to include opvp/oprp driver without iconv/libiconv. +if test -n "$P_DEVS0"; then + if test x$found_iconv = xno ; then + P_DEVS0=`echo $P_DEVS0 | sed -e 's|opvp||' -e 's|oprp||'` + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to include opvp/oprp driver due to missing iconv/libiconv..." >&5 +$as_echo "$as_me: WARNING: Unable to include opvp/oprp driver due to missing iconv/libiconv..." >&2;} + fi + +# Remove contributed drivers if requested and make sure we don't have any +# duplicates in there, add $(DD)foo.dev constructs + P_DEVS=`(for i in $P_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null ) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +fi + +if test -n "$F_DEVS0"; then + F_DEVS=`(for i in $F_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +fi + +if test -n "$CUPS_DEVS0"; then + CUPS_DEVS=`(for i in $CUPS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +fi + +if test -n "$XPS_DEVS0"; then + XPS_DEVS=`(for i in $XPS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +fi + +if test -n "$IJS_DEVS0"; then + IJS_DEVS=`(for i in $IJS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +fi + +if test -n "$PNG_DEVS0"; then + PNG_DEVS=`(for i in $PNG_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +fi + +if test -n "$X11_DEVS0"; then + X11_DEVS=`(for i in $X11_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +fi + + + + + + + + + +# This now gets done after handling --enable-dynamic +# AC_SUBST(X11_DEVS) + +DYNAMIC_CFLAGS="" +DYNAMIC_DEVS="" +DYNAMIC_FLAGS="" +GS_DYNAMIC_LDFLAGS="" +PCL_DYNAMIC_LDFLAGS="" +XPS_DYNAMIC_LDFLAGS="" +PDL_DYNAMIC_LDFLAGS="" +DYNAMIC_LIBS="" +INSTALL_SHARED="" +SO_LIB_EXT=".so" +DLL_EXT="" +SO_LIB_VERSION_SEPARATOR="." + +if test x"$cross_compiling" = x"yes"; then + DYNAMIC_CFLAGS="-fPIC" + GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" + if test $ac_cv_c_compiler_gnu = yes; then + # GCC high level flag + DYNAMIC_LIBS="-rdynamic" + else + DYNAMIC_LIBS="" + fi + SO_LIB_EXT=".so" +else + case `uname` in + Linux*|GNU*) + DYNAMIC_CFLAGS="-fPIC" + GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" + if test $ac_cv_c_compiler_gnu = yes; then + # GCC high level flag + DYNAMIC_LIBS="-rdynamic" + else + DYNAMIC_LIBS="" + fi + SO_LIB_EXT=".so" + ;; + MINGW*|MSYS*) + DYNAMIC_CFLAGS="" + GS_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(GS_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(PCL_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(XPS_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(PDL_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + SO_LIB_EXT="" + DLL_EXT=".dll" + SO_LIB_VERSION_SEPARATOR="-" + ;; + *BSD) + DYNAMIC_CFLAGS="-fPIC" + GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + DYNAMIC_LIBS="" + SO_LIB_EXT=".so" + ;; + Darwin*) + GS_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(GS_SONAME_MAJOR_MINOR)" + PCL_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(PCL_SONAME_MAJOR_MINOR)" + XPS_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(XPS_SONAME_MAJOR_MINOR)" + PDL_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(GPDL_SONAME_MAJOR_MINOR)" + DYNAMIC_LIBS="" + SO_LIB_EXT=".dylib" + ;; + SunOS) + if test $ac_cv_c_compiler_gnu = yes; then + DYNAMIC_CFLAGS="-fPIC" + else + DYNAMIC_CFLAGS="-KPIC" + fi + GS_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" + DYNAMIC_LIBS="" + SO_LIB_EXT=".so" + ;; + AIX) + if test $ac_cv_c_compiler_gnu = yes; then + DYNAMIC_CFLAGS="-fPIC" + GCFLAGS="-Wl,-brtl -D_LARGE_FILES $GCFLAGS" + GS_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + else + DYNAMIC_CFLAGS="" + GCFLAGS="-Wl,-brtl -D_LARGE_FILES $GCFLAGS" + GS_DYNAMIC_LDFLAGS="-G -qmkshrobj -Wl,-brtl,-G" + PCL_DYNAMIC_LDFLAGS="-G -qmkshrobj -Wl,-brtl,-G" + XPS_DYNAMIC_LDFLAGS="-G -qmkshrobj -Wl,-brtl,-G" + fi + SO_LIB_EXT=".so" + ;; + esac +fi + +# Check whether --enable-dynamic was given. +if test "${enable_dynamic+set}" = set; then : + enableval=$enable_dynamic; + if test "x$enable_dynamic" != xno; then + case `uname` in + Linux*|GNU*) + INSTALL_SHARED="install-shared" + if test "x$X_DEVS" != x; then + DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" + else + DYNAMIC_DEVS="" + fi + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + X11_DEVS="" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + *BSD) + DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + X11_DEVS="" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + Darwin*) + INSTALL_SHARED="install-shared" + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + X11_DEVS="" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + SunOS) + DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + *) + as_fn_error $? "Sorry, dynamic driver support not available on this platform!" "$LINENO" 5 + ;; + esac + fi + +fi + + + + + + + + + + + + + + + + + +# Check whether --with-fontpath was given. +if test "${with_fontpath+set}" = set; then : + withval=$with_fontpath; fontpath="$withval" +else + fontpath="" +fi + + +if test "x$prefix" = xNONE; then + prefix=/usr/local +fi + +if test "x$datadir" = 'x${prefix}/share'; then + datadir="$prefix/share" +fi + +if test "x$fontpath" = "x"; then + # These font directories are used by various Linux distributions... + fontpath="$datadir/fonts/default/ghostscript" + fontpath="${fontpath}:$datadir/fonts/default/Type1" + fontpath="${fontpath}:$datadir/fonts/default/TrueType" + + # These font directories are used by IRIX... + fontpath="${fontpath}:/usr/lib/DPS/outline/base" + + # These font directories are used by Solaris... + fontpath="${fontpath}:/usr/openwin/lib/X11/fonts/Type1" + fontpath="${fontpath}:/usr/openwin/lib/X11/fonts/TrueType" + + # This font directory is used by CUPS... + if test "x$CUPSCONFIG" != x; then + fontpath="${fontpath}:`$CUPSCONFIG --datadir`/fonts" + fi +fi + + + + +for ac_func in mkstemp +do : + ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp" +if test "x$ac_cv_func_mkstemp" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MKSTEMP 1 +_ACEOF + HAVE_MKSTEMP=-DHAVE_MKSTEMP +fi +done + + + +for ac_func in fopen64 +do : + ac_fn_c_check_func "$LINENO" "fopen64" "ac_cv_func_fopen64" +if test "x$ac_cv_func_fopen64" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FOPEN64 1 +_ACEOF + HAVE_FILE64=-DHAVE_FILE64 +fi +done + + + +for ac_func in fseeko +do : + ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" +if test "x$ac_cv_func_fseeko" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FSEEKO 1 +_ACEOF + HAVE_FSEEKO=-DHAVE_FSEEKO +fi +done + + + +for ac_func in mkstemp64 +do : + ac_fn_c_check_func "$LINENO" "mkstemp64" "ac_cv_func_mkstemp64" +if test "x$ac_cv_func_mkstemp64" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MKSTEMP64 1 +_ACEOF + HAVE_MKSTEMP64=-DHAVE_MKSTEMP64 +fi +done + + + +for ac_func in setlocale +do : + ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" +if test "x$ac_cv_func_setlocale" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SETLOCALE 1 +_ACEOF + HAVE_SETLOCALE=-DHAVE_SETLOCALE +fi +done + + + +for ac_func in strerror +do : + ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" +if test "x$ac_cv_func_strerror" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRERROR 1 +_ACEOF + HAVE_STRERROR=-DHAVE_STRERROR +fi +done + + + +for ac_func in isnan +do : + ac_fn_c_check_func "$LINENO" "isnan" "ac_cv_func_isnan" +if test "x$ac_cv_func_isnan" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ISNAN 1 +_ACEOF + HAVE_ISNAN=-DHAVE_ISNAN +fi +done + + + +for ac_func in isinf +do : + ac_fn_c_check_func "$LINENO" "isinf" "ac_cv_func_isinf" +if test "x$ac_cv_func_isinf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ISINF 1 +_ACEOF + HAVE_ISINF=-DHAVE_ISINF +fi +done + + + +for ac_func in fpclassify +do : + ac_fn_c_check_func "$LINENO" "fpclassify" "ac_cv_func_fpclassify" +if test "x$ac_cv_func_fpclassify" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FPCLASSIFY 1 +_ACEOF + HAVE_FPCLASSIFY=-DHAVE_FPCLASSIFY +fi +done + + + +if test $ac_cv_c_compiler_gnu = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 +$as_echo_n "checking whether $CC needs -traditional... " >&6; } +if ${ac_cv_prog_gcc_traditional+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_pattern="Autoconf.*'x'" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TIOCGETP +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +else + ac_cv_prog_gcc_traditional=no +fi +rm -f conftest* + + + if test $ac_cv_prog_gcc_traditional = no; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +Autoconf TCGETA +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "$ac_pattern" >/dev/null 2>&1; then : + ac_cv_prog_gcc_traditional=yes +fi +rm -f conftest* + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 +$as_echo "$ac_cv_prog_gcc_traditional" >&6; } + if test $ac_cv_prog_gcc_traditional = yes; then + CC="$CC -traditional" + fi +fi + + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include +#ifdef HAVE_VFORK_H +# include +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include , but some compilers + (e.g. gcc -O) don't grok . Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + +for ac_header in stdlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" +if test "x$ac_cv_header_stdlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDLIB_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 +$as_echo_n "checking for GNU libc compatible malloc... " >&6; } +if ${ac_cv_func_malloc_0_nonnull+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_malloc_0_nonnull=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include +#else +char *malloc (); +#endif + +int +main () +{ +return ! malloc (0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_malloc_0_nonnull=yes +else + ac_cv_func_malloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 +$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } +if test $ac_cv_func_malloc_0_nonnull = yes; then : + +$as_echo "#define HAVE_MALLOC 1" >>confdefs.h + +else + $as_echo "#define HAVE_MALLOC 0" >>confdefs.h + + case " $LIBOBJS " in + *" malloc.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS malloc.$ac_objext" + ;; +esac + -BMP_DEVS='bmpmono bmpgray bmpsep1 bmpsep8 bmp16 bmp256 bmp16m bmp32b' +$as_echo "#define malloc rpl_malloc" >>confdefs.h -JPEG_DEVS='jpeg jpeggray jpegcmyk' -# PNG_DEVS='png16 png16m png256 pngalpha pnggray pngmono' +fi -PCX_DEVS='pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk pcx2up' -PBM_DEVS='pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw pam pamcmyk4 pamcmyk32 plan plang planm planc plank' -PS_DEVS='psdf psdcmyk psdrgb pdfwrite ps2write epswrite bbox txtwrite inkcov' -MISC_FDEVS='ccr cif inferno mag16 mag256 mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm sgirgb sunhmono bit bitrgb bitrgbtags bitcmyk devicen spotcmyk xcf' -SVGDEV='svgwrite' -XPSDEV='xpswrite' -while test -n "$drivers"; do - if echo $drivers |grep "," >/dev/null; then - THIS="`echo $drivers |sed -e 's/,.*//'`" - SEDCMD="s/$THIS,//" - drivers="`echo $drivers |sed -e $SEDCMD`" - else - THIS=$drivers - drivers="" - fi - case "$THIS" in - ALL) - # ALL = PRINTERS + FILES... - if test -z "$drivers"; then - drivers="PRINTERS,FILES,X11" - else - drivers="$drivers,PRINTERS,FILES,X11" - fi - ;; - PRINTERS) - P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $APPLE_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS" - IJS_DEVS0="$IJSDEVS" - if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then - P_DEVS0="$P_DEVS0 $OPVP_DEVS" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&5 -$as_echo "$as_me: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&2;} - fi - ;; - FILES) - F_DEVS0="$F_DEVS0 $BMP_DEVS $FAX_DEVS $JPEG_DEVS $TIFFDEVS $PCX_DEVS $PBM_DEVS $PS_DEVS $MISC_FDEVS $SVGDEV $XPSDEV" - CUPS_DEVS0="$CUPSDEV" - JBIG2_DEVS="$JBIG2FILEDEVS" - PNG_DEVS0="$PNGDEVS" - ;; - APPLE) - # All Apple printers - P_DEVS0="$P_DEVS0 $APPLE_DEVS" - ;; - BMP) - # BMP file format - F_DEVS0="$F_DEVS0 $BMP_DEVS" - ;; - CANON) - # All Canon printers - P_DEVS0="$P_DEVS0 $CANON_DEVS" - ;; - EPSON) - # All Epson printers - P_DEVS0="$P_DEVS0 $EPSON_DEVS" - ;; - FAX) - # Fax file formats - F_DEVS0="$F_DEVS0 $FAX_DEVS" - ;; - JPEG) - # Jpeg file formats - F_DEVS0="$F_DEVS0 $JPEG_DEVS" - ;; - JBIG2) - # JBIG file formats - JBIG2_DEVS="$JBIG2DEVS" - ;; - PNG) - # PNG file formats - PNG_DEVS0="$PNGDEVS" - ;; - TIFF) - # TIFF file formats - F_DEVS0="$F_DEVS0 $TIFFDEVS" - ;; - PCLXL) - # PCL XL/PCL 6 drivers - F_DEVS0="$F_DEVS0 $PCLXL_DEVS" - ;; - PCX) - # PCX file formats - F_DEVS0="$F_DEVS0 $PCX_DEVS" - ;; - PBM) - # PBM file formats - F_DEVS0="$F_DEVS0 $PBM_DEVS" - ;; - CUPS) - # CUPS file format - CUPS_DEVS0="$CUPSDEV" - ;; - HP) - # All HP printers - P_DEVS0="$P_DEVS0 $HP_DEVS" - ;; - LEXMARK) - # All Lexmark printers - P_DEVS0="$P_DEVS0 $LEXMARK_DEVS" - ;; - BROTHER) - # All Brother printers - P_DEVS0="$P_DEVS0 $BROTHER_DEVS" - ;; - OKI) - # All OKI printers - P_DEVS0="$P_DEVS0 $OKI_DEVS" - ;; - IBM) - # All IBM printers - P_DEVS0="$P_DEVS0 $IBM_DEVS" - ;; - IJS) - # IJS printers - IJS_DEVS0="$IJSDEVS" - ;; - JAPAN) - # All old japanese printers - P_DEVS0="$P_DEVS0 $JAPAN_DEVS" - ;; - PS) - # PostScript/PDF writing - F_DEVS0="$F_DEVS0 $PS_DEVS" - ;; - SVG) - # SVG writing - SVG_DEVS0="$SVGDEV" - ;; - XPS) - # SVG writing - XPS_DEVS0="$XPSDEV" - ;; +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 +$as_echo_n "checking for working memcmp... " >&6; } +if ${ac_cv_func_memcmp_working+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_memcmp_working=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_memcmp_working=yes +else + ac_cv_func_memcmp_working=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 +$as_echo "$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } +if ${ac_cv_type_signal+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_signal=int +else + ac_cv_type_signal=void +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5 +$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; } +if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f conftest.sym conftest.file +echo >conftest.file +if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then + if test "$cross_compiling" = yes; then : + ac_cv_func_lstat_dereferences_slashed_symlink=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + /* Linux will dereference the symlink and fail, as required by POSIX. + That is better in the sense that it means we will not + have to compile and use the lstat wrapper. */ + return lstat ("conftest.sym/", &sbuf) == 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_lstat_dereferences_slashed_symlink=yes +else + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi - ETS) - # ETS Halftoning devices - F_DEVS0="$F_DEVS0 $ETS_HALFTONING_DEVS" - ;; - X11) - # X11 display devices - X11_DEVS0="$X_DEVS" - ;; - opvp) - # Open Vector Printing driver... - if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then - P_DEVS0="$P_DEVS0 $OPVP_DEVS" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&5 -$as_echo "$as_me: WARNING: Unable to include opvp/oprp driver due to missing or disabled prerequisites..." >&2;} - fi - ;; - *) - # It's a driver name (or a user messup) - P_DEVS0="$P_DEVS0 `echo $THIS |sed -e 's,\.dev$,,'`" - ;; - esac +else + # If the `ln -s' command failed, then we probably don't even + # have an lstat function. + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f conftest.sym conftest.file + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 +$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } + +test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && + +cat >>confdefs.h <<_ACEOF +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +_ACEOF + + +if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then + case " $LIBOBJS " in + *" lstat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; +esac + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5 +$as_echo_n "checking whether stat accepts an empty string... " >&6; } +if ${ac_cv_func_stat_empty_string_bug+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_stat_empty_string_bug=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + return stat ("", &sbuf) == 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_stat_empty_string_bug=no +else + ac_cv_func_stat_empty_string_bug=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5 +$as_echo "$ac_cv_func_stat_empty_string_bug" >&6; } +if test $ac_cv_func_stat_empty_string_bug = yes; then + case " $LIBOBJS " in + *" stat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS stat.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<_ACEOF +#define HAVE_STAT_EMPTY_STRING_BUG 1 +_ACEOF + +fi + +for ac_func in vprintf +do : + ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" +if test "x$ac_cv_func_vprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VPRINTF 1 +_ACEOF + +ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" +if test "x$ac_cv_func__doprnt" = xyes; then : + +$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h + +fi + +fi done -if test x$enable_threadsafe = xyes; then - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$P_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - P_DEVS0=`echo $P_DEVS0 | sed "s/\b$ntsdev\b//g"` - done +for ac_func in bzero dup2 floor gettimeofday memchr memmove memset mkdir mkfifo modf pow putenv rint setenv sqrt strchr strrchr strspn strstr +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$F_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - F_DEVS0=`echo $F_DEVS0 | sed "s/\b$ntsdev\b//g"` - done +fi +done - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$CUPS_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - CUPS_DEVS0=`echo $CUPS_DEVS0 | sed "s/\b$ntsdev\b//g"` - done - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$SVG_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - SVG_DEVS0=`echo $SVG_DEVS0 | sed "s/\b$ntsdev\b//g"` - done - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$XPS_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - XPS_DEVS0=`echo $XPS_DEVS0 | sed "s/\b$ntsdev\b//g"` - done +case `uname -a` in + *sparc*) + GCFLAGS="$GCFLAGS -DGS_USE_MEMORY_HEADER_ID=0" + ;; +esac - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$IJS_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - IJS_DEVS0=`echo $IJS_DEVS0 | sed "s/\b$ntsdev\b//g"` - done +LCMS_ENDIAN= +LCMS2_ENDIAN= - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$PNG_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - PNG_DEVS0=`echo $PNG_DEVS0 | sed "s/\b$ntsdev\b//g"` - done +if test x"$BIGENDIAN" != x"0"; then + LCMS_ENDIAN="-DUSE_BIG_ENDIAN=$BIGENDIAN" + LCMS2_ENDIAN="-DCMS_USE_BIG_ENDIAN=$BIGENDIAN" +fi - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$X11_DEVS0{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - X11_DEVS0=`echo $X11_DEVS0 | sed "s/\b$ntsdev\b//g"` - done - for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$JBIG2_DEVS{@:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - JBIG2_DEVS=`echo $JBIG2_DEVS | sed "s/\b$ntsdev\b//g"` - done - NTS_EXCLUDES=`echo "$NTS_EXCLUDES" | tr " " "\n" | sort | uniq | tr "\n" " "` -fi # x$enable_threadsafe = xyes -noncontribmakefiles=`find $srcdir -name '*.mak' -print | grep -v '^\./contrib/'` -# No need to include opvp/oprp driver without iconv/libiconv. -if test -n "$P_DEVS0"; then - if test x$found_iconv = xno ; then - P_DEVS0=`echo $P_DEVS0 | sed -e 's|opvp||' -e 's|oprp||'` - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to include opvp/oprp driver due to missing iconv/libiconv..." >&5 -$as_echo "$as_me: WARNING: Unable to include opvp/oprp driver due to missing iconv/libiconv..." >&2;} - fi +ALIGN_TEXT_PROG_INCS="\ +#include \ +#include " + + +ALIGN_TEXT_PROG="\ + struct altest \ + { \ + char a; \ + int b; \ + long c; \ + long long d; \ + float e; \ + double f; \ + void *g; \ + }; \ + struct altest *a; \ + struct altest d; \ + char *b, *c, *lim; \ + int ret = 0; \ + c = b = malloc(64 * sizeof(struct altest)); \ + lim = b + (64 * sizeof(struct altest)); \ + do \ + { \ + b++; \ + if ((b >= lim) || \ + ((((unsigned int)b) & 4) == 0 && (((unsigned int)b) & 8) != 0)) \ + { \ + break; \ + } \ + } while(1); \ + if (b >= lim) \ + { \ + ret = -1; \ + } \ + else \ + { \ + a = (struct altest *)b; \ + b = a->g; \ + ret = 0; \ + } \ + free(c); \ + exit(ret);" + + +GS_MEMPTR_ALIGNMENT= + + +# Check whether --with-memory-alignment was given. +if test "${with_memory_alignment+set}" = set; then : + withval=$with_memory_alignment; GS_MEMPTR_ALIGNMENT=$with_memory_alignment +else + GS_MEMPTR_ALIGNMENT=check +fi -# Remove contributed drivers if requested and make sure we don't have any -# duplicates in there, add $(DD)foo.dev constructs - P_DEVS=`(for i in $P_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null ) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` + +if test x"$GS_MEMPTR_ALIGNMENT" = xcheck ; then + if test x"$cross_compiling" = x"no"; then + case `uname` in + HP-UX) + GS_MEMPTR_ALIGNMENT=8 + ;; + SunOS) + GS_MEMPTR_ALIGNMENT=8 + ;; + AIX) + GS_MEMPTR_ALIGNMENT=8 + ;; + esac + fi fi -if test -n "$F_DEVS0"; then - F_DEVS=`(for i in $F_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +if test x"$GS_MEMPTR_ALIGNMENT" = xcheck ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking minimum memory pointer alignment" >&5 +$as_echo_n "checking minimum memory pointer alignment... " >&6; } + if test "$cross_compiling" = yes; then : + GS_MEMPTR_ALIGNMENT=4;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: cross compiling: assuming 4 byte - otherwise use \"--with-memory-alignment=\"" >&5 +$as_echo "cross compiling: assuming 4 byte - otherwise use \"--with-memory-alignment=\"" >&6; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ALIGN_TEXT_PROG_INCS +int +main () +{ + + $ALIGN_TEXT_PROG + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + GS_MEMPTR_ALIGNMENT=4;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } +else + GS_MEMPTR_ALIGNMENT=8;{ $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -if test -n "$CUPS_DEVS0"; then - CUPS_DEVS=`(for i in $CUPS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` + fi -if test -n "$SVG_DEVS0"; then - SVG_DEVS=`(for i in $SVG_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +if test x"$GS_MEMPTR_ALIGNMENT" != x4 && test x"$GS_MEMPTR_ALIGNMENT" != x8 ; then + as_fn_error -1 "4 and 8 are the only valid values for \"--with-memory-alignment\"" "$LINENO" 5 fi -if test -n "$XPS_DEVS0"; then - XPS_DEVS=`(for i in $XPS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +if test x"$GS_MEMPTR_ALIGNMENT" != x4 || test x"$with_memory_alignment" != x ; then + LCMS2_PTR_ALIGNMENT="-DCMS_PTR_ALIGNMENT=$GS_MEMPTR_ALIGNMENT" + + GCFLAGS="$GCFLAGS -DGS_MEMPTR_ALIGNMENT=$GS_MEMPTR_ALIGNMENT" +fi + + + + +ac_fn_c_check_func "$LINENO" "sqrtf" "ac_cv_func_sqrtf" +if test "x$ac_cv_func_sqrtf" = xyes; then : + SQRTF_SUBST= +else + SQRTF_SUBST="-Dsqrtf=\"(float)sqrt\"" +fi + + + + +for ac_func in strnlen +do : + ac_fn_c_check_func "$LINENO" "strnlen" "ac_cv_func_strnlen" +if test "x$ac_cv_func_strnlen" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRNLEN 1 +_ACEOF + HAVE_STRNLEN= +else + HAVE_STRNLEN="-D\"strnlen(a,b)=strlen(a)\"" +fi +done + + +GCFLAGS="$GCFLAGS $HAVE_STRNLEN" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking byteswap support" >&5 +$as_echo_n "checking byteswap support... " >&6; } + +HAVE_BSWAP32="" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + int a = 0; + int b = __builtin_bswap32(a); + return(0); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + HAVE_BSWAP32="-DHAVE_BSWAP32" +else + HAVE_BSWAP32="" fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext -if test -n "$IJS_DEVS0"; then - IJS_DEVS=`(for i in $IJS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +# Check whether --enable-bswap32 was given. +if test "${enable_bswap32+set}" = set; then : + enableval=$enable_bswap32; + if test "x$enable_bswap32" = xno; then + HAVE_BSWAP32="" + fi fi -if test -n "$PNG_DEVS0"; then - PNG_DEVS=`(for i in $PNG_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` -fi -if test -n "$X11_DEVS0"; then - X11_DEVS=`(for i in $X11_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` +if test "x$HAVE_BSWAP32" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for byteswap.h" >&5 +$as_echo_n "checking for byteswap.h... " >&6; } +HAVE_BYTESWAP_H="" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include "byteswap.h" +int +main () +{ + int a = 0; + int b = __builtin_bswap32(a); + return(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + HAVE_BYTESWAP_H="-DHAVE_BYTESWAP_H" +else + HAVE_BYTESWAP_H="" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Check whether --enable-byteswap-h was given. +if test "${enable_byteswap_h+set}" = set; then : + enableval=$enable_byteswap_h; + if test "x$enable_byteswap-h" = xno; then + HAVE_BYTESWAP_H="" + fi +fi - -# This now gets done after handling --enable-dynamic -# AC_SUBST(X11_DEVS) - -DYNAMIC_CFLAGS="" -DYNAMIC_DEVS="" -DYNAMIC_FLAGS="" -DYNAMIC_LDFLAGS="" -DYNAMIC_LIBS="" -INSTALL_SHARED="" -SO_LIB_EXT=".so" -DLL_EXT="" -SO_LIB_VERSION_SEPARATOR="." - -case `uname` in - Linux*|GNU*) - DYNAMIC_CFLAGS="-fPIC" - DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" - if test $ac_cv_c_compiler_gnu = yes; then - # GCC high level flag - DYNAMIC_LIBS="-rdynamic -ldl" - else - DYNAMIC_LIBS="" - fi - SO_LIB_EXT=".so" - ;; - MINGW*) - DYNAMIC_CFLAGS="" - DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(GS_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" - SO_LIB_EXT="" - DLL_EXT=".dll" - SO_LIB_VERSION_SEPARATOR="-" - ;; - *BSD) - DYNAMIC_CFLAGS="-fPIC" - DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" - DYNAMIC_LIBS="" - SO_LIB_EXT=".so" - ;; - Darwin*) - DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(GS_SONAME_MAJOR_MINOR)" - DYNAMIC_LIBS="" - SO_LIB_EXT=".dylib" - ;; - SunOS) - if test $ac_cv_c_compiler_gnu = yes; then - DYNAMIC_CFLAGS="-fPIC" - else - DYNAMIC_CFLAGS="-KPIC" - fi - - DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" - DYNAMIC_LIBS="" - SO_LIB_EXT=".so" - ;; -esac - -# Check whether --enable-dynamic was given. -if test "${enable_dynamic+set}" = set; then : - enableval=$enable_dynamic; - if test "x$enable_dynamic" != xno; then - case `uname` in - Linux*|GNU*) - INSTALL_SHARED="install-shared" - if test "x$X_DEVS" != x; then - DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" - else - DYNAMIC_DEVS="" - fi - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - X11_DEVS="" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - *BSD) - DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - X11_DEVS="" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - Darwin*) - INSTALL_SHARED="install-shared" - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - X11_DEVS="" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - SunOS) - DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - *) - as_fn_error $? "Sorry, dynamic driver support not available on this platform!" "$LINENO" 5 - ;; - esac - fi - +if test "x$HAVE_BYTESWAP_H" != x; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi +# -------------------------------------------------- +# Sun, BSD possibly other makes don't have quite the +# feature set of GNU make. We still prefer GNU make, +# but...... +# -------------------------------------------------- +# Check whether --with-gnu-make was given. +if test "${with_gnu_make+set}" = set; then : + withval=$with_gnu_make; gnu_make=no +fi +if test "x$gnu_make" != "xno"; then + SUB_MAKE_OPTION="-f \$(MAKEFILE)" + ORDER_ONLY="|" +else + SUB_MAKE_OPTION= + ORDER_ONLY="" +fi +# -------------------------------------------------- +# annoying: Windows doesn't allow "aux" as a +# directory nor file name, so if we're building in +# mingw, add the same prefix as the VS build uses +# -------------------------------------------------- +AUXDIRPOSTFIX="" +case `uname` in + MINGW*|MSYS*) + AUXDIRPOSTFIX="_" + if test x"$cross_compiling" != x"yes"; then + CFLAGS="-DGS_NO_UTF8=1 $CFLAGS" + fi + ;; +esac +# -------------------------------------------------- +# Set executable name extention +# usually empty on Unix-like systems +# -------------------------------------------------- +EXEEXT="" -# Check whether --with-fontpath was given. -if test "${with_fontpath+set}" = set; then : - withval=$with_fontpath; fontpath="$withval" +# Check whether --with-exe-ext was given. +if test "${with_exe_ext+set}" = set; then : + withval=$with_exe_ext; else - fontpath="" + exe_ext= fi -if test "x$prefix" = xNONE; then - prefix=/usr/local -fi - -if test "x$datadir" = 'x${prefix}/share'; then - datadir="$prefix/share" +if test "x"$with_exe_ext != "x"; then + EXEEXT="$with_exe_ext" +else + if test x"$cross_compiling" != x"yes"; then + case `uname` in + MINGW*|MSYS*) + EXEEXT=".exe" + ;; + esac + fi fi -if test "x$fontpath" = "x"; then - # These font directories are used by various Linux distributions... - fontpath="$datadir/fonts/default/ghostscript" - fontpath="${fontpath}:$datadir/fonts/default/Type1" - fontpath="${fontpath}:$datadir/fonts/default/TrueType" - # These font directories are used by IRIX... - fontpath="${fontpath}:/usr/lib/DPS/outline/base" - # These font directories are used by Solaris... - fontpath="${fontpath}:/usr/openwin/lib/X11/fonts/Type1" - fontpath="${fontpath}:/usr/openwin/lib/X11/fonts/TrueType" +# -------------------------------------------------- +# Check for disabling of versioned path option. +# By default the versioned path must be enabled! +# Using this option is user's own risk & responsibility. +# -------------------------------------------------- - # This font directory is used by CUPS... - if test "x$CUPSCONFIG" != x; then - fontpath="${fontpath}:`$CUPSCONFIG --datadir`/fonts" - fi +# Check whether --with-versioned-path was given. +if test "${with_versioned_path+set}" = set; then : + withval=$with_versioned_path; versioned_path=no fi - - -for ac_func in mkstemp -do : - ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp" -if test "x$ac_cv_func_mkstemp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_MKSTEMP 1 -_ACEOF - HAVE_MKSTEMP=-DHAVE_MKSTEMP +if test "x$versioned_path" != "xno"; then + VERSIONED_PATH='/$(GS_DOT_VERSION)' +else + VERSIONED_PATH='' fi -done - -for ac_func in fopen64 -do : - ac_fn_c_check_func "$LINENO" "fopen64" "ac_cv_func_fopen64" -if test "x$ac_cv_func_fopen64" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FOPEN64 1 -_ACEOF - HAVE_FILE64=-DHAVE_FILE64 -fi -done - +# -------------------------------------------------- +# Check if we are using GCC, and disable strict +# aliasing optimization if GCC supports it... +# +# NOTE: Strict aliasing can cause some parts +# of Ghostscript to malfunction. +# -------------------------------------------------- +if test $ac_cv_c_compiler_gnu = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to explicitly disable strict aliasing" >&5 +$as_echo_n "checking whether to explicitly disable strict aliasing... " >&6; } + CFLAGS_backup="$CFLAGS" + CFLAGS="$CFLAGS -fno-strict-aliasing" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -for ac_func in fseeko -do : - ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" -if test "x$ac_cv_func_fseeko" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FSEEKO 1 +int +main () +{ +return 0; + ; + return 0; +} _ACEOF - HAVE_FSEEKO=-DHAVE_FSEEKO -fi -done - +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + CFLAGS_backup="$CFLAGS" -for ac_func in mkstemp64 -do : - ac_fn_c_check_func "$LINENO" "mkstemp64" "ac_cv_func_mkstemp64" -if test "x$ac_cv_func_mkstemp64" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_MKSTEMP64 1 -_ACEOF - HAVE_MKSTEMP64=-DHAVE_MKSTEMP64 fi -done +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$CFLAGS_backup" +fi +# -------------------------------------------------- +# Modify build for internal cluster testing. +# DO NOT USE THIS OPTION OUTSIDE OF ARTIFEX! +# -------------------------------------------------- +# Check whether --enable-cluster was given. +if test "${enable_cluster+set}" = set; then : + enableval=$enable_cluster; +fi -for ac_func in setlocale -do : - ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" -if test "x$ac_cv_func_setlocale" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SETLOCALE 1 -_ACEOF - HAVE_SETLOCALE=-DHAVE_SETLOCALE +if test "x"$enable_cluster != "x"; then + CLUSTER_CFLAGS="-DCLUSTER" +else + CLUSTER_CFLAGS="" fi -done - -for ac_func in strerror -do : - ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" -if test "x$ac_cv_func_strerror" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STRERROR 1 -_ACEOF - HAVE_STRERROR=-DHAVE_STRERROR -fi -done +if test x"$CCAUX" != x"$CC"; then + ilog2() + { + ILOG2_VAL=$1 + ILOG2_RES=0 + while test $ILOG2_VAL -gt 1 ; do + ILOG2_VAL=$((ILOG2_VAL + 1)) + ILOG2_VAL=$((ILOG2_VAL >> 1)) + ILOG2_RES=$((ILOG2_RES + 1)) + done + return $ILOG2_RES + }; -if test $ac_cv_c_compiler_gnu = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 -$as_echo_n "checking whether $CC needs -traditional... " >&6; } -if ${ac_cv_prog_gcc_traditional+:} false; then : +# -------------------------------------------------- +# Generate arch.h headers +# -------------------------------------------------- + # The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of short" >&5 +$as_echo_n "checking alignment of short... " >&6; } +if ${ac_cv_alignof_short+:} false; then : $as_echo_n "(cached) " >&6 else - ac_pattern="Autoconf.*'x'" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -Autoconf TIOCGETP -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then : - ac_cv_prog_gcc_traditional=yes + if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_short" "$ac_includes_default +#ifndef offsetof +# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) +#endif +typedef struct { char x; short y; } ac__type_alignof_;"; then : + else - ac_cv_prog_gcc_traditional=no + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of short +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_short=0 + fi fi -rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_short" >&5 +$as_echo "$ac_cv_alignof_short" >&6; } - if test $ac_cv_prog_gcc_traditional = no; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -Autoconf TCGETA + + +cat >>confdefs.h <<_ACEOF +#define ALIGNOF_SHORT $ac_cv_alignof_short _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "$ac_pattern" >/dev/null 2>&1; then : - ac_cv_prog_gcc_traditional=yes -fi -rm -f conftest* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 -$as_echo "$ac_cv_prog_gcc_traditional" >&6; } - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi + + # The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of int" >&5 +$as_echo_n "checking alignment of int... " >&6; } +if ${ac_cv_alignof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_int" "$ac_includes_default +#ifndef offsetof +# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) +#endif +typedef struct { char x; int y; } ac__type_alignof_;"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of int +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_int=0 + fi fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_int" >&5 +$as_echo "$ac_cv_alignof_int" >&6; } -ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" -if test "x$ac_cv_type_pid_t" = xyes; then : -else cat >>confdefs.h <<_ACEOF -#define pid_t int +#define ALIGNOF_INT $ac_cv_alignof_int _ACEOF -fi -for ac_header in vfork.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" -if test "x$ac_cv_header_vfork_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VFORK_H 1 -_ACEOF + # The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of long" >&5 +$as_echo_n "checking alignment of long... " >&6; } +if ${ac_cv_alignof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_long" "$ac_includes_default +#ifndef offsetof +# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) +#endif +typedef struct { char x; long y; } ac__type_alignof_;"; then : +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of long +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_long=0 + fi fi -done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long" >&5 +$as_echo "$ac_cv_alignof_long" >&6; } -for ac_func in fork vfork -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 + + +cat >>confdefs.h <<_ACEOF +#define ALIGNOF_LONG $ac_cv_alignof_long _ACEOF -fi -done -if test "x$ac_cv_func_fork" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 -$as_echo_n "checking for working fork... " >&6; } -if ${ac_cv_func_fork_works+:} false; then : + # The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of void *" >&5 +$as_echo_n "checking alignment of void *... " >&6; } +if ${ac_cv_alignof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : - ac_cv_func_fork_works=cross -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* By Ruediger Kuhlmann. */ - return fork () < 0; + if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_void_p" "$ac_includes_default +#ifndef offsetof +# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) +#endif +typedef struct { char x; void * y; } ac__type_alignof_;"; then : - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_fork_works=yes else - ac_cv_func_fork_works=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + if test "$ac_cv_type_void_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of void * +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_void_p=0 + fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 -$as_echo "$ac_cv_func_fork_works" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_void_p" >&5 +$as_echo "$ac_cv_alignof_void_p" >&6; } -else - ac_cv_func_fork_works=$ac_cv_func_fork -fi -if test "x$ac_cv_func_fork_works" = xcross; then - case $host in - *-*-amigaos* | *-*-msdosdjgpp*) - # Override, as these systems have only a dummy fork() stub - ac_cv_func_fork_works=no - ;; - *) - ac_cv_func_fork_works=yes - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 -$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} -fi -ac_cv_func_vfork_works=$ac_cv_func_vfork -if test "x$ac_cv_func_vfork" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 -$as_echo_n "checking for working vfork... " >&6; } -if ${ac_cv_func_vfork_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_vfork_works=cross -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Thanks to Paul Eggert for this test. */ -$ac_includes_default -#include -#ifdef HAVE_VFORK_H -# include -#endif -/* On some sparc systems, changes by the child to local and incoming - argument registers are propagated back to the parent. The compiler - is told about this with #include , but some compilers - (e.g. gcc -O) don't grok . Test for this by using a - static variable whose address is put into a register that is - clobbered by the vfork. */ -static void -#ifdef __cplusplus -sparc_address_test (int arg) -# else -sparc_address_test (arg) int arg; -#endif -{ - static pid_t child; - if (!child) { - child = vfork (); - if (child < 0) { - perror ("vfork"); - _exit(2); - } - if (!child) { - arg = getpid(); - write(-1, "", 0); - _exit (arg); - } - } -} -int -main () -{ - pid_t parent = getpid (); - pid_t child; - sparc_address_test (0); +cat >>confdefs.h <<_ACEOF +#define ALIGNOF_VOID_P $ac_cv_alignof_void_p +_ACEOF - child = vfork (); - if (child == 0) { - /* Here is another test for sparc vfork register problems. This - test uses lots of local variables, at least as many local - variables as main has allocated so far including compiler - temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris - 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should - reuse the register of parent for one of the local variables, - since it will think that parent can't possibly be used any more - in this routine. Assigning to the local variable will thus - munge parent in the parent process. */ - pid_t - p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), - p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); - /* Convince the compiler that p..p7 are live; otherwise, it might - use the same hardware register for all 8 local variables. */ - if (p != p1 || p != p2 || p != p3 || p != p4 - || p != p5 || p != p6 || p != p7) - _exit(1); + # The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of float" >&5 +$as_echo_n "checking alignment of float... " >&6; } +if ${ac_cv_alignof_float+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_float" "$ac_includes_default +#ifndef offsetof +# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) +#endif +typedef struct { char x; float y; } ac__type_alignof_;"; then : - /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent - from child file descriptors. If the child closes a descriptor - before it execs or exits, this munges the parent's descriptor - as well. Test for this by closing stdout in the child. */ - _exit(close(fileno(stdout)) != 0); - } else { - int status; - struct stat st; +else + if test "$ac_cv_type_float" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of float +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_float=0 + fi +fi - while (wait(&status) != child) - ; - return ( - /* Was there some problem with vforking? */ - child < 0 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_float" >&5 +$as_echo "$ac_cv_alignof_float" >&6; } - /* Did the child fail? (This shouldn't happen.) */ - || status - /* Did the vfork/compiler bug occur? */ - || parent != getpid() - /* Did the file descriptor bug occur? */ - || fstat(fileno(stdout), &st) != 0 - ); - } -} +cat >>confdefs.h <<_ACEOF +#define ALIGNOF_FLOAT $ac_cv_alignof_float _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_vfork_works=yes + + + # The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of double" >&5 +$as_echo_n "checking alignment of double... " >&6; } +if ${ac_cv_alignof_double+:} false; then : + $as_echo_n "(cached) " >&6 else - ac_cv_func_vfork_works=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi + if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_double" "$ac_includes_default +#ifndef offsetof +# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) +#endif +typedef struct { char x; double y; } ac__type_alignof_;"; then : +else + if test "$ac_cv_type_double" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of double +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_double=0 + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 -$as_echo "$ac_cv_func_vfork_works" >&6; } -fi; -if test "x$ac_cv_func_fork_works" = xcross; then - ac_cv_func_vfork_works=$ac_cv_func_vfork - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 -$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_double" >&5 +$as_echo "$ac_cv_alignof_double" >&6; } -if test "x$ac_cv_func_vfork_works" = xyes; then -$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h -else +cat >>confdefs.h <<_ACEOF +#define ALIGNOF_DOUBLE $ac_cv_alignof_double +_ACEOF -$as_echo "#define vfork fork" >>confdefs.h -fi -if test "x$ac_cv_func_fork_works" = xyes; then -$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + ARCH_ALIGN_SHORT_MOD=$ac_cv_alignof_short -fi + ARCH_ALIGN_INT_MOD=$ac_cv_alignof_int -for ac_header in stdlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STDLIB_H 1 -_ACEOF + ARCH_ALIGN_LONG_MOD=$ac_cv_alignof_long -fi + ARCH_ALIGN_PTR_MOD=$ac_cv_alignof_void_p -done + ARCH_ALIGN_FLOAT_MOD=$ac_cv_alignof_float -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 -$as_echo_n "checking for GNU libc compatible malloc... " >&6; } -if ${ac_cv_func_malloc_0_nonnull+:} false; then : + ARCH_ALIGN_DOUBLE_MOD=$ac_cv_alignof_double + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 +$as_echo_n "checking size of char... " >&6; } +if ${ac_cv_sizeof_char+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : - ac_cv_func_malloc_0_nonnull=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else -char *malloc (); -#endif + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : -int -main () -{ -return ! malloc (0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_malloc_0_nonnull=yes else - ac_cv_func_malloc_0_nonnull=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + if test "$ac_cv_type_char" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_char=0 + fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 -$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } -if test $ac_cv_func_malloc_0_nonnull = yes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 +$as_echo "$ac_cv_sizeof_char" >&6; } -$as_echo "#define HAVE_MALLOC 1" >>confdefs.h -else - $as_echo "#define HAVE_MALLOC 0" >>confdefs.h - case " $LIBOBJS " in - *" malloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS malloc.$ac_objext" - ;; -esac +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF -$as_echo "#define malloc rpl_malloc" >>confdefs.h + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if ${ac_cv_sizeof_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi +fi fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 -$as_echo_n "checking for working memcmp... " >&6; } -if ${ac_cv_func_memcmp_working+:} false; then : + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : - ac_cv_func_memcmp_working=no + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi - /* Some versions of memcmp are not 8-bit clean. */ - char c0 = '\100', c1 = '\200', c2 = '\201'; - if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) - return 1; +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } - /* The Next x86 OpenStep bug shows up only when comparing 16 bytes - or more and with at least one buffer not starting on a 4-byte boundary. - William Lewis provided this test program. */ - { - char foo[21]; - char bar[21]; - int i; - for (i = 0; i < 4; i++) - { - char *a = foo + i; - char *b = bar + i; - strcpy (a, "--------01111111"); - strcpy (b, "--------10000000"); - if (memcmp (a, b, 16) >= 0) - return 1; - } - return 0; - } - ; - return 0; -} + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_memcmp_working=yes + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 else - ac_cv_func_memcmp_working=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 -$as_echo "$ac_cv_func_memcmp_working" >&6; } -test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in - *" memcmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" - ;; -esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 -$as_echo_n "checking return type of signal handlers... " >&6; } -if ${ac_cv_type_signal+:} false; then : + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +$as_echo_n "checking size of long long... " >&6; } +if ${ac_cv_sizeof_long_long+:} false; then : $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : -int -main () -{ -return *(signal (0, 0)) (0) == 1; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_type_signal=int else - ac_cv_type_signal=void + if test "$ac_cv_type_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long_long=0 + fi fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 -$as_echo "$ac_cv_type_signal" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +$as_echo "$ac_cv_sizeof_long_long" >&6; } + + cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE $ac_cv_type_signal +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long _ACEOF -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5 -$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; } -if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then : + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +$as_echo_n "checking size of void *... " >&6; } +if ${ac_cv_sizeof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else - rm -f conftest.sym conftest.file -echo >conftest.file -if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then - if test "$cross_compiling" = yes; then : - ac_cv_func_lstat_dereferences_slashed_symlink=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -struct stat sbuf; - /* Linux will dereference the symlink and fail, as required by POSIX. - That is better in the sense that it means we will not - have to compile and use the lstat wrapper. */ - return lstat ("conftest.sym/", &sbuf) == 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_lstat_dereferences_slashed_symlink=yes + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : + else - ac_cv_func_lstat_dereferences_slashed_symlink=no + if test "$ac_cv_type_void_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (void *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_void_p=0 + fi fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +$as_echo "$ac_cv_sizeof_void_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOID_P $ac_cv_sizeof_void_p +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of float" >&5 +$as_echo_n "checking size of float... " >&6; } +if ${ac_cv_sizeof_float+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (float))" "ac_cv_sizeof_float" "$ac_includes_default"; then : else - # If the `ln -s' command failed, then we probably don't even - # have an lstat function. - ac_cv_func_lstat_dereferences_slashed_symlink=no + if test "$ac_cv_type_float" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (float) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_float=0 + fi fi -rm -f conftest.sym conftest.file fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 -$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_float" >&5 +$as_echo "$ac_cv_sizeof_float" >&6; } + -test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && cat >>confdefs.h <<_ACEOF -#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +#define SIZEOF_FLOAT $ac_cv_sizeof_float _ACEOF -if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then - case " $LIBOBJS " in - *" lstat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS lstat.$ac_objext" - ;; -esac - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5 -$as_echo_n "checking whether stat accepts an empty string... " >&6; } -if ${ac_cv_func_stat_empty_string_bug+:} false; then : + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5 +$as_echo_n "checking size of double... " >&6; } +if ${ac_cv_sizeof_double+:} false; then : $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then : - ac_cv_func_stat_empty_string_bug=yes -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -struct stat sbuf; - return stat ("", &sbuf) == 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_stat_empty_string_bug=no + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then : + else - ac_cv_func_stat_empty_string_bug=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + if test "$ac_cv_type_double" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (double) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_double=0 + fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5 -$as_echo "$ac_cv_func_stat_empty_string_bug" >&6; } -if test $ac_cv_func_stat_empty_string_bug = yes; then - case " $LIBOBJS " in - *" stat.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS stat.$ac_objext" - ;; -esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5 +$as_echo "$ac_cv_sizeof_double" >&6; } + cat >>confdefs.h <<_ACEOF -#define HAVE_STAT_EMPTY_STRING_BUG 1 +#define SIZEOF_DOUBLE $ac_cv_sizeof_double _ACEOF -fi -for ac_func in vprintf -do : - ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" -if test "x$ac_cv_func_vprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VPRINTF 1 -_ACEOF -ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" -if test "x$ac_cv_func__doprnt" = xyes; then : + ilog2 $ac_cv_sizeof_char + ARCH_LOG2_SIZEOF_CHAR=$? -$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h -fi + ilog2 $ac_cv_sizeof_short + ARCH_LOG2_SIZEOF_SHORT=$? -fi -done + ilog2 $ac_cv_sizeof_int + ARCH_LOG2_SIZEOF_INT=$? -for ac_func in bzero dup2 floor gettimeofday memchr memmove memset mkdir mkfifo modf pow putenv rint setenv sqrt strchr strrchr strspn strstr -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF -fi -done + ilog2 $ac_cv_sizeof_long + ARCH_LOG2_SIZEOF_LONG=$? + ilog2 $ac_cv_sizeof_long_long + ARCH_LOG2_SIZEOF_LONG_LONG=$? -if test "x$BIGENDIAN" != "x0"; then - LCMS_ENDIAN="-DUSE_BIG_ENDIAN=$BIGENDIAN" - LCMS2_ENDIAN="-DCMS_USE_BIG_ENDIAN=$BIGENDIAN" -else - LCMS_ENDIAN= - LCMS2_ENDIAN= -fi + ARCH_SIZEOF_PTR=$ac_cv_sizeof_void_p + ilog2 $ac_cv_sizeof_void_p + ARCH_LOG2_SIZEOF_PTR=$? + ARCH_SIZEOF_FLOAT=$ac_cv_sizeof_float -ac_fn_c_check_func "$LINENO" "sqrtf" "ac_cv_func_sqrtf" -if test "x$ac_cv_func_sqrtf" = xyes; then : - SQRTF_SUBST= -else - SQRTF_SUBST="-Dsqrtf=\"(float)sqrt\"" -fi + ilog2 $ac_cv_sizeof_float + ARCH_LOG2_SIZEOF_FLOAT=$? + ARCH_SIZEOF_DOUBLE=$ac_cv_sizeof_double + ilog2 $ac_cv_sizeof_double + ARCH_LOG2_SIZEOF_DOUBLE=$? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking byteswap support" >&5 -$as_echo_n "checking byteswap support... " >&6; } -HAVE_BSWAP32="" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + ARCH_IS_BIG_ENDIAN=$BIGENDIAN + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if pointers are signed" >&5 +$as_echo_n "checking if pointers are signed... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int main () { - int a = 0; - int b = __builtin_bswap32(a); - return(0); + char b[(char *)(uintptr_t)-1 < (char *)(uintptr_t)0 ? -1 : 0]; + return sizeof(b); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - HAVE_BSWAP32="-DHAVE_BSWAP32" +if ac_fn_c_try_compile "$LINENO"; then : + ARCH_PTRS_ARE_SIGNED=0; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } else - HAVE_BSWAP32="" + ARCH_PTRS_ARE_SIGNED=1; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Check whether --enable-bswap32 was given. -if test "${enable_bswap32+set}" = set; then : - enableval=$enable_bswap32; - if test "x$enable_bswap32" = xno; then - HAVE_BSWAP32="" - fi -fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dividing negative by positive truncates" >&5 +$as_echo_n "checking if dividing negative by positive truncates... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -if test "x$HAVE_BSWAP32" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi +int +main () +{ + char b[-1 / 2 == 0 ? -1 : 0]; + return sizeof(b); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ARCH_DIV_NEG_POS_TRUNCATES=0; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + ARCH_DIV_NEG_POS_TRUNCATES=1; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for byteswap.h" >&5 -$as_echo_n "checking for byteswap.h... " >&6; } -HAVE_BYTESWAP_H="" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if arithmetic shift works properly" >&5 +$as_echo_n "checking if arithmetic shift works properly... " >&6; } + ARCH_ARITH_RSHIFT="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include "byteswap.h" + int main () { - int a = 0; - int b = __builtin_bswap32(a); - return(0); + char b[(-1L >> 2) != -1 || (-1 >> 1) != -1 || (-1 >> 2) != -1 ? 0 : -1]; + return sizeof(b); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - HAVE_BYTESWAP_H="-DHAVE_BYTESWAP_H" -else - HAVE_BYTESWAP_H="" + ARCH_ARITH_RSHIFT=0; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Check whether --enable-byteswap-h was given. -if test "${enable_byteswap_h+set}" = set; then : - enableval=$enable_byteswap_h; - if test "x$enable_byteswap-h" = xno; then - HAVE_BYTESWAP_H="" - fi -fi + if test "x${ARCH_ARITH_RSHIFT}" = "x"; then + # Turbo C problem + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int +main () +{ -if test "x$HAVE_BYTESWAP_H" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 + char b[(-1L >> 2) != -1 ? 0 : -1]; + return sizeof(b); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ARCH_ARITH_RSHIFT=1; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test "x${ARCH_ARITH_RSHIFT}" = "x"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + ARCH_ARITH_RSHIFT=2 + fi -# -------------------------------------------------- -# Sun, BSD possibly other makes don't have quite the -# feature set of GNU make. We still prefer GNU make, -# but...... -# -------------------------------------------------- -# Check whether --with-gnu-make was given. -if test "${with_gnu_make+set}" = set; then : - withval=$with_gnu_make; gnu_make=no + CONFIG_FILES_LIST="$CONFIG_FILES_LIST $ARCH_AUTOCONF_HEADER:$ARCH_AUTOCONF_HEADER_PROTO" fi +SRCDIR="$srcdir" + + + + + -if test "x$gnu_make" != "xno"; then - ORDER_ONLY="|" -else - ORDER_ONLY="" -fi -# -------------------------------------------------- -# annoying: Windows doesn't allow "aux" as a -# directory nor file name, so if we're building in -# mingw, add the same prefix as the VS build uses -# -------------------------------------------------- -AUXDIRPOSTFIX="" -case `uname` in - MINGW*) - AUXDIRPOSTFIX="_" - CFLAGS="-DGS_NO_UTF8=1 $CFLAGS" - ;; -esac @@ -9418,7 +12088,28 @@ -ac_config_files="$ac_config_files Makefile" + +CONFIG_FILES_LIST="$CONFIG_FILES_LIST $THEMAKEFILE" + +if test x"$THEMAKEFILE" != x"$MAKEFILE" && test x"$CCAUX" = x"$CC"; then + CONFIG_FILES_LIST="$CONFIG_FILES_LIST" +fi + +if test "x$AFS" = "x1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Using \"native\" font scaler which is now deprecated (rather than freetype)," >&5 +$as_echo "$as_me: WARNING: Using \"native\" font scaler which is now deprecated (rather than freetype)," >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Support for this will be removed in a future release" >&5 +$as_echo "$as_me: WARNING: Support for this will be removed in a future release" >&2;} +fi + +if test "x$NTS_EXCLUDES" != "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Due to the --enable-threadsafe option, the following devices have been excluded because they are not threadsafe:" >&5 +$as_echo "$as_me: WARNING: Due to the --enable-threadsafe option, the following devices have been excluded because they are not threadsafe:" >&2;} + echo "$NTS_EXCLUDES" +fi + +ac_config_files="$ac_config_files $CONFIG_FILES_LIST" + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -9566,6 +12257,7 @@ + : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files @@ -10125,7 +12817,7 @@ for ac_config_target in $ac_config_targets do case $ac_config_target in - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "$CONFIG_FILES_LIST") CONFIG_FILES="$CONFIG_FILES $CONFIG_FILES_LIST" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac @@ -10575,16 +13267,3 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi - -if test "x$AFS" = "x1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Using \"native\" font scaler which is now deprecated (rather than freetype)," >&5 -$as_echo "$as_me: WARNING: Using \"native\" font scaler which is now deprecated (rather than freetype)," >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Support for this will be removed in a future release" >&5 -$as_echo "$as_me: WARNING: Support for this will be removed in a future release" >&2;} -fi - -if test "x$NTS_EXCLUDES" != "x" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Due to the --enable-threadsafe option, the following devices have been excluded because they are not threadsafe:" >&5 -$as_echo "$as_me: WARNING: Due to the --enable-threadsafe option, the following devices have been excluded because they are not threadsafe:" >&2;} - echo "$NTS_EXCLUDES" -fi diff -Nru ghostscript-9.10~dfsg/configure.ac ghostscript-9.25~dfsg+1/configure.ac --- ghostscript-9.10~dfsg/configure.ac 2013-08-30 10:37:29.000000000 +0000 +++ ghostscript-9.25~dfsg+1/configure.ac 2018-09-13 10:02:01.000000000 +0000 @@ -1,4 +1,4 @@ -dnl Copyright (C) 2001-2012 Artifex Software, Inc. +dnl Copyright (C) 2001-2018 Artifex Software, Inc. dnl All Rights Reserved. dnl dnl This software is provided AS-IS with no warranty, either express or @@ -9,8 +9,8 @@ dnl of the license contained in the file LICENSE in this distribution. dnl dnl Refer to licensing information at http://www.artifex.com or contact -dnl Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, San Rafael, -dnl CA 94903, U.S.A., +1(415)492-9861, for further information. +dnl Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, +dnl CA 94945, U.S.A., +1(415)492-9861, for further information. dnl Process this file with autoconf to produce a configure script @@ -20,7 +20,7 @@ dnl ------------------------------------------------ AC_INIT -AC_PREREQ(2.52) +AC_PREREQ(2.63) AC_LANG(C) AC_CONFIG_SRCDIR(psi/gs.c) @@ -30,6 +30,20 @@ CXXFLAGS="${CXXFLAGS:=}" LDFLAGS="${LDFLAGS:=}" +if test x"$cross_compiling" = x"yes"; then + CFLAGSAUX="${CFLAGSAUX:=}" + LDFLAGSAUX="${LDFLAGSAUX:=}" +else + CFLAGSAUX="${CFLAGSAUX:-$CFLAGS}" + LDFLAGSAUX="${LDFLAGSAUX:-$LDFLAGS}" +fi + +THEMAKEFILE="${MAKEFILE:-Makefile}" +AUXFLAGS_MAK=auxflags.mak + +ARCH_AUTOCONF_HEADER=arch-config/arch_autoconf.h +ARCH_AUTOCONF_HEADER_PROTO=arch/arch_autoconf.h.in + dnl -------------------------------------------------- dnl List of non-threadsafe devices dnl defined at the top of the file for ease of access @@ -50,13 +64,13 @@ dnl -------------------------------------------------- dnl GS_SPLIT_LIBS( LIBS, LINKLINE ) -dnl Split a unix-style link line into a list of +dnl Split a unix-style link line into a list of dnl bare library names. For example, the line dnl '-L/usr/X11R6/lib -lX11 -lXt' splits into dnl LIB='X11 Xt' dnl AC_DEFUN([GS_SPLIT_LIBS], [ -# the makefile wants a list of just the library names +# the makefile wants a list of just the library names for gs_item in $2; do gs_stripped_item=`echo "$gs_item" | sed -e 's/^-l//'` if test "x$gs_stripped_item" != "x$gs_item"; then @@ -80,16 +94,93 @@ done ]) -dnl -------------------------------------------------- +dnl -------------------------------------------------- dnl Check for programs -dnl -------------------------------------------------- +dnl -------------------------------------------------- dnl AC_PROG_CC likes to add '-g -O2' to CFLAGS. however, dnl we ignore those flags and construct our own. -save_cflags=$CFLAGS +save_cflags="$CFLAGS" AC_PROG_CC AC_PROG_CPP -CFLAGS=$save_cflags +CFLAGS="$save_cflags" + +AUXFLAGS_MAK_LINE00="CCAUX=@CC@" +AUXFLAGS_MAK_LINE01="GCFLAGSAUX=@CPPFLAGS@ @GCFLAGS@ @CFLAGS@" +AUXFLAGS_MAK_LINE02="CAPOPTAUX=" +AUXFLAGS_MAK_LINE03="CFLAGSAUX_STANDARD=@OPT_CFLAGS@" +AUXFLAGS_MAK_LINE04="CFLAGSAUX_DEBUG=@DBG_CFLAGS@" +AUXFLAGS_MAK_LINE05="CFLAGSAUX_PROFILE=-pg @OPT_CFLAGS@" +AUXFLAGS_MAK_LINE06="LDFLAGSAUX=@LDFLAGS@" +AUXFLAGS_MAK_LINE07="AUXEXTRALIBS=@LIBS@" + +GCFLAGSAUXTMP="\$(GCFLAGS)" +CAPOPTAUXTMP="\$(CAPOPT)" +CFLAGSAUX_STANDARDTMP="\$(CFLAGS_STANDARD)" +CFLAGSAUX_DEBUGTMP="\$(CFLAGS_DEBUG)" +CFLAGSAUX_PROFILETMP="\$(CFLAGS_PROFILE)" +LDFLAGSAUXTMP="\$(LDFLAGS)" +AUXEXTRALIBSTMP="\$(EXTRALIBS)" + + +# purposefully do not include "help" output for this +AC_ARG_ENABLE([save_confaux]) + +if test x"$CCAUX" != x"" ; then + # rerun configure for the AUX tools, disabling a load of tests not relevant for CCAUX + olddir=`pwd` + if test x"$enable_save_confaux" = x"yes"; then + CONFAUXDIR=auxtmp + else + CONFAUXDIR=auxtmp$RANDOM$RANDOM + fi + mkdir $CONFAUXDIR + cd $CONFAUXDIR + echo -e $AUXFLAGS_MAK_CONTENTS > $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE00 > $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE01 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE02 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE03 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE04 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE05 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE06 >> $AUXFLAGS_MAK.in + echo $AUXFLAGS_MAK_LINE07 >> $AUXFLAGS_MAK.in + + ../$0 CC="$CCAUX" CFLAGS="$CFLAGSAUX" LDFLAGS="$LDFLAGSAUX" CCAUX= CFLAGSAUX= CFLAGSAUX= MAKEFILE=$AUXFLAGS_MAK --host= --build= --without-libtiff --disable-contrib --disable-fontconfig --disable-dbus --disable-freetype --disable-fapi --disable-cups --disable-openjpeg --disable-gtk --with-libiconv=no --without-libidn --without-libpaper --without-pdftoraster --without-ijs --without-luratech --without-jbig2dec --without-x --with-drivers="" + status=$? + cp config.log ../configaux.log + if test $status -eq 0 ; then + CCAUX=$(grep CCAUX $AUXFLAGS_MAK | sed "s/CCAUX=//g") + GCFLAGSAUXTMP=$(grep GCFLAGSAUX $AUXFLAGS_MAK | sed "s/GCFLAGSAUX=//g") + CAPOPTAUXTMP=$(grep CAPOPTAUX $AUXFLAGS_MAK | sed "s/CAPOPTAUX=//g") + CFLAGSAUX_STANDARDTMP=$(grep CFLAGSAUX_STANDARD $AUXFLAGS_MAK | sed "s/CFLAGSAUX_STANDARD=//g") + CFLAGSAUX_DEBUGTMP=$(grep CFLAGSAUX_DEBUG $AUXFLAGS_MAK | sed "s/CFLAGSAUX_DEBUG=//g") + CFLAGS_PROFILETMP=$(grep CFLAGS_PROFILE $AUXFLAGS_MAK | sed "s/CFLAGS_PROFILE=//g") + LDFLAGSAUXTMP=$(grep LDFLAGSAUX $AUXFLAGS_MAK | sed "s/LDFLAGSAUX=//g") + AUXEXTRALIBSTMP=$(grep AUXEXTRALIBS$ $AUXFLAGS_MAK | sed "s/AUXEXTRALIBS$=//g") + fi + cd $olddir + + if test x"$enable_save_confaux" != x"yes"; then + rm -rf $CONFAUXDIR + fi + + if test $status -ne 0 ; then + AC_MSG_ERROR([Recursive call to configure (for auxiliary tools) script failed], $status) + fi +fi + +GCFLAGSAUX=$GCFLAGSAUXTMP +CAPOPTAUX=$CAPOPTAUXTMP +CFLAGSAUX_STANDARD=$CFLAGSAUX_STANDARDTMP +CFLAGSAUX_DEBUG=$CFLAGSAUX_DEBUGTMP +CFLAGS_PROFILE=$CFLAGS_PROFILETMP +LDFLAGSAUX=$LDFLAGSAUXTMP +AUXEXTRALIBS=$AUXEXTRALIBSTMP + +# we have to do this here in case it took +# AC_PROG_CC to set CC (as it usually does) +CCAUX="${CCAUX:-$CC}" AC_PROG_SED dnl See if it is GNU sed or else. @@ -105,30 +196,66 @@ AC_PROG_RANLIB #AC_PROG_INSTALL + dnl pkg-config is used for several tests now... -AC_PATH_PROG(PKGCONFIG, pkg-config) +AC_PATH_TOOL(PKGCONFIG, pkg-config) + +# this is an unpleasant hack +# but if we are cross compiling, and there isn't a matching +# pkconfig for the --host setting, then don't use the 'local' +# pkconfig at all +if test x"$cross_compiling" = x"yes"; then + AC_PATH_PROG(BUILD_PKGCONFIG, pkg-config) + if test x"$BUILD_PKGCONFIG" = x"$PKGCONFIG" ; then + PKGCONFIG= + fi +fi + +AC_PATH_TOOL(STRIP_XE, strip) + +# this is an unpleasant hack +# but if we are cross compiling, and there isn't a matching +# pkconfig for the --host setting, then don't use the 'local' +# pkconfig at all +if test x"$cross_compiling" = x"yes"; then + AC_PATH_PROG(BUILD_STRIP_XE, strip) + if test x"$BUILD_STRIP_XE" = x"$STRIP_XE" ; then + STRIP_XE= + fi +fi dnl -------------------------------------------------- dnl Allow excluding the contributed drivers -dnl -------------------------------------------------- +dnl -------------------------------------------------- + +AC_ARG_ENABLE([contrib], AC_HELP_STRING([--disable-contrib], [Do not include contributed drivers])) -AC_ARG_ENABLE([contrib], AC_HELP_STRING([--disable-contrib], - [Do not include contributed drivers])) CONTRIBINCLUDE="include $srcdir/contrib/contrib.mak" INSTALL_CONTRIB="install-contrib-extras" -case `uname` in - MINGW*) - AC_MSG_WARN([disabling contrib devices]) - enable_contrib=no - ;; - *) +if test x"$enable_contrib" = x; then + if test x"$cross_compiling" = x"yes"; then + enable_contrib= + else + case `uname` in + MINGW*|MSYS*) + AC_MSG_WARN([disabling contrib devices]) + enable_contrib=no + ;; + *) + ;; + esac + fi +fi + +if test x"$enable_contrib" != x"no"; then # This is just an arbitrary file in contrib to check - if ! test -f $srcdir/contrib/gdevbjc_.c; then + if test -f $srcdir/contrib/gdevbjc_.c; then + enable_contrib=yes + else enable_contrib=no fi - ;; -esac +fi if test x$enable_contrib = xno; then CONTRIBINCLUDE="" @@ -147,7 +274,13 @@ CC_OPT_FLAGS_TO_TRY="-O" SET_DT_SONAME="-soname=" -case `uname` in +if test x"$cross_compiling" = x"yes"; then + if test $ac_cv_prog_gcc = yes; then + CC_OPT_FLAGS_TO_TRY="-O2" + CC_DBG_FLAGS_TO_TRY="-gdwarf-2 -g3 -O0" + fi +else + case `uname` in Linux*|GNU*) if test $ac_cv_prog_gcc = yes; then CC_OPT_FLAGS_TO_TRY="-O2" @@ -180,7 +313,15 @@ CC_DBG_FLAGS_TO_TRY="-g -O0" fi ;; -esac + AIX) + if test $ac_cv_prog_gcc = yes; then + CC_OPT_FLAGS_TO_TRY="-O2" + CC_DBG_FLAGS_TO_TRY="-gdwarf-2 -g3 -O0" + SET_DT_SONAME="so" + fi + ;; + esac +fi AC_SUBST(SET_DT_SONAME) @@ -188,8 +329,8 @@ if test $ac_cv_prog_gcc = yes; then cflags_to_try="-Wall -Wstrict-prototypes -Wundef \ -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings \ --Wno-strict-aliasing -Wdeclaration-after-statement \ --fno-builtin -fno-common" +-fno-strict-aliasing -Werror=declaration-after-statement \ +-fno-builtin -fno-common -Werror=return-type" optflags_to_try="$CC_OPT_FLAGS_TO_TRY" dbgflags_to_try="$CC_DBG_FLAGS_TO_TRY" else @@ -198,16 +339,50 @@ dbgflags_to_try="$CC_DBG_FLAGS_TO_TRY" fi +AC_MSG_CHECKING([if compiler supports restrict]) +AC_TRY_COMPILE([ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ == 199901L +void test (char * restrict p){} +#else +void test (char * __restrict p){} +#endif +],[ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ == 199901L + char *restrict t; +#else + char * __restrict t; +#endif + test(t); + return 1; + ],[ + CFLAGS="$CFLAGS -DHAVE_RESTRICT=1" + AC_MSG_RESULT([yes])],[ + CFLAGS="$CFLAGS -DHAVE_RESTRICT=0" + AC_MSG_RESULT([no])]) + + + +AC_ARG_WITH([arch_h], AC_HELP_STRING([--with-arch_h=], + [Use a custom arch.h (must be an absolute path)]),[], [with_arch_h=]) + ARCH_CONF_HEADER= -case `uname` in - Darwin*) - ARCH_CONF_HEADER="\$(GLSRCDIR)/../arch/osx-x86-x86_64-ppc-gcc.h" - ;; - *) - ARCH_CONF_HEADER= - ;; -esac +if test x"$with_arch_h" = x""; then + if test x"$cross_compiling" = x"yes"; then + ARCH_CONF_HEADER="\$(GLSRCDIR)/../$ARCH_AUTOCONF_HEADER" + else + case `uname` in + Darwin*) + ARCH_CONF_HEADER="\$(GLSRCDIR)/../arch/osx-x86-x86_64-ppc-gcc.h" + ;; + *) + ARCH_CONF_HEADER= + ;; + esac + fi +else + ARCH_CONF_HEADER=$with_arch_h +fi AC_SUBST(ARCH_CONF_HEADER) @@ -219,9 +394,11 @@ # CFLAGS="-DDEBUG $CFLAGS" #fi +# NOTE: To correctly disable GCC's strict aliasing with '-fno-strict-aliasing' +# option, the 'cflags_to_try' have to checked after 'optflags_to_try'. AC_MSG_CHECKING([supported compiler flags]) old_cflags=$CFLAGS -echo + for flag in $optflags_to_try; do CFLAGS="$CFLAGS $flag" AC_TRY_COMPILE(, [return 0;], [ @@ -239,7 +416,7 @@ CFLAGS=$old_cflags done old_cflags=$CFLAGS -echo + for flag in $dbgflags_to_try; do CFLAGS="$CFLAGS $flag" AC_TRY_COMPILE(, [return 0;], [ @@ -252,36 +429,30 @@ AC_MSG_RESULT([ ...done.]) dnl ---------------------------- -dnl check for big/little endian +dnl check for sanitize support dnl ---------------------------- +AC_MSG_CHECKING([compiler/linker address santizer support]) + +CFLAGS_SANITIZE="" +CFLAGS_SANITIZE_TRY="-fsanitize=address -fno-omit-frame-pointer" +CFLAGS_SAVED="$CFLAGS" +CFLAGS="$CFLAGS_SANITIZE_TRY" -BIGENDIAN= -AC_MSG_CHECKING([for big endian]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([#include ], [ + return(0); + ])], + [CFLAGS_SANITIZE="$CFLAGS"], [CFLAGS_SANITIZE="****************ADDRESS_SANITIZER_NOT_SUPPORTED*********************"]) -AC_ARG_ENABLE([big-endian], AC_HELP_STRING([--enable-big-endian], - [Force big endian]), [BIGENDIAN=1]) +CFLAGS="$CFLAGS_SAVED" -if test x$BIGENDIAN = x; then - AC_ARG_ENABLE([little-endian], AC_HELP_STRING([--enable-little-endian], - [Force little endian]), [BIGENDIAN=0]) -fi +AC_MSG_RESULT([ ...done.]) +dnl ---------------------------- +dnl check for big/little endian +dnl ---------------------------- -if test x$BIGENDIAN = x ; then - AC_RUN_IFELSE( - [AC_LANG_PROGRAM([#include ], [ - static const int one = 1; - return (*(char*)&one == 0 ? 0 : 1); - ])], - [BIGENDIAN=1;AC_MSG_RESULT(big)], - [BIGENDIAN=0;AC_MSG_RESULT(little)]) -else - if test x$BIGENDIAN = x1 ; then - AC_MSG_RESULT(big) - else - AC_MSG_RESULT(little) - fi -fi +AC_C_BIGENDIAN([BIGENDIAN=1], [BIGENDIAN=0]) dnl -------------------------------------------------- dnl check for sse2 intrinsics @@ -347,8 +518,6 @@ ;; esac AC_SUBST(OBJDIR_BSDMAKE_WORKAROUND) - -# for gdev3b1.c (AT&T terminal interface) AC_CHECK_HEADER([sys/window.h]) dnl -------------------------------------------------- @@ -364,7 +533,7 @@ AC_HEADER_TIME AC_STRUCT_TM -dnl see if we're on a system that puts the *int*_t types +dnl see if we're on a system that puts the *int*_t types dnl from stdint.h in sys/types.h if test "x$ac_cv_header_stdint_h" != xyes; then AC_CHECK_TYPES([int8_t, int16_t, int32_t, uint8_t, uint16_t, uint32_t],,,[#include ]) @@ -411,33 +580,79 @@ GCFLAGS="$GCFLAGS -DHAVE_INTTYPES_H=1" fi -dnl try to find a 64 bit type for devicen color index -uint64_type="none" - AC_CHECK_SIZEOF(unsigned long int) - if test $ac_cv_sizeof_unsigned_long_int = 8; then - uint64_type="unsigned long int" - else - AC_CHECK_SIZEOF(unsigned long long) - if test $ac_cv_sizeof_unsigned_long_long = 8; then - uint64_type="unsigned long long" - else - AC_CHECK_SIZEOF(unsigned __int64) - if test $ac_cv_sizeof_unsigned___int64 = 8; then - uint64_type="unsigned __int64" +AC_CHECK_LIB([dl], [dlopen], + [AC_CHECK_HEADER([dlfcn.h], [GCFLAGS="$GCFLAGS -DHAVE_LIBDL=1";LIBS="-ldl $LIBS"])] + ) + +large_color_index=1 + +AC_ARG_WITH([large_color_index],, large_color_index="$with_large_color_index") + +if test x"$large_color_index" != "x0"; then + dnl try to find a 64 bit type for devicen color index + color_ind_type="none" + AC_CHECK_SIZEOF(unsigned long long) + if test $ac_cv_sizeof_unsigned_long_long = 8; then + color_ind_type="unsigned long long" + color_ind_size=$ac_cv_sizeof_unsigned_long_long else - AC_CHECK_SIZEOF(u_int64_t) - if test $ac_cv_sizeof_u_int64_t = 8; then - uint64_type="u_int64_t" + AC_CHECK_SIZEOF(unsigned long int) + if test $ac_cv_sizeof_unsigned_long_int = 8; then + color_ind_type="unsigned long int" + color_ind_size=$ac_cv_sizeof_unsigned_long_int + else + AC_CHECK_SIZEOF(unsigned __int64) + if test $ac_cv_sizeof_unsigned___int64 = 8; then + color_ind_type="unsigned __int64" + color_ind_size=$ac_cv_sizeof_unsigned___int64 + else + AC_CHECK_SIZEOF(u_int64_t) + if test $ac_cv_sizeof_u_int64_t = 8; then + color_ind_type="u_int64_t" + color_ind_size=$ac_cv_sizeof_u_int64_t + fi + fi fi fi - fi - fi -dnl we don't need to do anything if a 64-bit type wasn't found -dnl the code falls back to a (probably 32-bit) default -if test "$uint64_type" != "none"; then - GCFLAGS="$GCFLAGS -DGX_COLOR_INDEX_TYPE=\"$uint64_type\"" +else + dnl try to find a 32 bit type for devicen color index + color_ind_type="none" + AC_CHECK_SIZEOF(unsigned long int) + if test $ac_cv_sizeof_unsigned_long_int = 4; then + color_ind_type="unsigned long int" + color_ind_size=$ac_cv_sizeof_unsigned_long_int + else + AC_CHECK_SIZEOF(unsigned int) + if test $ac_cv_sizeof_unsigned_int = 4; then + color_ind_type="unsigned int" + color_ind_size=$ac_cv_sizeof_unsigned_int + else + AC_CHECK_SIZEOF(unsigned __int32) + if test $ac_cv_sizeof_unsigned___int32 = 4; then + color_ind_type="unsigned __int32" + color_in_size=$ac_cv_sizeof_unsigned___int32 + else + AC_CHECK_SIZEOF(u_int32_t) + if test $ac_cv_sizeof_u_int32_t = 4; then + color_ind_type="u_int32_t" + color_ind_size=$ac_cv_sizeof_u_int32_t + fi + fi + fi + fi +fi + +dnl if a suitable type wasn't found above, we fall back to +dnl a default in genarch. +if test "$color_ind_type" != "none"; then + GCFLAGS="$GCFLAGS -DGX_COLOR_INDEX_TYPE=\"$color_ind_type\"" + ARCH_SIZEOF_GX_COLOR_INDEX=$color_ind_size fi +AC_SUBST(ARCH_SIZEOF_GX_COLOR_INDEX) + + + dnl -------------------------------------------------- dnl Set options that we want to pass into all other dnl configure scripts we might call @@ -445,10 +660,13 @@ SUBCONFIG_OPTS="" -if test x$build_alias != x; then -SUBCONFIG_OPTS="$SUBCONFIG_OPTS --build=$build_alias" +if test x"$build_alias" != x""; then + SUBCONFIG_OPTS="$SUBCONFIG_OPTS --build=$build_alias" fi +if test x"$host_alias" != x""; then + SUBCONFIG_OPTS="$SUBCONFIG_OPTS --host=$host_alias" +fi dnl -------------------------------------------------- dnl Check for libraries @@ -456,23 +674,72 @@ AC_CHECK_LIB(m, cos) +AC_CHECK_FUNCS([pread pwrite], [HAVE_PREAD_PWRITE="-DHAVE_PREAD_PWRITE=1"], [HAVE_PREAD_PWRITE=]) + +if test "x$HAVE_PREAD_PWRITE" != "x"; then + save_cflags=$CFLAGS + CFLAGS="$CFLAGS -D__USE_UNIX98=1 -D_XOPEN_SOURCE=500" + AC_CHECK_DECLS([pwrite,pread], [], [HAVE_PREAD_PWRITE=]) + CFLAGS=$save_cflags + if test "x$HAVE_PREAD_PWRITE" != "x"; then + GCFLAGS="$GCFLAGS -D__USE_UNIX98=1" + fi +fi + +AC_SUBST(HAVE_PREAD_PWRITE) + +AC_CHECK_DECL([popen], [HAVE_POPEN_PROTO="-DHAVE_POPEN_PROTO=1"], [AVE_POPEN_PROTO=]) +AC_SUBST(HAVE_POPEN_PROTO) + SYNC="nosync" PTHREAD_LIBS="" +RECURSIVE_MUTEXATTR="" -case `uname` in - MINGW*) - AC_MSG_WARN([disabling support for pthreads......]) - ;; - *) - AC_CHECK_LIB(pthread, pthread_create, [ - SYNC=posync; - PTHREAD_LIBS="-lpthread" - ]) - ;; -esac +AC_ARG_ENABLE([threading], AC_HELP_STRING([--disable-threading], + [disable support for multithreaded rendering])) + +# if you haven't got pread/pwrite, we can't use multithreading +if test "x$HAVE_PREAD_PWRITE" != "x"; then + if test "$enable_threading" != "no"; then + AC_CHECK_LIB(pthread, pthread_create, [ + SYNC=posync; + PTHREAD_LIBS="-lpthread" + ]) + AC_MSG_CHECKING([recursive mutexes.......]) + AC_TRY_COMPILE([#include ], + [ + static int k = PTHREAD_MUTEX_RECURSIVE; + #ifndef pthread_mutexattr_settype + #ifdef __cplusplus + (void) pthread_mutexattr_settype; + #else + (void) pthread_mutexattr_settype; + #endif + #endif + ; + return 0; + ], + [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE"], + [AC_TRY_COMPILE([#include ], + [ + static int k = PTHREAD_MUTEX_RECURSIVE_NP; + #ifndef pthread_mutexattr_settype + #ifdef __cplusplus + (void) pthread_mutexattr_settype; + #else + (void) pthread_mutexattr_settype; + #endif + #endif + ; + return 0; + ], + [RECURSIVE_MUTEXATTR="-DGS_RECURSIVE_MUTEXATTR=PTHREAD_MUTEX_RECURSIVE_NP"])]) + fi +fi AC_SUBST(SYNC) AC_SUBST(PTHREAD_LIBS) +AC_SUBST(RECURSIVE_MUTEXATTR) dnl Tests for iconv (Needed for OpenPrinting Vector, "opvp" output device) AC_ARG_WITH(libiconv, @@ -636,14 +903,13 @@ AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) -AC_CHECK_LIB(dl, dlopen) AC_ARG_ENABLE([freetype], AC_HELP_STRING([--disable-freetype], [Disable freetype for font rasterization])) FT_BRIDGE=0 SHARE_FT=0 -FTSRCDIR= +FTSRCDIR=src FT_CFLAGS= FT_LIBS= @@ -651,7 +917,7 @@ UFST_ROOT= UFST_CFLAGS= UFST_LIB_EXT= -FAPIUFST_MAK="\$(GLSRCDIR)/stub.mak" +FAPIUFST_MAK="\$(GLSRCDIR)\$(D)stub.mak" AC_ARG_ENABLE([fapi], AC_HELP_STRING([--disable-fapi], [Force use of the (deprecated) Artifex font scaler/renderer])) @@ -671,8 +937,17 @@ *) UFST_ROOT=`pwd`/$with_ufst ;; esac - FAPIUFST_MAK="\$(UFST_ROOT)/fapiufst.mak" - + # Various versions of UFST fail to build with -Werror=return-type so + # strip that off our GCFLAGS if it's there. + tmp_cflags="" + for tmp_cflag in $GCFLAGS ; do + echo $tmp_cflag + tmp_cflags="$tmp_cflags $(echo $tmp_cflag | grep -v "Werror=return-type")" + done + GCFLAGS="$tmp_cflags" + + FAPIUFST_MAK="\$(UFST_ROOT)\$(D)fapiufst.mak" + if ! test -f $UFST_ROOT/fapiufst.mak ; then echo $UFST_ROOT/fapiufst.mak AC_MSG_ERROR([UFST: fapiufst.mak not found]) @@ -712,7 +987,7 @@ fi done - if test -z $FTSRCDIR; then + if test x"$FTSRCDIR" = x"src"; then AC_MSG_RESULT([no]) if test "x$PKGCONFIG" != x; then AC_MSG_CHECKING(for system freetype2 >= 2.4.2 with pkg-config) @@ -729,13 +1004,13 @@ AC_MSG_WARN([freetype library source not found...using native rasterizer]) AFS=1 fi - else + else AC_CHECK_HEADER([ft2build.h], [FT_BRIDGE=1], [AFS=1]) - + if test "x$FT_BRIDGE" = x1; then AC_CHECK_LIB(freetype, FT_Init_FreeType, [FT_BRIDGE=1], [FT_BRIDGE=0; AFS=1]) - + if test "x$FT_BRIDGE" = x1; then AC_MSG_CHECKING(for system freetype2 library >= 2.4.2) AC_COMPILE_IFELSE( @@ -755,7 +1030,6 @@ [FT_BRIDGE=1;AC_MSG_RESULT(yes)], [FT_BRIDGE=0; AFS=1;AC_MSG_RESULT(no)]) fi fi - fi fi fi @@ -772,7 +1046,7 @@ AC_SUBST(FTSRCDIR) AC_SUBST(FT_CFLAGS) AC_SUBST(FT_LIBS) - + AC_MSG_CHECKING([for local jpeg library source]) dnl At present, we give the local source priority over the shared dnl build, so that the D_MAX_BLOCKS_IN_MCU patch will be applied. @@ -810,7 +1084,7 @@ AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) - AC_DEFINE([DONT_HAVE_JMEMSYS_H], 1, + AC_DEFINE([DONT_HAVE_JMEMSYS_H], 1, [define if the libjpeg memory system prototypes aren't available]) fi @@ -820,11 +1094,16 @@ # this seems a harmless default ZLIBDIR=src AUX_SHARED_ZLIB= +ZLIBCFLAGS="" if test -d $srcdir/zlib; then AC_MSG_RESULT([yes]) SHARE_ZLIB=0 ZLIBDIR=$srcdir/zlib + + if test x"$ac_cv_prog_gcc" = x"yes"; then + ZLIBCFLAGS="-Wno-write-strings" + fi else AC_MSG_RESULT([no]) AC_CHECK_LIB(z, deflate, [ @@ -852,13 +1131,14 @@ AC_SUBST(SHARE_ZLIB) AC_SUBST(AUX_SHARED_ZLIB) +AC_SUBST(ZLIBCFLAGS) AC_SUBST(ZLIBDIR) AC_SUBST(FT_SYS_ZLIB) dnl png for the png output device; it also requires zlib LIBPNGDIR=src PNGDEVS='' -PNGDEVS_ALL='png48 png16m pnggray pngmono png256 png16 pngalpha' +PNGDEVS_ALL='png48 png16m pnggray pngmono pngmonod png256 png16 pngalpha' AC_MSG_CHECKING([for local png library source]) if test -f $srcdir/libpng/pngread.c; then AC_MSG_RESULT([yes]) @@ -883,63 +1163,70 @@ WHICHLCMS= -AC_ARG_WITH([lcms], AC_HELP_STRING([--with-lcms], - [try to use LittleCMS 1.x instead of the default of LittleCMS 2.x])) - -if test x$with_lcms != xyes; then +AC_MSG_CHECKING([for local lcms2mt library source]) +LCMS2DIR=src +LCMS2MTDIR=src + +# First check for Artifex version +LCMS2MTSRC=$srcdir/lcms2mt +if test -f $LCMS2MTSRC/include/lcms2mt.h; then + AC_MSG_RESULT([yes]) + SHARELCMS=0 + WHICHLCMS=lcms2mt + LCMS2MTDIR=$LCMS2MTSRC +else + AC_MSG_RESULT([no]) + # Now check for local lcms2 (non-Artifex) AC_MSG_CHECKING([for local lcms2 library source]) - LCMS2DIR=$srcdir/lcms2 - if test -f $LCMS2DIR/include/lcms2.h; then - AC_MSG_RESULT([yes]) - SHARELCMS=0 - WHICHLCMS=lcms2 - else - AC_MSG_RESULT([no]) - AC_MSG_CHECKING([for system lcms2 library]) - AC_CHECK_LIB(lcms2, cmsGetTransformOutputFormat, [ - AC_CHECK_HEADERS([lcms2.h], [LCMS2DIR="";SHARELCMS=1;WHICHLCMS=lcms2]) - ]) - if test x$WHICHLCMS = x; then - AC_MSG_WARN([lcms2 not found, or too old]) - fi - fi -fi - -if test x$WHICHLCMS = x; then - AC_MSG_CHECKING([for local lcms library source]) - LCMSDIR=$srcdir/lcms - SHARELCMS=0 - if test -f $LCMSDIR/include/lcms.h; then - AC_MSG_RESULT([yes]) - SHARELCMS=0 - WHICHLCMS=lcms + LCMS2SRC=$srcdir/lcms2 + if test -f $LCMS2SRC/include/lcms2.h; then + AC_MSG_RESULT([yes]) + SHARELCMS=0 + WHICHLCMS=lcms2 + LCMS2DIR=$LCMS2SRC else - - AC_MSG_ERROR([LittleCMS source not found!]) - #AC_CHECK_LIB(lcms, cmsCreateXYZProfile, [ - # AC_CHECK_HEADERS([lcms.h], [SHARELCMS=1;LCMSDIR=""]) - # ]) - fi + # See if we have system library of lcms2 + AC_MSG_RESULT([no]) + AC_MSG_CHECKING([for system lcms2 library]) + AC_CHECK_LIB(lcms2, _cmsCreateMutex, [ + AC_CHECK_HEADERS([lcms2.h], [SHARELCMS=1;WHICHLCMS=lcms2]) + ]) + if test x$WHICHLCMS = x; then + AC_MSG_ERROR([lcms2 not found, or too old]) + fi + fi fi AC_SUBST(SHARELCMS) AC_SUBST(WHICHLCMS) -AC_SUBST(LCMSDIR) AC_SUBST(LCMS2DIR) +AC_SUBST(LCMS2MTDIR) dnl look for libtiff, it also requires lib dnl png for the png output device; it also requires zlib +AC_ARG_WITH([libtiff], AC_HELP_STRING([--without-libtiff], + [disable use of libtiff]), with_libtiff=no) + AC_ARG_WITH([system-libtiff], AC_HELP_STRING([--with-system-libtiff], [Force using the systems libtiff]), [], [with_system_libtiff=check]) + +if test x"$with_libtiff" = x"no" ; then + with_system_libtiff=none +fi + TIFFDEVS='' FAX_DEVS='' +XPSWRITEDEVICE='' + -LIBTIFFDIR='' +LIBTIFFDIR='src' LIBTIFFCONFDIR='' +TIFFCFLAGS='' -TIFFDEVS_ALL='tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled' +TIFFDEVS_ALL='tiffs tiff12nc tiff24nc tiff48nc tiff32nc tiff64nc tiffcrle tifflzw tiffpack tiffgray tiffsep tiffsep1 tiffscaled tiffscaled4 tiffscaled8 tiffscaled24 tiffscaled32' FAX_DEVS_ALL='cfax dfaxlow dfaxhigh fax faxg3 faxg32d faxg4 tiffg3 tiffg32d tiffg4 tfax' + case "x$with_system_libtiff" in xcheck) if test -d $srcdir/tiff; then @@ -967,11 +1254,11 @@ fi fi if test "x$HAVE_LOCAL_LIBTIFF" = x && test "x$HAVE_SYSTEM_LIBTIFF" = x; then - AC_MSG_NOTICE([Could not find a copy of libtiff on your system. -Disabling tiff output devices.]) + AC_MSG_NOTICE([Could not find a copy of libtiff on your system. Disabling tiff and xps output devices.]) else TIFFDEVS="$TIFFDEVS_ALL" FAX_DEVS="$FAX_DEVS_ALL" + XPSWRITEDEVICE='xpswrite' fi ;; xyes) @@ -996,9 +1283,9 @@ SHARE_LIBTIFF=1 TIFFDEVS="$TIFFDEVS_ALL" FAX_DEVS="$FAX_DEVS_ALL" + XPSWRITEDEVICE='xpswrite' else - AC_MSG_NOTICE([Could not find a copy of libtiff on your system. -Disabling tiff output devices.]) + AC_MSG_NOTICE([Could not find a copy of libtiff on your system. Disabling tiff and xps output devices.]) fi ;; xno) @@ -1010,27 +1297,44 @@ SHARE_LIBTIFF=0 TIFFDEVS="$TIFFDEVS_ALL" FAX_DEVS="$FAX_DEVS_ALL" + XPSWRITEDEVICE='xpswrite' else AC_MSG_RESULT([no]) - AC_MSG_NOTICE([Could not find local copy of libtiff. -Disabling tiff output devices.]) + AC_MSG_NOTICE([Could not find local copy of libtiff. Disabling tiff and xps output devices.]) fi ;; + xnone) + ;; esac -if test $SHARE_LIBTIFF -eq 0; then - echo +CGLAGS_STORE=$CFLAGS +CFLAGS=-Wno-misleading-indentation +AC_TRY_COMPILE([], [return 0;], + [CFLAGS_NMI="-Wno-misleading-indentation"],[CFLAGS_NMI=""]) + +CFLAGS=-Wno-undef +AC_TRY_COMPILE([], [return 0;], + [CFLAGS_NUD="-Wno-undef"],[CFLAGS_NUD=""]) + +CFLAGS=$CGLAGS_STORE + +if test x"$SHARE_LIBTIFF" = x"0" ; then echo "Running libtiff configure script..." olddir=`pwd` - if ! test -d $LIBTIFFCONFDIR ; then - mkdir $LIBTIFFCONFDIR + if ! test -d "$LIBTIFFCONFDIR" ; then + mkdir "$LIBTIFFCONFDIR" fi - cd "$LIBTIFFCONFDIR" && $olddir/$LIBTIFFDIR/configure --disable-jbig --disable-lzma $SUBCONFIG_OPTS + cd "$LIBTIFFCONFDIR" && ../"$LIBTIFFDIR"/configure --disable-jbig --disable-lzma $SUBCONFIG_OPTS status=$? - if test "$status" -ne 0 ; then + if test $status -ne 0 ; then AC_MSG_ERROR([libtiff configure script failed], $status) fi cd "$olddir" + + if test x"$ac_cv_prog_gcc" = x"yes"; then + TIFFCFLAGS="-Wno-write-strings $CFLAGS_NMI $CFLAGS_NUD -DJPEG_LIB_MK1_OR_12BIT=0" + fi + echo echo "Continuing with Ghostscript configuration..." fi @@ -1038,7 +1342,52 @@ AC_SUBST(SHARE_LIBTIFF) AC_SUBST(LIBTIFFDIR) AC_SUBST(LIBTIFFCONFDIR) +AC_SUBST(TIFFCFLAGS) + +SHARE_EXPAT=0 +EXPATDIR=src +EXPAT_CFLAGS= +EXPAT_LIBS= + +if test x"$with_xps" != x"no" ; then + if test -f $srcdir/xps/xps.mak; then + AC_MSG_CHECKING([for local expat library source]) + if test -f $srcdir/expat/lib/expat.h ; then + AC_MSG_RESULT([yes]) + SHARE_EXPAT=0 + EXPATDIR=$srcdir/expat + EXPAT_CFLAGS="-DHAVE_MEMMOVE" + if test x"$BIGENDIAN" != x"0"; then + EXPAT_CFLAGS="$EXPAT_CFLAGS -DBYTEORDER=4321" + else + EXPAT_CFLAGS="$EXPAT_CFLAGS -DBYTEORDER=1234" + fi + else + AC_CHECK_LIB(expat, XML_ParserCreateNS, [ + AC_CHECK_HEADER([expat.h], [SHARE_EXPAT=1]) + ], [ + AC_MSG_ERROR([expat lib not found]) + ]) + if test $SHARE_EXPAT = 1; then + if test "x$PKGCONFIG" != x; then + if $PKGCONFIG --exists expat; then + EXPAT_LIBS="`$PKGCONFIG --libs expat`" + CFLAGS="$CFLAGS `$PKGCONFIG --cflags expat`" + fi + fi + if test x"$XPS_LDFLAGS" = x ; then + EXPAT_LIBS="-lexpat" + fi + fi + fi + fi +fi + +AC_SUBST(SHARE_EXPAT) +AC_SUBST(EXPATDIR) +AC_SUBST(EXPAT_CFLAGS) +AC_SUBST(EXPAT_LIBS) dnl look for CUPS... AC_ARG_ENABLE([cups], AC_HELP_STRING([--disable-cups], @@ -1077,17 +1426,33 @@ SHARELCUPS=1 SHARELCUPSI=1 -if ( test -d $srcdir/cups ); then +if ( test -f $srcdir/cups/gdevcups.c ); then CUPS_DIR="$srcdir/cups" if test x$enable_cups != xno; then if test x$with_local_cups != xyes; then - AC_PATH_PROG(CUPSCONFIG,cups-config) - AC_CHECK_HEADER([cups/raster.h],[],[CUPSCONFIG=""]) + if test x"$CUPSCONFIG" = x""; then + AC_PATH_TOOL(CUPSCONFIG,cups-config) + if test x"$cross_compiling" = x"yes"; then + AC_PATH_PROG(BUILD_CUPSCONFIG, cups-config) + if test x"$BUILD_CUPSCONFIG" = x"$CUPSCONFIG" ; then + CUPSCONFIG= + fi + fi + fi + # check for a libcups header + AC_CHECK_HEADER([cups/cups.h],[],[CUPSCONFIG=""]) + # And check for a libcupsimage header + if test "x$CUPSCONFIG" != x; then + AC_CHECK_HEADER([cups/raster.h],[],[CUPSCONFIG=""]) + fi + if test "x$CUPSCONFIG" != x; then dnl Use values from CUPS config... CUPSCFLAGS="`$CUPSCONFIG --cflags` $CFLAGS" # CUPSLINK="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --static --image --libs | sed -e '1,$s/-lssl//'` $LIBS" CUPSLINK="`$CUPSCONFIG --ldflags` `$CUPSCONFIG --image --libs`" + CUPSAPIVERSION="`$CUPSCONFIG --api-version`" + GS_SPLIT_LIBS([CUPSLIBS], [$CUPSLINK]) GS_SPLIT_LIBPATHS([CUPSLIBDIRS],[$CUPSLINK]) @@ -1111,7 +1476,14 @@ CUPSINCLUDE="include $srcdir/cups/cups.mak" CUPSDEV="cups" + + # pwgraster support arrived in cups 1.5.x + if test "$CUPSAPIVERSION" ">" "1.4" ; then + CUPSDEV="$CUPSDEV pwgraster" + fi + CUPSVERSION="`$CUPSCONFIG --version`" + LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" if ( test x$with_pdftoraster != xno ); then @@ -1121,15 +1493,13 @@ fi fi else - if test "$(uname)" = "Linux"; then - AC_MSG_WARN([* USING LOCAL CUPS SOURCE *]) - SHARELCUPS=0 - SHARELCUPSI=0 - LCUPSBUILDTYPE=linux - LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" - LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" - CUPSDEV="cups" - fi + AC_MSG_WARN([USING LOCAL CUPS SOURCE]) + SHARELCUPS=0 + SHARELCUPSI=0 + LCUPSBUILDTYPE=linux + LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" + LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" + CUPSDEV="cups pwgraster" fi fi fi @@ -1158,15 +1528,16 @@ AC_ARG_WITH([ijs], AC_HELP_STRING([--without-ijs], [disable IJS driver support])) -case `uname` in - MINGW*) +if test x"$cross_compiling" != x"yes"; then + case `uname` in + MINGW*|MSYS*) AC_MSG_WARN([disabling the ijs device]) with_ijs=no ;; *) ;; -esac - + esac +fi dnl set safe defaults IJSDIR=src @@ -1218,21 +1589,29 @@ SHARE_JBIG2=0 JBIG2DIR=$srcdir/luratech/ldf_jb2 - case `uname` in - Darwin*) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD" - ;; - AIX) - if test $ac_cv_prog_gcc = yes; then - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX" + if test x"$cross_compiling" = x"yes"; then + if test x"$JBIG2_CFLAGS" != x""; then + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char $JBIG2_CFLAGS" else - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -qchars=signed -DLINUX" + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" fi - ;; - *) - JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DLINUX" - ;; - esac + else + case `uname` in + Darwin*) + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -DMAC -DMAC_OS_X_BUILD -fsigned-char" + ;; + AIX) + if test $ac_cv_prog_gcc = yes; then + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" + else + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -qchars=signed -DLINUX=1 -DFORTE" + fi + ;; + *) + JBIG2_AUTOCONF_CFLAGS="-DUSE_LDF_JB2 -fsigned-char -DLINUX=1 -DFORTE" + ;; + esac + fi JBIG2FILEDEVS='$(DD)gdevjbig2.dev' JBIG2DEVS='$(PSD)jbig2.dev' @@ -1293,7 +1672,6 @@ JBIG2_AUTOCONF_CFLAGS="$JBIG2_AUTOCONF_CFLAGS -DWORDS_BIGENDIAN" fi - echo AC_MSG_RESULT([$JBIG2DIR]) echo "Continuing with Ghostscript configuration..." else @@ -1330,6 +1708,7 @@ JPXDEVS='' JPX_DECODER= JPX_AUTOCONF_CFLAGS= +JPX_LRINTF_SUBST= if test x$with_luratech != xno; then AC_MSG_CHECKING([for local Luratech JPEG2K library source]) @@ -1339,29 +1718,55 @@ SHARE_JPX=0 JPXDIR=$srcdir/luratech/lwf_jp2 - case `uname` in - Darwin*) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD" - ;; - AIX) - if test $ac_cv_prog_gcc = yes; then - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -fsigned-char -DLINUX" + if test x"$cross_compiling" = x"yes"; then + if test x"$JPX_CFLAGS" != x""; then + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 $JPX_CFLAGS" else - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -qchars=signed -DLINUX" + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX=1 -DFORTE" fi - ;; - *) - JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX" - ;; - esac - + else + case `uname` in + Darwin*) + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DMAC -DMAC_OS_X_BUILD" + ;; + AIX) + if test $ac_cv_prog_gcc = yes; then + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -fsigned-char -DLINUX=1 -DFORTE" + else + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -qchars=signed -DLINUX=1 -DFORTE" + fi + ;; + *) + JPX_AUTOCONF_CFLAGS="-DUSE_LWF_JP2 -DLINUX=1 -DFORTE" + ;; + esac + fi JPXDEVS='$(PSD)jpx.dev' else AC_MSG_RESULT([no]) fi fi -OPENJPEGDIR=$srcdir/openjpeg +if test "x$ac_cv_header_stdint_h" = "xyes"; then + CFLAGS_OPJ_HAVE_STDINT_H="-DOPJ_HAVE_STDINT_H=1" +else + CFLAGS_OPJ_HAVE_STDINT_H= +fi + + +if test "x$ac_cv_header_inttypes_h" = "xyes"; then + CFLAGS_OPJ_HAVE_INTTYPES_H="-DOPJ_HAVE_INTTYPES_H=1" +else + CFLAGS_OPJ_HAVE_INTTYPES_H= +fi + +if test "x$BIGENDIAN" != "x0"; then + CFLAGS_OPJ_BIGENDIAN="-DOPJ_BIG_ENDIAN" +else + CFLAGS_OPJ_BIGENDIAN= +fi + +AC_CHECK_FUNCS([fseeko], [CFLAGS_OPJ_HAVE_FSEEKO="-DOPJ_HAVE_FSEEKO=1"], [CFLAGS_OPJ_HAVE_STDINT_H=]) JPX_SSE_CFLAGS="" @@ -1371,13 +1776,17 @@ fi fi +AC_CHECK_DECL(lrintf, , [OPJ_LRINTF_SUBST="-D\"lrintf(a)\"=\"((long)(a+0.5))\"]",[[#include ]]) + AC_ARG_ENABLE([openjpeg], AC_HELP_STRING([--disable-openjpeg], [Do not use OpenJPEG for JPX decoding])) +OPENJPEGDIR=$srcdir/openjpeg + if test "x$JPX_DECODER" = "x"; then if test "x$enable_openjpeg" != "xno"; then AC_MSG_CHECKING([for local OpenJPEG library source]) - if test -e $OPENJPEGDIR/libopenjpeg/openjpeg.h; then + if test -e $OPENJPEGDIR/src/lib/openjp2/openjpeg.h; then AC_MSG_RESULT([yes]) JPXDIR="$OPENJPEGDIR" JPX_DECODER=openjpeg @@ -1385,20 +1794,41 @@ AC_CHECK_FUNCS([memalign], [have_memalign=1]) if test "x$have_memalign" = "x1"; then - JPX_AUTOCONF_CFLAGS="-DUSE_OPENJPEG_JP2 $JPX_SSE_CFLAGS" + JPX_AUTOCONF_CFLAGS="" else - JPX_AUTOCONF_CFLAGS="-DUSE_OPENJPEG_JP2 $JPX_SSE_CFLAGS -D\"memalign(a,b)=malloc(b)\"" + JPX_AUTOCONF_CFLAGS="-D\"memalign(a,b)=malloc(b)\"" fi + JPX_AUTOCONF_CFLAGS="$JPX_AUTOCONF_CFLAGS -DMUTEX_pthread=0 $OPJ_LRINTF_SUBST -DUSE_JPIP -DUSE_OPENJPEG_JP2 $CFLAGS_OPJ_HAVE_STDINT_H $CFLAGS_OPJ_HAVE_INTTYPES_H $CFLAGS_OPJ_BIGENDIAN $CFLAGS_OPJ_HAVE_FSEEKO" + JPXDEVS='$(PSD)jpx.dev' else AC_MSG_RESULT([no]) + if test x"$PKGCONFIG" != x""; then + AC_MSG_CHECKING(for OpenJPEG2) + if $PKGCONFIG --exists libopenjp2; then + JPX_AUTOCONF_CFLAGS="`$PKGCONFIG libopenjp2 --cflags` -DUSE_OPENJPEG_JP2" + JPX_AUTOCONF_LIBS="`$PKGCONFIG libopenjp2 --libs`" + SHARE_JPX=1 + JPX_DECODER=openjpeg + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + else + AC_CHECK_LIB(openjp2, opj_stream_set_user_data, + [JPX_AUTOCONF_CFLAGS="$JPX_AUTOCONF_CFLAGS $OPJ_LRINTF_SUBST -DUSE_JPIP -DUSE_OPENJPEG_JP2 $CFLAGS_OPJ_HAVE_STDINT_H $CFLAGS_OPJ_HAVE_INTTYPES_H $CFLAGS_OPJ_BIGENDIAN $CFLAGS_OPJ_HAVE_FSEEKO"; + JPX_AUTOCONF_LIBS="-lopenjp2"; + SHARE_JPX=1] + ) + fi fi fi fi AC_SUBST(JPX_DECODER) AC_SUBST(JPX_AUTOCONF_CFLAGS) +AC_SUBST(JPX_AUTOCONF_LIBS) AC_SUBST(JPXDIR) AC_SUBST(SHARE_JPX) AC_SUBST(JPXDEVS) @@ -1414,7 +1844,7 @@ if test "x$PKGCONFIG" != x; then AC_MSG_CHECKING(for GTK+ 3.x) if $PKGCONFIG --exists gtk+-3.0; then - SOC_LOADER="dxmain.c" + SOC_LOADER="dxmain" SOC_CFLAGS="`$PKGCONFIG gtk+-3.0 --cflags`" SOC_LIBS="`$PKGCONFIG gtk+-3.0 --libs`" AC_MSG_RESULT([yes]) @@ -1426,7 +1856,7 @@ if test "x$SOC_LOADER" = "x"; then AC_MSG_CHECKING(for GTK+ 2.x) if $PKGCONFIG --exists gtk+-2.0; then - SOC_LOADER="dxmain.c" + SOC_LOADER="dxmain" SOC_CFLAGS="`$PKGCONFIG gtk+-2.0 --cflags`" SOC_LIBS="`$PKGCONFIG gtk+-2.0 --libs`" AC_MSG_RESULT([yes]) @@ -1438,29 +1868,13 @@ fi if test "x$SOC_LOADER" = "x"; then - SOC_LOADER="dxmainc.c" + SOC_LOADER="dxmainc" fi AC_SUBST(SOC_CFLAGS) AC_SUBST(SOC_LIBS) AC_SUBST(SOC_LOADER) -dnl look for omni implementation -AC_ARG_WITH([omni], AC_HELP_STRING([--with-omni], - [enable the omni driver])) -dnl set safe defaults -OMNIDEVS='' -INCLUDEOMNI=no -if ( ! test -z "$CONTRIBINCLUDE" ) && ( test x$with_omni = xyes ); then - INCLUDEOMNI=yes - OMNIDEVS='$(DD)omni.dev' - - if test -n "$GCC"; then - LIBS="$LIBS -lstdc++" - fi -fi -AC_SUBST(OMNIDEVS) - dnl optional X11 for display devices AC_PATH_XTRA @@ -1522,6 +1936,85 @@ [GS="$with_gs"],[GS='gs']) AC_SUBST(GS) +PCL=no_gpcl6 +PCL_TARGET= + +PLROMFS_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PL_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PCL_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PCL_TOP_MAK="\$(GLSRCDIR)\$(D)stub.mak" +PXL_MAK="\$(GLSRCDIR)\$(D)stub.mak" + +if test x"$with_pcl" != x"no" ; then + if test -f $srcdir/pcl/pl/pl.mak; then + AC_ARG_WITH([pcl], AC_HELP_STRING([--with-pcl=NAME], + [name of the GhostPCL executible (if the source is available, ignored otherwise) [[gpcl6]]]), + [PCL="$with_pcl"],[PCL='gpcl6']) + + PCL_TARGET=gpcl6 + + PLROMFS_MAK="\$(PLSRCDIR)\$(D)plromfs.mak" + PL_MAK="\$(PLSRCDIR)\$(D)pl.mak" + PCL_MAK="\$(PCL5SRCDIR)\$(D)pcl.mak" + PCL_TOP_MAK="\$(PCL5SRCDIR)\$(D)pcl_top.mak" + PXL_MAK="\$(PXLSRCDIR)\$(D)pxl.mak" + fi +fi +AC_SUBST(PCL) +AC_SUBST(PCL_TARGET) + +AC_SUBST(PLROMFS_MAK) +AC_SUBST(PL_MAK) +AC_SUBST(PCL_MAK) +AC_SUBST(PCL_TOP_MAK) +AC_SUBST(PXL_MAK) + + +XPS=no_gxps +XPS_TARGET= + +XPS_MAK="\$(GLSRCDIR)\$(D)stub.mak" +XPSROMFS_MAK="\$(GLSRCDIR)\$(D)stub.mak" +# gxps currently depends on code in pl +if test x"$with_xps" != x"no" ; then + if test x"$PCL_TARGET" != x ; then + if test -f $srcdir/xps/xps.mak; then + AC_ARG_WITH([xps], AC_HELP_STRING([--with-xps=NAME], + [name of the GhostXPS executible (if the source is available, ignored otherwise) [[gxps]]]), + [XPS="$with_xps"],[XPS='gxps']) + + XPS_TARGET=gxps + XPS_MAK="\$(XPSSRCDIR)\$(D)xps.mak" + XPSROMFS_MAK="\$(XPSSRCDIR)\$(D)xpsromfs.mak" + fi + fi +fi + +AC_SUBST(XPS) +AC_SUBST(XPS_TARGET) +AC_SUBST(XPS_MAK) +AC_SUBST(XPSROMFS_MAK) + +GPDL=no_gpdl +GPDL_TARGET= + +GPDL_MAK="\$(GLSRCDIR)\$(D)stub.mak" +# in order to build gpdl we need the pdls available + +if test "x$XPS_TARGET" != "x" && test "x$PCL_TARGET" != "x" ; then + if test -f $srcdir/gpdl/gpdl.mak; then + AC_ARG_WITH([gpdl], AC_HELP_STRING([--with-gpdl=NAME], + [name of the GhostPDL executible (if the source is available, ignored otherwise) [[gpdl]]]), + [GPDL="$with_gpdl"],[GPDL='gpdl']) + +# GPDL_TARGET=gpdl + GPDL_MAK="\$(GPDLSRCDIR)\$(D)gpdl.mak" + fi +fi +AC_SUBST(GPDL) +AC_SUBST(GPDL_TARGET) +AC_SUBST(GPDL_MAK) + dnl do we compile the postscript initialization files into Ghostscript? COMPILE_INITS="1" AC_ARG_ENABLE([compile-inits], AC_HELP_STRING([--disable-compile-inits], @@ -1578,7 +2071,6 @@ P_DEVS0="" F_DEVS0="" CUPS_DEVS0="" -SVG_DEVS0="" XPS_DEVS0="" JBIG2_DEVS="" IJS_DEVS0="" @@ -1593,11 +2085,10 @@ CANON_DEVS='bj10e bj200 bjc600 bjc800 lbp8 lips3 bjcmono bjcgray bjccmyk bjccolor' LEXMARK_DEVS='lxm5700m lxm3200 lex2050 lex3200 lex5700 lex7000' BROTHER_DEVS='hl7x0 hl1240 hl1250' -APPLE_DEVS='appledmp iwhi iwlo iwlq' IBM_DEVS='ibmpro jetp3852' OKI_DEVS='oki182 okiibm oki4w' JAPAN_DEVS='lips4 lips4v ljet4pjl lj4dithp dj505j picty180 lips2p bjc880j pr201 pr150 pr1000 pr1000_4 jj100 bj10v bj10vh mj700v2c mj500c mj6000c mj8000c fmpr fmlbp ml600 lbp310 lbp320 md50Mono md50Eco md1xMono escpage lp2000 npdl rpdl' -MISC_PDEVS='uniprint ap3250 atx23 atx24 atx38 coslw2p coslwxl cp50 declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696 t4693d2 t4693d4 t4693d8 dl2100 la50 la70 la75 la75plus ln03 xes md2k md5k gdi samsunggdi' +MISC_PDEVS='uniprint ap3250 atx23 atx24 atx38 itk24i itk38 coslw2p coslwxl declj250 fs600 imagen lj250 m8510 necp6 oce9050 r4081 sj48 tek4696 t4693d2 t4693d4 t4693d8 dl2100 la50 la70 la75 la75plus ln03 xes md2k md5k gdi samsunggdi' OPVP_DEVS='opvp oprp' ETS_HALFTONING_DEVS='rinkj' @@ -1608,12 +2099,14 @@ JPEG_DEVS='jpeg jpeggray jpegcmyk' # PNG_DEVS='png16 png16m png256 pngalpha pnggray pngmono' -PCX_DEVS='pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk pcx2up' +PCX_DEVS='pcxmono pcxgray pcx16 pcx256 pcx24b pcxcmyk' PBM_DEVS='pbm pbmraw pgm pgmraw pgnm pgnmraw pnm pnmraw ppm ppmraw pkm pkmraw pksm pksmraw pam pamcmyk4 pamcmyk32 plan plang planm planc plank' -PS_DEVS='psdf psdcmyk psdrgb pdfwrite ps2write epswrite bbox txtwrite inkcov' -MISC_FDEVS='ccr cif inferno mag16 mag256 mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm sgirgb sunhmono bit bitrgb bitrgbtags bitcmyk devicen spotcmyk xcf' -SVGDEV='svgwrite' -XPSDEV='xpswrite' +PS_DEVS='psdf psdcmyk psdrgb pdfwrite ps2write eps2write bbox txtwrite inkcov ink_cov psdcmykog fpng pdfimage8 pdfimage24 pdfimage32 PCLm' + +# the "display" device isn't an ideal fit in the list below, but it saves adding a "list" for just that one entry +MISC_FDEVS='ccr cif inferno mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8 mgrmono miff24 plan9bm bit bitrgb bitrgbtags bitcmyk devicen spotcmyk xcf plib plibg plibm plibc plibk gprf display' + +XPSDEV=$XPSWRITEDEVICE while test -n "$drivers"; do if echo $drivers |grep "," >/dev/null; then @@ -1634,7 +2127,7 @@ fi ;; PRINTERS) - P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $APPLE_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS" + P_DEVS0="$P_DEVS0 $CANON_DEVS $EPSON_DEVS $HP_DEVS $LEXMARK_DEVS $BROTHER_DEVS $IBM_DEVS $OKI_DEVS $JAPAN_DEVS $MISC_PDEVS $ETS_HALFTONING_DEVS" IJS_DEVS0="$IJSDEVS" if test x$ac_cv_lib_dl_dlopen != xno -a x$found_iconv != xno; then P_DEVS0="$P_DEVS0 $OPVP_DEVS" @@ -1643,15 +2136,11 @@ fi ;; FILES) - F_DEVS0="$F_DEVS0 $BMP_DEVS $FAX_DEVS $JPEG_DEVS $TIFFDEVS $PCX_DEVS $PBM_DEVS $PS_DEVS $MISC_FDEVS $SVGDEV $XPSDEV" + F_DEVS0="$F_DEVS0 $BMP_DEVS $FAX_DEVS $JPEG_DEVS $TIFFDEVS $PCX_DEVS $PBM_DEVS $PS_DEVS $MISC_FDEVS $XPSDEV" CUPS_DEVS0="$CUPSDEV" JBIG2_DEVS="$JBIG2FILEDEVS" PNG_DEVS0="$PNGDEVS" ;; - APPLE) - # All Apple printers - P_DEVS0="$P_DEVS0 $APPLE_DEVS" - ;; BMP) # BMP file format F_DEVS0="$F_DEVS0 $BMP_DEVS" @@ -1732,12 +2221,8 @@ # PostScript/PDF writing F_DEVS0="$F_DEVS0 $PS_DEVS" ;; - SVG) - # SVG writing - SVG_DEVS0="$SVGDEV" - ;; XPS) - # SVG writing + # XPS writing XPS_DEVS0="$XPSDEV" ;; @@ -1782,11 +2267,6 @@ done for ntsdev in $NTS_DEVS ; do - NTS_EXCLUDES="$(echo \"$SVG_DEVS0{[@]:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" - SVG_DEVS0=`echo $SVG_DEVS0 | sed "s/\b$ntsdev\b//g"` - done - - for ntsdev in $NTS_DEVS ; do NTS_EXCLUDES="$(echo \"$XPS_DEVS0{[@]:0}\" | grep -o $ntsdev) $NTS_EXCLUDES" XPS_DEVS0=`echo $XPS_DEVS0 | sed "s/\b$ntsdev\b//g"` done @@ -1814,16 +2294,16 @@ NTS_EXCLUDES=`echo "$NTS_EXCLUDES" | tr " " "\n" | sort | uniq | tr "\n" " "` fi # x$enable_threadsafe = xyes -noncontribmakefiles=`find $srcdir -name '*.mak' -print | grep -v '^\./contrib/'` +noncontribmakefiles=`find $srcdir -name '*.mak' -print | grep -v '/contrib/'` # No need to include opvp/oprp driver without iconv/libiconv. if test -n "$P_DEVS0"; then if test x$found_iconv = xno ; then - P_DEVS0=`echo $P_DEVS0 | sed -e 's|opvp||' -e 's|oprp||'` + P_DEVS0=`echo $P_DEVS0 | sed -e 's|opvp||' -e 's|oprp||'` AC_MSG_WARN(Unable to include opvp/oprp driver due to missing iconv/libiconv...) fi -# Remove contributed drivers if requested and make sure we don't have any +# Remove contributed drivers if requested and make sure we don't have any # duplicates in there, add $(DD)foo.dev constructs P_DEVS=`(for i in $P_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null ) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` fi @@ -1836,10 +2316,6 @@ CUPS_DEVS=`(for i in $CUPS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` fi -if test -n "$SVG_DEVS0"; then - SVG_DEVS=`(for i in $SVG_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` -fi - if test -n "$XPS_DEVS0"; then XPS_DEVS=`(for i in $XPS_DEVS0; do d='$(DD)'${i}.dev; if ( grep '^'$d $noncontribmakefiles 2>&1 >/dev/null) || ( ! test -z "$CONTRIBINCLUDE" ); then echo $d; fi; done) | sort | uniq | tr '\012\015' ' '` fi @@ -1859,7 +2335,6 @@ AC_SUBST(P_DEVS) AC_SUBST(F_DEVS) AC_SUBST(CUPS_DEVS) -AC_SUBST(SVG_DEVS) AC_SUBST(XPS_DEVS) AC_SUBST(JBIG2_DEVS) AC_SUBST(IJS_DEVS) @@ -1872,104 +2347,155 @@ DYNAMIC_CFLAGS="" DYNAMIC_DEVS="" DYNAMIC_FLAGS="" -DYNAMIC_LDFLAGS="" +GS_DYNAMIC_LDFLAGS="" +PCL_DYNAMIC_LDFLAGS="" +XPS_DYNAMIC_LDFLAGS="" +PDL_DYNAMIC_LDFLAGS="" DYNAMIC_LIBS="" INSTALL_SHARED="" SO_LIB_EXT=".so" DLL_EXT="" SO_LIB_VERSION_SEPARATOR="." -case `uname` in - Linux*|GNU*) - DYNAMIC_CFLAGS="-fPIC" - DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" - if test $ac_cv_prog_gcc = yes; then - # GCC high level flag - DYNAMIC_LIBS="-rdynamic -ldl" - else - DYNAMIC_LIBS="" - fi - SO_LIB_EXT=".so" - ;; - MINGW*) - DYNAMIC_CFLAGS="" - DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(GS_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" - SO_LIB_EXT="" - DLL_EXT=".dll" - SO_LIB_VERSION_SEPARATOR="-" - ;; - *BSD) - DYNAMIC_CFLAGS="-fPIC" - DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" - DYNAMIC_LIBS="" - SO_LIB_EXT=".so" - ;; - Darwin*) - DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(GS_SONAME_MAJOR_MINOR)" - DYNAMIC_LIBS="" - SO_LIB_EXT=".dylib" - ;; - SunOS) - if test $ac_cv_prog_gcc = yes; then - DYNAMIC_CFLAGS="-fPIC" - else - DYNAMIC_CFLAGS="-KPIC" - fi - - DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" - DYNAMIC_LIBS="" - SO_LIB_EXT=".so" - ;; -esac +if test x"$cross_compiling" = x"yes"; then + DYNAMIC_CFLAGS="-fPIC" + GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" + if test $ac_cv_prog_gcc = yes; then + # GCC high level flag + DYNAMIC_LIBS="-rdynamic" + else + DYNAMIC_LIBS="" + fi + SO_LIB_EXT=".so" +else + case `uname` in + Linux*|GNU*) + DYNAMIC_CFLAGS="-fPIC" + GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" + if test $ac_cv_prog_gcc = yes; then + # GCC high level flag + DYNAMIC_LIBS="-rdynamic" + else + DYNAMIC_LIBS="" + fi + SO_LIB_EXT=".so" + ;; + MINGW*|MSYS*) + DYNAMIC_CFLAGS="" + GS_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(GS_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(PCL_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(XPS_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,--out-implib=\$(BINDIR)/lib\$(PDL_SO_BASE).dll.a -Wl,--export-all-symbols -Wl,--enable-auto-import" + SO_LIB_EXT="" + DLL_EXT=".dll" + SO_LIB_VERSION_SEPARATOR="-" + ;; + *BSD) + DYNAMIC_CFLAGS="-fPIC" + GS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + DYNAMIC_LIBS="" + SO_LIB_EXT=".so" + ;; + Darwin*) + GS_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(GS_SONAME_MAJOR_MINOR)" + PCL_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(PCL_SONAME_MAJOR_MINOR)" + XPS_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(XPS_SONAME_MAJOR_MINOR)" + PDL_DYNAMIC_LDFLAGS="-dynamiclib -install_name \$(GPDL_SONAME_MAJOR_MINOR)" + DYNAMIC_LIBS="" + SO_LIB_EXT=".dylib" + ;; + SunOS) + if test $ac_cv_prog_gcc = yes; then + DYNAMIC_CFLAGS="-fPIC" + else + DYNAMIC_CFLAGS="-KPIC" + fi + GS_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GS_SONAME_MAJOR)" + PCL_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(PCL_SONAME_MAJOR)" + XPS_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(XPS_SONAME_MAJOR)" + PDL_DYNAMIC_LDFLAGS="-G -shared -Wl,\$(LD_SET_DT_SONAME)\$(LDFLAGS_SO_PREFIX)\$(GPDL_SONAME_MAJOR)" + DYNAMIC_LIBS="" + SO_LIB_EXT=".so" + ;; + AIX) + if test $ac_cv_prog_gcc = yes; then + DYNAMIC_CFLAGS="-fPIC" + GCFLAGS="-Wl,-brtl -D_LARGE_FILES $GCFLAGS" + GS_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + PCL_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + XPS_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + PDL_DYNAMIC_LDFLAGS="-shared -Wl,-brtl,-G -fPIC" + else + DYNAMIC_CFLAGS="" + GCFLAGS="-Wl,-brtl -D_LARGE_FILES $GCFLAGS" + GS_DYNAMIC_LDFLAGS="-G -qmkshrobj -Wl,-brtl,-G" + PCL_DYNAMIC_LDFLAGS="-G -qmkshrobj -Wl,-brtl,-G" + XPS_DYNAMIC_LDFLAGS="-G -qmkshrobj -Wl,-brtl,-G" + fi + SO_LIB_EXT=".so" + ;; + esac +fi AC_ARG_ENABLE([dynamic], AC_HELP_STRING([--enable-dynamic], [Enable dynamically loaded drivers]), [ - if test "x$enable_dynamic" != xno; then - case `uname` in - Linux*|GNU*) - INSTALL_SHARED="install-shared" - if test "x$X_DEVS" != x; then - DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" - else - DYNAMIC_DEVS="" - fi - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - X11_DEVS="" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - *BSD) - DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - X11_DEVS="" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - Darwin*) - INSTALL_SHARED="install-shared" - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - X11_DEVS="" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - SunOS) - DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" - DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" - OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" - DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" - ;; - *) - AC_MSG_ERROR([Sorry, dynamic driver support not available on this platform!]) - ;; - esac - fi + if test "x$enable_dynamic" != xno; then + case `uname` in + Linux*|GNU*) + INSTALL_SHARED="install-shared" + if test "x$X_DEVS" != x; then + DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" + else + DYNAMIC_DEVS="" + fi + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + X11_DEVS="" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + *BSD) + DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + X11_DEVS="" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + Darwin*) + INSTALL_SHARED="install-shared" + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + X11_DEVS="" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + SunOS) + DYNAMIC_DEVS="\$(GLOBJDIR)/X11.so" + DYNAMIC_FLAGS="-DGS_DEVS_SHARED -DGS_DEVS_SHARED_DIR=\\\"\$(gssharedir)\\\"" + OPT_CFLAGS="$DYNAMIC_CFLAGS $OPT_CFLAGS" + DBG_CFLAGS="$DYNAMIC_CFLAGS $DBG_CFLAGS" + ;; + *) + AC_MSG_ERROR([Sorry, dynamic driver support not available on this platform!]) + ;; + esac + fi ]) AC_SUBST(DYNAMIC_CFLAGS) AC_SUBST(DYNAMIC_DEVS) AC_SUBST(DYNAMIC_FLAGS) -AC_SUBST(DYNAMIC_LDFLAGS) +AC_SUBST(GS_DYNAMIC_LDFLAGS) +AC_SUBST(PCL_DYNAMIC_LDFLAGS) +AC_SUBST(XPS_DYNAMIC_LDFLAGS) +AC_SUBST(PDL_DYNAMIC_LDFLAGS) AC_SUBST(DYNAMIC_LIBS) AC_SUBST(INSTALL_SHARED) AC_SUBST(X11_DEVS) @@ -2035,6 +2561,15 @@ AC_CHECK_FUNCS([strerror], [HAVE_STRERROR=-DHAVE_STRERROR]) AC_SUBST(HAVE_STRERROR) +AC_CHECK_FUNCS([isnan], [HAVE_ISNAN=-DHAVE_ISNAN]) +AC_SUBST(HAVE_ISNAN) + +AC_CHECK_FUNCS([isinf], [HAVE_ISINF=-DHAVE_ISINF]) +AC_SUBST(HAVE_ISINF) + +AC_CHECK_FUNCS([fpclassify], [HAVE_FPCLASSIFY=-DHAVE_FPCLASSIFY]) +AC_SUBST(HAVE_FPCLASSIFY) + AC_PROG_GCC_TRADITIONAL dnl NB: We don't actually provide autoconf-switched fallbacks for any @@ -2048,21 +2583,126 @@ AC_CHECK_FUNCS([bzero dup2 floor gettimeofday memchr memmove memset mkdir mkfifo modf pow putenv rint setenv sqrt strchr strrchr strspn strstr]) dnl -------------------------------------------------- +dnl disable the memory header ID code on SPARC +dnl -------------------------------------------------- + +case `uname -a` in + *sparc*) + GCFLAGS="$GCFLAGS -DGS_USE_MEMORY_HEADER_ID=0" + ;; +esac + +dnl -------------------------------------------------- dnl set big/little endian for LCMS dnl -------------------------------------------------- +LCMS_ENDIAN= +LCMS2_ENDIAN= -if test "x$BIGENDIAN" != "x0"; then +if test x"$BIGENDIAN" != x"0"; then LCMS_ENDIAN="-DUSE_BIG_ENDIAN=$BIGENDIAN" LCMS2_ENDIAN="-DCMS_USE_BIG_ENDIAN=$BIGENDIAN" -else - LCMS_ENDIAN= - LCMS2_ENDIAN= fi AC_SUBST(LCMS_ENDIAN) AC_SUBST(LCMS2_ENDIAN) dnl -------------------------------------------------- +dnl set memory manager's ptr alignment +dnl -------------------------------------------------- + +ALIGN_TEXT_PROG_INCS="\ +#include \ +#include " + + +ALIGN_TEXT_PROG="\ + struct altest \ + { \ + char a; \ + int b; \ + long c; \ + long long d; \ + float e; \ + double f; \ + void *g; \ + }; \ + struct altest *a; \ + struct altest d; \ + char *b, *c, *lim; \ + int ret = 0; \ + c = b = malloc(64 * sizeof(struct altest)); \ + lim = b + (64 * sizeof(struct altest)); \ + do \ + { \ + b++; \ + if ((b >= lim) || \ + ((((unsigned int)b) & 4) == 0 && (((unsigned int)b) & 8) != 0)) \ + { \ + break; \ + } \ + } while(1); \ + if (b >= lim) \ + { \ + ret = -1; \ + } \ + else \ + { \ + a = (struct altest *)b; \ + b = a->g; \ + ret = 0; \ + } \ + free(c); \ + exit(ret);" + + +GS_MEMPTR_ALIGNMENT= + +AC_ARG_WITH(memory-alignment, + [AC_HELP_STRING([--with-memory-alignment], + [Allows setting minimum alignment for the memory manager (4 or 8 bytes]))], + [GS_MEMPTR_ALIGNMENT=$with_memory_alignment],[GS_MEMPTR_ALIGNMENT=check]) + +if test x"$GS_MEMPTR_ALIGNMENT" = xcheck ; then + if test x"$cross_compiling" = x"no"; then + case `uname` in + HP-UX) + GS_MEMPTR_ALIGNMENT=8 + ;; + SunOS) + GS_MEMPTR_ALIGNMENT=8 + ;; + AIX) + GS_MEMPTR_ALIGNMENT=8 + ;; + esac + fi +fi + +if test x"$GS_MEMPTR_ALIGNMENT" = xcheck ; then + AC_MSG_CHECKING([minimum memory pointer alignment]) + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([$ALIGN_TEXT_PROG_INCS], [ + $ALIGN_TEXT_PROG + ])], + [GS_MEMPTR_ALIGNMENT=4;AC_MSG_RESULT(done)], + [GS_MEMPTR_ALIGNMENT=8;AC_MSG_RESULT(done)], + [GS_MEMPTR_ALIGNMENT=4;AC_MSG_RESULT(cross compiling: assuming 4 byte - otherwise use "--with-memory-alignment=")]) + +fi + +if test x"$GS_MEMPTR_ALIGNMENT" != x4 && test x"$GS_MEMPTR_ALIGNMENT" != x8 ; then + AC_MSG_ERROR([4 and 8 are the only valid values for "--with-memory-alignment"], -1) +fi + +if test x"$GS_MEMPTR_ALIGNMENT" != x4 || test x"$with_memory_alignment" != x ; then + LCMS2_PTR_ALIGNMENT="-DCMS_PTR_ALIGNMENT=$GS_MEMPTR_ALIGNMENT" + + GCFLAGS="$GCFLAGS -DGS_MEMPTR_ALIGNMENT=$GS_MEMPTR_ALIGNMENT" +fi + +AC_SUBST(LCMS2_PTR_ALIGNMENT) + +dnl -------------------------------------------------- dnl decide if we have to "hack" sqrtf() for lcms2 dnl -------------------------------------------------- @@ -2071,6 +2711,14 @@ AC_SUBST(SQRTF_SUBST) dnl -------------------------------------------------- +dnl check for and possibly replace strnlen +dnl -------------------------------------------------- +AC_CHECK_FUNCS([strnlen], [HAVE_STRNLEN=],[HAVE_STRNLEN="-D\"strnlen(a,b)=strlen(a)\""]) + +GCFLAGS="$GCFLAGS $HAVE_STRNLEN" + + +dnl -------------------------------------------------- dnl check for byte swap intrinsics dnl -------------------------------------------------- AC_MSG_CHECKING([byteswap support]) @@ -2117,7 +2765,7 @@ if test "x$enable_byteswap-h" = xno; then HAVE_BYTESWAP_H="" fi]) - + if test "x$HAVE_BYTESWAP_H" != x; then AC_MSG_RESULT(yes) else @@ -2135,12 +2783,15 @@ [disable GNU make features]), gnu_make=no) if test "x$gnu_make" != "xno"; then + SUB_MAKE_OPTION="-f \$(MAKEFILE)" ORDER_ONLY="|" else + SUB_MAKE_OPTION= ORDER_ONLY="" fi AC_SUBST(ORDER_ONLY) +AC_SUBST(SUB_MAKE_OPTION) # -------------------------------------------------- # annoying: Windows doesn't allow "aux" as a @@ -2149,23 +2800,234 @@ # -------------------------------------------------- AUXDIRPOSTFIX="" case `uname` in - MINGW*) + MINGW*|MSYS*) AUXDIRPOSTFIX="_" - CFLAGS="-DGS_NO_UTF8=1 $CFLAGS" + if test x"$cross_compiling" != x"yes"; then + CFLAGS="-DGS_NO_UTF8=1 $CFLAGS" + fi ;; esac AC_SUBST(AUXDIRPOSTFIX) +# -------------------------------------------------- +# Set executable name extention +# usually empty on Unix-like systems +# -------------------------------------------------- +EXEEXT="" + +AC_ARG_WITH([exe-ext], AC_HELP_STRING([--with-exe-ext=EXT], + [set the file name executable extension (must include any separator e.g. the period in ".exe")]),[], [exe_ext=]) + +if test "x"$with_exe_ext != "x"; then + EXEEXT="$with_exe_ext" +else + if test x"$cross_compiling" != x"yes"; then + case `uname` in + MINGW*|MSYS*) + EXEEXT=".exe" + ;; + esac + fi +fi + +AC_SUBST(EXEEXT) + +# -------------------------------------------------- +# Check for disabling of versioned path option. +# By default the versioned path must be enabled! +# Using this option is user's own risk & responsibility. +# -------------------------------------------------- +AC_ARG_WITH([versioned-path], +[ --without-versioned-path + Do not use file paths containing the version of GS. + + WARNING: This option is dangerous & unsupported, and + you take full responsibility for using it!], +versioned_path=no) + +if test "x$versioned_path" != "xno"; then + VERSIONED_PATH='/$(GS_DOT_VERSION)' +else + VERSIONED_PATH='' +fi + +AC_SUBST(VERSIONED_PATH) + +# -------------------------------------------------- +# Check if we are using GCC, and disable strict +# aliasing optimization if GCC supports it... +# +# NOTE: Strict aliasing can cause some parts +# of Ghostscript to malfunction. +# -------------------------------------------------- +if test $ac_cv_prog_gcc = yes; then + AC_MSG_CHECKING([whether to explicitly disable strict aliasing]) + CFLAGS_backup="$CFLAGS" + CFLAGS="$CFLAGS -fno-strict-aliasing" + AC_TRY_COMPILE(, [return 0;], [ + AC_MSG_RESULT([yes]) + CFLAGS_backup="$CFLAGS" + ]) + CFLAGS="$CFLAGS_backup" +fi + +# -------------------------------------------------- +# Modify build for internal cluster testing. +# DO NOT USE THIS OPTION OUTSIDE OF ARTIFEX! +# -------------------------------------------------- +AC_ARG_ENABLE([cluster]) + +if test "x"$enable_cluster != "x"; then + CLUSTER_CFLAGS="-DCLUSTER" +else + CLUSTER_CFLAGS="" +fi + +AC_SUBST(CLUSTER_CFLAGS) + +if test x"$CCAUX" != x"$CC"; then + + ilog2() + { + ILOG2_VAL=$1 + ILOG2_RES=0 + while test $ILOG2_VAL -gt 1 ; do + ILOG2_VAL=$((ILOG2_VAL + 1)) + ILOG2_VAL=$((ILOG2_VAL >> 1)) + ILOG2_RES=$((ILOG2_RES + 1)) + done + return $ILOG2_RES + }; + +# -------------------------------------------------- +# Generate arch.h headers +# -------------------------------------------------- + AC_CHECK_ALIGNOF([short]) + AC_CHECK_ALIGNOF([int]) + AC_CHECK_ALIGNOF([long]) + AC_CHECK_ALIGNOF([void *]) + AC_CHECK_ALIGNOF([float]) + AC_CHECK_ALIGNOF([double]) + + AC_SUBST(ARCH_ALIGN_SHORT_MOD, $ac_cv_alignof_short) + AC_SUBST(ARCH_ALIGN_INT_MOD, $ac_cv_alignof_int) + AC_SUBST(ARCH_ALIGN_LONG_MOD, $ac_cv_alignof_long) + AC_SUBST(ARCH_ALIGN_PTR_MOD, $ac_cv_alignof_void_p) + AC_SUBST(ARCH_ALIGN_FLOAT_MOD, $ac_cv_alignof_float) + AC_SUBST(ARCH_ALIGN_DOUBLE_MOD, $ac_cv_alignof_double) + + AC_CHECK_SIZEOF([char]) + AC_CHECK_SIZEOF([short]) + AC_CHECK_SIZEOF([int]) + AC_CHECK_SIZEOF([long]) + AC_CHECK_SIZEOF([long long]) + AC_CHECK_SIZEOF([void *]) + AC_CHECK_SIZEOF([float]) + AC_CHECK_SIZEOF([double]) + + ilog2 $ac_cv_sizeof_char + AC_SUBST(ARCH_LOG2_SIZEOF_CHAR, $?) + + ilog2 $ac_cv_sizeof_short + AC_SUBST(ARCH_LOG2_SIZEOF_SHORT, $?) + + ilog2 $ac_cv_sizeof_int + AC_SUBST(ARCH_LOG2_SIZEOF_INT, $?) + + ilog2 $ac_cv_sizeof_long + AC_SUBST(ARCH_LOG2_SIZEOF_LONG, $?) + + ilog2 $ac_cv_sizeof_long_long + AC_SUBST(ARCH_LOG2_SIZEOF_LONG_LONG, $?) + + AC_SUBST(ARCH_SIZEOF_PTR, $ac_cv_sizeof_void_p) + ilog2 $ac_cv_sizeof_void_p + AC_SUBST(ARCH_LOG2_SIZEOF_PTR, $?) + + AC_SUBST(ARCH_SIZEOF_FLOAT, $ac_cv_sizeof_float) + ilog2 $ac_cv_sizeof_float + AC_SUBST(ARCH_LOG2_SIZEOF_FLOAT, $?) + + AC_SUBST(ARCH_SIZEOF_DOUBLE, $ac_cv_sizeof_double) + ilog2 $ac_cv_sizeof_double + AC_SUBST(ARCH_LOG2_SIZEOF_DOUBLE, $?) + + AC_SUBST(ARCH_IS_BIG_ENDIAN, $BIGENDIAN) + + AC_MSG_CHECKING([if pointers are signed]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([#include ], [ + char b[[(char *)(uintptr_t)-1 < (char *)(uintptr_t)0 ? -1 : 0]]; + return sizeof(b); + ])], + [ARCH_PTRS_ARE_SIGNED=0; AC_MSG_RESULT(no)], [ARCH_PTRS_ARE_SIGNED=1; AC_MSG_RESULT(yes)]) + AC_SUBST(ARCH_PTRS_ARE_SIGNED) + + AC_MSG_CHECKING([if dividing negative by positive truncates]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([], [ + char b[[-1 / 2 == 0 ? -1 : 0]]; + return sizeof(b); + ])], + [ARCH_DIV_NEG_POS_TRUNCATES=0; AC_MSG_RESULT(no)], [ARCH_DIV_NEG_POS_TRUNCATES=1; AC_MSG_RESULT(yes)]) + AC_SUBST(ARCH_DIV_NEG_POS_TRUNCATES) + + AC_MSG_CHECKING([if arithmetic shift works properly]) + ARCH_ARITH_RSHIFT="" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([], [ + char b[[(-1L >> 2) != -1 || (-1 >> 1) != -1 || (-1 >> 2) != -1 ? 0 : -1]]; + return sizeof(b); + ])], + [ARCH_ARITH_RSHIFT=0; AC_MSG_RESULT(no)]) + + if test "x${ARCH_ARITH_RSHIFT}" = "x"; then + # Turbo C problem + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([], [ + char b[[(-1L >> 2) != -1 ? 0 : -1]]; + return sizeof(b); + ])], + [ARCH_ARITH_RSHIFT=1; AC_MSG_RESULT(no)]) + fi + + if test "x${ARCH_ARITH_RSHIFT}" = "x"; then + AC_MSG_RESULT(yes) + ARCH_ARITH_RSHIFT=2 + fi + AC_SUBST(ARCH_ARITH_RSHIFT) + + AC_SUBST(ARCH_SIZEOF_GX_COLOR_INDEX) + CONFIG_FILES_LIST="$CONFIG_FILES_LIST $ARCH_AUTOCONF_HEADER:$ARCH_AUTOCONF_HEADER_PROTO" +fi dnl -------------------------------------------------- dnl Do substitutions dnl -------------------------------------------------- - +SRCDIR="$srcdir" +AC_SUBST(SRCDIR) AC_SUBST(OPT_CFLAGS) AC_SUBST(DBG_CFLAGS) AC_SUBST(GCFLAGS) +AC_SUBST(CFLAGS_SANITIZE) +AC_SUBST(STRIP_XE) +AC_SUBST(JPX_SSE_CFLAGS) + +AC_SUBST(CCAUX) +AC_SUBST(GCFLAGSAUX) +AC_SUBST(CAPOPTAUX) +AC_SUBST(CFLAGSAUX_STANDARD) +AC_SUBST(CFLAGSAUX_DEBUG) +AC_SUBST(CFLAGSAUX_PROFILE) +AC_SUBST(LDFLAGSAUX) +AC_SUBST(AUXEXTRALIBS) + + +CONFIG_FILES_LIST="$CONFIG_FILES_LIST $THEMAKEFILE" -AC_OUTPUT(Makefile) +if test x"$THEMAKEFILE" != x"$MAKEFILE" && test x"$CCAUX" = x"$CC"; then + CONFIG_FILES_LIST="$CONFIG_FILES_LIST" +fi if test "x$AFS" = "x1"; then AC_MSG_WARN([Using "native" font scaler which is now deprecated (rather than freetype),]) @@ -2176,3 +3038,7 @@ AC_MSG_WARN([Due to the --enable-threadsafe option, the following devices have been excluded because they are not threadsafe:]) echo "$NTS_EXCLUDES" fi + +AC_CONFIG_FILES($CONFIG_FILES_LIST) + +AC_OUTPUT diff -Nru ghostscript-9.10~dfsg/contrib/contrib.mak ghostscript-9.25~dfsg+1/contrib/contrib.mak --- ghostscript-9.10~dfsg/contrib/contrib.mak 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/contrib.mak 2018-09-13 10:02:01.000000000 +0000 @@ -19,7 +19,7 @@ # # Define the name of this makefile. -CONTRIB_MAK=$(CONTRIBDIR)$(D)contrib.mak +CONTRIB_MAK=$(CONTRIBDIR)$(D)contrib.mak $(TOP_MAKEFILES) CONTRIBSRC=$(CONTRIBDIR)$(D) ###### --------------------------- Catalog -------------------------- ###### @@ -131,11 +131,6 @@ # # None currently # -# Other raster file formats and devices: -# -# mag16 MAG file format (from Red Hat's japanese driver pack) -# mag256 MAG file format (from Red Hat's japanese driver pack) -# # Special features # # uniprint/: Some additional .upp files @@ -157,22 +152,28 @@ bjc_=$(DEVOBJ)gdevbjc_.$(OBJ) $(DEVOBJ)gdevbjca.$(OBJ) -$(DEVOBJ)gdevbjc_.$(OBJ) : $(CONTRIBSRC)gdevbjc_.c $(PDEVH) $(bjc_h) +$(DEVOBJ)gdevbjc_.$(OBJ) : $(CONTRIBSRC)gdevbjc_.c $(PDEVH) $(bjc_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevbjc_.$(OBJ) $(C_) $(CONTRIBSRC)gdevbjc_.c -$(DEVOBJ)gdevbjca.$(OBJ) : $(CONTRIBSRC)gdevbjca.c $(PDEVH) $(bjc_h) +$(DEVOBJ)gdevbjca.$(OBJ) : $(CONTRIBSRC)gdevbjca.c $(PDEVH) $(bjc_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevbjca.$(OBJ) $(C_) $(CONTRIBSRC)gdevbjca.c -$(DD)bjcmono.dev : $(bjc_) $(DD)page.dev +$(DD)bjcmono.dev : $(bjc_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)bjcmono $(bjc_) -$(DD)bjcgray.dev : $(bjc_) $(DD)page.dev +$(DD)bjcgray.dev : $(bjc_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)bjcgray $(bjc_) -$(DD)bjccmyk.dev : $(bjc_) $(DD)page.dev +$(DD)bjccmyk.dev : $(bjc_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)bjccmyk $(bjc_) -$(DD)bjccolor.dev : $(bjc_) $(DD)page.dev +$(DD)bjccolor.dev : $(bjc_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)bjccolor $(bjc_) @@ -182,26 +183,31 @@ # Author: Uli Wortmann (uliw@erdw.ethz.ch), Martin Gerbershagen (ger@ulm.temic.de) # Printer: HP 670 -$(DD)cdj670.dev : $(cdeskjet8_) $(DD)page.dev +$(DD)cdj670.dev : $(cdeskjet8_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV2) $(DD)cdj670 $(cdeskjet8_) # Author: Uli Wortmann (uliw@erdw.ethz.ch) # Printer: HP 850 -$(DD)cdj850.dev : $(cdeskjet8_) $(DD)page.dev +$(DD)cdj850.dev : $(cdeskjet8_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV2) $(DD)cdj850 $(cdeskjet8_) # Author: Uli Wortmann (uliw@erdw.ethz.ch), Martin Gerbershagen (ger@ulm.temic.de) # Printer: HP 890 -$(DD)cdj890.dev : $(cdeskjet8_) $(DD)page.dev +$(DD)cdj890.dev : $(cdeskjet8_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV2) $(DD)cdj890 $(cdeskjet8_) # Author: Uli Wortmann (uliw@erdw.ethz.ch), Martin Gerbershagen (ger@ulm.temic.de) # Printer: HP 1600 -$(DD)cdj1600.dev : $(cdeskjet8_) $(DD)page.dev +$(DD)cdj1600.dev : $(cdeskjet8_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV2) $(DD)cdj1600 $(cdeskjet8_) $(DEVOBJ)gdevcd8.$(OBJ) : $(CONTRIBSRC)gdevcd8.c $(PDEVH) $(math__h)\ - $(gsparam_h) $(gxlum_h) $(gdevpcl_h) + $(gsparam_h) $(gxlum_h) $(gdevpcl_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevcd8.$(OBJ) $(C_) $(CONTRIBSRC)gdevcd8.c @@ -224,11 +230,12 @@ # Author: Rene Harsch (rene@harsch.net) # Printer: HP 970Cxi -$(DD)cdj970.dev : $(cdeskjet9_) $(DD)page.dev +$(DD)cdj970.dev : $(cdeskjet9_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV2) $(DD)cdj970 $(cdeskjet9_) $(DEVOBJ)gdevdj9.$(OBJ) : $(CONTRIBSRC)gdevdj9.c $(PDEVH) $(math__h) $(string__h)\ - $(gsparam_h) $(gxlum_h) $(gdevpcl_h) + $(gsparam_h) $(gxlum_h) $(gdevpcl_h) $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevdj9.$(OBJ) $(C_) $(CONTRIBSRC)gdevdj9.c @@ -236,7 +243,8 @@ ### NOTE: Same as chp2200 (some PJL and CRD changes). -$(DD)cdnj500.dev : $(cdeskjet8_) $(DD)page.dev +$(DD)cdnj500.dev : $(cdeskjet8_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV2) $(DD)cdnj500 $(cdeskjet8_) @@ -244,7 +252,8 @@ ### NOTE: Depends on the presence of the cdj850 section. -$(DD)chp2200.dev : $(cdeskjet8_) $(DD)page.dev +$(DD)chp2200.dev : $(cdeskjet8_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV2) $(DD)chp2200 $(cdeskjet8_) @@ -254,13 +263,16 @@ GDIMONO=$(DEVOBJ)gdevgdi.$(OBJ) $(HPPCL) -$(DD)gdi.dev : $(GDIMONO) $(DD)page.dev +$(DD)gdi.dev : $(GDIMONO) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)gdi $(GDIMONO) -$(DD)samsunggdi.dev : $(GDIMONO) $(DD)page.dev +$(DD)samsunggdi.dev : $(GDIMONO) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)samsunggdi $(GDIMONO) -$(DEVOBJ)gdevgdi.$(OBJ) : $(CONTRIBSRC)gdevgdi.c $(PDEVH) $(gdevpcl_h) +$(DEVOBJ)gdevgdi.$(OBJ) : $(CONTRIBSRC)gdevgdi.c $(PDEVH) $(gdevpcl_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevgdi.$(OBJ) $(C_) $(CONTRIBSRC)gdevgdi.c @@ -269,15 +281,18 @@ ### selection and special 1200x600 dpi mode. ### hl1250_=$(DEVOBJ)gdevhl12.$(OBJ) $(HPDLJM) -$(DD)hl1250.dev : $(hl1250_) $(DD)page.dev +$(DD)hl1250.dev : $(hl1250_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hl1250 $(hl1250_) -$(DD)hl1240.dev : $(hl1250_) $(DD)page.dev +$(DD)hl1240.dev : $(hl1250_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hl1240 $(hl1250_) # Author: Marek Michalkiewicz # Printer: Brother HL-1250 (may work with some other models too) -$(DEVOBJ)gdevhl12.$(OBJ) : $(CONTRIBSRC)gdevhl12.c $(PDEVH) $(gdevdljm_h) +$(DEVOBJ)gdevhl12.$(OBJ) : $(CONTRIBSRC)gdevhl12.c $(PDEVH) $(gdevdljm_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevhl12.$(OBJ) $(C_) $(CONTRIBSRC)gdevhl12.c @@ -287,35 +302,42 @@ # Author: Ulrich Mueller (ulm@vsnhd1.cern.ch) # Printer: DEC LN03 -$(DD)ln03.dev : $(ln03_) $(DD)page.dev +$(DD)ln03.dev : $(ln03_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)ln03 $(ln03_) # Author: Nick Brown (nick.brown@coe.int) # Printer: DEClaser 2100 -$(DD)dl2100.dev : $(ln03_) $(DD)page.dev +$(DD)dl2100.dev : $(ln03_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)dl2100 $(ln03_) # Author: Ian MacPhedran (macphed@dvinci.USask.CA) # Printer: DEC LA50 -$(DD)la50.dev : $(ln03_) $(DD)page.dev +$(DD)la50.dev : $(ln03_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)la50 $(ln03_) # Author: Bruce Lowekamp (lowekamp@csugrad.cs.vt.edu) # Printer: DEC LA70 -$(DD)la70.dev : $(ln03_) $(DD)page.dev +$(DD)la70.dev : $(ln03_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)la70 $(ln03_) # Author: Ian MacPhedran (macphed@dvinci.USask.CA) # Printer: DEC LA75 -$(DD)la75.dev : $(ln03_) $(DD)page.dev +$(DD)la75.dev : $(ln03_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)la75 $(ln03_) # Author: Andre' Beck (Andre_Beck@IRS.Inf.TU-Dresden.de) # Printer: DEC LA75plus -$(DD)la75plus.dev : $(ln03_) $(DD)page.dev +$(DD)la75plus.dev : $(ln03_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)la75plus $(ln03_) -$(DEVOBJ)gdevln03.$(OBJ) : $(CONTRIBSRC)gdevln03.c $(PDEVH) +$(DEVOBJ)gdevln03.$(OBJ) : $(CONTRIBSRC)gdevln03.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevln03.$(OBJ) $(C_) $(CONTRIBSRC)gdevln03.c @@ -329,184 +351,242 @@ escv_=$(DEVOBJ)gdevescv.$(OBJ) -$(DEVOBJ)gdevescv.$(OBJ) : $(ESCV_SRC)gdevescv.c $(ESCV_SRC)gdevescv.h $(PDEVH) $(time__h) +$(DEVOBJ)gdevescv.$(OBJ) : $(ESCV_SRC)gdevescv.c $(ESCV_SRC)gdevescv.h $(PDEVH) $(time__h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) -DA4 $(DEVO_)gdevescv.$(OBJ) $(C_) $(escv_opts) $(ESCV_SRC)gdevescv.c -$(DD)alc1900.dev : $(escv_) $(DD)page.dev +$(DD)alc1900.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)alc1900 $(escv_) -$(DD)alc2000.dev : $(escv_) $(DD)page.dev +$(DD)alc2000.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)alc2000 $(escv_) -$(DD)alc4000.dev : $(escv_) $(DD)page.dev +$(DD)alc4000.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)alc4000 $(escv_) -$(DD)alc4100.dev : $(escv_) $(DD)page.dev +$(DD)alc4100.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)alc4100 $(escv_) -$(DD)alc8500.dev : $(escv_) $(DD)page.dev +$(DD)alc8500.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)alc8500 $(escv_) -$(DD)alc8600.dev : $(escv_) $(DD)page.dev +$(DD)alc8600.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)alc8600 $(escv_) -$(DD)alc9100.dev : $(escv_) $(DD)page.dev +$(DD)alc9100.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)alc9100 $(escv_) -$(DD)lp3000c.dev : $(escv_) $(DD)page.dev +$(DD)lp3000c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp3000c $(escv_) -$(DD)lp8000c.dev : $(escv_) $(DD)page.dev +$(DD)lp8000c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8000c $(escv_) -$(DD)lp8200c.dev : $(escv_) $(DD)page.dev +$(DD)lp8200c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8200c $(escv_) -$(DD)lp8300c.dev : $(escv_) $(DD)page.dev +$(DD)lp8300c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8300c $(escv_) -$(DD)lp8500c.dev : $(escv_) $(DD)page.dev +$(DD)lp8500c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8500c $(escv_) -$(DD)lp8800c.dev : $(escv_) $(DD)page.dev +$(DD)lp8800c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8800c $(escv_) -$(DD)lp9000c.dev : $(escv_) $(DD)page.dev +$(DD)lp9000c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9000c $(escv_) -$(DD)lp9200c.dev : $(escv_) $(DD)page.dev +$(DD)lp9200c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9200c $(escv_) -$(DD)lp9500c.dev : $(escv_) $(DD)page.dev +$(DD)lp9500c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9500c $(escv_) -$(DD)lp9800c.dev : $(escv_) $(DD)page.dev +$(DD)lp9800c.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9800c $(escv_) -$(DD)lps6500.dev : $(escv_) $(DD)page.dev +$(DD)lps6500.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lps6500 $(escv_) -$(DD)epl2050.dev : $(escv_) $(DD)page.dev +$(DD)epl2050.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl2050 $(escv_) -$(DD)epl2050p.dev : $(escv_) $(DD)page.dev +$(DD)epl2050p.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl2050p $(escv_) -$(DD)epl2120.dev : $(escv_) $(DD)page.dev +$(DD)epl2120.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl2120 $(escv_) -$(DD)epl2500.dev : $(escv_) $(DD)page.dev +$(DD)epl2500.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl2500 $(escv_) -$(DD)epl2750.dev : $(escv_) $(DD)page.dev +$(DD)epl2750.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl2750 $(escv_) -$(DD)epl5800.dev : $(escv_) $(DD)page.dev +$(DD)epl5800.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl5800 $(escv_) -$(DD)epl5900.dev : $(escv_) $(DD)page.dev +$(DD)epl5900.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl5900 $(escv_) -$(DD)epl6100.dev : $(escv_) $(DD)page.dev +$(DD)epl6100.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl6100 $(escv_) -$(DD)epl6200.dev : $(escv_) $(DD)page.dev +$(DD)epl6200.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)epl6200 $(escv_) -$(DD)lp1800.dev : $(escv_) $(DD)page.dev +$(DD)lp1800.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp1800 $(escv_) -$(DD)lp1900.dev : $(escv_) $(DD)page.dev +$(DD)lp1900.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp1900 $(escv_) -$(DD)lp2200.dev : $(escv_) $(DD)page.dev +$(DD)lp2200.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp2200 $(escv_) -$(DD)lp2400.dev : $(escv_) $(DD)page.dev +$(DD)lp2400.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp2400 $(escv_) -$(DD)lp2500.dev : $(escv_) $(DD)page.dev +$(DD)lp2500.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp2500 $(escv_) -$(DD)lp7500.dev : $(escv_) $(DD)page.dev +$(DD)lp7500.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp7500 $(escv_) -$(DD)lp7700.dev : $(escv_) $(DD)page.dev +$(DD)lp7700.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp7700 $(escv_) -$(DD)lp7900.dev : $(escv_) $(DD)page.dev +$(DD)lp7900.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp7900 $(escv_) -$(DD)lp8100.dev : $(escv_) $(DD)page.dev +$(DD)lp8100.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8100 $(escv_) -$(DD)lp8300f.dev : $(escv_) $(DD)page.dev +$(DD)lp8300f.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8300f $(escv_) -$(DD)lp8400f.dev : $(escv_) $(DD)page.dev +$(DD)lp8400f.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8400f $(escv_) -$(DD)lp8600.dev : $(escv_) $(DD)page.dev +$(DD)lp8600.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8600 $(escv_) -$(DD)lp8600f.dev : $(escv_) $(DD)page.dev +$(DD)lp8600f.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8600f $(escv_) -$(DD)lp8700.dev : $(escv_) $(DD)page.dev +$(DD)lp8700.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8700 $(escv_) -$(DD)lp8900.dev : $(escv_) $(DD)page.dev +$(DD)lp8900.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp8900 $(escv_) -$(DD)lp9000b.dev : $(escv_) $(DD)page.dev +$(DD)lp9000b.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9000b $(escv_) -$(DD)lp9100.dev : $(escv_) $(DD)page.dev +$(DD)lp9100.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9100 $(escv_) -$(DD)lp9200b.dev : $(escv_) $(DD)page.dev +$(DD)lp9200b.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9200b $(escv_) -$(DD)lp9300.dev : $(escv_) $(DD)page.dev +$(DD)lp9300.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9300 $(escv_) -$(DD)lp9400.dev : $(escv_) $(DD)page.dev +$(DD)lp9400.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9400 $(escv_) -$(DD)lp9600.dev : $(escv_) $(DD)page.dev +$(DD)lp9600.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9600 $(escv_) -$(DD)lp9600s.dev : $(escv_) $(DD)page.dev +$(DD)lp9600s.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp9600s $(escv_) -$(DD)lps4500.dev : $(escv_) $(DD)page.dev +$(DD)lps4500.dev : $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lps4500 $(escv_) -$(DD)eplcolor.dev: $(escv_) $(DD)page.dev +$(DD)eplcolor.dev: $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)eplcolor $(escv_) -$(DD)eplmono.dev: $(escv_) $(DD)page.dev +$(DD)eplmono.dev: $(escv_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)eplmono $(escv_) # ------ The Lexmark 5700 and 7000 devices ------ # lex7000_=$(DEVOBJ)gdevlx7.$(OBJ) -$(DD)lex7000.dev : $(lex7000_) $(DD)page.dev +$(DD)lex7000.dev : $(lex7000_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lex7000 $(lex7000_) lex5700_=$(DEVOBJ)gdevlx7.$(OBJ) -$(DD)lex5700.dev : $(lex5700_) $(DD)page.dev +$(DD)lex5700.dev : $(lex5700_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lex5700 $(lex5700_) lex3200_=$(DEVOBJ)gdevlx7.$(OBJ) -$(DD)lex3200.dev : $(lex3200_) $(DD)page.dev +$(DD)lex3200.dev : $(lex3200_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lex3200 $(lex3200_) lex2050_=$(DEVOBJ)gdevlx7.$(OBJ) -$(DD)lex2050.dev : $(lex2050_) $(DD)page.dev +$(DD)lex2050.dev : $(lex2050_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lex2050 $(lex2050_) -$(DEVOBJ)gdevlx7.$(OBJ) : $(CONTRIBSRC)gdevlx7.c $(PDEVH) +$(DEVOBJ)gdevlx7.$(OBJ) : $(CONTRIBSRC)gdevlx7.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevlx7.$(OBJ) $(C_) $(CONTRIBSRC)gdevlx7.c @@ -514,10 +594,12 @@ lxm3200_=$(DEVOBJ)gdevlx32.$(OBJ) -$(DEVOBJ)gdevlx32.$(OBJ) : $(CONTRIBSRC)gdevlx32.c $(PDEVH) $(gsparam_h) +$(DEVOBJ)gdevlx32.$(OBJ) : $(CONTRIBSRC)gdevlx32.c $(PDEVH) $(gsparam_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevlx32.$(OBJ) $(C_) $(CONTRIBSRC)gdevlx32.c -$(DD)lxm3200.dev : $(lxm3200_) $(DD)page.dev +$(DD)lxm3200.dev : $(lxm3200_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lxm3200 $(lxm3200_) @@ -528,39 +610,45 @@ LIPS_OPT=-DGS_VERSION_MAJOR=$(GS_VERSION_MAJOR) $(I_)$(LIPS_SRC) $(II)$(PSSRC)$(_I) $(DEVOBJ)gdevlprn.$(OBJ) : $(LIPS_SRC)gdevlprn.c $(LIPS_SRC)gdevlprn.h\ - $(gdevprn_h) $(PDEVH) + $(gdevprn_h) $(PDEVH) $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevlprn.$(OBJ) $(LIPS_OPT) $(C_) $(LIPS_SRC)gdevlprn.c lipsr_=$(DEVOBJ)gdevl4r.$(OBJ) $(DEVOBJ)gdevlips.$(OBJ) $(DEVOBJ)gdevlprn.$(OBJ) -$(DEVOBJ)gdevl4r.$(OBJ) : $(LIPS_SRC)gdevl4r.c $(LIPS_SRC)gdevlips.h $(PDEVH) +$(DEVOBJ)gdevl4r.$(OBJ) : $(LIPS_SRC)gdevl4r.c $(LIPS_SRC)gdevlips.h $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) -DA4 $(DEVO_)gdevl4r.$(OBJ) $(LIPS_OPT) $(C_)\ $(LIPS_SRC)gdevl4r.c -$(DEVOBJ)gdevlips.$(OBJ) : $(GX) $(LIPS_SRC)gdevlips.c $(std_h) +$(DEVOBJ)gdevlips.$(OBJ) : $(GX) $(LIPS_SRC)gdevlips.c $(std_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevlips.$(OBJ) $(LIPS_OPT) $(C_) $(LIPS_SRC)gdevlips.c -$(DD)lips4.dev : $(lipsr_) $(DD)page.dev +$(DD)lips4.dev : $(lipsr_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lips4 $(lipsr_) lipsv_=$(DEVOBJ)gdevl4v.$(OBJ) $(DEVOBJ)gdevlips.$(OBJ) -$(DD)lips4v.dev : $(ECHOGS_XE) $(lipsv_) $(DD)vector.dev +$(DD)lips4v.dev : $(ECHOGS_XE) $(lipsv_) $(DD)vector.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETDEV) $(DD)lips4v $(lipsv_) $(ADDMOD) $(DD)lips4v -include $(GLD)vector $(DEVOBJ)gdevl4v.$(OBJ) : $(LIPS_SRC)gdevl4v.c $(LIPS_SRC)gdevlips.h $(GDEV)\ $(math__h) $(gscspace_h) $(gsutil_h) $(gsparam_h) $(gsmatrix_h) $(gdevvec_h)\ - $(ghost_h) $(gzstate_h) $(igstate_h) + $(ghost_h) $(gzstate_h) $(igstate_h) $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) -DA4 $(DEVO_)gdevl4v.$(OBJ) $(LIPS_OPT) $(C_)\ $(LIPS_SRC)gdevl4v.c ### --------------- Some extra devices: lips2p, bjc880j ---------------- ### -$(DD)lips2p.dev : $(lipsr_) $(DD)page.dev +$(DD)lips2p.dev : $(lipsr_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lips2p $(lipsr_) -$(DD)bjc880j.dev : $(lipsr_) $(DD)page.dev +$(DD)bjc880j.dev : $(lipsr_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)bjc880j $(lipsr_) @@ -568,35 +656,30 @@ md2k_=$(DEVOBJ)gdevmd2k.$(OBJ) -$(DD)md2k.dev : $(md2k_) $(DD)page.dev +$(DD)md2k.dev : $(md2k_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)md2k $(md2k_) -$(DD)md5k.dev : $(md2k_) $(DD)page.dev +$(DD)md5k.dev : $(md2k_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)md5k $(md2k_) -$(DEVOBJ)gdevmd2k.$(OBJ) : $(CONTRIBSRC)gdevmd2k.c $(PDEVH) $(gsparam_h) +$(DEVOBJ)gdevmd2k.$(OBJ) : $(CONTRIBSRC)gdevmd2k.c $(PDEVH) $(gsparam_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevmd2k.$(OBJ) $(C_) $(CONTRIBSRC)gdevmd2k.c -###--------------- IBM Omni Driver Framework --------------------------### - -epclr_h1=$(CONTRIBSRC)defs.h - -$(DD)omni.dev : $(DEVOBJ)gomni.$(OBJ) $(DD)page.dev - $(SETPDEV) $(DD)omni $(DEVOBJ)gomni.$(OBJ) - -$(DEVOBJ)gomni.$(OBJ) : $(CONTRIBSRC)gomni.c $(epclr_h1) $(PDEVH) - $(DEVCC) $(DEVO_)gomni.$(OBJ) $(C_) $(CONTRIBSRC)gomni.c - ### ----------------- The Okidata OkiPage 4w+ device ------------------- ### oki4w_=$(DEVOBJ)gdevop4w.$(OBJ) -$(DD)oki4w.dev : $(oki4w_) $(DD)page.dev +$(DD)oki4w.dev : $(oki4w_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)oki4w $(oki4w_) # Author: Ivan Schreter (ivan@shadow.sk) # Printer: Okidata OkiPage 4w+ -$(DEVOBJ)gdevop4w.$(OBJ) : $(CONTRIBSRC)gdevop4w.c $(PDEVH) +$(DEVOBJ)gdevop4w.$(OBJ) : $(CONTRIBSRC)gdevop4w.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevop4w.$(OBJ) $(C_) $(CONTRIBSRC)gdevop4w.c @@ -609,13 +692,15 @@ opvp_=$(DEVOBJ)gdevopvp.$(OBJ) $(DEVOBJ)gdevopvp.$(OBJ) : $(OPVP_SRC)gdevopvp.c $(OPVP_SRC)opvp_common.h\ - $(PDEVH) + $(PDEVH) $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevopvp.$(OBJ) $(OPVP_OPT) $(C_) $(OPVP_SRC)gdevopvp.c -$(DD)opvp.dev : $(opvp_) $(DD)page.dev +$(DD)opvp.dev : $(opvp_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)opvp $(opvp_) -$(DD)oprp.dev : $(opvp_) $(DD)page.dev +$(DD)oprp.dev : $(opvp_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)oprp $(opvp_) @@ -708,25 +793,31 @@ # Rules for individual files $(DEVOBJ)mediasize.$(OBJ) : $(std_h) \ - $(eprn_src)mediasize.c $(eprn_src)mediasize.h + $(eprn_src)mediasize.c $(eprn_src)mediasize.h \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(eprn_opts) $(eprn_src)mediasize.c -$(DEVOBJ)gdeveprn.$(OBJ) : $(eprn_headers) $(eprn_src)pagecount.h +$(DEVOBJ)gdeveprn.$(OBJ) : $(eprn_headers) $(eprn_src)pagecount.h \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(eprn_opts) $(eprn_src)gdeveprn.c -$(DEVOBJ)eprnparm.$(OBJ) : $(eprn_src)eprnparm.c $(eprn_headers) +$(DEVOBJ)eprnparm.$(OBJ) : $(eprn_src)eprnparm.c $(eprn_headers) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(eprn_opts) $(eprn_src)eprnparm.c -$(DEVOBJ)eprnrend.$(OBJ) : $(eprn_src)eprnrend.c $(eprn_headers) +$(DEVOBJ)eprnrend.$(OBJ) : $(eprn_src)eprnrend.c $(eprn_headers) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(eprn_opts) $(eprn_src)eprnrend.c -$(DEVOBJ)eprnfs.$(OBJ) : $(eprn_src)eprnfs.c $(eprn_headers) +$(DEVOBJ)eprnfs.$(OBJ) : $(eprn_src)eprnfs.c $(eprn_headers) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(eprn_opts) $(eprn_fs_options) \ $(eprn_src)eprnfs.c # File also used by hpdj: $(DEVOBJ)pagecount.$(OBJ) : $(std_h) \ - $(eprn_src)pagecount.c $(eprn_src)pagecount.h + $(eprn_src)pagecount.c $(eprn_src)pagecount.h \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(eprn_opts) $(eprn_src)pagecount.c #============================================================================== @@ -755,21 +846,26 @@ # Rules for individual files -$(DEVOBJ)pclgen.$(OBJ) : $(pcl3_src)pclgen.c $(pcl3_src)pclgen.h +$(DEVOBJ)pclgen.$(OBJ) : $(pcl3_src)pclgen.c $(pcl3_src)pclgen.h \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(pcl3_opts) $(pcl3_src)pclgen.c $(DEVOBJ)pclsize.$(OBJ) : $(pcl3_src)pclsize.c $(eprn_src)mediasize.h \ - $(pcl3_src)pclsize.h $(pcl3_src)pclgen.h + $(pcl3_src)pclsize.h $(pcl3_src)pclgen.h \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(pcl3_opts) $(pcl3_src)pclsize.c -$(DEVOBJ)pclcap.$(OBJ) : $(pcl3_src)pclcap.c $(pcl3_headers) +$(DEVOBJ)pclcap.$(OBJ) : $(pcl3_src)pclcap.c $(pcl3_headers) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(pcl3_opts) $(pcl3_src)pclcap.c -$(DEVOBJ)gdevpcl3.$(OBJ) : $(pcl3_src)gdevpcl3.c $(pcl3_headers) +$(DEVOBJ)gdevpcl3.$(OBJ) : $(pcl3_src)gdevpcl3.c $(pcl3_headers) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(pcl3_opts) $(pcl3_src)gdevpcl3.c # File also used by hpdj: -$(DEVOBJ)pclcomp.$(OBJ) : $(pcl3_src)pclcomp.c $(pcl3_src)pclgen.h +$(DEVOBJ)pclcomp.$(OBJ) : $(pcl3_src)pclcomp.c $(pcl3_src)pclgen.h \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(C_) $(O_)$@ $(pcl3_opts) $(pcl3_src)pclcomp.c #------------------------------------------------------------------------------ @@ -778,55 +874,79 @@ # can add to the DEVICE_DEVS* variables in the platform-specific make file. # The generic pcl3 device with selectable subdevices -$(DD)pcl3.dev : $(pcl3_) $(DD)page.dev +$(DD)pcl3.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)pcl3 $(pcl3_) # Fixed devices for specific printers -$(DD)hpdjplus.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdjplus.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdjplus $(pcl3_) -$(DD)hpdjportable.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdjportable.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdjportable $(pcl3_) -$(DD)hpdj310.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj310.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj310 $(pcl3_) -$(DD)hpdj320.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj320.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj320 $(pcl3_) -$(DD)hpdj340.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj340.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj340 $(pcl3_) -$(DD)hpdj400.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj400.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj400 $(pcl3_) -$(DD)hpdj500.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj500.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj500 $(pcl3_) -$(DD)hpdj500c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj500c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj500c $(pcl3_) -$(DD)hpdj510.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj510.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj510 $(pcl3_) -$(DD)hpdj520.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj520.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj520 $(pcl3_) -$(DD)hpdj540.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj540.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj540 $(pcl3_) -$(DD)hpdj550c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj550c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj550c $(pcl3_) -$(DD)hpdj560c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj560c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj560c $(pcl3_) -$(DD)hpdj600.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj600.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj600 $(pcl3_) -$(DD)hpdj660c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj660c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj660c $(pcl3_) -$(DD)hpdj670c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj670c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj670c $(pcl3_) -$(DD)hpdj680c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj680c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj680c $(pcl3_) -$(DD)hpdj690c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj690c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj690c $(pcl3_) -$(DD)hpdj850c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj850c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj850c $(pcl3_) -$(DD)hpdj855c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj855c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj855c $(pcl3_) -$(DD)hpdj870c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj870c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj870c $(pcl3_) -$(DD)hpdj890c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj890c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj890c $(pcl3_) -$(DD)hpdj1120c.dev : $(pcl3_) $(DD)page.dev +$(DD)hpdj1120c.dev : $(pcl3_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)hpdj1120c $(pcl3_) #------------------------------------------------------------------------------ @@ -836,11 +956,13 @@ # rule is unlikely to work and (b) the code is unlikely to compile on any but # UNIX systems. -pcl3opts: $(BINDIR)$(D)pcl3opts$(XE) +pcl3opts: $(BINDIR)$(D)pcl3opts$(XE) \ + $(CONTRIB_MAK) $(MAKEDIRS) pcl3opts_=$(pcl3_src)pcl3opts.c $(pcl3_src)pclscan.c $(eprn_src)mediasize.c \ $(pcl3_src)pclsize.c -$(BINDIR)$(D)pcl3opts$(XE): $(pcl3opts_) +$(BINDIR)$(D)pcl3opts$(XE): $(pcl3opts_) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(CC_) -o $@ -I$(eprn_src) $(pcl3opts_) gencat $(DEVOBJ)pcl3opts-en.cat $(pcl3_src)pcl3opts-en.msg #gencat $(DEVOBJ)pcl3opts-de.cat $(pcl3_src)pcl3opts-de.msg @@ -860,12 +982,14 @@ ### ----------------- The Xerox XES printer device --------------------- ### xes_=$(DEVOBJ)gdevxes.$(OBJ) -$(DD)xes.dev : $(xes_) $(DD)page.dev +$(DD)xes.dev : $(xes_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)xes $(xes_) # Author: Peter Flass (flass@lbdrscs.bitnet) # Printer: Xerox XES (2700, 3700, 4045, etc.) -$(DEVOBJ)gdevxes.$(OBJ) : $(CONTRIBSRC)gdevxes.c $(PDEVH) +$(DEVOBJ)gdevxes.$(OBJ) : $(CONTRIBSRC)gdevxes.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevxes.$(OBJ) $(C_) $(CONTRIBSRC)gdevxes.c ######################################################################### @@ -879,74 +1003,70 @@ pr201_=$(DEVOBJ)gdevp201.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DD)pr201.dev : $(pr201_) +$(DD)pr201.dev : $(pr201_) $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)pr201 $(pr201_) -$(DD)pr150.dev : $(pr201_) +$(DD)pr150.dev : $(pr201_) $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)pr150 $(pr201_) -$(DD)pr1000.dev : $(pr201_) +$(DD)pr1000.dev : $(pr201_) $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)pr1000 $(pr201_) -$(DD)pr1000_4.dev : $(pr201_) +$(DD)pr1000_4.dev : $(pr201_) $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)pr1000_4 $(pr201_) -$(DEVOBJ)gdevp201.$(OBJ) : $(JAPSRC)gdevp201.c $(PDEVH) +$(DEVOBJ)gdevp201.$(OBJ) : $(JAPSRC)gdevp201.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevp201.$(OBJ) $(C_) $(JAPSRC)gdevp201.c ### ----------------- The Star JJ-100 printer device ----------------- ### jj100_=$(DEVOBJ)gdevj100.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DD)jj100.dev : $(jj100_) +$(DD)jj100.dev : $(jj100_) $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)jj100 $(jj100_) -$(DEVOBJ)gdevj100.$(OBJ) : $(JAPSRC)gdevj100.c $(PDEVH) +$(DEVOBJ)gdevj100.$(OBJ) : $(JAPSRC)gdevj100.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(O_)$@ $(C_) $(JAPSRC)gdevj100.c ### ----------------- The Canon BubbleJet BJ10v device ----------------- ### bj10v_=$(DEVOBJ)gdev10v.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DD)bj10v.dev : $(bj10v_) +$(DD)bj10v.dev : $(bj10v_) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)bj10v $(bj10v_) -$(DD)bj10vh.dev : $(bj10v_) +$(DD)bj10vh.dev : $(bj10v_) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)bj10vh $(bj10v_) # Uncomment the following line if you are using MS-DOS on PC9801 series. -$(DEVOBJ)gdev10v.$(OBJ) : $(JAPSRC)gdev10v.c $(PDEVH) +$(DEVOBJ)gdev10v.$(OBJ) : $(JAPSRC)gdev10v.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(O_)$@ $(C_) $(JAPSRC)gdev10v.c # $(DEVCC) -DPC9801 $(O_)$@ $(C_) $(JAPSRC)gdev10v.c -### ------------------------- MAG file formats ------------------------- ### - -maguro_=$(DEVOBJ)gdevmag.$(OBJ) $(DEVOBJ)gdevpccm.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DEVOBJ)gdevmag.$(OBJ) : $(JAPSRC)gdevmag.c $(PDEVH) - $(DEVCC) $(O_)$@ $(C_) $(JAPSRC)gdevmag.c - -$(DD)mag16.dev : $(maguro_) - $(SETDEV) $(DD)mag16 $(maguro_) - -$(DD)mag256.dev : $(maguro_) - $(SETDEV) $(DD)mag256 $(maguro_) - ### ---------------- Dot matrix printer device ---------------- ### dmprt_=$(DEVOBJ)gdevdmpr.$(OBJ) $(DEVOBJ)dviprlib.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DD)dmprt.dev : $(dmprt_) $(DD)page.dev +$(DD)dmprt.dev : $(dmprt_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETDEV) $(DD)dmprt $(dmprt_) $(ADDMOD) $(DD)dmprt -ps dmp_init -$(DEVOBJ)gdevdmpr.$(OBJ) : $(JAPSRC)gdevdmpr.c $(JAPSRC)dviprlib.h $(PDEVH) +$(DEVOBJ)gdevdmpr.$(OBJ) : $(JAPSRC)gdevdmpr.c $(JAPSRC)dviprlib.h $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(O_)$@ $(C_) $(JAPSRC)gdevdmpr.c -$(DEVOBJ)dviprlib.$(OBJ) : $(JAPSRC)dviprlib.c $(JAPSRC)dviprlib.h +$(DEVOBJ)dviprlib.$(OBJ) : $(JAPSRC)dviprlib.c $(JAPSRC)dviprlib.h \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(O_)$@ $(C_) $(JAPSRC)dviprlib.c -extra-dmprt-install: +extra-dmprt-install: install-libdata $(INSTALL_DATA) $(JAPSRC)dmp_init.ps $(DESTDIR)$(gsdatadir)$(D)lib || exit 1 $(INSTALL_DATA) $(JAPSRC)dmp_site.ps $(DESTDIR)$(gsdatadir)$(D)lib || exit 1 $(INSTALL_DATA) $(JAPSRC)escp_24.src $(DESTDIR)$(gsdatadir)$(D)lib || exit 1 @@ -959,39 +1079,48 @@ mj700v2c_=$(DEVOBJ)gdevmjc.$(OBJ) $(HPPCL) -$(DEVOBJ)gdevmjc.$(OBJ) : $(JAPSRC)gdevmjc.c $(JAPSRC)gdevmjc.h $(PDEVH) $(gdevpcl_h) +$(DEVOBJ)gdevmjc.$(OBJ) : $(JAPSRC)gdevmjc.c $(JAPSRC)gdevmjc.h $(PDEVH) $(gdevpcl_h) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) -DA4 $(DEVO_)gdevmjc.$(OBJ) $(C_) $(JAPSRC)gdevmjc.c -$(DD)mj700v2c.dev : $(mj700v2c_) $(DD)page.dev +$(DD)mj700v2c.dev : $(mj700v2c_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)mj700v2c $(mj700v2c_) -$(DD)mj500c.dev : $(mj700v2c_) $(DD)page.dev +$(DD)mj500c.dev : $(mj700v2c_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)mj500c $(mj700v2c_) -$(DD)mj6000c.dev : $(mj700v2c_) $(DD)page.dev +$(DD)mj6000c.dev : $(mj700v2c_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)mj6000c $(mj700v2c_) -$(DD)mj8000c.dev : $(mj700v2c_) $(DD)page.dev +$(DD)mj8000c.dev : $(mj700v2c_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)mj8000c $(mj700v2c_) ### ----------------- The Fujitsu FMPR printer device ----------------- ### fmpr_=$(DEVOBJ)gdevfmpr.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DD)fmpr.dev : $(fmpr_) $(DD)page.dev +$(DD)fmpr.dev : $(fmpr_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)fmpr $(fmpr_) -$(DEVOBJ)gdevfmpr.$(OBJ) : $(JAPSRC)gdevfmpr.c $(PDEVH) +$(DEVOBJ)gdevfmpr.$(OBJ) : $(JAPSRC)gdevfmpr.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevfmpr.$(OBJ) $(C_) $(JAPSRC)gdevfmpr.c ### --------------- The Fujitsu FMLBP-2xx printer device --------------- ### fmlbp_=$(DEVOBJ)gdevfmlbp.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DD)fmlbp.dev : $(fmlbp_) $(DD)page.dev +$(DD)fmlbp.dev : $(fmlbp_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)fmlbp $(fmlbp_) -$(DEVOBJ)gdevfmlbp.$(OBJ) : $(JAPSRC)gdevfmlbp.c $(PDEVH) +$(DEVOBJ)gdevfmlbp.$(OBJ) : $(JAPSRC)gdevfmlbp.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) -DFMLBP_NOADJUST_MARGIN $(O_)$@ $(C_) $(JAPSRC)gdevfmlbp.c ### ------ The OKI MICROLINE620CL (IPL) printer device ------- ### @@ -1003,10 +1132,12 @@ ml6_=$(DEVOBJ)gdevml6.$(OBJ) $(DEVOBJ)gdevprn.$(OBJ) -$(DD)ml600.dev : $(ml6_) $(DD)page.dev +$(DD)ml600.dev : $(ml6_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)ml600 $(ml6_) -$(DEVOBJ)gdevml6.$(OBJ) : $(JAPSRC)gdevml6.c $(PDEVH) +$(DEVOBJ)gdevml6.$(OBJ) : $(JAPSRC)gdevml6.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(O_)$@ $(C_) $(JAPSRC)gdevml6.c @@ -1014,10 +1145,12 @@ lbp3x0_=$(DEVOBJ)gdevlbp3.$(OBJ) -$(DD)lbp310.dev :$(lbp3x0_) $(DD)page.dev +$(DD)lbp310.dev :$(lbp3x0_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lbp310 $(lbp3x0_) -$(DD)lbp320.dev :$(lbp3x0_) $(DD)page.dev +$(DD)lbp320.dev :$(lbp3x0_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lbp320 $(lbp3x0_) $(DEVOBJ)gdevlbp3.$(OBJ) : $(JAPSRC)gdevlbp3.c $(PDEVH) @@ -1027,59 +1160,73 @@ npdl_=$(DEVOBJ)gdevnpdl.$(OBJ) $(DEVOBJ)gdevlprn.$(OBJ) -$(DEVOBJ)gdevnpdl.$(OBJ) : $(JAPSRC)gdevnpdl.c $(LIPS_SRC)gdevlprn.h $(PDEVH) +$(DEVOBJ)gdevnpdl.$(OBJ) : $(JAPSRC)gdevnpdl.c $(LIPS_SRC)gdevlprn.h $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) -DA4 $(DEVO_)gdevnpdl.$(OBJ) $(LIPS_OPT) $(C_) $(JAPSRC)gdevnpdl.c -$(DD)npdl.dev : $(npdl_) $(DD)page.dev +$(DD)npdl.dev : $(npdl_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)npdl $(npdl_) ### ------- EPSON ESC/Page printer device ----------------- ### escpage_=$(DEVOBJ)gdevespg.$(OBJ) $(DEVOBJ)gdevlprn.$(OBJ) $(DEVOBJ)gdevlips.$(OBJ) -$(DEVOBJ)gdevespg.$(OBJ) : $(JAPSRC)gdevespg.c $(LIPS_SRC)gdevlprn.h $(PDEVH) +$(DEVOBJ)gdevespg.$(OBJ) : $(JAPSRC)gdevespg.c $(LIPS_SRC)gdevlprn.h $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) -DA4 $(DEVO_)gdevespg.$(OBJ) $(LIPS_OPT) $(C_) $(JAPSRC)gdevespg.c -$(DD)escpage.dev : $(escpage_) $(DD)page.dev +$(DD)escpage.dev : $(escpage_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)escpage $(escpage_) -$(DD)lp2000.dev : $(escpage_) $(DD)page.dev +$(DD)lp2000.dev : $(escpage_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)lp2000 $(escpage_) ### --- The RICOH RPDL language printer device ------ ### rpdl_=$(DEVOBJ)gdevrpdl.$(OBJ) $(DEVOBJ)gdevlprn.$(OBJ) -$(DEVOBJ)gdevrpdl.$(OBJ) : $(JAPSRC)gdevrpdl.c $(LIPS_SRC)gdevlprn.h $(PDEVH) +$(DEVOBJ)gdevrpdl.$(OBJ) : $(JAPSRC)gdevrpdl.c $(LIPS_SRC)gdevlprn.h $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(DEVO_)gdevrpdl.$(OBJ) $(LIPS_OPT) $(C_) $(JAPSRC)gdevrpdl.c -$(DD)rpdl.dev : $(rpdl_) $(DD)page.dev +$(DD)rpdl.dev : $(rpdl_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)rpdl $(rpdl_) ### ---------- RICOH RPDL IV(600dpi) printer devices ---------- ### #rpdl_=$(DEVOBJ)gdevrpdl.$(OBJ) -#$(DEVOBJ)gdevrpdl.$(OBJ) : $(JAPSRC)gdevrpdl.c +#$(DEVOBJ)gdevrpdl.$(OBJ) : $(JAPSRC)gdevrpdl.c \ + $(CONTRIB_MAK) $(MAKEDIRS) # $(DEVCC) $(DEVO_)gdevrpdl.$(OBJ) $(C_) $(JAPSRC)gdevrpdl.c # -#$(DD)nx100f.dev : $(rpdl_) $(DD)page.dev +#$(DD)nx100f.dev : $(rpdl_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) # $(SETPDEV2) $(DD)nx100f $(rpdl_) # -#$(DD)nx100v.dev : $(rpdl_) $(DD)page.dev +#$(DD)nx100v.dev : $(rpdl_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) # $(SETPDEV2) $(DD)nx100v $(rpdl_) ### ------------ The ALPS Micro Dry printer devices ------------ ### alps_=$(DEVOBJ)gdevalps.$(OBJ) -$(DD)md50Mono.dev : $(alps_) $(DD)page.dev +$(DD)md50Mono.dev : $(alps_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)md50Mono $(alps_) -$(DD)md50Eco.dev : $(alps_) $(DD)page.dev +$(DD)md50Eco.dev : $(alps_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)md50Eco $(alps_) -$(DD)md1xMono.dev : $(alps_) $(DD)page.dev +$(DD)md1xMono.dev : $(alps_) $(DD)page.dev \ + $(CONTRIB_MAK) $(MAKEDIRS) $(SETPDEV) $(DD)md1xMono $(alps_) -$(DEVOBJ)gdevalps.$(OBJ) : $(JAPSRC)gdevalps.c $(PDEVH) +$(DEVOBJ)gdevalps.$(OBJ) : $(JAPSRC)gdevalps.c $(PDEVH) \ + $(CONTRIB_MAK) $(MAKEDIRS) $(DEVCC) $(O_)$@ $(C_) $(JAPSRC)gdevalps.c ######################################################################### @@ -1087,7 +1234,7 @@ ### ----------------- Additional .upp files ---------------- ### -extra-upp-install: +extra-upp-install: install-libdata for f in $(CONTRIBSRC)uniprint$(D)*.upp; do \ $(INSTALL_DATA) $$f $(DESTDIR)$(gsdatadir)$(D)lib || exit 1; \ done diff -Nru ghostscript-9.10~dfsg/contrib/defs.h ghostscript-9.25~dfsg+1/contrib/defs.h --- ghostscript-9.10~dfsg/contrib/defs.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/defs.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,320 +0,0 @@ -/*******************************************************************************/ -/* */ -/* FILE: defs.h */ -/* */ -/* Header file to satisfy defines for gomni.c .*/ -/* */ -/* */ -/* Created: 03-21-2000 */ -/* */ -/* */ -/* */ -/*******************************************************************************/ -/* - * IBM Omni driver - * Copyright (c) International Business Machines Corp., 2000 - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Portions of this file are used with permission granted by Aladdin - * Enterprises - * - */ - -#define APIENTRY -#define LOCAL - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -typedef unsigned char BYTE; - -typedef unsigned char *PBYTE; - -typedef int INT; -typedef unsigned int UINT; - -typedef INT *PINT; - -typedef INT BOOL; -typedef BOOL *PBOOL; -typedef unsigned short WORD; -typedef unsigned long DWORD; - -typedef char CHAR; -typedef unsigned char UCHAR; -typedef short SHORT; -typedef SHORT *PSHORT; -typedef unsigned short USHORT; -typedef USHORT *PUSHORT; -typedef long LONG; -typedef LONG *PLONG; -typedef unsigned long ULONG; -typedef ULONG *PULONG; -typedef unsigned long HFILE; -typedef HFILE *PHFILE; - -typedef void VOID; -typedef VOID *PVOID; -typedef PVOID *PPVOID; - -typedef struct _SIZEL /* sizl */ -{ - LONG cx; - LONG cy; -} SIZEL; -typedef SIZEL *PSIZEL; - -typedef struct _POINTL { - LONG x; - LONG y; -} POINTL; -typedef POINTL *PPOINTL; - -typedef struct _RECTL { /* rcl */ - LONG xLeft; - LONG yBottom; - LONG xRight; - LONG yTop; -} RECTL; -typedef RECTL *PRECTL; - -typedef struct _RGB { /* rgb */ - BYTE bBlue; - BYTE bGreen; - BYTE bRed; -} RGB; -/* typedef RGB *PRGB; */ - -typedef LONG APIRET; - -/* Extract high and low order parts of 16 and 32 bit quantity */ -#define LOBYTE(w) LOUCHAR(w) -#define HIBYTE(w) HIUCHAR(w) -#define LOUCHAR(w) ((UCHAR)(w)) -#define HIUCHAR(w) ((UCHAR)(((USHORT)(w) >> 8) & 0xff)) -#define LOUSHORT(l) ((USHORT)((ULONG)l)) -#define HIUSHORT(l) ((USHORT)(((ULONG)(l) >> 16) & 0xffff)) - -#define CLR_FALSE (-5L) -#define CLR_TRUE (-4L) - -#define CLR_ERROR (-255L) -#define CLR_DEFAULT (-3L) -#define CLR_WHITE (-2L) -#define CLR_BLACK (-1L) -#define CLR_BACKGROUND 0L -#define CLR_BLUE 1L -#define CLR_RED 2L -#define CLR_PINK 3L -#define CLR_GREEN 4L -#define CLR_CYAN 5L -#define CLR_YELLOW 6L -#define CLR_NEUTRAL 7L - -#define CLR_DARKGRAY 8L -#define CLR_DARKBLUE 9L -#define CLR_DARKRED 10L -#define CLR_DARKPINK 11L -#define CLR_DARKGREEN 12L -#define CLR_DARKCYAN 13L -#define CLR_BROWN 14L -#define CLR_PALEGRAY 15L - -/* rgb colors */ -#define RGB_ERROR (-255L) -#define RGB_BLACK 0x00000000L -#define RGB_BLUE 0x000000FFL -#define RGB_GREEN 0x0000FF00L -#define RGB_CYAN 0x0000FFFFL -#define RGB_RED 0x00FF0000L -#define RGB_PINK 0x00FF00FFL -#define RGB_YELLOW 0x00FFFF00L -#define RGB_WHITE 0x00FFFFFFL - -#define BMAP_MEMORY 0x00000001 - -/* bitmap parameterization used by GpiCreateBitmap and others */ -typedef struct _BITMAPINFOHEADER /* bmp */ -{ - ULONG cbFix; - USHORT cx; - USHORT cy; - USHORT cPlanes; - USHORT cBitCount; -} BITMAPINFOHEADER; -typedef BITMAPINFOHEADER *PBITMAPINFOHEADER; - -typedef struct _BMAPINFO /* bmapinfo */ -{ - ULONG ulLength; - ULONG ulType; - ULONG ulWidth; - ULONG ulHeight; - ULONG ulBpp; - ULONG ulBytesPerLine; - PBYTE pBits; -} BMAPINFO; -typedef BMAPINFO *PBMAPINFO; - -typedef struct _BITMAPINFOHEADER2 /* bmp2 */ -{ - ULONG cbFix; /* Length of structure */ - ULONG cx; /* Bit-map width in pels */ - ULONG cy; /* Bit-map height in pels */ - USHORT cPlanes; /* Number of bit planes */ - USHORT cBitCount; /* Number of bits per pel within a plane */ - ULONG ulCompression; /* Compression scheme used to store the bitmap */ - ULONG cbImage; /* Length of bit-map storage data in bytes*/ - ULONG cxResolution; /* x resolution of target device */ - ULONG cyResolution; /* y resolution of target device */ - ULONG cclrUsed; /* Number of color indices used */ - ULONG cclrImportant; /* Number of important color indices */ - USHORT usUnits; /* Units of measure */ - USHORT usReserved; /* Reserved */ - USHORT usRecording; /* Recording algorithm */ - USHORT usRendering; /* Halftoning algorithm */ - ULONG cSize1; /* Size value 1 */ - ULONG cSize2; /* Size value 2 */ - ULONG ulColorEncoding; /* Color encoding */ - ULONG ulIdentifier; /* Reserved for application use */ -} BITMAPINFOHEADER2; -typedef BITMAPINFOHEADER2 *PBITMAPINFOHEADER2; - -typedef struct _RGB2 /* rgb2 */ -{ - BYTE bBlue; /* Blue component of the color definition */ - BYTE bGreen; /* Green component of the color definition*/ - BYTE bRed; /* Red component of the color definition */ - BYTE fcOptions; /* Reserved, must be zero */ -} RGB2; -typedef RGB2 *PRGB2; - -typedef struct _BITMAPINFO2 /* bmi2 */ -{ - int cbFix; - int cx; - int cy; - int cPlanes; - int cBitCount; - int ulCompresstion; - int cclrUsed; - int cclrImportant; - RGB2 argbColor[1]; -} BITMAPINFO2; -typedef BITMAPINFO2 *PBITMAPINFO2; - -/******************************************************************************/ -/* PPOINTL pptlSrc; // src left, bottom, width and height. */ -/* PPOINTL pptlDst; // dst left, bottom, width and height. */ -/* ULONG ulSrcBytesPerLine; // src bytes per line */ -/* PBYTE pbSrcBits; // pointer to src image data */ -/* ULONG ulTrgBytesPerLine; // dst bytes per line */ -/* PBYTE pbTrgBits; // pointer to dst image data */ -/* ULONG ulOptions; // options */ -/* ULONG ulcClrs; // count of colors in rgb2 table */ -/* PRGB2 pargb2; // rgb2 table */ -/******************************************************************************/ - -typedef struct _IMAGEINFOS /* imginfo */ -{ - PPOINTL pptlSrc; - PPOINTL pptlDst; - ULONG ulSrcBpp; - ULONG ulSrcBytesPerLine; - PBYTE pbSrcBits; - ULONG ulcSrcClrs; - ULONG ulSrcClrType; - PRGB2 pargb2Src; - ULONG ulTrgBpp; - ULONG ulTrgBytesPerLine; - PBYTE pbTrgBits; - ULONG ulcTrgClrs; - ULONG ulTrgClrType; - PRGB2 pargb2Trg; - ULONG ulOptions; - ULONG ulPelSizeCorrection; -} IMAGEINFOS; -typedef IMAGEINFOS * PIMAGEINFO; /* pimginfo */ - -#define GDM_NO_DITHER 0x0000 /* No dithering in system */ -#define GDM_USERDEF_DITHER 0x0001 /* Users supplies own Dithering routines */ -#define GDM_MATRIX_DITHER 0x0002 /* Use System ordered dithering */ -#define GDM_ERRORDIF_DITHER 0x0004 /* Use System error diffusion dithering */ -#define GDM_DITHER_BEGIN 0x0008 /* Use System Floyd-Steinberg dithering */ -#define GDM_DITHER_END 0x0010 /* Use System error propigation dithering */ -#define GDM_COLOR_CONVERT 0x0020 /* use device's clr mapping functions */ - -/*******************************************************************************************/ -/* ULONG ulLength; // length of structure - 88 */ -/* ULONG ulType; // type of dither info structure - GDM_MATRIX_DITHER*/ -/* ULONG fOptions; // dither info options - DI_MONOINVERT - 00 */ -/* ULONG ulIntensity; // RGB Gama Correction Value - 00 */ -/* BYTE bRedWt; // weight of primary color red - 25 */ -/* BYTE bGreenWt; // weight of primary color green - 60 */ -/* BYTE bBlueWt; // weight of primary color blue - 15 */ -/* BYTE bPad; // 4 byte align - 00 */ -/* SIZEL szMatrix; // halftone pattern size - 8 */ -/* BYTE bHalftone[]; // array of halftone patterns - see 32gdata.c */ -/*******************************************************************************************/ - -typedef struct _MATRIXDITHERINFO /* mtrxdi */ -{ - ULONG ulLength; - ULONG ulType; - ULONG fOptions; - ULONG ulIntensity; - BYTE bRedWt; - BYTE bGreenWt; - BYTE bBlueWt; - BYTE bPad; - SIZEL szMatrix; - BYTE bHalftone[1]; -} MATRIXDITHERINFO; -typedef MATRIXDITHERINFO *PMDI; /* pmtrxdi */ - -#define STUCKI_DIF 0x01 -#define JJN_DIF 0x02 -#define RND_DIF 0x04 -#define USER_DIF 0x08 - -typedef struct _DIFFUSIONDITHERINFO /* difdi */ -{ - ULONG ulLength; - ULONG ulType; /* Stucki, user defined, etc. */ - ULONG fOptions; - ULONG ulIntensity; - BYTE bRedWt; - BYTE bGreenWt; - BYTE bBlueWt; - BYTE bPad; - PBYTE pBuffer; - SIZEL szFilter; - BYTE bFilterArry[1]; - -} DIFFUSIONDITHERINFO; -typedef DIFFUSIONDITHERINFO *PDDI; /* pdifdi */ - -/* bitblt type */ -typedef enum { - BITBLT_BITMAP, - BITBLT_AREA, - BITBLT_TEXT -} BITBLT_TYPE; diff -Nru ghostscript-9.10~dfsg/contrib/eplaser/gdevescv.c ghostscript-9.25~dfsg+1/contrib/eplaser/gdevescv.c --- ghostscript-9.10~dfsg/contrib/eplaser/gdevescv.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/eplaser/gdevescv.c 2018-09-13 10:02:01.000000000 +0000 @@ -51,8 +51,7 @@ #include "gdevpstr.h" #include "ghost.h" #include "gzstate.h" -#include "imemory.h" -#include "igstate.h" + #include "gdevescv.h" #include "gspath.h" #include "gzpath.h" @@ -228,7 +227,7 @@ 0, /* int prev_y; */\ 0, /* gx_color_index prev_color; */\ 0, /* gx_color_index current_color; */\ - 3, /* floatp lwidth; */\ + 3, /* double lwidth; */\ 0, /* long cap; */\ 3, /* long join; */\ 0, /* long reverse_x; */\ @@ -333,8 +332,8 @@ static int escv_setfillcolor(P2(gx_device_vector * vdev, const gx_drawing_color * pdc)); static int escv_setstrokecolor(P2(gx_device_vector * vdev, const gx_drawing_color * pdc)); static int escv_setdash(P4(gx_device_vector * vdev, const float *pattern, - uint count, floatp offset)); -static int escv_setflat(P2(gx_device_vector * vdev, floatp flatness)); + uint count, double offset)); +static int escv_setflat(P2(gx_device_vector * vdev, double flatness)); static int escv_setlogop(P3(gx_device_vector * vdev, gs_logical_operation_t lop, gs_logical_operation_t diff)); static int escv_vector_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, @@ -342,43 +341,43 @@ static int escv_vector_dopath(gx_device_vector * vdev, const gx_path * ppath, gx_path_type_t type); static int escv_beginpath(P2(gx_device_vector * vdev, gx_path_type_t type)); -static int escv_moveto(P6(gx_device_vector * vdev, floatp x0, floatp y0, - floatp x, floatp y, gx_path_type_t type)); -static int escv_lineto(P6(gx_device_vector * vdev, floatp x0, floatp y0, - floatp x, floatp y, gx_path_type_t type)); -static int escv_curveto(P10(gx_device_vector * vdev, floatp x0, floatp y0, - floatp x1, floatp y1, floatp x2, floatp y2, - floatp x3, floatp y3, gx_path_type_t type)); -static int escv_closepath(P6(gx_device_vector * vdev, floatp x, floatp y, - floatp x_start, floatp y_start, gx_path_type_t type)); +static int escv_moveto(P6(gx_device_vector * vdev, double x0, double y0, + double x, double y, gx_path_type_t type)); +static int escv_lineto(P6(gx_device_vector * vdev, double x0, double y0, + double x, double y, gx_path_type_t type)); +static int escv_curveto(P10(gx_device_vector * vdev, double x0, double y0, + double x1, double y1, double x2, double y2, + double x3, double y3, gx_path_type_t type)); +static int escv_closepath(P6(gx_device_vector * vdev, double x, double y, + double x_start, double y_start, gx_path_type_t type)); static int escv_endpath(P2(gx_device_vector * vdev, gx_path_type_t type)); -static int escv_setlinewidth(gx_device_vector * vdev, floatp width); +static int escv_setlinewidth(gx_device_vector * vdev, double width); static int escv_setlinecap(gx_device_vector * vdev, gs_line_cap cap); static int escv_setlinejoin(gx_device_vector * vdev, gs_line_join join); -static int escv_setmiterlimit(gx_device_vector * vdev, floatp limit); +static int escv_setmiterlimit(gx_device_vector * vdev, double limit); #else /* 6 <= GS_VERSION_MAJOR */ /* Page management */ static int escv_beginpage (gx_device_vector * vdev); /* Imager state */ -static int escv_setlinewidth (gx_device_vector * vdev, floatp width); +static int escv_setlinewidth (gx_device_vector * vdev, double width); static int escv_setlinecap (gx_device_vector * vdev, gs_line_cap cap); static int escv_setlinejoin (gx_device_vector * vdev, gs_line_join join); -static int escv_setmiterlimit (gx_device_vector * vdev, floatp limit); +static int escv_setmiterlimit (gx_device_vector * vdev, double limit); static int escv_setdash (gx_device_vector * vdev, const float *pattern, - uint count, floatp offset); -static int escv_setflat (gx_device_vector * vdev, floatp flatness); + uint count, double offset); +static int escv_setflat (gx_device_vector * vdev, double flatness); static int escv_setlogop (gx_device_vector * vdev, gs_logical_operation_t lop, gs_logical_operation_t diff); /* Other state */ #if ( 8 <= GS_VERSION_MAJOR ) -static bool escv_can_handle_hl_color (gx_device_vector * vdev, const gs_imager_state * pis, +static bool escv_can_handle_hl_color (gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); -static int escv_setfillcolor (gx_device_vector * vdev, const gs_imager_state * pis, +static int escv_setfillcolor (gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); -static int escv_setstrokecolor (gx_device_vector * vdev, const gs_imager_state * pis, +static int escv_setstrokecolor (gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); #else static int escv_setfillcolor (gx_device_vector * vdev, const gx_drawing_color * pdc); @@ -391,15 +390,15 @@ static int escv_vector_dorect (gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, fixed y1, gx_path_type_t type); static int escv_beginpath (gx_device_vector * vdev, gx_path_type_t type); -static int escv_moveto (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x, floatp y, gx_path_type_t type); -static int escv_lineto (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x, floatp y, gx_path_type_t type); -static int escv_curveto (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x1, floatp y1, floatp x2, floatp y2, - floatp x3, floatp y3, gx_path_type_t type); -static int escv_closepath (gx_device_vector * vdev, floatp x0, floatp y0, - floatp x_start, floatp y_start, gx_path_type_t type); +static int escv_moveto (gx_device_vector * vdev, double x0, double y0, + double x, double y, gx_path_type_t type); +static int escv_lineto (gx_device_vector * vdev, double x0, double y0, + double x, double y, gx_path_type_t type); +static int escv_curveto (gx_device_vector * vdev, double x0, double y0, + double x1, double y1, double x2, double y2, + double x3, double y3, gx_path_type_t type); +static int escv_closepath (gx_device_vector * vdev, double x0, double y0, + double x_start, double y_start, gx_path_type_t type); static int escv_endpath (gx_device_vector * vdev, gx_path_type_t type); #endif /* GS_VERSION_MAJOR */ @@ -434,7 +433,7 @@ }; static void escv_write_begin(gx_device *dev, int bits, int x, int y, int sw, int sh, int dw, int dh, int roll); -static void escv_write_data(gx_device *dev, int bits, char *buf, int bsize, int w, int ras); +static void escv_write_data(gx_device *dev, int bits, byte *buf, int bsize, int w, int ras); static void escv_write_end(gx_device *dev, int bits); /* ---------------- Utilities ---------------- */ @@ -514,7 +513,7 @@ bool do_close = (type & gx_path_type_stroke) != 0; gs_fixed_rect rect; gs_point scale; - double x_start = 0, y_start = 0, x_prev = 0, y_prev = 0; + double x_start = 0, y_start = 0; bool first = true; gs_path_enum cenum; int code; @@ -536,88 +535,88 @@ pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); - sw:switch (pe_op) { - case 0: /* done */ - return (*vdev_proc(vdev, endpath)) (vdev, type); - - case gs_pe_moveto: - x = fixed2float(vs[0]) / scale.x; - y = fixed2float(vs[1]) / scale.y; - - /* ֥ѥ̿ p1 */ - (void)gs_sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x, (int)y); - lputs(s, obuf); + sw: + switch (pe_op) { + case 0: /* done */ + return (*vdev_proc(vdev, endpath)) (vdev, type); + + case gs_pe_moveto: + x = fixed2float(vs[0]) / scale.x; + y = fixed2float(vs[1]) / scale.y; - if (first) - x_start = x, y_start = y, first = false; - break; + /* ֥ѥ̿ p1 */ + (void)gs_sprintf(obuf, ESC_GS "0;%d;%dmvpG", (int)x, (int)y); + lputs(s, obuf); - case gs_pe_lineto: - cnt = 1; - for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_line; cnt++, pseg = pseg->next); + if (first) + x_start = x, y_start = y, first = false; + break; - (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt); - lputs(s, obuf); + case gs_pe_lineto: + cnt = 1; + for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_line; cnt++, pseg = pseg->next); - do { - (void)gs_sprintf(obuf, ";%d;%d", - (int)(fixed2float(vs[0]) / scale.x), - (int)(fixed2float(vs[1]) / scale.y)); + (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt); lputs(s, obuf); - pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); - } while (pe_op == gs_pe_lineto); + do { + (void)gs_sprintf(obuf, ";%d;%d", + (int)(fixed2float(vs[0]) / scale.x), + (int)(fixed2float(vs[1]) / scale.y)); + lputs(s, obuf); - /* ѥݥ饤̿ */ - lputs(s, "lnpG"); - pdev->ispath = 1; - - goto sw; - - case gs_pe_curveto: - cnt = 1; - for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_curve; cnt++, pseg = pseg->next); - (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt * 3); - lputs(s, obuf); + pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); + } while (pe_op == gs_pe_lineto); + + /* ѥݥ饤̿ */ + lputs(s, "lnpG"); + pdev->ispath = 1; + + goto sw; + + case gs_pe_curveto: + cnt = 1; + for (pseg = cenum.pseg; pseg != 0 && pseg->type == s_curve; cnt++, pseg = pseg->next); + (void)gs_sprintf(obuf, ESC_GS "0;%d", cnt * 3); + lputs(s, obuf); - do { - (void)gs_sprintf(obuf, ";%d;%d;%d;%d;%d;%d", + do { + (void)gs_sprintf(obuf, ";%d;%d;%d;%d;%d;%d", (int)(fixed2float(vs[0]) / scale.x), (int)(fixed2float(vs[1]) / scale.y), (int)(fixed2float(vs[2]) / scale.x), (int)(fixed2float(vs[3]) / scale.y), (int)(fixed2float(vs[4]) / scale.x), (int)(fixed2float(vs[5]) / scale.y)); - lputs(s, obuf); - - pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); - } while (pe_op == gs_pe_curveto); + lputs(s, obuf); - /* ٥ */ - lputs(s, "bzpG"); - pdev->ispath = 1; - - goto sw; - - case gs_pe_closepath: - x = x_start, y = y_start; - if (do_close) { - lputs(s, ESC_GS "clpG"); - break; - } + pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); + } while (pe_op == gs_pe_curveto); - pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); - if (pe_op != 0) { - lputs(s, ESC_GS "clpG"); + /* ٥ */ + lputs(s, "bzpG"); + pdev->ispath = 1; - if (code < 0) - return code; goto sw; + + case gs_pe_closepath: + x = x_start, y = y_start; + if (do_close) { + lputs(s, ESC_GS "clpG"); + break; + } + + pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); + if (pe_op != 0) { + lputs(s, ESC_GS "clpG"); + + if (code < 0) + return code; + goto sw; + } + return (*vdev_proc(vdev, endpath)) (vdev, type); + default: /* can't happen */ + return_error(gs_error_unknownerror); } - return (*vdev_proc(vdev, endpath)) (vdev, type); - default: /* can't happen */ - return_error(gs_error_unknownerror); - } if (code < 0) return code; - x_prev = x, y_prev = y; } } @@ -1261,7 +1260,7 @@ lputs(s, LP8200_CODE); } - put_bytes(s, ESC_GS "7;0;2;0cam{E\012\000\000\000\000\000\000", 20); + put_bytes(s, (const byte *)ESC_GS "7;0;2;0cam{E\012\000\000\000\000\000\000", 20); lputs(s, ESC_GS "0;0cmmE"); if (vdev->x_pixels_per_inch == 1200) { @@ -1283,7 +1282,7 @@ lputs(s, COLOR_START_CODE1); lputs(s, ESC_GS "8;1;2;2;2plr{E"); - put_bytes(s, "\377\377\377\377\000\000\000\000", 8); + put_bytes(s, (const byte *)"\377\377\377\377\000\000\000\000", 8); lputs(s, ESC_GS "0sarG"); /* кɸ */ lputs(s, ESC_GS "2;204wfE"); /* rop */ @@ -1296,7 +1295,7 @@ } static int -escv_setlinewidth(gx_device_vector * vdev, floatp width) +escv_setlinewidth(gx_device_vector * vdev, double width) { stream *s = gdev_vector_stream(vdev); gx_device_escv *const pdev = (gx_device_escv *) vdev; @@ -1304,7 +1303,7 @@ #if GS_VERSION_MAJOR == 5 /* Scale ݤƤΤ, Ghostscript 5.10/5.50 ΥХΤ */ - floatp xscale, yscale; + double xscale, yscale; xscale = fabs(igs->ctm.xx); yscale = fabs(igs->ctm.xy); @@ -1382,7 +1381,7 @@ } static int -escv_setmiterlimit(gx_device_vector * vdev, floatp limit) +escv_setmiterlimit(gx_device_vector * vdev, double limit) { stream *s = gdev_vector_stream(vdev); gx_device_escv *const pdev = (gx_device_escv *) vdev; @@ -1409,7 +1408,7 @@ #if ( 8 <= GS_VERSION_MAJOR ) static bool -escv_can_handle_hl_color(gx_device_vector * vdev, const gs_imager_state * pis, +escv_can_handle_hl_color(gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc) { return false; @@ -1419,7 +1418,7 @@ static int escv_setfillcolor(gx_device_vector * vdev, #if ( 8 <= GS_VERSION_MAJOR ) - const gs_imager_state * pis, + const gs_gstate * pgs, #endif const gx_drawing_color * pdc) { @@ -1462,7 +1461,7 @@ static int escv_setstrokecolor(gx_device_vector * vdev, #if ( 8 <= GS_VERSION_MAJOR ) - const gs_imager_state * pis, + const gs_gstate * pgs, #endif const gx_drawing_color * pdc) { @@ -1508,7 +1507,7 @@ /* ̿ */ static int -escv_setdash(gx_device_vector * vdev, const float *pattern, uint count, floatp offset) +escv_setdash(gx_device_vector * vdev, const float *pattern, uint count, double offset) { stream *s = gdev_vector_stream(vdev); int i; @@ -1570,7 +1569,7 @@ /* ѥʿٻ */ static int -escv_setflat(gx_device_vector * vdev, floatp flatness) +escv_setflat(gx_device_vector * vdev, double flatness) { return 0; } @@ -1602,7 +1601,7 @@ static int escv_moveto(gx_device_vector * vdev, - floatp x0, floatp y0, floatp x1, floatp y1, gx_path_type_t type) + double x0, double y0, double x1, double y1, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); char obuf[64]; @@ -1616,7 +1615,7 @@ static int escv_lineto(gx_device_vector * vdev, - floatp x0, floatp y0, floatp x1, floatp y1, gx_path_type_t type) + double x0, double y0, double x1, double y1, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); gx_device_escv *pdev = (gx_device_escv *) vdev; @@ -1630,8 +1629,8 @@ } static int -escv_curveto(gx_device_vector * vdev, floatp x0, floatp y0, - floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3, +escv_curveto(gx_device_vector * vdev, double x0, double y0, + double x1, double y1, double x2, double y2, double x3, double y3, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); @@ -1648,8 +1647,8 @@ } static int -escv_closepath(gx_device_vector * vdev, floatp x, floatp y, - floatp x_start, floatp y_start, gx_path_type_t type) +escv_closepath(gx_device_vector * vdev, double x, double y, + double x_start, double y_start, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); @@ -1880,7 +1879,7 @@ switch (code = param_read_string(plist, (param_name = key), &gsstr)) { case 0: writesize = ( bufmax < gsstr.size )? bufmax : gsstr.size ; - strncpy( strvalue, gsstr.data, writesize ); + strncpy( strvalue, (const char *)gsstr.data, writesize ); strvalue[ writesize ] = '\0'; break; default: @@ -2004,27 +2003,27 @@ goto pmediae; } else { /* Check the validity of ``MediaType'' characters */ - if (strcmp(pmedia.data, "NM") == 0) { + if (strcmp((const char *)pmedia.data, "NM") == 0) { pdev->MediaType = 0; - } else if ((strcmp(pmedia.data, "THICK") == 0) || - (strcmp(pmedia.data, "TH") == 0)) { + } else if ((strcmp((const char *)pmedia.data, "THICK") == 0) || + (strcmp((const char *)pmedia.data, "TH") == 0)) { pdev->MediaType = 1; - } else if ((strcmp(pmedia.data, "TRANS") == 0) || - (strcmp(pmedia.data, "TR") == 0)) { + } else if ((strcmp((const char *)pmedia.data, "TRANS") == 0) || + (strcmp((const char *)pmedia.data, "TR") == 0)) { pdev->MediaType = 2; - } else if (strcmp(pmedia.data, "TN") == 0) { + } else if (strcmp((const char *)pmedia.data, "TN") == 0) { pdev->MediaType = 3; - } else if (strcmp(pmedia.data, "LH") == 0) { + } else if (strcmp((const char *)pmedia.data, "LH") == 0) { pdev->MediaType = 4; - } else if (strcmp(pmedia.data, "CT") == 0) { + } else if (strcmp((const char *)pmedia.data, "CT") == 0) { pdev->MediaType = 5; - } else if (strcmp(pmedia.data, "ET") == 0) { + } else if (strcmp((const char *)pmedia.data, "ET") == 0) { pdev->MediaType = 6; - } else if (strcmp(pmedia.data, "HQ") == 0) { + } else if (strcmp((const char *)pmedia.data, "HQ") == 0) { pdev->MediaType = 7; - } else if (strcmp(pmedia.data, "UT") == 0) { + } else if (strcmp((const char *)pmedia.data, "UT") == 0) { pdev->MediaType = 8; - } else if (strcmp(pmedia.data, "UM") == 0) { + } else if (strcmp((const char *)pmedia.data, "UM") == 0) { pdev->MediaType = 9; } else { ecode = gs_error_rangecheck; @@ -2154,7 +2153,7 @@ int depth = 1; #if ( 8 <= GS_VERSION_MAJOR ) /* FIXME! add for gs815 */ - const gs_imager_state * pis = (const gs_imager_state *)0; + const gs_gstate * pgs = (const gs_gstate *)0; #endif if (id != gs_no_id && zero == gx_no_color_index && one != gx_no_color_index && data_x == 0) { @@ -2163,7 +2162,7 @@ color_set_pure(&dcolor, one); escv_setfillcolor(vdev, #if ( 8 <= GS_VERSION_MAJOR ) - pis, + pgs, #endif &dcolor); /* FIXME! gs815 */ } @@ -2251,7 +2250,7 @@ color_set_pure(&color, one); code = gdev_vector_update_fill_color((gx_device_vector *) pdev, #if ( 8 <= GS_VERSION_MAJOR ) - pis, + pgs, #endif &color); @@ -2366,7 +2365,7 @@ #if ( 8 <= GS_VERSION_MAJOR ) /* FIXME! add for gs815 */ - const gs_imager_state * pis = (const gs_imager_state *)0; + const gs_gstate * pgs = (const gs_gstate *)0; #endif if (w <= 0 || h <= 0) return 0; @@ -2374,7 +2373,7 @@ if (depth > 1 || gdev_vector_update_fill_color(vdev, #if ( 8 <= GS_VERSION_MAJOR ) - pis, + pgs, #endif pdcolor) < 0 || gdev_vector_update_clip_path(vdev, pcpath) < 0 || @@ -2476,7 +2475,7 @@ /* Start processing an image. */ static int escv_begin_image(gx_device * dev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, gx_image_enum_common_t **pinfo) @@ -2495,14 +2494,13 @@ gs_matrix imat; int code; - int ty, bx, by, cx, cy, dx, dy, sx, sy; + int ty, bx, by, cy, sx, sy; - gx_color_index color = gx_dc_pure_color(pdcolor); char obuf[128]; if (pie == 0) return_error(gs_error_VMerror); pie->memory = mem; - code = gdev_vector_begin_image(vdev, pis, pim, format, prect, + code = gdev_vector_begin_image(vdev, pgs, pim, format, prect, pdcolor, pcpath, mem, &escv_image_enum_procs, pie); if (code < 0) return code; @@ -2533,7 +2531,7 @@ } } if (!can_do) { - return gx_default_begin_image(dev, pis, pim, format, prect, + return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, mem, &pie->default_info); } @@ -2544,7 +2542,7 @@ if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ } else { /* ESC/Page-Color */ lputs(s, ESC_GS "8;1;2;2;2plr{E"); - put_bytes(s, "\000\000\000\000\377\377\377\377", 8); + put_bytes(s, (const byte *)"\000\000\000\000\377\377\377\377", 8); } /* ESC/Page-Color */ pdev->MaskReverse = 0; } @@ -2552,15 +2550,12 @@ /* Write the image/colorimage/imagemask preamble. */ gs_matrix_invert(&pim->ImageMatrix, &imat); - gs_matrix_multiply(&imat, &ctm_only(pis), &imat); + gs_matrix_multiply(&imat, &ctm_only(pgs), &imat); ty = imat.ty; bx = imat.xx * pim->Width + imat.yx * pim->Height + imat.tx; by = imat.xy * pim->Width + imat.yy * pim->Height + imat.ty; - cx = imat.yx * pim->Height + imat.tx; cy = imat.yy * pim->Height + imat.ty; - dx = imat.xx * pim->Width + imat.tx; - dy = imat.xy * pim->Width + imat.ty; sx = bx - (int)imat.tx; sy = by - (int)imat.ty; @@ -2601,6 +2596,7 @@ if (pdev->MaskState != 1) { if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ + gx_color_index color = gx_dc_pure_color(pdcolor); /* lputs(s, ESC_GS "1owE");*/ (void)gs_sprintf(obuf, ESC_GS "1;1;%ldccE", color); @@ -2889,7 +2885,7 @@ stream *s = gdev_vector_stream((gx_device_vector *)pdev); lputs(s, ESC_GS "8;1;2;2;2plr{E"); - put_bytes(s, "\377\377\377\377\000\000\000\000", 8); + put_bytes(s, (const byte *)"\377\377\377\377\000\000\000\000", 8); } /* ESC/Page-Color */ } pdev->MaskReverse = -1; @@ -2903,7 +2899,8 @@ gx_device_vector *const vdev = (gx_device_vector *) dev; gx_device_escv *const pdev = (gx_device_escv *)dev; stream *s = gdev_vector_stream((gx_device_vector *)dev); - char obuf[128], *tmp, *p; + char obuf[128]; + byte *tmp, *p; int i, comp; if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ @@ -2988,17 +2985,17 @@ return; } -static void escv_write_data(gx_device *dev, int bits, char *buf, int bsize, int w, int ras) +static void escv_write_data(gx_device *dev, int bits, byte *buf, int bsize, int w, int ras) { - gx_device_vector *const vdev = (gx_device_vector *) dev; - gx_device_escv *const pdev = (gx_device_escv *) dev; - stream *s = gdev_vector_stream((gx_device_vector *)pdev); - char obuf[128]; - int size; - char *tmps, *p; - unsigned char *rgbbuf; - unsigned char *ucp; - double gray8; + gx_device_vector *const vdev = (gx_device_vector *) dev; + gx_device_escv *const pdev = (gx_device_escv *) dev; + stream *s = gdev_vector_stream((gx_device_vector *)pdev); + char obuf[128]; + int size; + byte *tmps, *p; + unsigned char *rgbbuf; + unsigned char *ucp; + double gray8; if( 0 == pdev->colormode ) { /* ESC/Page (Monochrome) */ diff -Nru ghostscript-9.10~dfsg/contrib/eplaser/gdevescv.h ghostscript-9.25~dfsg+1/contrib/eplaser/gdevescv.h --- ghostscript-9.10~dfsg/contrib/eplaser/gdevescv.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/eplaser/gdevescv.h 2018-09-13 10:02:01.000000000 +0000 @@ -141,7 +141,7 @@ int prev_y; gx_color_index prev_color; gx_color_index current_color; - floatp lwidth; + double lwidth; long cap; long join; long reverse_x; diff -Nru ghostscript-9.10~dfsg/contrib/gdevbjca.c ghostscript-9.25~dfsg+1/contrib/gdevbjca.c --- ghostscript-9.10~dfsg/contrib/gdevbjca.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevbjca.c 2018-09-13 10:02:01.000000000 +0000 @@ -46,7 +46,7 @@ #include #include -static void bjc_put_bytes(FILE *file, const char *data, int count); +static void bjc_put_bytes(FILE *file, const byte *data, int count); static void bjc_put_hi_lo(FILE *file, int value); static void bjc_put_lo_hi(FILE *file, int value); static void bjc_put_command(FILE *file, char command, int count); @@ -54,9 +54,8 @@ /* ---------------- Utilities ---------------- */ static void -bjc_put_bytes(FILE *file, const char *data, int count) +bjc_put_bytes(FILE *file, const byte *data, int count) { - fwrite(data, count, 1, file); } @@ -109,14 +108,14 @@ void bjc_put_initialize(FILE *file) { - bjc_put_bytes(file, "\033@", 2); + bjc_put_bytes(file, (const byte *)"\033@", 2); } /* Set initial condition (ESC [ K ) */ void bjc_put_set_initial(FILE *file) { - bjc_put_bytes(file, "\033[K\002\000\000\017", 7); + bjc_put_bytes(file, (const byte *)"\033[K\002\000\000\017", 7); } /* Set data compression (ESC [ b ) */ @@ -170,10 +169,10 @@ void bjc_put_page_margins(FILE *file, int length, int lm, int rm, int top) { - char parms[4]; + byte parms[4]; parms[0] = length, parms[1] = lm, parms[2] = rm, parms[3] = top; -/* count = 4; */ /* could be 1..3 */ +/* count = 4; */ /* could be 1..3 */ bjc_put_command(file, 'g', 4); bjc_put_bytes(file, parms, 4); } @@ -199,7 +198,7 @@ /* CMYK raster image (ESC ( A ) */ void bjc_put_cmyk_image(FILE *file, char component, - const char *data, int count) + const byte *data, int count) { bjc_put_command(file, 'A', count + 1); fputc(component, file); @@ -254,7 +253,7 @@ /* Continue raster image (ESC ( F ) */ void -bjc_put_continue_image(FILE *file, const char *data, int count) +bjc_put_continue_image(FILE *file, const byte *data, int count) { bjc_put_command(file, 'F', count); bjc_put_bytes(file, data, count); @@ -266,7 +265,7 @@ bjc_put_indexed_image(FILE *file, int dot_rows, int dot_cols, int layers) { bjc_put_command(file, 'f', 5); - fputc('R', file); /* per spec */ + fputc('R', file); /* per spec */ fputc(dot_rows, file); fputc(dot_cols, file); fputc(layers, file); @@ -283,8 +282,8 @@ if(!(inverse)) *row = ~(*row); if(*row) ret = true; } - if(!(inverse)) *row ^= 0xff; - *row &= lastmask; + if(!(inverse)) *row ^= 0xff; + *row &= lastmask; return ret; } @@ -364,7 +363,7 @@ /* and [end_dis..next) should be encoded as similar. */ /* Note that either of these ranges may be empty. */ - for ( ; ; ) { /* Encode up to 128 dissimilar bytes */ + for ( ; ; ) { /* Encode up to 128 dissimilar bytes */ uint count = end_dis - compr; /* uint for faster switch */ switch ( count ) { /* Use memcpy only if it's worthwhile. */ case 6: cptr[6] = compr[5]; @@ -387,7 +386,7 @@ break; } - { /* Encode up to 128 similar bytes. */ + { /* Encode up to 128 similar bytes. */ /* Note that count may be <0 at end of row. */ int count = next - end_dis; if (next < end_row || test != 0) @@ -477,8 +476,8 @@ * Errors are accumulated into the array fserrors[], at a resolution of * 1/16th of a pixel count. The error at a given pixel is propagated * to its not-yet-processed neighbors using the standard F-S fractions, - * ... (here) 7/16 - * 3/16 5/16 1/16 + * ... (here) 7/16 + * 3/16 5/16 1/16 * We work left-to-right on even rows, right-to-left on odd rows. * * We can get away with a single array (holding one row's worth of errors) diff -Nru ghostscript-9.10~dfsg/contrib/gdevbjc_.c ghostscript-9.25~dfsg+1/contrib/gdevbjc_.c --- ghostscript-9.10~dfsg/contrib/gdevbjc_.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevbjc_.c 2018-09-13 10:02:01.000000000 +0000 @@ -46,7 +46,6 @@ #include "gdevbjc_.h" /* ------ The device descriptors ------ */ -static dev_proc_print_page(bjc_print_page); static dev_proc_print_page(bjc_print_page_mono); static dev_proc_print_page(bjc_print_page_gray); static dev_proc_print_page(bjc_print_page_cmyk); @@ -83,113 +82,113 @@ /* String parameter definitions */ stringParamDescription strPrinterType[] = { - { { "BJC-250", 7, false }, 0 }, - { { "BJC-250ex", 9, false }, 1 }, - { { "BJC-1000", 8, false }, 2 }, - - { { "250", 3, false }, 0 }, - { { "250ex", 5, false }, 1 }, - { { "1000", 4, false }, 2 }, + { { (const byte *)"BJC-250", 7, false }, 0 }, + { { (const byte *)"BJC-250ex", 9, false }, 1 }, + { { (const byte *)"BJC-1000", 8, false }, 2 }, + + { { (const byte *)"250", 3, false }, 0 }, + { { (const byte *)"250ex", 5, false }, 1 }, + { { (const byte *)"1000", 4, false }, 2 }, { {0} } }; stringParamDescription strFeeder[] = { - { { "Manual", 6, false }, 0x11 }, - { { "Auto", 4, false }, 0x10 }, + { { (const byte *)"Manual", 6, false }, 0x11 }, + { { (const byte *)"Auto", 4, false }, 0x10 }, - { { "m", 1, false }, 0x11 }, - { { "a", 1, false }, 0x10 }, + { { (const byte *)"m", 1, false }, 0x11 }, + { { (const byte *)"a", 1, false }, 0x10 }, { {0} } }; stringParamDescription strQuality[] = { - { { "Normal", 6, false }, 0 }, - { { "High", 4, false }, 1 }, - { { "Draft", 5, false }, 2 }, - { { "NonBleed", 8, false }, 8 }, - - { { "n", 1, false }, 0 }, - { { "h", 1, false }, 1 }, - { { "d", 1, false }, 2 }, - { { "b", 1, false }, 8 }, + { { (const byte *)"Normal", 6, false }, 0 }, + { { (const byte *)"High", 4, false }, 1 }, + { { (const byte *)"Draft", 5, false }, 2 }, + { { (const byte *)"NonBleed", 8, false }, 8 }, + + { { (const byte *)"n", 1, false }, 0 }, + { { (const byte *)"h", 1, false }, 1 }, + { { (const byte *)"d", 1, false }, 2 }, + { { (const byte *)"b", 1, false }, 8 }, { {0} } }; stringParamDescription strInk[] = { - { { "Black", 5, false }, 8 }, - { { "Cyan", 4, false }, 1 }, - { { "Magenta", 7, false }, 2 }, - { { "Yellow", 6, false }, 4 }, - { { "Red", 3, false }, 6 }, - { { "Green", 5, false }, 5 }, - { { "Blue", 4, false }, 3 }, - - { { "K", 1, false }, 8 }, - { { "C", 1, false }, 1 }, - { { "M", 1, false }, 2 }, - { { "Y", 1, false }, 4 }, - { { "R", 1, false }, 6 }, - { { "G", 1, false }, 5 }, - { { "B", 1, false }, 3 }, - { { "CK", 2, false }, 9 }, - { { "MK", 2, false }, 10 }, - { { "YK", 2, false }, 12 }, - { { "RK", 2, false }, 14 }, - { { "GK", 2, false }, 13 }, - { { "BK", 2, false }, 11 }, - { { "CMY", 3, false }, 7 }, - { { "CMYK", 4, false }, 15 }, + { { (const byte *)"Black", 5, false }, 8 }, + { { (const byte *)"Cyan", 4, false }, 1 }, + { { (const byte *)"Magenta", 7, false }, 2 }, + { { (const byte *)"Yellow", 6, false }, 4 }, + { { (const byte *)"Red", 3, false }, 6 }, + { { (const byte *)"Green", 5, false }, 5 }, + { { (const byte *)"Blue", 4, false }, 3 }, + + { { (const byte *)"K", 1, false }, 8 }, + { { (const byte *)"C", 1, false }, 1 }, + { { (const byte *)"M", 1, false }, 2 }, + { { (const byte *)"Y", 1, false }, 4 }, + { { (const byte *)"R", 1, false }, 6 }, + { { (const byte *)"G", 1, false }, 5 }, + { { (const byte *)"B", 1, false }, 3 }, + { { (const byte *)"CK", 2, false }, 9 }, + { { (const byte *)"MK", 2, false }, 10 }, + { { (const byte *)"YK", 2, false }, 12 }, + { { (const byte *)"RK", 2, false }, 14 }, + { { (const byte *)"GK", 2, false }, 13 }, + { { (const byte *)"BK", 2, false }, 11 }, + { { (const byte *)"CMY", 3, false }, 7 }, + { { (const byte *)"CMYK", 4, false }, 15 }, { {0} } }; static stringParamDescription strMedia[] = { - {{"PlainPaper", 10, false}, 0}, - {{"CoatedPaper", 11, false}, 1}, - {{"TransparencyFilm", 16, false}, 2}, - {{"BackprintFilm", 13, false}, 3}, - {{"T-ShirtTransfer", 15, false}, 3}, - {{"FabricSheet", 11, false}, 4}, - {{"GlossyPaper", 11, false}, 5}, - {{"GlossyPhotoPaper", 16, false}, 5}, - {{"HighGlossPaper", 14, false}, 5}, - {{"HighGlossyFilm", 14, false}, 6}, - {{"Envelope", 8, false}, 7}, - {{"OtherPaper", 10, false}, 8}, - {{"HighResolutionPaper", 19, false}, 9}, -/* { { "HighResPaper", 12, false }, 11 }, */ - {{"GlossyPhotoCard", 15, false}, 10}, -/* { { "FullBleed", 9, false }, 12 }, */ - {{"Banner", 6, false}, 11}, - - {{"Plain", 5, false}, 0}, - {{"Coated", 6, false}, 1}, - {{"Trans", 5, false}, 2}, - {{"Back", 4, false}, 3}, - {{"Shirt", 4, false}, 3}, -/* { { "Lead", 4, false }, 4 }, */ - {{"Fabric", 6, false}, 4}, - {{"Glossy", 6, false}, 5}, - {{"HGloss", 6, false}, 6}, - {{"Env", 3, false}, 7}, - {{"Oth", 3, false}, 8}, - {{"HiRes", 5, false}, 9}, -/* { { "Bleed", 5, false }, 12 }, */ - {{"Card", 4, false}, 10}, - {{"Ban", 3, false}, 11}, - - {{"p", 1, false}, 0}, - {{"c", 1, false}, 1}, - {{"t", 1, false}, 2}, - {{"b", 1, false}, 3}, - {{"s", 1, false}, 3}, - {{"f", 1, false}, 4}, - {{"g", 1, false}, 5}, - {{"F", 1, false}, 6}, - {{"e", 1, false}, 7}, - {{"o", 1, false}, 8}, - {{"h", 1, false}, 9}, - {{"C", 1, false}, 10}, - {{"B", 1, false}, 11}, + {{(const byte *)"PlainPaper", 10, false}, 0}, + {{(const byte *)"CoatedPaper", 11, false}, 1}, + {{(const byte *)"TransparencyFilm", 16, false}, 2}, + {{(const byte *)"BackprintFilm", 13, false}, 3}, + {{(const byte *)"T-ShirtTransfer", 15, false}, 3}, + {{(const byte *)"FabricSheet", 11, false}, 4}, + {{(const byte *)"GlossyPaper", 11, false}, 5}, + {{(const byte *)"GlossyPhotoPaper", 16, false}, 5}, + {{(const byte *)"HighGlossPaper", 14, false}, 5}, + {{(const byte *)"HighGlossyFilm", 14, false}, 6}, + {{(const byte *)"Envelope", 8, false}, 7}, + {{(const byte *)"OtherPaper", 10, false}, 8}, + {{(const byte *)"HighResolutionPaper", 19, false}, 9}, +/* { { (const byte *)"HighResPaper", 12, false }, 11 }, */ + {{(const byte *)"GlossyPhotoCard", 15, false}, 10}, +/* { { (const byte *)"FullBleed", 9, false }, 12 }, */ + {{(const byte *)"Banner", 6, false}, 11}, + + {{(const byte *)"Plain", 5, false}, 0}, + {{(const byte *)"Coated", 6, false}, 1}, + {{(const byte *)"Trans", 5, false}, 2}, + {{(const byte *)"Back", 4, false}, 3}, + {{(const byte *)"Shirt", 4, false}, 3}, +/* { { (const byte *)"Lead", 4, false }, 4 }, */ + {{(const byte *)"Fabric", 6, false}, 4}, + {{(const byte *)"Glossy", 6, false}, 5}, + {{(const byte *)"HGloss", 6, false}, 6}, + {{(const byte *)"Env", 3, false}, 7}, + {{(const byte *)"Oth", 3, false}, 8}, + {{(const byte *)"HiRes", 5, false}, 9}, +/* { { (const byte *)"Bleed", 5, false }, 12 }, */ + {{(const byte *)"Card", 4, false}, 10}, + {{(const byte *)"Ban", 3, false}, 11}, + + {{(const byte *)"p", 1, false}, 0}, + {{(const byte *)"c", 1, false}, 1}, + {{(const byte *)"t", 1, false}, 2}, + {{(const byte *)"b", 1, false}, 3}, + {{(const byte *)"s", 1, false}, 3}, + {{(const byte *)"f", 1, false}, 4}, + {{(const byte *)"g", 1, false}, 5}, + {{(const byte *)"F", 1, false}, 6}, + {{(const byte *)"e", 1, false}, 7}, + {{(const byte *)"o", 1, false}, 8}, + {{(const byte *)"h", 1, false}, 9}, + {{(const byte *)"C", 1, false}, 10}, + {{(const byte *)"B", 1, false}, 11}, {{0}} }; @@ -428,7 +427,7 @@ const char *param_name; gs_param_string tmppar; uint parsize; - stringParamDescription *tmpstr=NULL; + const stringParamDescription *tmpstr=NULL; # define ppdev ((gx_device_bjc_printer *)pdev) @@ -731,7 +730,6 @@ char color = 0x10; /* color */ char ink = 0x01; /* regular ink type */ char compress = (ppdev->compress == true ? 0x01 : 0x00); /* compression or not */ - char skip_x; int x_resolution = pdev->HWResolution[0]; int y_resolution = pdev->HWResolution[1]; int length = 0/*x71*/, lm = 0/*x01*/, rm = 0/*x01*/, top = 0/*x50*/; @@ -761,7 +759,6 @@ for (y = 0; y < pdev->height ; y++) { - skip_x = 0; for (plane = 0; plane < 4; plane++) { /* print each color component */ gx_render_plane_init(&render_plane, (gx_device *)pdev, plane); gdev_prn_get_lines(pdev, y, 1, row + raster*plane, raster, diff -Nru ghostscript-9.10~dfsg/contrib/gdevbjc_.h ghostscript-9.25~dfsg+1/contrib/gdevbjc_.h --- ghostscript-9.10~dfsg/contrib/gdevbjc_.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevbjc_.h 2018-09-13 10:02:01.000000000 +0000 @@ -16,9 +16,13 @@ * * If this program is being distributed under the terms of the GPL, you * should have received a copy of the GPL along with this program, normally - * in a plain ASCII text file named COPYING; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 - * U.S.A. + * in a plain ASCII text file named COPYING; if not, write to the: + * + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 + * USA + * */ /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved. @@ -212,13 +216,13 @@ void bjc_put_raster_skip(FILE *file, int skip); void bjc_put_page_margins(FILE *file, int length, int lm, int rm, int top); void bjc_put_media_supply(FILE *file, char supply, char type); -void bjc_put_cmyk_image(FILE *file, char component, const char *data, int count); +void bjc_put_cmyk_image(FILE *file, char component, const byte *data, int count); void bjc_put_move_lines(FILE *file, int lines); void bjc_put_move_lines_unit(FILE *file, int unit); void bjc_put_extended_margins(FILE *file, int length, int lm, int rm, int top); void bjc_put_image_format(FILE *file, char depth, char format, char ink); void bjc_put_page_id(FILE *file, int id); -void bjc_put_continue_image(FILE *file, const char *data, int count); +void bjc_put_continue_image(FILE *file, const byte *data, int count); void bjc_put_indexed_image(FILE *file, int dot_rows, int dot_cols, int layers); bool bjc_invert_bytes(byte *row, uint raster, bool inverse, byte lastmask); diff -Nru ghostscript-9.10~dfsg/contrib/gdevcd8.c ghostscript-9.25~dfsg+1/contrib/gdevcd8.c --- ghostscript-9.10~dfsg/contrib/gdevcd8.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevcd8.c 2018-09-13 10:02:01.000000000 +0000 @@ -14,8 +14,12 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program; if not, write to: + + Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor + Boston, MA 02110-1301 + USA This program may also be distributed as part of Aladdin Ghostscript, under the terms of the Aladdin Free Public License (the "License"). @@ -1179,8 +1183,10 @@ struct error_val_field *error_values, const Gamma *gamma, FILE * prn_stream); +#ifdef UNUSED static void do_gamma(float mastergamma, float gammaval, byte * values); +#endif static void do_black_correction(float kvalue, int *kcorrect); @@ -2083,6 +2089,7 @@ fwrite(out_data, sizeof(byte), out_count, prn_stream); } +#ifdef UNUSED /* print_c0plane() * * Outputs a plane with no compression. @@ -2095,6 +2102,7 @@ if (plane_size > 0) fwrite(curr, sizeof(byte), plane_size, prn_stream); } +#endif /* Printing non-blank lines */ static void @@ -2270,10 +2278,6 @@ byte *dpc; int *epc; - /* the b/w pointers */ - byte *kP, *dp; - int *ep; - /* the color pointers, lower byte */ cPa = data_ptrs->plane_data_c[cscan + 2][2]; mPa = data_ptrs->plane_data_c[cscan + 2][1]; @@ -2285,10 +2289,6 @@ /* data and error */ dpc = data_ptrs->data_c[cscan + 2]; epc = data_ptrs->errors_c[cscan]; - /* the b/w pointers */ - kP = data_ptrs->plane_data[scan + 2][3]; - dp = data_ptrs->data[scan + 2]; - ep = data_ptrs->errors[scan]; switch (cdj850->intensities) { case 2: @@ -2309,6 +2309,7 @@ return; } +#ifdef UNUSED /* here we do our own gamma-correction */ static void do_gamma(float mastergamma, float gammaval, byte values[256]) @@ -2330,6 +2331,7 @@ return; } +#endif /* here we calculate a lookup-table which is used to compensate the relative loss of color due to undercolor-removal */ @@ -2413,12 +2415,10 @@ const byte yvalues[256], const int kcorrect[256], word * inword) { - int i, ucr, kadd, is_color = 0; - float uca_fac; + int i, ucr, is_color = 0; byte *black, *cyan, *magenta, *yellow; word last_color_value = 0; word *last_color; - char output[255], out2[128]; /* initialise *last_color with a dummmy value */ last_color = &last_color_value; @@ -2439,6 +2439,7 @@ #if 0 if ((*cyan > 0) && (*magenta > 0) && (*yellow > 0)) { + char output[255]; gs_sprintf(output, "%3d %3d %3d %3d - ", *cyan, *magenta, *yellow, *black); debug_print_string(output, strlen(output)); } @@ -2484,20 +2485,21 @@ } else { /* do gamma only if no black */ } #if 0 - if (ucr > 0) - { - gs_sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr); - debug_print_string(output, strlen(output)); - } + if (ucr > 0) + { + char output[255]; + gs_sprintf(output, "%3d %3d %3d %3d - %5d\n", *cyan, *magenta, *yellow, *black, ucr); + debug_print_string(output, strlen(output)); + } #endif /* 0 */ - if ( *cyan > 255) *cyan = 255; - if (*magenta > 255) *magenta = 255; - if ( *yellow > 255) *yellow = 255; - - *cyan = *(cvalues + *cyan); - *magenta = *(mvalues + *magenta); - *yellow = *(yvalues + *yellow); - last_color = inword; /* save pointer */ + if ( *cyan > 255) *cyan = 255; + if (*magenta > 255) *magenta = 255; + if ( *yellow > 255) *yellow = 255; + + *cyan = *(cvalues + *cyan); + *magenta = *(mvalues + *magenta); + *yellow = *(yvalues + *yellow); + last_color = inword; /* save pointer */ }/* end current_color */ } /* end of if c+m+y > 0 */ *black = *(kvalues + *black); @@ -3321,7 +3323,6 @@ { /* x,y resolution for color planes, assume x=y */ int xres = cdj850->x_pixels_per_inch; - int yres = cdj850->y_pixels_per_inch; float x = pdev->width / pdev->x_pixels_per_inch * 10; float y = pdev->height / pdev->y_pixels_per_inch * 10; @@ -3414,7 +3415,7 @@ if (cprn_device->cmyk) { switch (ccomps) { default: - return gs_error_rangecheck; + return_error(gs_error_rangecheck); /*NOTREACHED */ break; @@ -3513,7 +3514,7 @@ break; } default: - bppe:return gs_error_rangecheck; + bppe:return_error(gs_error_rangecheck); } if (cprn_device->cmyk == -1) { @@ -3545,7 +3546,7 @@ break; } cce: default: - return gs_error_rangecheck; + return_error(gs_error_rangecheck); } if (cprn_device->cmyk) { diff -Nru ghostscript-9.10~dfsg/contrib/gdevdj9.c ghostscript-9.25~dfsg+1/contrib/gdevdj9.c --- ghostscript-9.10~dfsg/contrib/gdevdj9.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevdj9.c 2018-09-13 10:02:01.000000000 +0000 @@ -16,8 +16,13 @@ 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 U.S.A. + along with this program; if not, write to: + + Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor + Boston, MA 02110-1301 + USA +s This program may also be distributed as part of Aladdin Ghostscript, under the terms of the Aladdin Free Public License (the "License"). @@ -103,7 +108,7 @@ #include "math_.h" #include "string.h" -#include /* for rand() */ +#include /* for rand() */ #include #include "gdevprn.h" #include "gdevpcl.h" @@ -113,60 +118,61 @@ #include "gxlum.h" /* this holds the initialisation data of the hp970 */ -typedef struct hp970_cmyk_init_s { +typedef struct hp970_cmyk_init_s +{ byte a[26]; } hp970_cmyk_init_t; -static const hp970_cmyk_init_t hp970_cmyk_init = -{ + +static const hp970_cmyk_init_t hp970_cmyk_init = { { - 0x02, /* format */ - 0x04, /* number of components */ - /* black */ - 0x01, /* MSB x resolution */ - 0x2c, /* LSB x resolution */ - 0x01, /* MSB y resolution */ - 0x2c, /* LSB y resolution */ - 0x00, /* MSB intensity levels */ - 0x02, /* LSB intensity levels */ - - /* cyan */ - 0x01, /* MSB x resolution */ - 0x2c, /* LSB x resolution */ - 0x01, /* MSB y resolution */ - 0x2c, /* LSB y resolution */ - 0x00, /* MSB intensity levels */ - 0x02, /* LSB intensity levels */ - - /* magenta */ - 0x01, /* MSB x resolution */ - 0x2c, /* LSB x resolution */ - 0x01, /* MSB y resolution */ - 0x2c, /* LSB y resolution */ - 0x00, /* MSB intensity levels */ - 0x02, /* LSB intensity levels */ - - /* yellow */ - 0x01, /* MSB x resolution */ - 0x2c, /* LSB x resolution */ - 0x01, /* MSB y resolution */ - 0x2c, /* LSB y resolution */ - 0x00, /* MSB intensity levels */ - 0x02 /* LSB intensity levels */ - } + 0x02, /* format */ + 0x04, /* number of components */ + /* black */ + 0x01, /* MSB x resolution */ + 0x2c, /* LSB x resolution */ + 0x01, /* MSB y resolution */ + 0x2c, /* LSB y resolution */ + 0x00, /* MSB intensity levels */ + 0x02, /* LSB intensity levels */ + + /* cyan */ + 0x01, /* MSB x resolution */ + 0x2c, /* LSB x resolution */ + 0x01, /* MSB y resolution */ + 0x2c, /* LSB y resolution */ + 0x00, /* MSB intensity levels */ + 0x02, /* LSB intensity levels */ + + /* magenta */ + 0x01, /* MSB x resolution */ + 0x2c, /* LSB x resolution */ + 0x01, /* MSB y resolution */ + 0x2c, /* LSB y resolution */ + 0x00, /* MSB intensity levels */ + 0x02, /* LSB intensity levels */ + + /* yellow */ + 0x01, /* MSB x resolution */ + 0x2c, /* LSB x resolution */ + 0x01, /* MSB y resolution */ + 0x2c, /* LSB y resolution */ + 0x00, /* MSB intensity levels */ + 0x02 /* LSB intensity levels */ + } }; /* this holds the color lookuptable data of the hp970 */ -typedef struct { - byte c[256]; /* Lookuptable for cyan */ - byte m[256]; /* dito for magenta */ - byte y[256]; /* dito for yellow */ - byte k[256]; /* dito for black */ - int correct[256]; /* potential undercolor black correction */ +typedef struct +{ + byte c[256]; /* Lookuptable for cyan */ + byte m[256]; /* dito for magenta */ + byte y[256]; /* dito for yellow */ + byte k[256]; /* dito for black */ + int correct[256]; /* potential undercolor black correction */ } Gamma; -static const Gamma gammat970 = -{ - /* Lookup values for cyan */ +static const Gamma gammat970 = { + /* Lookup values for cyan */ {0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 15, 16, 16, 17, 17, @@ -183,7 +189,7 @@ 129, 131, 132, 135, 136, 138, 140, 142, 144, 146, 147, 150, 152, 154, 157, 159, 162, 164, 166, 168, 171, 174, 176, 180, 182, 187, 192, 197, 204, 215, 255}, - /* Lookup values for magenta */ + /* Lookup values for magenta */ {0, 0, 0, 1, 1, 1, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, @@ -200,7 +206,7 @@ 130, 133, 134, 135, 138, 139, 142, 144, 145, 148, 150, 152, 154, 157, 159, 162, 164, 168, 169, 170, 172, 175, 177, 179, 182, 185, 189, 193, 198, 204, 215, 255}, - /* Lookup values for yellow */ + /* Lookup values for yellow */ {0, 0, 0, 2, 2, 2, 3, 3, 3, 5, 5, 5, 7, 7, 6, 7, 7, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 17, 17, 18, 18, @@ -217,7 +223,7 @@ 131, 134, 135, 137, 139, 140, 143, 145, 146, 148, 150, 152, 154, 156, 158, 160, 163, 166, 167, 169, 171, 173, 176, 178, 181, 184, 188, 192, 198, 204, 215, 255}, - /* Lookup values for black */ + /* Lookup values for black */ {0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 2, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, @@ -235,31 +241,28 @@ 166, 169, 174, 177, 182, 187, 194, 203, 215, 255} }; -static const Gamma * const gammat[] = -{ - &gammat970, /* CDJ970Cxi */ +static const Gamma *const gammat[] = { + &gammat970, /* CDJ970Cxi */ }; static int - rescale_byte_wise1x1(int bytecount, const byte * inbytea, - const byte * inbyteb, byte * outbyte); +rescale_byte_wise1x1(int bytecount, const byte * inbytea, + const byte * inbyteb, byte * outbyte); static int - rescale_byte_wise2x1(int bytecount, const byte * inbytea, - const byte * inbyteb, byte * outbyte); +rescale_byte_wise2x1(int bytecount, const byte * inbytea, + const byte * inbyteb, byte * outbyte); static int - rescale_byte_wise1x2(int bytecount, const byte * inbytea, - const byte * inbyteb, byte * outbyte); +rescale_byte_wise1x2(int bytecount, const byte * inbytea, + const byte * inbyteb, byte * outbyte); static int - rescale_byte_wise2x2(int bytecount, const byte * inbytea, - const byte * inbyteb, byte * outbyte); +rescale_byte_wise2x2(int bytecount, const byte * inbytea, + const byte * inbyteb, byte * outbyte); -static int (* const rescale_color_plane[2][2]) (int, const byte *, const byte *, byte *) = { - { - rescale_byte_wise1x1, rescale_byte_wise1x2 - }, +static int (*const rescale_color_plane[2][2]) (int, const byte *, + const byte *, byte *) = { { - rescale_byte_wise2x1, rescale_byte_wise2x2 - } + rescale_byte_wise1x1, rescale_byte_wise1x2}, { + rescale_byte_wise2x1, rescale_byte_wise2x2} }; /* static int (* const rescale_color_plane[2][2]) (int, const byte *, const byte *, byte *) = { @@ -282,10 +285,10 @@ #define DUPLEX_BOTTOM_MARGIN_A4 205 #define DUPLEX_LEFT_MARGIN_A4 120 -#define DUPLEX_BOTTOM_MARGIN_LETTER 205 /* ???? */ -#define DUPLEX_LEFT_MARGIN_LETTER 120 /* ???? */ +#define DUPLEX_BOTTOM_MARGIN_LETTER 205 /* ???? */ +#define DUPLEX_LEFT_MARGIN_LETTER 120 /* ???? */ -#define DESKJET_PRINT_LIMIT 0.04 /* 'real' top margin? */ +#define DESKJET_PRINT_LIMIT 0.04 /* 'real' top margin? */ /* Margins are left, bottom, right, top. */ #define DESKJET_MARGINS_LETTER 0.25, 0.50, 0.25, 0.167 #define DESKJET_MARGINS_A4 0.13, 0.46, 0.13, 0.04 @@ -293,29 +296,33 @@ #ifndef BITSPERPIXEL # define BITSPERPIXEL 32 #endif -#define DOFFSET (dev_t_margin(pdev) - DESKJET_PRINT_LIMIT) /* Print position */ +#define DOFFSET (dev_t_margin(pdev) - DESKJET_PRINT_LIMIT) /* Print position */ #define W sizeof(word) #define I sizeof(int) /* paper types */ -typedef enum { +typedef enum +{ PLAIN_PAPER, BOND_PAPER, SPECIAL_PAPER, GLOSSY_FILM, TRANSPARENCY_FILM } cdj_paper_type_t; /* quality */ -typedef enum { +typedef enum +{ DRAFT = -1, NORMAL = 0, PRESENTATION = 1 } cdj_quality_t; /* duplex mode */ -typedef enum { - NONE, BLOCK, BOOK +typedef enum +{ + NONE, BLOCK, BOOK } cdj_duplex_t; /* Printer types */ -typedef enum { - DJ970C +typedef enum +{ + DJ970C } cdj_printer_type_t; /* No. of ink jets (used to minimise head movements) */ @@ -349,110 +356,114 @@ #define gx_prn_colour_device_common \ gx_prn_device_common; \ - int cmyk; /* 0: not CMYK-capable, > 0: printing CMYK, */ \ + int cmyk; /* 0: not CMYK-capable, > 0: printing CMYK, */ \ /* < 0 : CMYK-capable, not printing CMYK */ \ - uint default_depth; /* Used only for CMYK-capable printers now. */ \ + uint default_depth; /* Used only for CMYK-capable printers now. */ \ uint correction /* some definitions needed later */ -struct error_val_field { - int c; /* Current value of Cyan error during dithering */ - int m; /* Current value of Magenta error during dithering */ - int y; /* Current value of Yellow error during dithering */ - int k; /* Current value of Black error during dithering */ +struct error_val_field +{ + int c; /* Current value of Cyan error during dithering */ + int m; /* Current value of Magenta error during dithering */ + int y; /* Current value of Yellow error during dithering */ + int k; /* Current value of Black error during dithering */ }; /* this structure holds all the pointers to the different values in all those data fields */ /* - * The principal data pointers are stored as pairs of values, with - * the selection being made by the 'scan' variable. The function of the - * scan variable is overloaded, as it controls both the alternating - * raster scan direction used in the Floyd-Steinberg dithering and also - * the buffer alternation required for line-difference compression. - * - * Thus, the number of pointers required is as follows: + * The principal data pointers are stored as pairs of values, with + * the selection being made by the 'scan' variable. The function of the + * scan variable is overloaded, as it controls both the alternating + * raster scan direction used in the Floyd-Steinberg dithering and also + * the buffer alternation required for line-difference compression. + * + * Thus, the number of pointers required is as follows: */ -struct ptr_arrays { - byte *data[4]; /* 4 600dpi data, scan direction and alternating buffers */ - byte *data_c[4]; /* 4 300dpi data, as above, */ - byte *plane_data[4][4]; /*4 b/w-planes, scan direction and alternating buffers */ - byte *plane_data_c[4][8]; /* as above, but for 8 planes */ - byte *out_data; /* output buffer for the b/w data, one 600dpi plane */ - byte *test_data[4]; /* holds a copy of the last plane */ - int *errors[2]; /* 2 b/w dithering erros (scan direction only) */ - int *errors_c[2]; /* 2 color dithering errors (scan direction only) */ - word *storage; /* pointer to the beginning of the b/w-buffer */ - word *storage_start; /* used for debugging */ - word *storage_end; /* used for debugging */ - word *storage_size; /* used for debugging */ +struct ptr_arrays +{ + byte *data[4]; /* 4 600dpi data, scan direction and alternating buffers */ + byte *data_c[4]; /* 4 300dpi data, as above, */ + byte *plane_data[4][4]; /*4 b/w-planes, scan direction and alternating buffers */ + byte *plane_data_c[4][8]; /* as above, but for 8 planes */ + byte *out_data; /* output buffer for the b/w data, one 600dpi plane */ + byte *test_data[4]; /* holds a copy of the last plane */ + int *errors[2]; /* 2 b/w dithering erros (scan direction only) */ + int *errors_c[2]; /* 2 color dithering errors (scan direction only) */ + word *storage; /* pointer to the beginning of the b/w-buffer */ + word *storage_start; /* used for debugging */ + word *storage_end; /* used for debugging */ + word *storage_size; /* used for debugging */ }; /* Some miscellaneous variables */ -struct misc_struct { - int line_size; /* size of scan_line */ - int line_size_c; /* size of rescaled scan_line */ - int line_size_words; /* size of scan_line in words */ - int paper_size; /* size of paper */ - int num_comps; /* number of color components (1 - 4) */ - int bits_per_pixel; /* bits per pixel 1,4,8,16,24,32 */ - int storage_bpp; /* = bits_per_pixel */ - int expanded_bpp; /* = bits_per_pixel */ - int plane_size; /* size of b/w bit plane */ - int plane_size_c; /* size of color bit plane */ - int databuff_size; /* size of databuffer for b/w data */ - int databuff_size_c; /* size of databuffer for color data */ - int errbuff_size; /* size of error buffer b/w -data */ - int errbuff_size_c; /* size of error buffer color -data */ - int outbuff_size; /* size of output buffer for b/w data */ - int scan; /* scan-line variable [0,1] */ - int cscan; /* dito for the color-planes */ - int is_two_pass; /* checks if b/w data has already been printed */ - int zero_row_count; /* How many empty lines */ - uint storage_size_words; /* size of storage in words for b/w data */ - uint storage_size_words_c; /* size of storage in words for c-data */ - int is_color_data; /* indicates whether there is color data */ +struct misc_struct +{ + int line_size; /* size of scan_line */ + int line_size_c; /* size of rescaled scan_line */ + int line_size_words; /* size of scan_line in words */ + int paper_size; /* size of paper */ + int num_comps; /* number of color components (1 - 4) */ + int bits_per_pixel; /* bits per pixel 1,4,8,16,24,32 */ + int storage_bpp; /* = bits_per_pixel */ + int expanded_bpp; /* = bits_per_pixel */ + int plane_size; /* size of b/w bit plane */ + int plane_size_c; /* size of color bit plane */ + int databuff_size; /* size of databuffer for b/w data */ + int databuff_size_c; /* size of databuffer for color data */ + int errbuff_size; /* size of error buffer b/w -data */ + int errbuff_size_c; /* size of error buffer color -data */ + int outbuff_size; /* size of output buffer for b/w data */ + int scan; /* scan-line variable [0,1] */ + int cscan; /* dito for the color-planes */ + int is_two_pass; /* checks if b/w data has already been printed */ + int zero_row_count; /* How many empty lines */ + uint storage_size_words; /* size of storage in words for b/w data */ + uint storage_size_words_c; /* size of storage in words for c-data */ + int is_color_data; /* indicates whether there is color data */ }; /* function pointer typedefs for device driver struct */ typedef void (*StartRasterMode) (gx_device_printer * pdev, int paper_size, FILE * prn_stream); typedef void (*PrintNonBlankLines) (gx_device_printer * pdev, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars, - struct error_val_field *error_values, - const Gamma *gamma, - FILE * prn_stream); + struct ptr_arrays * data_ptrs, + struct misc_struct * misc_vars, + struct error_val_field * error_values, + const Gamma * gamma, FILE * prn_stream); typedef void (*TerminatePage) (gx_device_printer * pdev, FILE * prn_stream); -typedef struct gx_device_cdj970_s { +typedef struct gx_device_cdj970_s +{ gx_device_common; gx_prn_colour_device_common; - int /*cdj_quality_t*/ quality; /* -1 draft, 0 normal, 1 best */ - int /*cdj_paper_type_t*/ papertype; /* papertype [0,4] */ - int /*cdj_duplex_t*/ duplex; - int intensities; /* intensity values per pixel [2,4] */ - int xscal; /* boolean to indicate x scaling by 2 */ - int yscal; /* boolean to indicate y scaling by 2 */ - int /*cdj_printer_type_t*/ ptype; /* printer type, one of DJ670C, DJ970C, DJ890C, DJ1600C */ - int compression; /* compression level */ - float mastergamma; /* Gammavalue applied to all colors */ - float gammavalc; /* range to which gamma-correction is + int /*cdj_quality_t */ quality; /* -1 draft, 0 normal, 1 best */ + int /*cdj_paper_type_t */ papertype; /* papertype [0,4] */ + int /*cdj_duplex_t */ duplex; + int intensities; /* intensity values per pixel [2,4] */ + int xscal; /* boolean to indicate x scaling by 2 */ + int yscal; /* boolean to indicate y scaling by 2 */ + int /*cdj_printer_type_t */ ptype; /* printer type, one of DJ670C, DJ970C, DJ890C, DJ1600C */ + int compression; /* compression level */ + float mastergamma; /* Gammavalue applied to all colors */ + float gammavalc; /* range to which gamma-correction is applied to bw values */ - float gammavalm; /* amount of gamma correction for bw */ - float gammavaly; /* range to which gamma-correction i + float gammavalm; /* amount of gamma correction for bw */ + float gammavaly; /* range to which gamma-correction i applied to color values */ - float gammavalk; /* amount of gamma correction for color */ - float blackcorrect; /* amount of gamma correction for color */ - StartRasterMode start_raster_mode; /* output function to start raster mode */ - PrintNonBlankLines print_non_blank_lines; /* output function to print a non blank line */ - TerminatePage terminate_page; /* page termination output function */ + float gammavalk; /* amount of gamma correction for color */ + float blackcorrect; /* amount of gamma correction for color */ + StartRasterMode start_raster_mode; /* output function to start raster mode */ + PrintNonBlankLines print_non_blank_lines; /* output function to print a non blank line */ + TerminatePage terminate_page; /* page termination output function */ int PageCtr; } gx_device_cdj970; -typedef struct { +typedef struct +{ gx_device_common; gx_prn_colour_device_common; } gx_device_colour_prn; @@ -462,7 +473,7 @@ devices. */ #define cprn_device ((gx_device_colour_prn*) pdev) -#define cdj970 ((gx_device_cdj970 *)pdev) +#define cdj970 ((gx_device_cdj970 *)pdev) #define prn_cmyk_colour_device(dtype, procs, dev_name, x_dpi, y_dpi, bpp, print_page, correct)\ prn_colour_device_body(dtype, procs, dev_name,\ @@ -521,103 +532,108 @@ } static void - cdj970_start_raster_mode(gx_device_printer * pdev, - int papersize, FILE * prn_stream); +cdj970_start_raster_mode(gx_device_printer * pdev, + int papersize, FILE * prn_stream); static void - cdj970_print_non_blank_lines(gx_device_printer * pdev, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars, - struct error_val_field *error_values, - const Gamma *gamma, - FILE * prn_stream); +cdj970_print_non_blank_lines(gx_device_printer * pdev, + struct ptr_arrays *data_ptrs, + struct misc_struct *misc_vars, + struct error_val_field *error_values, + const Gamma * gamma, FILE * prn_stream); static void - cdj970_terminate_page(gx_device_printer * pdev, FILE * prn_stream); +cdj970_terminate_page(gx_device_printer * pdev, FILE * prn_stream); static const gx_device_procs cdj970_procs = cmyk_colour_procs(hp_colour_open, cdj970_get_params, cdj970_put_params, - cdj970_close, NULL, gdev_cmyk_map_color_rgb, gdev_cmyk_map_cmyk_color); + cdj970_close, NULL, gdev_cmyk_map_color_rgb, + gdev_cmyk_map_cmyk_color); const gx_device_cdj970 gs_cdj970_device = - cdj_970_device(cdj970_procs, "cdj970", 600, 600, 32, cdj970_print_page, 0, - NORMAL, PLAIN_PAPER, NONE, 4, DJ970C, 2, - 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, - cdj970_start_raster_mode, cdj970_print_non_blank_lines, - cdj970_terminate_page); +cdj_970_device(cdj970_procs, "cdj970", 600, 600, 32, cdj970_print_page, 0, + NORMAL, PLAIN_PAPER, NONE, 4, DJ970C, 2, + 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, + cdj970_start_raster_mode, cdj970_print_non_blank_lines, + cdj970_terminate_page); /* Forward references */ static int cdj_put_param_int(gs_param_list *, gs_param_name, - int *, int, int, int); + int *, int, int, int); static int cdj_put_param_float(gs_param_list *, gs_param_name, float - *, float, float, int); + *, float, float, int); static int cdj_put_param_bpp(gx_device *, gs_param_list *, int, int, int); static int cdj_set_bpp(gx_device *, int, int); /**********************************************************************************/ /* */ -/* private functions */ +/* private functions */ /* */ /**********************************************************************************/ /* hp_colour_open: Open the printer and set up the margins. ----------------------------------------------------------------------------------*/ -static int hp_colour_open(gx_device * pdev) +static int +hp_colour_open(gx_device * pdev) { - int retCode; + int retCode; - cdj970->PageCtr = 0; + cdj970->PageCtr = 0; - /* Set up colour params if put_params has not already done so */ - if (pdev->color_info.num_components == 0) { - int code = cdj_set_bpp(pdev, pdev->color_info.depth, - pdev->color_info.num_components); + /* Set up colour params if put_params has not already done so */ + if (pdev->color_info.num_components == 0) { + int code = cdj_set_bpp(pdev, pdev->color_info.depth, + pdev->color_info.num_components); - if (code < 0) - return code; - } + if (code < 0) + return code; + } - retCode = gdev_prn_open (pdev); + retCode = gdev_prn_open(pdev); + if (retCode < 0) + return (retCode); + else { + retCode = gdev_prn_open_printer(pdev, true); if (retCode < 0) - return (retCode); - else { - retCode = gdev_prn_open_printer(pdev, true); - if (retCode < 0) - return (retCode); - } + return (retCode); + } - return 0; + return 0; } /* cdj970_get_params: Added parameters for DeskJet 970C ----------------------------------------------------------------------------------*/ -static int cdj970_get_params(gx_device * pdev, gs_param_list * plist) +static int +cdj970_get_params(gx_device * pdev, gs_param_list * plist) { - int code = gdev_prn_get_params(pdev, plist); + int code = gdev_prn_get_params(pdev, plist); - if (code < 0 || - (code = param_write_int(plist, "Quality", &cdj970->quality)) < 0 || - (code = param_write_int(plist, "Duplex", &cdj970->duplex)) < 0 || - (code = param_write_int(plist, "Papertype", &cdj970->papertype)) < 0 || - (code = param_write_float(plist, "MasterGamma", &cdj970->gammavalc)) - < 0 || - (code = param_write_float(plist, "GammaValC", &cdj970->gammavalc)) < - 0 || - (code = param_write_float(plist, "GammaValM", &cdj970->gammavalm)) < - 0 || - (code = param_write_float(plist, "GammaValY", &cdj970->gammavaly)) < - 0 || - (code = param_write_float(plist, "GammaValK", &cdj970->gammavalk)) < - 0 || - (code = param_write_float(plist, "BlackCorrect", - &cdj970->blackcorrect)) < 0) + if (code < 0 || + (code = param_write_int(plist, "Quality", &cdj970->quality)) < 0 || + (code = param_write_int(plist, "Duplex", &cdj970->duplex)) < 0 || + (code = param_write_int(plist, "Papertype", &cdj970->papertype)) < 0 + || (code = + param_write_float(plist, "MasterGamma", &cdj970->gammavalc)) + < 0 + || (code = + param_write_float(plist, "GammaValC", &cdj970->gammavalc)) < 0 + || (code = + param_write_float(plist, "GammaValM", &cdj970->gammavalm)) < 0 + || (code = + param_write_float(plist, "GammaValY", &cdj970->gammavaly)) < 0 + || (code = + param_write_float(plist, "GammaValK", &cdj970->gammavalk)) < 0 + || (code = + param_write_float(plist, "BlackCorrect", + &cdj970->blackcorrect)) < 0) - return (code); return (code); + return (code); } /* cdj970_put_params: ----------------------------------------------------------------------------------*/ -static int cdj970_put_params(gx_device * pdev, gs_param_list * plist) +static int +cdj970_put_params(gx_device * pdev, gs_param_list * plist) { int quality = cdj970->quality; int papertype = cdj970->papertype; @@ -636,21 +652,28 @@ code = cdj_put_param_int(plist, "Quality", &quality, 0, 2, code); code = cdj_put_param_int(plist, "Papertype", &papertype, 0, 4, code); code = cdj_put_param_int(plist, "Duplex", &duplex, 0, 2, code); - code = cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, code); - code = cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code); - code = cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0, 9.0, code); - code = cdj_put_param_float(plist, "GammaValY", &gammavaly, 0.0, 9.0, code); - code = cdj_put_param_float(plist, "GammaValK", &gammavalk, 0.0, 9.0, code); - code = cdj_put_param_float(plist, "BlackCorrect", &blackcorrect, 0.0, - 9.0, code); + code = + cdj_put_param_float(plist, "MasterGamma", &mastergamma, 0.1, 9.0, + code); + code = + cdj_put_param_float(plist, "GammaValC", &gammavalc, 0.0, 9.0, code); + code = + cdj_put_param_float(plist, "GammaValM", &gammavalm, 0.0, 9.0, code); + code = + cdj_put_param_float(plist, "GammaValY", &gammavaly, 0.0, 9.0, code); + code = + cdj_put_param_float(plist, "GammaValK", &gammavalk, 0.0, 9.0, code); + code = + cdj_put_param_float(plist, "BlackCorrect", &blackcorrect, 0.0, 9.0, + code); if (code < 0) - return code; + return code; code = cdj_put_param_bpp(pdev, plist, bpp, bpp, 0); if (code < 0) - return code; + return code; cdj970->quality = quality; cdj970->papertype = papertype; @@ -667,7 +690,7 @@ /**********************************************************************************/ /* */ -/* Internal routines */ +/* Internal routines */ /* */ /**********************************************************************************/ @@ -682,93 +705,89 @@ /* internal functions */ static void - FSDlinebw(int scan, int plane_size, - struct error_val_field *error_values, - byte * kP, - int n, int *ep, byte * dp); +FSDlinebw(int scan, int plane_size, + struct error_val_field *error_values, + byte * kP, int n, int *ep, byte * dp); static void - FSDlinec2(int scan, int plane_size, - struct error_val_field *error_values, - byte * cPa, byte * mPa, byte * yPa, int n, - byte * dp, int *ep); +FSDlinec2(int scan, int plane_size, + struct error_val_field *error_values, + byte * cPa, byte * mPa, byte * yPa, int n, byte * dp, int *ep); static void - FSDlinec3(int scan, int plane_size, - struct error_val_field *error_values, - byte * cPa, byte * mPa, byte * yPa, - byte * cPb, byte * mPb, byte * yPb, - int n, byte * dp, int *ep); +FSDlinec3(int scan, int plane_size, + struct error_val_field *error_values, + byte * cPa, byte * mPa, byte * yPa, + byte * cPb, byte * mPb, byte * yPb, int n, byte * dp, int *ep); static void - FSDlinec4(int scan, int plane_size, - struct error_val_field *error_values, - byte * cPa, byte * mPa, byte * yPa, - byte * cPb, byte * mPb, byte * yPb, - int n, byte * dp, int *ep); +FSDlinec4(int scan, int plane_size, + struct error_val_field *error_values, + byte * cPa, byte * mPa, byte * yPa, + byte * cPb, byte * mPb, byte * yPb, int n, byte * dp, int *ep); static void - init_error_buffer(struct misc_struct *misc_vars, - struct ptr_arrays *data_ptrs); +init_error_buffer(struct misc_struct *misc_vars, + struct ptr_arrays *data_ptrs); static void - do_floyd_steinberg(int scan, int cscan, int plane_size, - int plane_size_c, int n, - struct ptr_arrays *data_ptrs, - gx_device_printer * pdev, - struct error_val_field *error_values); +do_floyd_steinberg(int scan, int cscan, int plane_size, + int plane_size_c, int n, + struct ptr_arrays *data_ptrs, + gx_device_printer * pdev, + struct error_val_field *error_values); static int - do_gcr(int bytecount, byte * inbyte, const byte * kvalues, - const byte * cvalues, const byte * mvalues, - const byte * yvalues, const int *kcorrect); +do_gcr(int bytecount, byte * inbyte, const byte * kvalues, + const byte * cvalues, const byte * mvalues, + const byte * yvalues, const int *kcorrect); static void - send_scan_lines(gx_device_printer * pdev, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars, - struct error_val_field *error_values, - const Gamma *gamma, - FILE * prn_stream); +send_scan_lines(gx_device_printer * pdev, + struct ptr_arrays *data_ptrs, + struct misc_struct *misc_vars, + struct error_val_field *error_values, + const Gamma * gamma, FILE * prn_stream); -static void - do_gamma(float mastergamma, float gammaval, byte * values); +static void do_gamma(float mastergamma, float gammaval, byte * values); -static void - do_black_correction(float kvalue, int *kcorrect); +static void do_black_correction(float kvalue, int *kcorrect); static void - init_data_structure(gx_device_printer * pdev, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars); +init_data_structure(gx_device_printer * pdev, + struct ptr_arrays *data_ptrs, + struct misc_struct *misc_vars); static void - calculate_memory_size(gx_device_printer * pdev, - struct misc_struct *misc_vars); +calculate_memory_size(gx_device_printer * pdev, + struct misc_struct *misc_vars); /* assign_dpi: ----------------------------------------------------------------------------------*/ -static void assign_dpi(int dpi, byte * msb) +static void +assign_dpi(int dpi, byte * msb) { - if (dpi == 600) { - msb[0] = 0x02; - msb[1] = 0x58; - } else { - msb[0] = 0x01; - msb[1] = 0x2c; - } + if (dpi == 600) { + msb[0] = 0x02; + msb[1] = 0x58; + } else { + msb[0] = 0x01; + msb[1] = 0x2c; + } } /* cdj970_terminate_page: ----------------------------------------------------------------------------------*/ -static void cdj970_terminate_page(gx_device_printer * pdev, FILE * prn_stream) +static void +cdj970_terminate_page(gx_device_printer * pdev, FILE * prn_stream) { - fputs("\033*rC\f\033&l-2H", prn_stream); /* End Graphics, Reset */ + fputs("\033*rC\f\033&l-2H", prn_stream); /* End Graphics, Reset */ } /* cdj970_one_time_initialisation: ----------------------------------------------------------------------------------*/ -static void cdj970_one_time_initialisation(gx_device_printer * pdev) +static void +cdj970_one_time_initialisation(gx_device_printer * pdev) { /* Change the margins if necessary. */ static const float dj_a4[4] = { @@ -782,102 +801,107 @@ /* quality setup */ if (cdj970->quality == DRAFT) { - gx_device_set_resolution((gx_device *)pdev, 300.0, 300.0); + gx_device_set_resolution((gx_device *) pdev, 300.0, 300.0); cdj970->xscal = 0; cdj970->yscal = 0; cdj970->intensities = 2; } else if (cdj970->quality == NORMAL) { - gx_device_set_resolution((gx_device *)pdev, 600.0, 600.0); + gx_device_set_resolution((gx_device *) pdev, 600.0, 600.0); cdj970->xscal = 1; cdj970->yscal = 1; /* intensities = 4 from initialization */ - } else { /* quality == PRESENTATION */ - gx_device_set_resolution((gx_device *)pdev, 600.0, 600.0); + } else { /* quality == PRESENTATION */ + gx_device_set_resolution((gx_device *) pdev, 600.0, 600.0); cdj970->xscal = 0; - cdj970->yscal = 0 ; + cdj970->yscal = 0; /* intensities = 4 from initialization */ } - m = (gdev_pcl_paper_size((gx_device *)pdev) == PAPER_SIZE_A4 ? dj_a4 : dj_letter); + m = (gdev_pcl_paper_size((gx_device *) pdev) == + PAPER_SIZE_A4 ? dj_a4 : dj_letter); - gx_device_set_margins((gx_device *)pdev, m, true); + gx_device_set_margins((gx_device *) pdev, m, true); - cdj970_write_header ((gx_device *)pdev, pdev->file); + cdj970_write_header((gx_device *) pdev, pdev->file); } /* cdj970_print_page: Here comes the hp970 output routine ----------------------------------------------------------------------------------*/ -static int cdj970_print_page(gx_device_printer * pdev, FILE * prn_stream) +static int +cdj970_print_page(gx_device_printer * pdev, FILE * prn_stream) { - struct error_val_field error_values; - struct ptr_arrays data_ptrs; - struct misc_struct misc_vars; - - Gamma gamma; - - if (cdj970->PageCtr == 0 && cdj970->ptype == DJ970C) { - cdj970_one_time_initialisation(pdev); - } + struct error_val_field error_values; + struct ptr_arrays data_ptrs; + struct misc_struct misc_vars; - /* make a local writable copy of the Gamma tables */ - memcpy(&gamma, gammat[cdj970->ptype], sizeof(Gamma)); + Gamma gamma; - /* if mastergamma, don't use the built in functions */ - if (cdj970->mastergamma > 1.0) { - /* prepare the bw lookup table */ - do_gamma(cdj970->mastergamma, cdj970->gammavalk, gamma.k); - /* prepare the color lookup table */ - do_gamma(cdj970->mastergamma, cdj970->gammavalc, gamma.c); - do_gamma(cdj970->mastergamma, cdj970->gammavalm, gamma.m); - do_gamma(cdj970->mastergamma, cdj970->gammavaly, gamma.y); - } + if (cdj970->PageCtr == 0 && cdj970->ptype == DJ970C) { + cdj970_one_time_initialisation(pdev); + } - /* prepare the black correction table for the unbunt mask */ - do_black_correction(cdj970->blackcorrect, gamma.correct); + /* make a local writable copy of the Gamma tables */ + memcpy(&gamma, gammat[cdj970->ptype], sizeof(Gamma)); - /* Calculate the needed memory */ - calculate_memory_size(pdev, &misc_vars); + /* if mastergamma, don't use the built in functions */ + if (cdj970->mastergamma > 1.0) { + /* prepare the bw lookup table */ + do_gamma(cdj970->mastergamma, cdj970->gammavalk, gamma.k); + /* prepare the color lookup table */ + do_gamma(cdj970->mastergamma, cdj970->gammavalc, gamma.c); + do_gamma(cdj970->mastergamma, cdj970->gammavalm, gamma.m); + do_gamma(cdj970->mastergamma, cdj970->gammavaly, gamma.y); + } - /* and allocate the memory */ + /* prepare the black correction table for the unbunt mask */ + do_black_correction(cdj970->blackcorrect, gamma.correct); - /* Since we need 600 and 300 dpi, we set up several buffers: - storage contains the data as copied from gs, as well as the - plane-data and the out_row buffer. - storagec will contain the rescaled color data. It also contains the - plane_data for the color-planes - these are needed by the - compression routine, but would be overwritten by the - b/w-dithering. The color planes allow for overwriting the - color-data by the error-data. Since we might use the - 2bpp feature of the hp970 someday, it is sized like storage. - storagee contains the errors from b/w fs-ditherng */ + /* Calculate the needed memory */ + calculate_memory_size(pdev, &misc_vars); - data_ptrs.storage = (ulong *) gs_malloc(pdev->memory->non_gc_memory, misc_vars.storage_size_words, W, - "cdj970_print_page"); + /* and allocate the memory */ - /* if we can't allocate working area */ - if (data_ptrs.storage == 0) { - return_error(gs_error_VMerror); - } + /* Since we need 600 and 300 dpi, we set up several buffers: + storage contains the data as copied from gs, as well as the + plane-data and the out_row buffer. + storagec will contain the rescaled color data. It also contains the + plane_data for the color-planes - these are needed by the + compression routine, but would be overwritten by the + b/w-dithering. The color planes allow for overwriting the + color-data by the error-data. Since we might use the + 2bpp feature of the hp970 someday, it is sized like storage. + storagee contains the errors from b/w fs-ditherng */ + + data_ptrs.storage = + (ulong *) gs_malloc(pdev->memory->non_gc_memory, + misc_vars.storage_size_words, W, + "cdj970_print_page"); + + /* if we can't allocate working area */ + if (data_ptrs.storage == 0) { + return_error(gs_error_VMerror); + } - /* Initialise the needed pointers */ - init_data_structure(pdev, &data_ptrs, &misc_vars); + /* Initialise the needed pointers */ + init_data_structure(pdev, &data_ptrs, &misc_vars); - /* Start Raster mode */ - (*cdj970->start_raster_mode) (pdev, misc_vars.paper_size, prn_stream); + /* Start Raster mode */ + (*cdj970->start_raster_mode) (pdev, misc_vars.paper_size, prn_stream); - /* Send each scan line in turn */ - send_scan_lines(pdev, &data_ptrs, &misc_vars, &error_values, &gamma, prn_stream); + /* Send each scan line in turn */ + send_scan_lines(pdev, &data_ptrs, &misc_vars, &error_values, &gamma, + prn_stream); - /* terminate page and eject paper */ - (*cdj970->terminate_page) (pdev, prn_stream); + /* terminate page and eject paper */ + (*cdj970->terminate_page) (pdev, prn_stream); - /* Free Memory */ - gs_free(pdev->memory->non_gc_memory, (char *)data_ptrs.storage, misc_vars.storage_size_words, W, - "hp970_print_page"); + /* Free Memory */ + gs_free(pdev->memory->non_gc_memory, (char *)data_ptrs.storage, + misc_vars.storage_size_words, W, "hp970_print_page"); - cdj970->PageCtr ++; + cdj970->PageCtr++; - return (0); + return (0); } #define odd(i) ((i & 01) != 0) @@ -885,335 +909,356 @@ /* GetScanLine: ----------------------------------------------------------------------------------*/ -static int GetScanLine( gx_device_printer * pdev, - int *lnum, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars, - word rmask) -{ - word *data_words = (word *) data_ptrs->data[misc_vars->scan]; - register word *end_data = data_words + misc_vars->line_size_words; - unsigned long tempBuffer[BUFFER_SIZE]; - int i = 0; - register word *enddata2; - - if ((cdj970->duplex == BOOK) && (cdj970->PageCtr%2 == 1)) --(*lnum); - else ++(*lnum); - - gdev_prn_copy_scan_lines(pdev, *lnum, (byte *) data_words, misc_vars->line_size); - - if (cdj970->quality == DRAFT) - enddata2 = (unsigned long*)end_data - ((gdev_pcl_paper_size((gx_device*)pdev) == - PAPER_SIZE_A4 ? DUPLEX_LEFT_MARGIN_A4/2 : DUPLEX_LEFT_MARGIN_LETTER/2)); - - else - enddata2 = (unsigned long*)end_data - ((gdev_pcl_paper_size((gx_device*)pdev) == - PAPER_SIZE_A4 ? DUPLEX_LEFT_MARGIN_A4 : DUPLEX_LEFT_MARGIN_LETTER)); - - end_data = enddata2; - - if ((cdj970->duplex == BOOK) && (cdj970->PageCtr%2 == 1)) { - memset (tempBuffer, 0, BUFFER_SIZE*sizeof(unsigned long)); - - while (enddata2 > data_words) { - tempBuffer[i++] = *((unsigned long*)enddata2); - enddata2 --; - } +static int +GetScanLine(gx_device_printer * pdev, + int *lnum, + struct ptr_arrays *data_ptrs, + struct misc_struct *misc_vars, word rmask) +{ + word *data_words = (word *) data_ptrs->data[misc_vars->scan]; + register word *end_data = data_words + misc_vars->line_size_words; + unsigned long tempBuffer[BUFFER_SIZE]; + int i = 0; + register word *enddata2; + + if ((cdj970->duplex == BOOK) && (cdj970->PageCtr % 2 == 1)) + --(*lnum); + else + ++(*lnum); + + gdev_prn_copy_scan_lines(pdev, *lnum, (byte *) data_words, + misc_vars->line_size); + + if (cdj970->quality == DRAFT) + enddata2 = + (unsigned long *)end_data - + ((gdev_pcl_paper_size((gx_device *) pdev) == + PAPER_SIZE_A4 ? DUPLEX_LEFT_MARGIN_A4 / + 2 : DUPLEX_LEFT_MARGIN_LETTER / 2)); + + else + enddata2 = + (unsigned long *)end_data - + ((gdev_pcl_paper_size((gx_device *) pdev) == + PAPER_SIZE_A4 ? DUPLEX_LEFT_MARGIN_A4 : + DUPLEX_LEFT_MARGIN_LETTER)); + + end_data = enddata2; + + if ((cdj970->duplex == BOOK) && (cdj970->PageCtr % 2 == 1)) { + memset(tempBuffer, 0, BUFFER_SIZE * sizeof(unsigned long)); + + while (enddata2 > data_words) { + tempBuffer[i++] = *((unsigned long *)enddata2); + enddata2--; + } - memcpy (data_words, tempBuffer, i*sizeof(unsigned long)); + memcpy(data_words, tempBuffer, i * sizeof(unsigned long)); - } + } - misc_vars->scan = 1 - misc_vars->scan; /* toggle scan direction */ - misc_vars->is_two_pass = odd(*lnum); /* color output for odd lines */ + misc_vars->scan = 1 - misc_vars->scan; /* toggle scan direction */ + misc_vars->is_two_pass = odd(*lnum); /* color output for odd lines */ - /* Mask off 1-bits beyond the line width. */ - end_data[-1] &= rmask; + /* Mask off 1-bits beyond the line width. */ + end_data[-1] &= rmask; - /* Remove trailing 0s. */ - while (end_data > data_words && end_data[-1] == 0) - end_data--; + /* Remove trailing 0s. */ + while (end_data > data_words && end_data[-1] == 0) + end_data--; - return (end_data - data_words); + return (end_data - data_words); } #define PAGE_CTR_OK ( ((cdj970->duplex < BOOK) && (lnum < lend)) || ((cdj970->duplex == BOOK) && (lnum >= 0) && (cdj970->PageCtr%2 == 1)) || ((cdj970->duplex == BOOK) && (cdj970->PageCtr%2 == 0) && (lnum < lend))) /* send_scan_lines: Send the scan lines to the printer ----------------------------------------------------------------------------------*/ -static void send_scan_lines( gx_device_printer *pdev, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars, - struct error_val_field *error_values, - const Gamma *gamma, - FILE *prn_stream) +static void +send_scan_lines(gx_device_printer * pdev, + struct ptr_arrays *data_ptrs, + struct misc_struct *misc_vars, + struct error_val_field *error_values, + const Gamma * gamma, FILE * prn_stream) { - int lnum, lend, llen; - int num_blank_lines = 0; + int lnum, lend, llen; + int num_blank_lines = 0; - word rmask = ~(word) 0 << ((-pdev->width * misc_vars->storage_bpp) & (W * 8 - 1)); + word rmask = + ~(word) 0 << ((-pdev->width * misc_vars->storage_bpp) & (W * 8 - 1)); - lend = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * y_dpi; + lend = pdev->height - (dev_t_margin(pdev) + dev_b_margin(pdev)) * y_dpi; - error_values->c = error_values->m = error_values->y = error_values->k = 0; + error_values->c = error_values->m = error_values->y = error_values->k = 0; - /* init the error buffer */ - init_error_buffer(misc_vars, data_ptrs); + /* init the error buffer */ + init_error_buffer(misc_vars, data_ptrs); - misc_vars->zero_row_count = 0; + misc_vars->zero_row_count = 0; - if ((cdj970->duplex == BOOK) && (cdj970->PageCtr%2==1)) { - lnum = lend; + if ((cdj970->duplex == BOOK) && (cdj970->PageCtr % 2 == 1)) { + lnum = lend; - if (cdj970->quality == DRAFT) - num_blank_lines = (gdev_pcl_paper_size((gx_device*)pdev) == PAPER_SIZE_A4 - ? DUPLEX_BOTTOM_MARGIN_A4/2 : DUPLEX_BOTTOM_MARGIN_LETTER/2); - else - num_blank_lines = (gdev_pcl_paper_size((gx_device*)pdev) == PAPER_SIZE_A4 - ? DUPLEX_BOTTOM_MARGIN_A4 : DUPLEX_BOTTOM_MARGIN_LETTER); - } else lnum = -1; + if (cdj970->quality == DRAFT) + num_blank_lines = + (gdev_pcl_paper_size((gx_device *) pdev) == + PAPER_SIZE_A4 ? DUPLEX_BOTTOM_MARGIN_A4 / + 2 : DUPLEX_BOTTOM_MARGIN_LETTER / 2); + else + num_blank_lines = + (gdev_pcl_paper_size((gx_device *) pdev) == + PAPER_SIZE_A4 ? DUPLEX_BOTTOM_MARGIN_A4 : + DUPLEX_BOTTOM_MARGIN_LETTER); + } else + lnum = -1; - llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask); + llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask); - while ( PAGE_CTR_OK ) { + while (PAGE_CTR_OK) { - while (PAGE_CTR_OK && llen == 0) { - ++num_blank_lines; - llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask); - } + while (PAGE_CTR_OK && llen == 0) { + ++num_blank_lines; + llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask); + } - if (! PAGE_CTR_OK) { - break; - } + if (!PAGE_CTR_OK) { + break; + } - /* Skip blank lines if any */ - if (num_blank_lines > 0) { - fprintf(prn_stream, "%dy", num_blank_lines / (cdj970->yscal + 1)); - memset(data_ptrs->plane_data[0][0], 0, (misc_vars->plane_size * 2 * misc_vars->num_comps)); - memset(data_ptrs->plane_data_c[0][0], 0, (misc_vars->plane_size_c * 2 * misc_vars->num_comps)); - - } - - /* all blank lines printed, now for the non-blank lines */ - if (cdj970->yscal && odd(lnum)) { - /* output a blank black plane for odd lines */ - putc('v', prn_stream); - } - /* now output all non blank lines */ - while (PAGE_CTR_OK && llen != 0) { - misc_vars->is_color_data = 0; /* maybe we have color ? */ - (*cdj970->print_non_blank_lines) (pdev, data_ptrs, misc_vars, - error_values, gamma, prn_stream); - llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask); - } - if (cdj970->yscal && odd(lnum)) { /* output empty line for odd lines */ - (*cdj970->print_non_blank_lines) (pdev, data_ptrs, misc_vars, - error_values, gamma, prn_stream); - } - /* the current line is empty => run the next iteration */ - num_blank_lines = 0; - } + /* Skip blank lines if any */ + if (num_blank_lines > 0) { + fprintf(prn_stream, "%dy", num_blank_lines / (cdj970->yscal + 1)); + memset(data_ptrs->plane_data[0][0], 0, + (misc_vars->plane_size * 2 * misc_vars->num_comps)); + memset(data_ptrs->plane_data_c[0][0], 0, + (misc_vars->plane_size_c * 2 * misc_vars->num_comps)); + + } + + /* all blank lines printed, now for the non-blank lines */ + if (cdj970->yscal && odd(lnum)) { + /* output a blank black plane for odd lines */ + putc('v', prn_stream); + } + /* now output all non blank lines */ + while (PAGE_CTR_OK && llen != 0) { + misc_vars->is_color_data = 0; /* maybe we have color ? */ + (*cdj970->print_non_blank_lines) (pdev, data_ptrs, misc_vars, + error_values, gamma, + prn_stream); + llen = GetScanLine(pdev, &lnum, data_ptrs, misc_vars, rmask); + } + if (cdj970->yscal && odd(lnum)) { /* output empty line for odd lines */ + (*cdj970->print_non_blank_lines) (pdev, data_ptrs, misc_vars, + error_values, gamma, + prn_stream); + } + /* the current line is empty => run the next iteration */ + num_blank_lines = 0; + } } /* print_c2plane: Sprint_line compresses (mode 2) and outputs one plane ----------------------------------------------------------------------------------*/ -static void print_c2plane( FILE *prn_stream, - char plane_code, - int plane_size, - const byte *curr, - const byte *prev, - byte *out_data) -{ - const word *row = (const word *)curr; - const word *end_row = row + plane_size/W; - int out_count; - - out_count = gdev_pcl_mode2compress(row, end_row, out_data); - - /* and output the data */ - if (out_count > 0) { - fprintf(prn_stream, "%d%c", out_count, plane_code); - fwrite(out_data, sizeof(byte), out_count, prn_stream); - } else { - putc(plane_code, prn_stream); - } +static void +print_c2plane(FILE * prn_stream, + char plane_code, + int plane_size, + const byte * curr, const byte * prev, byte * out_data) +{ + const word *row = (const word *)curr; + const word *end_row = row + plane_size / W; + int out_count; + + out_count = gdev_pcl_mode2compress(row, end_row, out_data); + + /* and output the data */ + if (out_count > 0) { + fprintf(prn_stream, "%d%c", out_count, plane_code); + fwrite(out_data, sizeof(byte), out_count, prn_stream); + } else { + putc(plane_code, prn_stream); + } } #define SET_BLACK(n) *cPa=*cPa|n; *mPa=*mPa|n; *yPa=*yPa|n; /* cdj970_print_non_blank_lines: Printing non-blank lines ----------------------------------------------------------------------------------*/ -static void cdj970_print_non_blank_lines( gx_device_printer *pdev, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars, - struct error_val_field *error_values, - const Gamma *gamma, - FILE *prn_stream) -{ - static const char *const plane_code[2] = {"vvvv", "wvvv"}; - - int i; - byte *kP = data_ptrs->plane_data[misc_vars->scan + 2][3]; - byte *dp = data_ptrs->data[misc_vars->scan + 2]; - int *ep = data_ptrs->errors[misc_vars->scan]; - - /* we need cmyk color separation befor all the rest, since - black may be contained in the color fields. This needs to - be done on all pixel-rows, since even unused color-bytes - might generate black */ - - misc_vars->is_color_data = - do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], - gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct); - - /* dithering the black-plane */ - FSDlinebw(misc_vars->scan, misc_vars->plane_size, - error_values, kP, misc_vars->num_comps, ep, dp); - /* output the black plane */ - print_c2plane(prn_stream, 'v', misc_vars->plane_size, - data_ptrs->plane_data[misc_vars->scan][3], - data_ptrs->plane_data[1 - misc_vars->scan][3], - data_ptrs->out_data); - - /* since color resolution is only half of the b/w-resolution, - we only output every second row */ - if (!cdj970->yscal || misc_vars->is_two_pass) { - int plane_size_c = (*rescale_color_plane[cdj970->xscal][cdj970->yscal]) - (misc_vars->databuff_size, - data_ptrs->data[misc_vars->scan], - data_ptrs->data[1 - misc_vars->scan], - data_ptrs->data_c[misc_vars->cscan]) / misc_vars->storage_bpp; - - /* dither the color planes */ - do_floyd_steinberg(misc_vars->scan, misc_vars->cscan, - misc_vars->plane_size, plane_size_c, - misc_vars->num_comps, data_ptrs, pdev, error_values); - - /* the color pointers, lower byte */ - /* Transfer raster graphics in the order C, M, Y, that is planes 2,1,0 */ - for (i = misc_vars->num_comps - 2; i >= 0; i--) { +static void +cdj970_print_non_blank_lines(gx_device_printer * pdev, + struct ptr_arrays *data_ptrs, + struct misc_struct *misc_vars, + struct error_val_field *error_values, + const Gamma * gamma, FILE * prn_stream) +{ + static const char *const plane_code[2] = { "vvvv", "wvvv" }; + + int i; + byte *kP = data_ptrs->plane_data[misc_vars->scan + 2][3]; + byte *dp = data_ptrs->data[misc_vars->scan + 2]; + int *ep = data_ptrs->errors[misc_vars->scan]; + + /* we need cmyk color separation befor all the rest, since + black may be contained in the color fields. This needs to + be done on all pixel-rows, since even unused color-bytes + might generate black */ + + misc_vars->is_color_data = + do_gcr(misc_vars->databuff_size, data_ptrs->data[misc_vars->scan], + gamma->k, gamma->c, gamma->m, gamma->y, gamma->correct); + + /* dithering the black-plane */ + FSDlinebw(misc_vars->scan, misc_vars->plane_size, + error_values, kP, misc_vars->num_comps, ep, dp); + /* output the black plane */ + print_c2plane(prn_stream, 'v', misc_vars->plane_size, + data_ptrs->plane_data[misc_vars->scan][3], + data_ptrs->plane_data[1 - misc_vars->scan][3], + data_ptrs->out_data); + + /* since color resolution is only half of the b/w-resolution, + we only output every second row */ + if (!cdj970->yscal || misc_vars->is_two_pass) { + int plane_size_c = + (*rescale_color_plane[cdj970->xscal][cdj970->yscal]) + (misc_vars->databuff_size, + data_ptrs->data[misc_vars->scan], + data_ptrs->data[1 - misc_vars->scan], + data_ptrs->data_c[misc_vars->cscan]) / misc_vars->storage_bpp; + + /* dither the color planes */ + do_floyd_steinberg(misc_vars->scan, misc_vars->cscan, + misc_vars->plane_size, plane_size_c, + misc_vars->num_comps, data_ptrs, pdev, + error_values); + + /* the color pointers, lower byte */ + /* Transfer raster graphics in the order C, M, Y, that is planes 2,1,0 */ + for (i = misc_vars->num_comps - 2; i >= 0; i--) { - /* output the lower color planes */ - if (cdj970->intensities > 2) { + /* output the lower color planes */ + if (cdj970->intensities > 2) { /* output the upper color planes */ - print_c2plane(prn_stream, plane_code[0][i], plane_size_c, - data_ptrs->plane_data_c[misc_vars->cscan][i + 4], - data_ptrs->plane_data_c[1 - misc_vars->cscan][i + 4], - data_ptrs->out_data); - - } - print_c2plane(prn_stream, plane_code[1][i], - plane_size_c, - data_ptrs->plane_data_c[misc_vars->cscan][i], - data_ptrs->plane_data_c[1 - misc_vars->cscan][i], - data_ptrs->out_data); - - } /* End For i = num_comps */ - - misc_vars->cscan = 1 - misc_vars->cscan; - - } /* End of is_two_pass */ - - return; -} - -/* do_floyd_steinberg: moved that code into his own subroutine, - * otherwise things get somewhat clumsy -----------------------------------------------------------------------------------*/ -static void do_floyd_steinberg( int scan, - int cscan, - int plane_size, - int plane_size_c, - int n, - struct ptr_arrays *data_ptrs, - gx_device_printer *pdev, - struct error_val_field *error_values) -{ - /* the color pointers */ - byte *cPa, *mPa, *yPa, *cPb, *mPb, *yPb; - byte *dpc; - int *epc; - - /* the b/w pointers */ - byte *kP, *dp; - int *ep; + print_c2plane(prn_stream, plane_code[0][i], plane_size_c, + data_ptrs->plane_data_c[misc_vars->cscan][i + + 4], + data_ptrs->plane_data_c[1 - + misc_vars->cscan][i + + 4], + data_ptrs->out_data); - /* the color pointers, lower byte */ - cPa = data_ptrs->plane_data_c[cscan + 2][2]; - mPa = data_ptrs->plane_data_c[cscan + 2][1]; - yPa = data_ptrs->plane_data_c[cscan + 2][0]; - - /* upper byte */ - cPb = data_ptrs->plane_data_c[cscan + 2][6]; - mPb = data_ptrs->plane_data_c[cscan + 2][5]; - yPb = data_ptrs->plane_data_c[cscan + 2][4]; - - /* data and error */ - dpc = data_ptrs->data_c[cscan + 2]; - epc = data_ptrs->errors_c[cscan]; - - /* the b/w pointers */ - kP = data_ptrs->plane_data[scan + 2][3]; - dp = data_ptrs->data[scan + 2]; - ep = data_ptrs->errors[scan]; - - switch (cdj970->intensities) { - case 2: - FSDlinec2(cscan, plane_size_c, error_values, - cPa, mPa, yPa, n, dpc, epc); - break; + } + print_c2plane(prn_stream, plane_code[1][i], + plane_size_c, + data_ptrs->plane_data_c[misc_vars->cscan][i], + data_ptrs->plane_data_c[1 - misc_vars->cscan][i], + data_ptrs->out_data); - case 3: - FSDlinec3(cscan, plane_size_c, error_values, - cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc); - break; + } /* End For i = num_comps */ - case 4: - FSDlinec4(cscan, plane_size_c, error_values, - cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc); - break; + misc_vars->cscan = 1 - misc_vars->cscan; - default: - assert(0); - } + } + /* End of is_two_pass */ + return; +} + +/* do_floyd_steinberg: moved that code into his own subroutine, + * otherwise things get somewhat clumsy +----------------------------------------------------------------------------------*/ +static void +do_floyd_steinberg(int scan, + int cscan, + int plane_size, + int plane_size_c, + int n, + struct ptr_arrays *data_ptrs, + gx_device_printer * pdev, + struct error_val_field *error_values) +{ + /* the color pointers */ + byte *cPa, *mPa, *yPa, *cPb, *mPb, *yPb; + byte *dpc; + int *epc; + + /* the color pointers, lower byte */ + cPa = data_ptrs->plane_data_c[cscan + 2][2]; + mPa = data_ptrs->plane_data_c[cscan + 2][1]; + yPa = data_ptrs->plane_data_c[cscan + 2][0]; + + /* upper byte */ + cPb = data_ptrs->plane_data_c[cscan + 2][6]; + mPb = data_ptrs->plane_data_c[cscan + 2][5]; + yPb = data_ptrs->plane_data_c[cscan + 2][4]; + + /* data and error */ + dpc = data_ptrs->data_c[cscan + 2]; + epc = data_ptrs->errors_c[cscan]; + + switch (cdj970->intensities) { + case 2: + FSDlinec2(cscan, plane_size_c, error_values, + cPa, mPa, yPa, n, dpc, epc); + break; + + case 3: + FSDlinec3(cscan, plane_size_c, error_values, + cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc); + break; + + case 4: + FSDlinec4(cscan, plane_size_c, error_values, + cPa, mPa, yPa, cPb, mPb, yPb, n, dpc, epc); + break; - return; + default: + assert(0); + } + + return; } /* do_gamma: here we do our own gamma-correction ----------------------------------------------------------------------------------*/ -static void do_gamma(float mastergamma, float gammaval, byte values[256]) +static void +do_gamma(float mastergamma, float gammaval, byte values[256]) { - int i; - float gamma; + int i; + float gamma; - if (gammaval > 0.0) { - gamma = gammaval; - } else { - gamma = mastergamma; - } + if (gammaval > 0.0) { + gamma = gammaval; + } else { + gamma = mastergamma; + } - for (i = 0; i < 256; i++) { - values[i] = (byte) (255.0 * (1.0 - pow(((double)(255.0 - (float)i) / 255.0), - (double)(1.0 / gamma)))); - } + for (i = 0; i < 256; i++) { + values[i] = + (byte) (255.0 * + (1.0 - + pow(((double)(255.0 - (float)i) / 255.0), + (double)(1.0 / gamma)))); + } - return; + return; } /* do_black_correction: here we calculate a lookup-table which is used to - * compensate the relativ loss of color due to - * undercolor-removal + * compensate the relativ loss of color due to + * undercolor-removal ----------------------------------------------------------------------------------*/ -static void do_black_correction(float kvalue, int kcorrect[256]) +static void +do_black_correction(float kvalue, int kcorrect[256]) { - int i; + int i; - for (i = 0; i < 256; i++) { - kcorrect[i] = (int)(100.0 * kvalue * (pow(10.0, pow((i / 255.0), 3.0)) - 1.0)); - } + for (i = 0; i < 256; i++) { + kcorrect[i] = + (int)(100.0 * kvalue * (pow(10.0, pow((i / 255.0), 3.0)) - 1.0)); + } - return; + return; } /* DOUCR: For Better Performance we use a macro here @@ -1259,157 +1304,168 @@ } /* do_gcr: Since resolution can be different on different planes, we need to - * do real color separation, here we try a real grey component - * replacement + * do real color separation, here we try a real grey component + * replacement ----------------------------------------------------------------------------------*/ -static int do_gcr( int bytecount, - byte *inbyte, - const byte kvalues[256], - const byte cvalues[256], - const byte mvalues[256], - const byte yvalues[256], - const int kcorrect[256]) -{ - int i, ucr, kadd, is_color = 0; - byte *black, *cyan, *magenta, *yellow; - float uca_fac; - - /* Grey component replacement */ - for (i = 0; i < bytecount; i += 4) { - black = inbyte++; /* Assign to black the current address of inbyte */ - cyan = inbyte++; - magenta = inbyte++; - yellow = inbyte++; +static int +do_gcr(int bytecount, + byte * inbyte, + const byte kvalues[256], + const byte cvalues[256], + const byte mvalues[256], + const byte yvalues[256], const int kcorrect[256]) +{ + int i, ucr, kadd, is_color = 0; + byte *black, *cyan, *magenta, *yellow; + float uca_fac; + + /* Grey component replacement */ + for (i = 0; i < bytecount; i += 4) { + black = inbyte++; /* Assign to black the current address of inbyte */ + cyan = inbyte++; + magenta = inbyte++; + yellow = inbyte++; - if (*magenta + *yellow + *cyan > 0) { /* if any color at all */ + if (*magenta + *yellow + *cyan > 0) { /* if any color at all */ is_color = 1; - if ((*cyan >= *magenta) && (*magenta >= *yellow) && (*yellow > 0)) { /* if any grey component */ - DOGCR(cyan, magenta, yellow, black); - } else if ((*cyan >= *yellow) && (*yellow >= *magenta) && (*magenta > 0)) { - DOGCR(cyan, yellow, magenta, black); - } else if ((*yellow >= *magenta) && (*magenta >= *cyan) && (*cyan > 0)) { - DOGCR(yellow, magenta, cyan, black); - } else if ((*yellow >= *cyan) && (*cyan >= *magenta) && (*magenta > 0)) { - DOGCR(yellow, cyan, magenta, black); - } else if ((*magenta >= *yellow) && (*yellow >= *cyan) && (*cyan > 0)) { - DOGCR(magenta, yellow, cyan, black); - } else if ((*magenta >= *cyan) && (*cyan >= *yellow) && (*yellow > 0)) { - DOGCR(magenta, cyan, yellow, black); - } else { /* do gamma only if no black */ - ; + if ((*cyan >= *magenta) && (*magenta >= *yellow) && (*yellow > 0)) { /* if any grey component */ + DOGCR(cyan, magenta, yellow, black); + } else if ((*cyan >= *yellow) && (*yellow >= *magenta) + && (*magenta > 0)) { + DOGCR(cyan, yellow, magenta, black); + } else if ((*yellow >= *magenta) && (*magenta >= *cyan) + && (*cyan > 0)) { + DOGCR(yellow, magenta, cyan, black); + } else if ((*yellow >= *cyan) && (*cyan >= *magenta) + && (*magenta > 0)) { + DOGCR(yellow, cyan, magenta, black); + } else if ((*magenta >= *yellow) && (*yellow >= *cyan) + && (*cyan > 0)) { + DOGCR(magenta, yellow, cyan, black); + } else if ((*magenta >= *cyan) && (*cyan >= *yellow) + && (*yellow > 0)) { + DOGCR(magenta, cyan, yellow, black); + } else { /* do gamma only if no black */ + ; } *cyan = *(cvalues + *cyan); *magenta = *(mvalues + *magenta); *yellow = *(yvalues + *yellow); - } /* end of if c+m+y > 0 */ - - *black = *(kvalues + *black); - } /* end of for bytecount */ + } + /* end of if c+m+y > 0 */ + *black = *(kvalues + *black); + } /* end of for bytecount */ - return (is_color); + return (is_color); } -/* rescale_byte_wise2x2: Since resolution can be different on different planes, - * we need to rescale the data byte by byte +/* rescale_byte_wise2x2: Since resolution can be different on different planes, + * we need to rescale the data byte by byte ----------------------------------------------------------------------------------*/ -static int rescale_byte_wise2x2( int bytecount, - const byte *inbytea, - const byte *inbyteb, - byte *outbyte) +static int +rescale_byte_wise2x2(int bytecount, + const byte * inbytea, + const byte * inbyteb, byte * outbyte) { - register int i, j; - int max = bytecount / 2; + register int i, j; + int max = bytecount / 2; - for (i = 0; i < max; i += 4) { - j = 2 * i; - /* cyan */ - outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5] + inbyteb[j + 1] + inbyteb[j + 5]) / 4; + for (i = 0; i < max; i += 4) { + j = 2 * i; + /* cyan */ + outbyte[i + 1] = + (inbytea[j + 1] + inbytea[j + 5] + inbyteb[j + 1] + + inbyteb[j + 5]) / 4; - /* magenta */ - outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6] + inbyteb[j + 2] + inbyteb[j + 6]) / 4; + /* magenta */ + outbyte[i + 2] = + (inbytea[j + 2] + inbytea[j + 6] + inbyteb[j + 2] + + inbyteb[j + 6]) / 4; - /* yellow */ - outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7] + inbyteb[j + 3] + inbyteb[j + 7]) / 4; - } + /* yellow */ + outbyte[i + 3] = + (inbytea[j + 3] + inbytea[j + 7] + inbyteb[j + 3] + + inbyteb[j + 7]) / 4; + } - return (max); + return (max); } -/* rescale_byte_wise2x1: Since resolution can be different on different planes, - * we need to rescale the data byte by byte +/* rescale_byte_wise2x1: Since resolution can be different on different planes, + * we need to rescale the data byte by byte ----------------------------------------------------------------------------------*/ -static int rescale_byte_wise2x1( int bytecount, - const byte *inbytea, - const byte *inbyteb, - byte *outbyte) +static int +rescale_byte_wise2x1(int bytecount, + const byte * inbytea, + const byte * inbyteb, byte * outbyte) { - register int i, j; - int max = bytecount / 2; + register int i, j; + int max = bytecount / 2; - for (i = 0; i < max; i += 4) { - j = 2 * i; + for (i = 0; i < max; i += 4) { + j = 2 * i; - /* cyan */ - outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5]) / 2; + /* cyan */ + outbyte[i + 1] = (inbytea[j + 1] + inbytea[j + 5]) / 2; - /* magenta */ - outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6]) / 2; + /* magenta */ + outbyte[i + 2] = (inbytea[j + 2] + inbytea[j + 6]) / 2; - /* yellow */ - outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7]) / 2; - } + /* yellow */ + outbyte[i + 3] = (inbytea[j + 3] + inbytea[j + 7]) / 2; + } - return (max); + return (max); } -/* rescale_byte_wise1x2: Since resolution can be different on different planes, - * we need to rescale the data byte by byte +/* rescale_byte_wise1x2: Since resolution can be different on different planes, + * we need to rescale the data byte by byte ----------------------------------------------------------------------------------*/ -static int rescale_byte_wise1x2( int bytecount, - const byte *inbytea, - const byte *inbyteb, - byte *outbyte) +static int +rescale_byte_wise1x2(int bytecount, + const byte * inbytea, + const byte * inbyteb, byte * outbyte) { - register int i; + register int i; - for (i = 0; i < bytecount; i += 4) { - /* cyan */ - outbyte[i + 1] = (inbytea[i + 1] + inbyteb[i + 1]) / 2; + for (i = 0; i < bytecount; i += 4) { + /* cyan */ + outbyte[i + 1] = (inbytea[i + 1] + inbyteb[i + 1]) / 2; - /* magenta */ - outbyte[i + 2] = (inbytea[i + 2] + inbyteb[i + 2]) / 2; + /* magenta */ + outbyte[i + 2] = (inbytea[i + 2] + inbyteb[i + 2]) / 2; - /* yellow */ - outbyte[i + 3] = (inbytea[i + 3] + inbyteb[i + 3]) / 2; - } + /* yellow */ + outbyte[i + 3] = (inbytea[i + 3] + inbyteb[i + 3]) / 2; + } - return bytecount; + return bytecount; } -/* rescale_byte_wise1x1: Since resolution can be different on different planes, - * we need to rescale the data byte by byte +/* rescale_byte_wise1x1: Since resolution can be different on different planes, + * we need to rescale the data byte by byte ----------------------------------------------------------------------------------*/ -static int rescale_byte_wise1x1( int bytecount, - const byte *inbytea, - const byte *inbyteb, - byte *outbyte) +static int +rescale_byte_wise1x1(int bytecount, + const byte * inbytea, + const byte * inbyteb, byte * outbyte) { - register int i; + register int i; - for (i = 0; i < bytecount; i += 4) { - /* cyan */ - outbyte[i + 1] = inbytea[i + 1]; + for (i = 0; i < bytecount; i += 4) { + /* cyan */ + outbyte[i + 1] = inbytea[i + 1]; - /* magenta */ - outbyte[i + 2] = inbytea[i + 2]; + /* magenta */ + outbyte[i + 2] = inbytea[i + 2]; - /* yellow */ - outbyte[i + 3] = inbytea[i + 3]; - } + /* yellow */ + outbyte[i + 3] = inbytea[i + 3]; + } - return (bytecount); + return (bytecount); } /* MACROS FOR DITHERING (we use macros for compact source and faster code) */ @@ -1444,31 +1500,31 @@ /* --------------------------- */ -/* init_error_buffer: initialise the error_buffer +/* init_error_buffer: initialise the error_buffer ----------------------------------------------------------------------------------*/ -static void init_error_buffer( struct misc_struct *misc_vars, - struct ptr_arrays *data_ptrs) +static void +init_error_buffer(struct misc_struct *misc_vars, struct ptr_arrays *data_ptrs) { - int i; - int *ep; - int *epc; - - ep = data_ptrs->errors[0]; - epc = data_ptrs->errors_c[0]; - - if (misc_vars->bits_per_pixel > 4) { /* Randomly seed initial error buffer */ - /* Otherwise, the first dithered rows would look rather uniform */ - for (i = 0; i < misc_vars->databuff_size; i++) { /* 600dpi planes */ + int i; + int *ep; + int *epc; + + ep = data_ptrs->errors[0]; + epc = data_ptrs->errors_c[0]; + + if (misc_vars->bits_per_pixel > 4) { /* Randomly seed initial error buffer */ + /* Otherwise, the first dithered rows would look rather uniform */ + for (i = 0; i < misc_vars->databuff_size; i++) { /* 600dpi planes */ *ep++ = RANDOM; - } + } - /* Now for the 2 * 300dpi color planes */ - for (i = 0; i < misc_vars->databuff_size_c; i++) { + /* Now for the 2 * 300dpi color planes */ + for (i = 0; i < misc_vars->databuff_size_c; i++) { *epc++ = RANDOM; - } } + } - return; + return; } /* FSdither: @@ -1489,115 +1545,109 @@ /* FSDlinebw: The hp970 has 600dpi black and 300 dpi color. ----------------------------------------------------------------------------------*/ -static void FSDlinebw( int scan, - int plane_size, - struct error_val_field *error_values, - byte *kP, - int n, - int *ep, - byte *dp) -{ - if (scan == 0) { /* going_up */ - byte k, bitmask; /* k = outbyte byte, whereas bitmask defines the - bit to be set within k */ - int oldErr, i; +static void +FSDlinebw(int scan, + int plane_size, + struct error_val_field *error_values, + byte * kP, int n, int *ep, byte * dp) +{ + if (scan == 0) { /* going_up */ + byte k, bitmask; /* k = outbyte byte, whereas bitmask defines the + bit to be set within k */ + int oldErr, i; - for (i = 0; i < plane_size; i++) { - bitmask = 0x80; + for (i = 0; i < plane_size; i++) { + bitmask = 0x80; for (k = 0; bitmask != 0; bitmask >>= 1) { - /* dp points to the first word of the input data which is in kcmy-format */ - /* k points to the beginning of the first outbut byte, which - is filled up, bit by bit while looping over bytemask */ - /* ep points to the first word of the error-plane which - contains the errors kcmy format */ - /* err_values->k tempararily holds the error-value */ - /* bitmask selects the bit to be set in the outbyte */ - /* n gives the offset for the byte selection within - words. With simple cmyk-printing, this should be 4 */ - /* 0 points to the active color within the input-word, i.e. 0 - = black, 1 = cyan, 2 = yellow, 3 = magenta */ - - FSdither(dp, k, ep, error_values->k, bitmask, -n, 0); - dp += n, ep += n; /* increment the input and error pointer one - word (=4 byte) further, in order to - convert the next word into an bit */ - } - *kP++ = k; /* fill the output-plane byte with the computet byte - and increment the output plane pointer one byte */ - } - } else { /* going_down */ - byte k, bitmask; - int oldErr, i; + /* dp points to the first word of the input data which is in kcmy-format */ + /* k points to the beginning of the first outbut byte, which + is filled up, bit by bit while looping over bytemask */ + /* ep points to the first word of the error-plane which + contains the errors kcmy format */ + /* err_values->k tempararily holds the error-value */ + /* bitmask selects the bit to be set in the outbyte */ + /* n gives the offset for the byte selection within + words. With simple cmyk-printing, this should be 4 */ + /* 0 points to the active color within the input-word, i.e. 0 + = black, 1 = cyan, 2 = yellow, 3 = magenta */ + + FSdither(dp, k, ep, error_values->k, bitmask, -n, 0); + dp += n, ep += n; /* increment the input and error pointer one + word (=4 byte) further, in order to + convert the next word into an bit */ + } + *kP++ = k; /* fill the output-plane byte with the computet byte + and increment the output plane pointer one byte */ + } + } else { /* going_down */ + byte k, bitmask; + int oldErr, i; - for (i = 0; i < plane_size; i++) { + for (i = 0; i < plane_size; i++) { bitmask = 0x01; - for (k = 0; bitmask != 0; bitmask <<= 1) { - dp -= n, ep -= n; - FSdither(dp, k, ep, error_values->k, bitmask, n, 0); - } - *--kP = k; - } + for (k = 0; bitmask != 0; bitmask <<= 1) { + dp -= n, ep -= n; + FSdither(dp, k, ep, error_values->k, bitmask, n, 0); + } + *--kP = k; } + } - return; + return; } /* FSDlinec2: Since bw has already been dithered for the hp970c, we need - * an adapted dither algorythm + * an adapted dither algorythm ----------------------------------------------------------------------------------*/ -static void FSDlinec2( int scan, - int plane_size, - struct error_val_field *error_values, - byte *cPa, - byte *mPa, - byte *yPa, - int n, - byte *dp, - int *ep) -{ - if (scan == 0) { /* going_up */ - int oldErr, i; - byte ca, ya, ma, bitmask; +static void +FSDlinec2(int scan, + int plane_size, + struct error_val_field *error_values, + byte * cPa, byte * mPa, byte * yPa, int n, byte * dp, int *ep) +{ + if (scan == 0) { /* going_up */ + int oldErr, i; + byte ca, ya, ma, bitmask; - for (i = 0; i < plane_size; i++) { + for (i = 0; i < plane_size; i++) { bitmask = 0x80; ca = ya = ma = 0; - for (ca = 0; bitmask != 0; bitmask >>= 1) { - FSdither(dp, ca, ep, error_values->c, bitmask, -n, n - 3); - FSdither(dp, ma, ep, error_values->m, bitmask, -n, n - 2); - FSdither(dp, ya, ep, error_values->y, bitmask, -n, n - 1); - dp += n, ep += n; + for (ca = 0; bitmask != 0; bitmask >>= 1) { + FSdither(dp, ca, ep, error_values->c, bitmask, -n, n - 3); + FSdither(dp, ma, ep, error_values->m, bitmask, -n, n - 2); + FSdither(dp, ya, ep, error_values->y, bitmask, -n, n - 1); + dp += n, ep += n; } *cPa++ = ca; *mPa++ = ma; *yPa++ = ya; - } - } else { /* going_down */ - byte ca, ya, ma, bitmask; - int oldErr, i; + } + } else { /* going_down */ + byte ca, ya, ma, bitmask; + int oldErr, i; - for (i = 0; i < plane_size; i++) { + for (i = 0; i < plane_size; i++) { bitmask = 0x01; ca = ya = ma = 0; for (ca = 0; bitmask != 0; bitmask <<= 1) { - dp -= n, ep -= n; - FSdither(dp, ya, ep, error_values->y, bitmask, n, n - 1); - FSdither(dp, ma, ep, error_values->m, bitmask, n, n - 2); - FSdither(dp, ca, ep, error_values->c, bitmask, n, n - 3); + dp -= n, ep -= n; + FSdither(dp, ya, ep, error_values->y, bitmask, n, n - 1); + FSdither(dp, ma, ep, error_values->m, bitmask, n, n - 2); + FSdither(dp, ca, ep, error_values->c, bitmask, n, n - 3); } *--yPa = ya; *--mPa = ma; *--cPa = ca; - } } + } - return; + return; } /* FSdither9703: while printing on paper, we only use 3 -intensities @@ -1622,32 +1672,31 @@ /* FSDlinec3: On ordinary paper, we'll only use 3 intensities with the hp970 ----------------------------------------------------------------------------------*/ -static void FSDlinec3( int scan, - int plane_size, - struct error_val_field *error_values, - byte *cPa, - byte *mPa, - byte *yPa, - byte *cPb, - byte *mPb, - byte *yPb, - int n, - byte *dp, - int *ep) -{ - if (scan == 0) { /* going_up */ - byte ca, ya, ma, cb, yb, mb, bitmask; - int oldErr, i; +static void +FSDlinec3(int scan, + int plane_size, + struct error_val_field *error_values, + byte * cPa, + byte * mPa, + byte * yPa, + byte * cPb, byte * mPb, byte * yPb, int n, byte * dp, int *ep) +{ + if (scan == 0) { /* going_up */ + byte ca, ya, ma, cb, yb, mb, bitmask; + int oldErr, i; - for (i = 0; i < plane_size; i++) { + for (i = 0; i < plane_size; i++) { bitmask = 0x80; ca = ya = ma = cb = yb = mb = 0; for (ca = 0; bitmask != 0; bitmask >>= 1) { - FSdither9703(dp, ca, cb, ep, error_values->c, bitmask, -n, n - 3); - FSdither9703(dp, ma, mb, ep, error_values->m, bitmask, -n, n - 2); - FSdither9703(dp, ya, yb, ep, error_values->y, bitmask, -n, n - 1); - dp += n, ep += n; + FSdither9703(dp, ca, cb, ep, error_values->c, bitmask, -n, + n - 3); + FSdither9703(dp, ma, mb, ep, error_values->m, bitmask, -n, + n - 2); + FSdither9703(dp, ya, yb, ep, error_values->y, bitmask, -n, + n - 1); + dp += n, ep += n; } *cPa++ = ca; @@ -1656,20 +1705,23 @@ *cPb++ = cb; *mPb++ = mb; *yPb++ = yb; - } - } else { /* going_down */ - byte ca, ya, ma, cb, yb, mb, bitmask; - int oldErr, i; + } + } else { /* going_down */ + byte ca, ya, ma, cb, yb, mb, bitmask; + int oldErr, i; - for (i = 0; i < plane_size; i++) { + for (i = 0; i < plane_size; i++) { bitmask = 0x01; ca = ya = ma = cb = yb = mb = 0; for (ca = 0; bitmask != 0; bitmask <<= 1) { - dp -= n, ep -= n; - FSdither9703(dp, ya, yb, ep, error_values->y, bitmask, n, n - 1); - FSdither9703(dp, ma, mb, ep, error_values->m, bitmask, n, n - 2); - FSdither9703(dp, ca, cb, ep, error_values->c, bitmask, n, n - 3); + dp -= n, ep -= n; + FSdither9703(dp, ya, yb, ep, error_values->y, bitmask, n, + n - 1); + FSdither9703(dp, ma, mb, ep, error_values->m, bitmask, n, + n - 2); + FSdither9703(dp, ca, cb, ep, error_values->c, bitmask, n, + n - 3); } *--yPa = ya; @@ -1678,10 +1730,10 @@ *--yPb = yb; *--mPb = mb; *--cPb = cb; - } } + } - return; + return; } /* FSdither9704: the hp970 knows about 4 different color intensities per color @@ -1710,34 +1762,33 @@ } /* FSDlinec4: The hp970c knows about 4 intensity levels per color. Once more, - * we need an adapted dither algorythm + * we need an adapted dither algorythm ----------------------------------------------------------------------------------*/ -static void FSDlinec4( int scan, - int plane_size, - struct error_val_field *error_values, - byte *cPa, - byte *mPa, - byte *yPa, - byte *cPb, - byte *mPb, - byte *yPb, - int n, - byte *dp, - int *ep) -{ - if (scan == 0) { /* going_up */ - byte ca, ya, ma, cb, yb, mb, bitmask; - int oldErr, i; +static void +FSDlinec4(int scan, + int plane_size, + struct error_val_field *error_values, + byte * cPa, + byte * mPa, + byte * yPa, + byte * cPb, byte * mPb, byte * yPb, int n, byte * dp, int *ep) +{ + if (scan == 0) { /* going_up */ + byte ca, ya, ma, cb, yb, mb, bitmask; + int oldErr, i; - for (i = 0; i < plane_size; i++) { + for (i = 0; i < plane_size; i++) { bitmask = 0x80; ca = ya = ma = cb = yb = mb = 0; for (ca = 0; bitmask != 0; bitmask >>= 1) { - FSdither9704(dp, ca, cb, ep, error_values->c, bitmask, -n, n - 3); - FSdither9704(dp, ma, mb, ep, error_values->m, bitmask, -n, n - 2); - FSdither9704(dp, ya, yb, ep, error_values->y, bitmask, -n, n - 1); - dp += n, ep += n; + FSdither9704(dp, ca, cb, ep, error_values->c, bitmask, -n, + n - 3); + FSdither9704(dp, ma, mb, ep, error_values->m, bitmask, -n, + n - 2); + FSdither9704(dp, ya, yb, ep, error_values->y, bitmask, -n, + n - 1); + dp += n, ep += n; } @@ -1747,20 +1798,23 @@ *cPb++ = cb; *mPb++ = mb; *yPb++ = yb; - } - } else { /* going_down */ - byte ca, ya, ma, cb, yb, mb, bitmask; - int oldErr, i; + } + } else { /* going_down */ + byte ca, ya, ma, cb, yb, mb, bitmask; + int oldErr, i; - for (i = 0; i < plane_size; i++) { + for (i = 0; i < plane_size; i++) { bitmask = 0x01; ca = ya = ma = cb = yb = mb = 0; for (ca = 0; bitmask != 0; bitmask <<= 1) { - dp -= n, ep -= n; - FSdither9704(dp, ya, yb, ep, error_values->y, bitmask, n, n - 1); - FSdither9704(dp, ma, mb, ep, error_values->m, bitmask, n, n - 2); - FSdither9704(dp, ca, cb, ep, error_values->c, bitmask, n, n - 3); + dp -= n, ep -= n; + FSdither9704(dp, ya, yb, ep, error_values->y, bitmask, n, + n - 1); + FSdither9704(dp, ma, mb, ep, error_values->m, bitmask, n, + n - 2); + FSdither9704(dp, ca, cb, ep, error_values->c, bitmask, n, + n - 3); } *--yPa = ya; *--mPa = ma; @@ -1768,466 +1822,467 @@ *--yPb = yb; *--mPb = mb; *--cPb = cb; - } } + } - return; + return; } /* calculate_memory_size: calculate the needed memory ----------------------------------------------------------------------------------*/ -static void calculate_memory_size( gx_device_printer *pdev, - struct misc_struct *misc_vars) +static void +calculate_memory_size(gx_device_printer * pdev, struct misc_struct *misc_vars) { - int xfac = cdj970->xscal ? 2 : 1; + int xfac = cdj970->xscal ? 2 : 1; - misc_vars->line_size = gdev_prn_raster(pdev); - misc_vars->line_size_c = misc_vars->line_size / xfac; - misc_vars->line_size_words = (misc_vars->line_size + W - 1) / W; - misc_vars->paper_size = gdev_pcl_paper_size((gx_device *) pdev); - misc_vars->num_comps = pdev->color_info.num_components; - misc_vars->bits_per_pixel = pdev->color_info.depth; - misc_vars->storage_bpp = misc_vars->num_comps * 8; - misc_vars->expanded_bpp = misc_vars->num_comps * 8; - misc_vars->errbuff_size = 0; - misc_vars->errbuff_size_c = 0; - - misc_vars->plane_size = calc_buffsize(misc_vars->line_size, misc_vars->storage_bpp); - - /* plane_size_c is dependedend on the bits used for - dithering. Currently 2 bits are sufficient */ - misc_vars->plane_size_c = 2 * misc_vars->plane_size / xfac; - - /* 4n extra values for line ends */ - /* might be wrong, see gdevcdj.c */ - misc_vars->errbuff_size = - calc_buffsize((misc_vars->plane_size * misc_vars->expanded_bpp + - misc_vars->num_comps * 4) * I, 1); - - /* 4n extra values for line ends */ - misc_vars->errbuff_size_c = - calc_buffsize((misc_vars->plane_size_c / 2 * misc_vars->expanded_bpp - + misc_vars->num_comps * 4) * I, 1); - - misc_vars->databuff_size = - misc_vars->plane_size * misc_vars->storage_bpp; - - misc_vars->databuff_size_c = - misc_vars->plane_size_c / 2 * misc_vars->storage_bpp; - - misc_vars->outbuff_size = misc_vars->plane_size * 4; - - misc_vars->storage_size_words = (((misc_vars->plane_size) * 2 - * misc_vars->num_comps) - + misc_vars->databuff_size - + misc_vars->errbuff_size - + misc_vars->outbuff_size - + ((misc_vars->plane_size_c) - * 2 - * misc_vars->num_comps) - + misc_vars->databuff_size_c - + misc_vars->errbuff_size_c - + (4 * misc_vars->plane_size_c)) - / W; + misc_vars->line_size = gdev_prn_raster(pdev); + misc_vars->line_size_c = misc_vars->line_size / xfac; + misc_vars->line_size_words = (misc_vars->line_size + W - 1) / W; + misc_vars->paper_size = gdev_pcl_paper_size((gx_device *) pdev); + misc_vars->num_comps = pdev->color_info.num_components; + misc_vars->bits_per_pixel = pdev->color_info.depth; + misc_vars->storage_bpp = misc_vars->num_comps * 8; + misc_vars->expanded_bpp = misc_vars->num_comps * 8; + misc_vars->errbuff_size = 0; + misc_vars->errbuff_size_c = 0; + + misc_vars->plane_size = + calc_buffsize(misc_vars->line_size, misc_vars->storage_bpp); + + /* plane_size_c is dependedend on the bits used for + dithering. Currently 2 bits are sufficient */ + misc_vars->plane_size_c = 2 * misc_vars->plane_size / xfac; + + /* 4n extra values for line ends */ + /* might be wrong, see gdevcdj.c */ + misc_vars->errbuff_size = + calc_buffsize((misc_vars->plane_size * misc_vars->expanded_bpp + + misc_vars->num_comps * 4) * I, 1); + + /* 4n extra values for line ends */ + misc_vars->errbuff_size_c = + calc_buffsize((misc_vars->plane_size_c / 2 * misc_vars->expanded_bpp + + misc_vars->num_comps * 4) * I, 1); + + misc_vars->databuff_size = misc_vars->plane_size * misc_vars->storage_bpp; + + misc_vars->databuff_size_c = + misc_vars->plane_size_c / 2 * misc_vars->storage_bpp; + + misc_vars->outbuff_size = misc_vars->plane_size * 4; + + misc_vars->storage_size_words = (((misc_vars->plane_size) * 2 + * misc_vars->num_comps) + + misc_vars->databuff_size + + misc_vars->errbuff_size + + misc_vars->outbuff_size + + ((misc_vars->plane_size_c) + * 2 * misc_vars->num_comps) + + misc_vars->databuff_size_c + + misc_vars->errbuff_size_c + + (4 * misc_vars->plane_size_c)) + / W; - return; + return; } /* init_data_structure: Initialise the needed pointers ----------------------------------------------------------------------------------*/ -static void init_data_structure( gx_device_printer *pdev, - struct ptr_arrays *data_ptrs, - struct misc_struct *misc_vars) -{ - int i; - byte *p = (byte *) data_ptrs->storage; - - misc_vars->scan = 0; - misc_vars->cscan = 0; - misc_vars->is_two_pass = 1; - - /* the b/w pointer */ - data_ptrs->data[0] = data_ptrs->data[1] = data_ptrs->data[2] = p; - data_ptrs->data[3] = p + misc_vars->databuff_size; - /* Note: The output data will overwrite part of the input-data */ - - if (misc_vars->bits_per_pixel > 1) { - p += misc_vars->databuff_size; - } +static void +init_data_structure(gx_device_printer * pdev, + struct ptr_arrays *data_ptrs, + struct misc_struct *misc_vars) +{ + int i; + byte *p = (byte *) data_ptrs->storage; + + misc_vars->scan = 0; + misc_vars->cscan = 0; + misc_vars->is_two_pass = 1; + + /* the b/w pointer */ + data_ptrs->data[0] = data_ptrs->data[1] = data_ptrs->data[2] = p; + data_ptrs->data[3] = p + misc_vars->databuff_size; + /* Note: The output data will overwrite part of the input-data */ - if (misc_vars->bits_per_pixel > 4) { - data_ptrs->errors[0] = (int *)p + misc_vars->num_comps * 2; - data_ptrs->errors[1] = data_ptrs->errors[0] + misc_vars->databuff_size; - p += misc_vars->errbuff_size; - } + if (misc_vars->bits_per_pixel > 1) { + p += misc_vars->databuff_size; + } - for (i = 0; i < misc_vars->num_comps; i++) { - data_ptrs->plane_data[0][i] = data_ptrs->plane_data[2][i] = p; - p += misc_vars->plane_size; - } + if (misc_vars->bits_per_pixel > 4) { + data_ptrs->errors[0] = (int *)p + misc_vars->num_comps * 2; + data_ptrs->errors[1] = + data_ptrs->errors[0] + misc_vars->databuff_size; + p += misc_vars->errbuff_size; + } - for (i = 0; i < misc_vars->num_comps; i++) { - data_ptrs->plane_data[1][i] = p; - data_ptrs->plane_data[3][i] = p + misc_vars->plane_size; - p += misc_vars->plane_size; - } + for (i = 0; i < misc_vars->num_comps; i++) { + data_ptrs->plane_data[0][i] = data_ptrs->plane_data[2][i] = p; + p += misc_vars->plane_size; + } - data_ptrs->out_data = p; - p += misc_vars->outbuff_size; + for (i = 0; i < misc_vars->num_comps; i++) { + data_ptrs->plane_data[1][i] = p; + data_ptrs->plane_data[3][i] = p + misc_vars->plane_size; + p += misc_vars->plane_size; + } - /* --------------------------------------------------------- - now for the color pointers - --------------------------------------------------------- */ + data_ptrs->out_data = p; + p += misc_vars->outbuff_size; - data_ptrs->data_c[0] = data_ptrs->data_c[1] = data_ptrs->data_c[2] = p; - data_ptrs->data_c[3] = p + misc_vars->databuff_size_c; - /* Note: The output data will overwrite part of the input-data */ + /* --------------------------------------------------------- + now for the color pointers + --------------------------------------------------------- */ + + data_ptrs->data_c[0] = data_ptrs->data_c[1] = data_ptrs->data_c[2] = p; + data_ptrs->data_c[3] = p + misc_vars->databuff_size_c; + /* Note: The output data will overwrite part of the input-data */ - if (misc_vars->bits_per_pixel > 1) { - p += misc_vars->databuff_size_c; - } + if (misc_vars->bits_per_pixel > 1) { + p += misc_vars->databuff_size_c; + } - if (misc_vars->bits_per_pixel > 4) { - data_ptrs->errors_c[0] = (int *)p + misc_vars->num_comps * 2; - data_ptrs->errors_c[1] = data_ptrs->errors_c[0] + misc_vars->databuff_size_c; - p += misc_vars->errbuff_size_c; - } + if (misc_vars->bits_per_pixel > 4) { + data_ptrs->errors_c[0] = (int *)p + misc_vars->num_comps * 2; + data_ptrs->errors_c[1] = + data_ptrs->errors_c[0] + misc_vars->databuff_size_c; + p += misc_vars->errbuff_size_c; + } - /* pointer for the lower bits of the output data */ - for (i = 0; i < misc_vars->num_comps; i++) { - data_ptrs->plane_data_c[0][i] = data_ptrs->plane_data_c[2][i] = p; - p += misc_vars->plane_size_c / 2; - } + /* pointer for the lower bits of the output data */ + for (i = 0; i < misc_vars->num_comps; i++) { + data_ptrs->plane_data_c[0][i] = data_ptrs->plane_data_c[2][i] = p; + p += misc_vars->plane_size_c / 2; + } - for (i = 0; i < misc_vars->num_comps; i++) { - data_ptrs->plane_data_c[1][i] = p; - data_ptrs->plane_data_c[3][i] = p + misc_vars->plane_size_c / 2; - p += misc_vars->plane_size_c / 2; - } + for (i = 0; i < misc_vars->num_comps; i++) { + data_ptrs->plane_data_c[1][i] = p; + data_ptrs->plane_data_c[3][i] = p + misc_vars->plane_size_c / 2; + p += misc_vars->plane_size_c / 2; + } - /* pointer for the upper bits of the output data */ - for (i = 0; i < misc_vars->num_comps; i++) { - data_ptrs->plane_data_c[0][i + 4] = data_ptrs->plane_data_c[2][i + 4] = p; - p += misc_vars->plane_size_c / 2; - } + /* pointer for the upper bits of the output data */ + for (i = 0; i < misc_vars->num_comps; i++) { + data_ptrs->plane_data_c[0][i + 4] = + data_ptrs->plane_data_c[2][i + 4] = p; + p += misc_vars->plane_size_c / 2; + } - for (i = 0; i < misc_vars->num_comps; i++) { - data_ptrs->plane_data_c[1][i + 4] = p; - data_ptrs->plane_data_c[3][i + 4] = p + misc_vars->plane_size_c / 2; - p += misc_vars->plane_size_c / 2; - } + for (i = 0; i < misc_vars->num_comps; i++) { + data_ptrs->plane_data_c[1][i + 4] = p; + data_ptrs->plane_data_c[3][i + 4] = p + misc_vars->plane_size_c / 2; + p += misc_vars->plane_size_c / 2; + } - for (i = 0; i < misc_vars->num_comps; i++) { - data_ptrs->test_data[i] = p; - p += misc_vars->plane_size_c / 2; - } + for (i = 0; i < misc_vars->num_comps; i++) { + data_ptrs->test_data[i] = p; + p += misc_vars->plane_size_c / 2; + } - /* Clear temp storage */ - memset(data_ptrs->storage, 0, misc_vars->storage_size_words * W); + /* Clear temp storage */ + memset(data_ptrs->storage, 0, misc_vars->storage_size_words * W); - return; + return; } /* cdj970_start_raster_mode: Configure the printer and start Raster mode ----------------------------------------------------------------------------------*/ -static void cdj970_start_raster_mode( gx_device_printer *pdev, - int paper_size, - FILE *prn_stream) -{ - int xres, yres; /* x,y resolution for color planes */ - hp970_cmyk_init_t init; - - init = hp970_cmyk_init; - - init.a[13] = cdj970->intensities; /* Intensity levels cyan */ - init.a[19] = cdj970->intensities; /* Intensity levels magenta */ - init.a[25] = cdj970->intensities; /* Intensity levels yellow */ - - /* black plane resolution */ - assign_dpi(cdj970->x_pixels_per_inch, init.a + 2); - assign_dpi(cdj970->y_pixels_per_inch, init.a + 4); - - /* color plane resolution */ - xres = cdj970->x_pixels_per_inch / (cdj970->xscal + 1); - yres = cdj970->y_pixels_per_inch / (cdj970->yscal + 1); +static void +cdj970_start_raster_mode(gx_device_printer * pdev, + int paper_size, FILE * prn_stream) +{ + int xres, yres; /* x,y resolution for color planes */ + hp970_cmyk_init_t init; - /* cyan */ - assign_dpi(xres, init.a + 8); - assign_dpi(yres, init.a + 10); + init = hp970_cmyk_init; - /* magenta */ - assign_dpi(xres, init.a + 14); - assign_dpi(yres, init.a + 16); + init.a[13] = cdj970->intensities; /* Intensity levels cyan */ + init.a[19] = cdj970->intensities; /* Intensity levels magenta */ + init.a[25] = cdj970->intensities; /* Intensity levels yellow */ - /* yellow */ - assign_dpi(xres, init.a + 20); - assign_dpi(yres, init.a + 22); + /* black plane resolution */ + assign_dpi(cdj970->x_pixels_per_inch, init.a + 2); + assign_dpi(cdj970->y_pixels_per_inch, init.a + 4); - /* Page size, orientation, top margin & perforation skip */ - fprintf(prn_stream, "\033&l%dA", paper_size); + /* color plane resolution */ + xres = cdj970->x_pixels_per_inch / (cdj970->xscal + 1); + yres = cdj970->y_pixels_per_inch / (cdj970->yscal + 1); - /* Print Quality, -1 = draft, 0 = normal, 1 = presentation */ - fprintf(prn_stream, "\033*o%dM", cdj970->quality); + /* cyan */ + assign_dpi(xres, init.a + 8); + assign_dpi(yres, init.a + 10); - /* Media Type,0 = plain paper, 1 = bond paper, 2 = special - paper, 3 = glossy film, 4 = transparency film */ - fprintf(prn_stream, "\033&l%dM", cdj970->papertype); + /* magenta */ + assign_dpi(xres, init.a + 14); + assign_dpi(yres, init.a + 16); - fprintf (prn_stream, "\033u%dD\033&l0e0L", xres); + /* yellow */ + assign_dpi(xres, init.a + 20); + assign_dpi(yres, init.a + 22); - /* fputs("\033u%dD\033&l0e0L", prn_stream); */ + /* Page size, orientation, top margin & perforation skip */ + fprintf(prn_stream, "\033&l%dA", paper_size); - fprintf(prn_stream, "\033*p%dY", (int)(600 * DOFFSET)); + /* Print Quality, -1 = draft, 0 = normal, 1 = presentation */ + fprintf(prn_stream, "\033*o%dM", cdj970->quality); - /* This will start and configure the raster-mode */ - fprintf(prn_stream, "\033*g%dW", (int)sizeof(init.a)); /* The new configure - raster data comand */ - fwrite(init.a, sizeof(byte), sizeof(init.a), prn_stream); /* Transmit config - data */ - fputs("\033&l0H", prn_stream); - fputs("\033*r1A", prn_stream); - /* From now on, all escape commands start with \033*b, so we - * combine them (if the printer supports this). */ - fputs("\033*b", prn_stream); + /* Media Type,0 = plain paper, 1 = bond paper, 2 = special + paper, 3 = glossy film, 4 = transparency film */ + fprintf(prn_stream, "\033&l%dM", cdj970->papertype); - /* Set compression if the mode has been defined. */ - if (cdj970->compression) - fprintf(prn_stream, "%dm", cdj970->compression); + fprintf(prn_stream, "\033u%dD\033&l0e0L", xres); - return; -} + /* fputs("\033u%dD\033&l0e0L", prn_stream); */ -/* cdj_put_param_int: -----------------------------------------------------------------------------------*/ -static int cdj_put_param_int( gs_param_list *plist, - gs_param_name pname, - int *pvalue, - int minval, - int maxval, - int ecode) -{ - int code, value; + fprintf(prn_stream, "\033*p%dY", (int)(600 * DOFFSET)); - switch (code = param_read_int(plist, pname, &value)) { - default: - return code; + /* This will start and configure the raster-mode */ + fprintf(prn_stream, "\033*g%dW", (int)sizeof(init.a)); /* The new configure + raster data comand */ + fwrite(init.a, sizeof(byte), sizeof(init.a), prn_stream); /* Transmit config + data */ + fputs("\033&l0H", prn_stream); + fputs("\033*r1A", prn_stream); + /* From now on, all escape commands start with \033*b, so we + * combine them (if the printer supports this). */ + fputs("\033*b", prn_stream); - case 1: - return ecode; + /* Set compression if the mode has been defined. */ + if (cdj970->compression) + fprintf(prn_stream, "%dm", cdj970->compression); - case 0: - if (value < minval || value > maxval) - param_signal_error(plist, pname, gs_error_rangecheck); - *pvalue = value; - return (ecode < 0 ? ecode : 1); - } + return; } -/* cdj_put_param_float: +/* cdj_put_param_int: ----------------------------------------------------------------------------------*/ -static int cdj_put_param_float( gs_param_list *plist, - gs_param_name pname, - float *pvalue, - float minval, - float maxval, - int ecode) -{ - int code; - float value; - - switch (code = param_read_float(plist, pname, &value)) { - default: - return code; - - case 1: - return ecode; +static int +cdj_put_param_int(gs_param_list * plist, + gs_param_name pname, + int *pvalue, int minval, int maxval, int ecode) +{ + int code, value; + + switch (code = param_read_int(plist, pname, &value)) { + default: + return code; + + case 1: + return ecode; + + case 0: + if (value < minval || value > maxval) + param_signal_error(plist, pname, gs_error_rangecheck); + *pvalue = value; + return (ecode < 0 ? ecode : 1); + } +} - case 0: - if (value < minval || value > maxval) - param_signal_error(plist, pname, gs_error_rangecheck); - *pvalue = value; - return (ecode < 0 ? ecode : 1); - } +/* cdj_put_param_float: +----------------------------------------------------------------------------------*/ +static int +cdj_put_param_float(gs_param_list * plist, + gs_param_name pname, + float *pvalue, float minval, float maxval, int ecode) +{ + int code; + float value; + + switch (code = param_read_float(plist, pname, &value)) { + default: + return code; + + case 1: + return ecode; + + case 0: + if (value < minval || value > maxval) + param_signal_error(plist, pname, gs_error_rangecheck); + *pvalue = value; + return (ecode < 0 ? ecode : 1); + } } /* cdj_set_bpp: ----------------------------------------------------------------------------------*/ -static int cdj_set_bpp(gx_device * pdev, int bpp, int ccomps) +static int +cdj_set_bpp(gx_device * pdev, int bpp, int ccomps) { - gx_device_color_info *ci = &pdev->color_info; + gx_device_color_info *ci = &pdev->color_info; - if (ccomps && bpp == 0) { - if (cprn_device->cmyk) { + if (ccomps && bpp == 0) { + if (cprn_device->cmyk) { switch (ccomps) { - default: - return gs_error_rangecheck; - /*NOTREACHED */ - break; - - case 1: - bpp = 1; - break; - - case 3: - bpp = 24; - break; - - case 4: - switch (ci->depth) { - case 8: - case 16: - case 24: - case 32: - break; - - default: - bpp = cprn_device->default_depth; - break; - } - break; - } - } - } + default: + return_error(gs_error_rangecheck); + /*NOTREACHED */ + break; + + case 1: + bpp = 1; + break; + + case 3: + bpp = 24; + break; + + case 4: + switch (ci->depth) { + case 8: + case 16: + case 24: + case 32: + break; - if (bpp == 0) { - bpp = ci->depth; /* Use the current setting. */ + default: + bpp = cprn_device->default_depth; + break; + } + break; + } } + } + + if (bpp == 0) { + bpp = ci->depth; /* Use the current setting. */ + } - if (cprn_device->cmyk < 0) { - /* Reset procedures because we may have been in another mode. */ - dev_proc(pdev, map_cmyk_color) = gdev_cmyk_map_cmyk_color; - dev_proc(pdev, map_rgb_color) = NULL; - dev_proc(pdev, map_color_rgb) = gdev_cmyk_map_color_rgb; + if (cprn_device->cmyk < 0) { + /* Reset procedures because we may have been in another mode. */ + dev_proc(pdev, map_cmyk_color) = gdev_cmyk_map_cmyk_color; + dev_proc(pdev, map_rgb_color) = NULL; + dev_proc(pdev, map_color_rgb) = gdev_cmyk_map_color_rgb; - if (pdev->is_open) + if (pdev->is_open) gs_closedevice(pdev); } /* Check for valid bpp values */ switch (bpp) { - case 16: - case 32: - if (cprn_device->cmyk && ccomps && ccomps != 4) - goto bppe; - break; + case 16: + case 32: + if (cprn_device->cmyk && ccomps && ccomps != 4) + goto bppe; + break; - case 24: - if (!cprn_device->cmyk || ccomps == 0 || ccomps == 4) { - break; - } else if (ccomps == 1) { - goto bppe; - } else { - /* 3 components 24 bpp printing for CMYK device. */ - cprn_device->cmyk = -1; - } - break; + case 24: + if (!cprn_device->cmyk || ccomps == 0 || ccomps == 4) { + break; + } else if (ccomps == 1) { + goto bppe; + } else { + /* 3 components 24 bpp printing for CMYK device. */ + cprn_device->cmyk = -1; + } + break; - case 8: - if (cprn_device->cmyk) { - if (ccomps) { - if (ccomps == 3) { - cprn_device->cmyk = -1; - bpp = 3; - } else if (ccomps != 1 && ccomps != 4) { - goto bppe; - } - } - - if (ccomps != 1) - break; - } else { - break; - } - case 1: - if (ccomps != 1) - goto bppe; - - if (cprn_device->cmyk && bpp != pdev->color_info.depth) { - dev_proc(pdev, map_cmyk_color) = NULL; - dev_proc(pdev, map_rgb_color) = gdev_cmyk_map_rgb_color; - - if (pdev->is_open) { - gs_closedevice(pdev); - } - } - break; - - case 3: - if (!cprn_device->cmyk) { - break; - } - default: - bppe:return gs_error_rangecheck; + case 8: + if (cprn_device->cmyk) { + if (ccomps) { + if (ccomps == 3) { + cprn_device->cmyk = -1; + bpp = 3; + } else if (ccomps != 1 && ccomps != 4) { + goto bppe; + } + } + + if (ccomps != 1) + break; + } else { + break; + } + case 1: + if (ccomps != 1) + goto bppe; + + if (cprn_device->cmyk && bpp != pdev->color_info.depth) { + dev_proc(pdev, map_cmyk_color) = NULL; + dev_proc(pdev, map_rgb_color) = gdev_cmyk_map_rgb_color; + + if (pdev->is_open) { + gs_closedevice(pdev); + } + } + break; + + case 3: + if (!cprn_device->cmyk) { + break; + } + default: + bppe:return_error(gs_error_rangecheck); } if (cprn_device->cmyk == -1) { - dev_proc(pdev, map_cmyk_color) = NULL; - dev_proc(pdev, map_rgb_color) = gdev_pcl_map_rgb_color; - dev_proc(pdev, map_color_rgb) = gdev_pcl_map_color_rgb; - - if (pdev->is_open) { - gs_closedevice(pdev); - } + dev_proc(pdev, map_cmyk_color) = NULL; + dev_proc(pdev, map_rgb_color) = gdev_pcl_map_rgb_color; + dev_proc(pdev, map_color_rgb) = gdev_pcl_map_color_rgb; + + if (pdev->is_open) { + gs_closedevice(pdev); + } } switch (ccomps) { - case 0: - break; + case 0: + break; - case 1: - if (bpp != 1 && bpp != 8) - goto cce; - break; - - case 4: - if (cprn_device->cmyk) { - if (bpp >= 8) - break; - } - - case 3: - if (bpp == 1 || bpp == 3 || bpp == 8 || bpp == 16 || bpp == 24 || bpp == 32) { - break; - } + case 1: + if (bpp != 1 && bpp != 8) + goto cce; + break; + + case 4: + if (cprn_device->cmyk) { + if (bpp >= 8) + break; + } - cce: - default: - return gs_error_rangecheck; + case 3: + if (bpp == 1 || bpp == 3 || bpp == 8 || bpp == 16 || bpp == 24 + || bpp == 32) { + break; + } + + cce: + default: + return_error(gs_error_rangecheck); } if (cprn_device->cmyk) { - if (cprn_device->cmyk > 0) { - ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 4); - } else { - ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 3); - } + if (cprn_device->cmyk > 0) { + ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 4); + } else { + ci->num_components = ccomps ? ccomps : (bpp < 8 ? 1 : 3); + } - if (bpp != 1 && ci->num_components == 1) { /* We do dithered grays. */ - bpp = bpp < 8 ? 8 : bpp; - } + if (bpp != 1 && ci->num_components == 1) { /* We do dithered grays. */ + bpp = bpp < 8 ? 8 : bpp; + } - ci->max_color = (1 << (bpp >> 2)) - 1; - ci->max_gray = (bpp >= 8 ? 255 : 1); + ci->max_color = (1 << (bpp >> 2)) - 1; + ci->max_gray = (bpp >= 8 ? 255 : 1); - if (ci->num_components == 1) { + if (ci->num_components == 1) { ci->dither_grays = (bpp >= 8 ? 5 : 2); ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0); - } else { + } else { ci->dither_grays = (bpp > 8 ? 5 : 2); ci->dither_colors = (bpp > 8 ? 5 : bpp > 1 ? 2 : 0); - } - } else { - ci->num_components = (bpp == 1 || bpp == 8 ? 1 : 3); - ci->max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0); - ci->max_gray = (bpp >= 8 ? 255 : 1); - ci->dither_grays = (bpp >= 8 ? 5 : 2); - ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0); } + } else { + ci->num_components = (bpp == 1 || bpp == 8 ? 1 : 3); + ci->max_color = (bpp >= 8 ? 255 : bpp > 1 ? 1 : 0); + ci->max_gray = (bpp >= 8 ? 255 : 1); + ci->dither_grays = (bpp >= 8 ? 5 : 2); + ci->dither_colors = (bpp >= 8 ? 5 : bpp > 1 ? 2 : 0); + } - ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp); + ci->depth = ((bpp > 1) && (bpp < 8) ? 8 : bpp); - return (0); + return (0); } /* @@ -2258,128 +2313,149 @@ /* gdev_cmyk_map_cmyk_color: ----------------------------------------------------------------------------------*/ -static gx_color_index gdev_cmyk_map_cmyk_color(gx_device * pdev, - const gx_color_value cv[]) +static gx_color_index +gdev_cmyk_map_cmyk_color(gx_device * pdev, const gx_color_value cv[]) { - gx_color_index color; - gx_color_value cyan, magenta, yellow, black; + gx_color_index color; + gx_color_value cyan, magenta, yellow, black; - cyan = cv[0]; magenta = cv[1]; yellow = cv[2]; black = cv[3]; - switch (pdev->color_info.depth) { - case 1: - color = (cyan | magenta | yellow | black) > gx_max_color_value / 2 ? - ( gx_color_index) 1 : (gx_color_index) 0; - break; - - default:{ - int nbits = pdev->color_info.depth; - - if (cyan == magenta && magenta == yellow) { - /* Convert CMYK to gray -- Red Book 6.2.2 */ - float bpart = ((float)cyan) * (lum_red_weight / 100.) + - ((float)magenta) * (lum_green_weight / 100.) + - ((float)yellow) * (lum_blue_weight / 100.) + - (float)black; - - cyan = magenta = yellow = (gx_color_index) 0; - black = (gx_color_index) (bpart > gx_max_color_value ? - gx_max_color_value : bpart); - } - color = gx_cmyk_value_bits(cyan, magenta, yellow, black, - nbits >> 2); + cyan = cv[0]; + magenta = cv[1]; + yellow = cv[2]; + black = cv[3]; + switch (pdev->color_info.depth) { + case 1: + color = + (cyan | magenta | yellow | black) > + gx_max_color_value / + 2 ? (gx_color_index) 1 : (gx_color_index) 0; + break; + + default:{ + int nbits = pdev->color_info.depth; + + if (cyan == magenta && magenta == yellow) { + /* Convert CMYK to gray -- Red Book 6.2.2 */ + float bpart = ((float)cyan) * (lum_red_weight / 100.) + + ((float)magenta) * (lum_green_weight / 100.) + + ((float)yellow) * (lum_blue_weight / 100.) + + (float)black; + + cyan = magenta = yellow = (gx_color_index) 0; + black = (gx_color_index) (bpart > gx_max_color_value ? + gx_max_color_value : bpart); } - } + color = gx_cmyk_value_bits(cyan, magenta, yellow, black, + nbits >> 2); + } + } - return (color); + return (color); } /* gdev_cmyk_map_rgb_color: Mapping of RGB colors to gray values. ----------------------------------------------------------------------------------*/ -static gx_color_index gdev_cmyk_map_rgb_color( gx_device * pdev, - const gx_color_value cv[]) +static gx_color_index +gdev_cmyk_map_rgb_color(gx_device * pdev, const gx_color_value cv[]) { - gx_color_value r, g, b; + gx_color_value r, g, b; - r = cv[0]; g = cv[1]; b = cv[2]; - if (gx_color_value_to_byte(r & g & b) == 0xff) { - return (gx_color_index) 0; /* White */ - } else { - gx_color_value c = gx_max_color_value - r; - gx_color_value m = gx_max_color_value - g; - gx_color_value y = gx_max_color_value - b; + r = cv[0]; + g = cv[1]; + b = cv[2]; + if (gx_color_value_to_byte(r & g & b) == 0xff) { + return (gx_color_index) 0; /* White */ + } else { + gx_color_value c = gx_max_color_value - r; + gx_color_value m = gx_max_color_value - g; + gx_color_value y = gx_max_color_value - b; - switch (pdev->color_info.depth) { + switch (pdev->color_info.depth) { case 1: - return (c | m | y) > gx_max_color_value / 2 ? (gx_color_index) 1 : (gx_color_index) 0; - /*NOTREACHED */ - break; + return (c | m | y) > + gx_max_color_value / + 2 ? (gx_color_index) 1 : (gx_color_index) 0; + /*NOTREACHED */ + break; case 8: - return ((ulong) c * lum_red_weight * 10 - + (ulong) m * lum_green_weight * 10 - + (ulong) y * lum_blue_weight * 10) - >> (gx_color_value_bits + 2); - /*NOTREACHED */ - break; - } + return ((ulong) c * lum_red_weight * 10 + + (ulong) m * lum_green_weight * 10 + + (ulong) y * lum_blue_weight * 10) + >> (gx_color_value_bits + 2); + /*NOTREACHED */ + break; } + } - return (gx_color_index) 0; /* This should never happen. */ + return (gx_color_index) 0; /* This should never happen. */ } /* gdev_cmyk_map_rgb_color: Mapping of CMYK colors. ----------------------------------------------------------------------------------*/ -static int gdev_cmyk_map_color_rgb( gx_device *pdev, - gx_color_index color, - gx_color_value prgb[3]) +static int +gdev_cmyk_map_color_rgb(gx_device * pdev, + gx_color_index color, gx_color_value prgb[3]) { - switch (pdev->color_info.depth) { - case 1: - prgb[0] = prgb[1] = prgb[2] = gx_max_color_value * (1 - color); - break; + switch (pdev->color_info.depth) { + case 1: + prgb[0] = prgb[1] = prgb[2] = gx_max_color_value * (1 - color); + break; + + case 8: + if (pdev->color_info.num_components == 1) { + gx_color_value value = (gx_color_value) color ^ 0xff; + + prgb[0] = prgb[1] = prgb[2] = (value << 8) + value; + break; + } - case 8: - if (pdev->color_info.num_components == 1) { - gx_color_value value = (gx_color_value) color ^ 0xff; - prgb[0] = prgb[1] = prgb[2] = (value << 8) + value; - break; - } - - default:{ - unsigned long bcyan, bmagenta, byellow, black; - int nbits = pdev->color_info.depth; - - gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black, nbits >> 2); - -# ifdef USE_ADOBE_CMYK_RGB - - /* R = 1.0 - min(1.0, C + K), etc. */ - - bcyan += black, bmagenta += black, byellow += black; - prgb[0] = (bcyan > gx_max_color_value ? (gx_color_value) 0 : - gx_max_color_value - bcyan); - prgb[1] = (bmagenta > gx_max_color_value ? (gx_color_value) 0 : - gx_max_color_value - bmagenta); - prgb[2] = (byellow > gx_max_color_value ? (gx_color_value) 0 : - gx_max_color_value - byellow); - -# else - - /* R = (1.0 - C) * (1.0 - K), etc. */ - - prgb[0] = (gx_color_value)((ulong) (gx_max_color_value - bcyan) * - (gx_max_color_value - black) / gx_max_color_value); - prgb[1] = (gx_color_value)((ulong) (gx_max_color_value - bmagenta) * - (gx_max_color_value - black) / gx_max_color_value); - prgb[2] = (gx_color_value)((ulong) (gx_max_color_value - byellow) * - (gx_max_color_value - black) / gx_max_color_value); + default:{ + unsigned long bcyan, bmagenta, byellow, black; + int nbits = pdev->color_info.depth; + + gx_value_cmyk_bits(color, bcyan, bmagenta, byellow, black, + nbits >> 2); + +#ifdef USE_ADOBE_CMYK_RGB + + /* R = 1.0 - min(1.0, C + K), etc. */ + + bcyan += black, bmagenta += black, byellow += black; + prgb[0] = (bcyan > gx_max_color_value ? (gx_color_value) 0 : + gx_max_color_value - bcyan); + prgb[1] = + (bmagenta > + gx_max_color_value ? (gx_color_value) 0 : + gx_max_color_value - bmagenta); + prgb[2] = + (byellow > + gx_max_color_value ? (gx_color_value) 0 : + gx_max_color_value - byellow); + +#else + + /* R = (1.0 - C) * (1.0 - K), etc. */ + + prgb[0] = + (gx_color_value) ((ulong) (gx_max_color_value - bcyan) * + (gx_max_color_value - + black) / gx_max_color_value); + prgb[1] = + (gx_color_value) ((ulong) (gx_max_color_value - bmagenta) + * (gx_max_color_value - + black) / gx_max_color_value); + prgb[2] = + (gx_color_value) ((ulong) (gx_max_color_value - byellow) * + (gx_max_color_value - + black) / gx_max_color_value); #endif - } - } + } + } - return (0); + return (0); } #define gx_color_value_to_1bit(cv) ((cv) >> (gx_color_value_bits - 1)) @@ -2391,227 +2467,240 @@ /* gdev_pcl_map_rgb_color: ----------------------------------------------------------------------------------*/ -static gx_color_index gdev_pcl_map_rgb_color( gx_device * pdev, - const gx_color_value cv[]) +static gx_color_index +gdev_pcl_map_rgb_color(gx_device * pdev, const gx_color_value cv[]) { - gx_color_value r, g, b; + gx_color_value r, g, b; - r = cv[0]; g = cv[1]; b = cv[2]; - if (gx_color_value_to_byte(r & g & b) == 0xff) - return (gx_color_index) 0; /* white */ - else { - gx_color_value c = gx_max_color_value - r; - gx_color_value m = gx_max_color_value - g; - gx_color_value y = gx_max_color_value - b; + r = cv[0]; + g = cv[1]; + b = cv[2]; + if (gx_color_value_to_byte(r & g & b) == 0xff) + return (gx_color_index) 0; /* white */ + else { + gx_color_value c = gx_max_color_value - r; + gx_color_value m = gx_max_color_value - g; + gx_color_value y = gx_max_color_value - b; - switch (pdev->color_info.depth) { + switch (pdev->color_info.depth) { case 1: - return ((c | m | y) > gx_max_color_value / 2 ? (gx_color_index) 1 : (gx_color_index) 0); + return ((c | m | y) > + gx_max_color_value / + 2 ? (gx_color_index) 1 : (gx_color_index) 0); case 8: - if (pdev->color_info.num_components >= 3) - return (gx_color_value_to_1bit(c) - + (gx_color_value_to_1bit(m) << 1) - + (gx_color_value_to_1bit(y) << 2)); - else - return ((((ulong) c * red_weight + (ulong) m * green_weight + (ulong) y * blue_weight) - >> (gx_color_value_bits + 2))); - - case 16: - return (gx_color_value_to_5bits(y) + - (gx_color_value_to_6bits(m) << 5) + - (gx_color_value_to_5bits(c) << 11)); + if (pdev->color_info.num_components >= 3) + return (gx_color_value_to_1bit(c) + + (gx_color_value_to_1bit(m) << 1) + + (gx_color_value_to_1bit(y) << 2)); + else + return ((((ulong) c * red_weight + + (ulong) m * green_weight + + (ulong) y * blue_weight) + >> (gx_color_value_bits + 2))); + + case 16: + return (gx_color_value_to_5bits(y) + + (gx_color_value_to_6bits(m) << 5) + + (gx_color_value_to_5bits(c) << 11)); case 24: - return (gx_color_value_to_byte(y) + - (gx_color_value_to_byte(m) << 8) + - ((ulong) gx_color_value_to_byte(c) << 16)); - case 32: { - return ((c == m && c == y) ? ((ulong) gx_color_value_to_byte(c) << 24) - : (gx_color_value_to_byte(y) + - (gx_color_value_to_byte(m) << 8) + - ((ulong) gx_color_value_to_byte(c) << 16))); - } + return (gx_color_value_to_byte(y) + + (gx_color_value_to_byte(m) << 8) + + ((ulong) gx_color_value_to_byte(c) << 16)); + case 32:{ + return ((c == m + && c == + y) ? ((ulong) gx_color_value_to_byte(c) << 24) + : (gx_color_value_to_byte(y) + + (gx_color_value_to_byte(m) << 8) + + ((ulong) gx_color_value_to_byte(c) << 16))); } } + } - return ((gx_color_index) 0); /* This never happens */ + return ((gx_color_index) 0); /* This never happens */ } #define gx_maxcol gx_color_value_from_byte(gx_color_value_to_byte(gx_max_color_value)) /* gdev_pcl_map_color_rgb: Map a color index to a r-g-b color. ----------------------------------------------------------------------------------*/ -static int gdev_pcl_map_color_rgb( gx_device *pdev, - gx_color_index color, - gx_color_value prgb[3]) +static int +gdev_pcl_map_color_rgb(gx_device * pdev, + gx_color_index color, gx_color_value prgb[3]) { - /* For the moment, we simply ignore any black correction */ - switch (pdev->color_info.depth) { - case 1: - prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1); - break; + /* For the moment, we simply ignore any black correction */ + switch (pdev->color_info.depth) { + case 1: + prgb[0] = prgb[1] = prgb[2] = -((gx_color_value) color ^ 1); + break; + + case 8: + if (pdev->color_info.num_components >= 3) { + gx_color_value c = (gx_color_value) color ^ 7; + + prgb[0] = -(c & 1); + prgb[1] = -((c >> 1) & 1); + prgb[2] = -(c >> 2); + } else { + gx_color_value value = (gx_color_value) color ^ 0xff; - case 8: - if (pdev->color_info.num_components >= 3) { - gx_color_value c = (gx_color_value) color ^ 7; - - prgb[0] = -(c & 1); - prgb[1] = -((c >> 1) & 1); - prgb[2] = -(c >> 2); - } else { - gx_color_value value = (gx_color_value) color ^ 0xff; - prgb[0] = prgb[1] = prgb[2] = (value << 8) + value; - } - break; - case 16: { - gx_color_value c = (gx_color_value) color ^ 0xffff; - ushort value = c >> 11; - - prgb[0] = ((value << 11) + (value << 6) + (value << 1) + - (value >> 4)) >> (16 - gx_color_value_bits); - value = (c >> 6) & 0x3f; - prgb[1] = ((value << 10) + (value << 4) + (value >> 2)) - >> (16 - gx_color_value_bits); - value = c & 0x1f; - prgb[2] = ((value << 11) + (value << 6) + (value << 1) + - (value >> 4)) >> (16 - gx_color_value_bits); - } - break; - - case 24: { - gx_color_value c = (gx_color_value) color ^ 0xffffff; + prgb[0] = prgb[1] = prgb[2] = (value << 8) + value; + } + break; + case 16:{ + gx_color_value c = (gx_color_value) color ^ 0xffff; + ushort value = c >> 11; + + prgb[0] = ((value << 11) + (value << 6) + (value << 1) + + (value >> 4)) >> (16 - gx_color_value_bits); + value = (c >> 6) & 0x3f; + prgb[1] = ((value << 10) + (value << 4) + (value >> 2)) + >> (16 - gx_color_value_bits); + value = c & 0x1f; + prgb[2] = ((value << 11) + (value << 6) + (value << 1) + + (value >> 4)) >> (16 - gx_color_value_bits); + } + break; - prgb[0] = gx_color_value_from_byte(c >> 16); - prgb[1] = gx_color_value_from_byte((c >> 8) & 0xff); - prgb[2] = gx_color_value_from_byte(c & 0xff); - } - break; + case 24:{ + gx_color_value c = (gx_color_value) color ^ 0xffffff; - case 32: { - gx_color_value w = gx_maxcol - gx_color_value_from_byte(color >> 24); + prgb[0] = gx_color_value_from_byte(c >> 16); + prgb[1] = gx_color_value_from_byte((c >> 8) & 0xff); + prgb[2] = gx_color_value_from_byte(c & 0xff); + } + break; - prgb[0] = w - gx_color_value_from_byte((color >> 16) & 0xff); - prgb[1] = w - gx_color_value_from_byte((color >> 8) & 0xff); - prgb[2] = w - gx_color_value_from_byte(color & 0xff); - } - break; - } + case 32:{ + gx_color_value w = + gx_maxcol - gx_color_value_from_byte(color >> 24); + + prgb[0] = w - gx_color_value_from_byte((color >> 16) & 0xff); + prgb[1] = w - gx_color_value_from_byte((color >> 8) & 0xff); + prgb[2] = w - gx_color_value_from_byte(color & 0xff); + } + break; + } - return (0); + return (0); } #define save_ccomps save_info.num_components /* cdj_put_param_bpp: new_bpp == save_bpp or new_bpp == 0 means don't change bpp. - * ccomps == 0 means don't change number of color comps. - * If new_bpp != 0, it must be the value of the BitsPerPixel element of - * the plist; real_bpp may differ from new_bpp. -----------------------------------------------------------------------------------*/ -static int cdj_put_param_bpp( gx_device *pdev, - gs_param_list *plist, - int new_bpp, - int real_bpp, - int ccomps) -{ - if (new_bpp == 0 && ccomps == 0) - return gdev_prn_put_params(pdev, plist); - else { - gx_device_color_info save_info; - int save_bpp; - int code; - - save_info = pdev->color_info; - save_bpp = save_info.depth; + * ccomps == 0 means don't change number of color comps. + * If new_bpp != 0, it must be the value of the BitsPerPixel element of + * the plist; real_bpp may differ from new_bpp. +----------------------------------------------------------------------------------*/ +static int +cdj_put_param_bpp(gx_device * pdev, + gs_param_list * plist, + int new_bpp, int real_bpp, int ccomps) +{ + if (new_bpp == 0 && ccomps == 0) + return gdev_prn_put_params(pdev, plist); + else { + gx_device_color_info save_info; + int save_bpp; + int code; + + save_info = pdev->color_info; + save_bpp = save_info.depth; - if (save_bpp == 8 && save_ccomps == 3 && !cprn_device->cmyk) - save_bpp = 3; + if (save_bpp == 8 && save_ccomps == 3 && !cprn_device->cmyk) + save_bpp = 3; - code = cdj_set_bpp(pdev, real_bpp, ccomps); + code = cdj_set_bpp(pdev, real_bpp, ccomps); - if (code < 0) { + if (code < 0) { param_signal_error(plist, "BitsPerPixel", code); param_signal_error(plist, "ProcessColorModel", code); return (code); - } + } - pdev->color_info.depth = new_bpp; /* cdj_set_bpp maps 3/6 to 8 */ - code = gdev_prn_put_params(pdev, plist); + pdev->color_info.depth = new_bpp; /* cdj_set_bpp maps 3/6 to 8 */ + code = gdev_prn_put_params(pdev, plist); - if (code < 0) { + if (code < 0) { cdj_set_bpp(pdev, save_bpp, save_ccomps); return (code); - } + } - cdj_set_bpp(pdev, real_bpp, ccomps); /* reset depth if needed */ - if ((cdj970->color_info.depth != save_bpp - || (ccomps != 0 && ccomps != save_ccomps)) - && pdev->is_open) + cdj_set_bpp(pdev, real_bpp, ccomps); /* reset depth if needed */ + if ((cdj970->color_info.depth != save_bpp + || (ccomps != 0 && ccomps != save_ccomps)) + && pdev->is_open) return (gs_closedevice(pdev)); return (0); #undef save_ccomps - } + } } /* cdj970_write_header: ----------------------------------------------------------------------------------*/ -static int cdj970_write_header (gx_device *pdev, FILE * prn_stream) +static int +cdj970_write_header(gx_device * pdev, FILE * prn_stream) { - char startbuffer[1260]; + char startbuffer[1260]; - memset (startbuffer, 0, 1260); + memset(startbuffer, 0, 1260); - gs_sprintf (&(startbuffer[600]), "\033E\033%%-12345X@PJL JOB NAME = \"GHOST BY RENE HARSCH\"\n@PJL ENTER LANGUAGE=PCL3GUI\n"); + gs_sprintf(&(startbuffer[600]), + "\033E\033%%-12345X@PJL JOB NAME = \"GHOST BY RENE HARSCH\"\n@PJL ENTER LANGUAGE=PCL3GUI\n"); - fwrite (startbuffer, sizeof(char), 678, prn_stream); + fwrite(startbuffer, sizeof(char), 678, prn_stream); - fputs("\033&l1H\033&l-2H", prn_stream); /* reverse engineering */ + fputs("\033&l1H\033&l-2H", prn_stream); /* reverse engineering */ - /* enter duplex mode / reverse engineering */ - if (cdj970->duplex > NONE) { - fputs("\033&l2S\033&b16WPML", prn_stream); + /* enter duplex mode / reverse engineering */ + if (cdj970->duplex > NONE) { + fputs("\033&l2S\033&b16WPML", prn_stream); - fputc (0x20, prn_stream); - fputc (0x04, prn_stream); - fputc (0x00, prn_stream); - fputc (0x06, prn_stream); - fputc (0x01, prn_stream); - fputc (0x04, prn_stream); - fputc (0x01, prn_stream); - fputc (0x04, prn_stream); - fputc (0x01, prn_stream); - fputc (0x06, prn_stream); - fputc (0x08, prn_stream); - fputc (0x01, prn_stream); - fputc (0x00, prn_stream); - } + fputc(0x20, prn_stream); + fputc(0x04, prn_stream); + fputc(0x00, prn_stream); + fputc(0x06, prn_stream); + fputc(0x01, prn_stream); + fputc(0x04, prn_stream); + fputc(0x01, prn_stream); + fputc(0x04, prn_stream); + fputc(0x01, prn_stream); + fputc(0x06, prn_stream); + fputc(0x08, prn_stream); + fputc(0x01, prn_stream); + fputc(0x00, prn_stream); + } - return 0; + return 0; } /* cdj970_write_trailer: ----------------------------------------------------------------------------------*/ -static int cdj970_write_trailer (gx_device *pdev, FILE * prn_stream) +static int +cdj970_write_trailer(gx_device * pdev, FILE * prn_stream) { - fprintf(prn_stream, "\033E\033%%-12345X"); /* reverse engineering */ + fprintf(prn_stream, "\033E\033%%-12345X"); /* reverse engineering */ - return 0; + return 0; } /* cdj970_close: ----------------------------------------------------------------------------------*/ -static int cdj970_close(gx_device *pdev) +static int +cdj970_close(gx_device * pdev) { - gx_device_printer *const ppdev = (gx_device_printer *)pdev; - int retCode = gdev_prn_open_printer (pdev, true); + gx_device_printer *const ppdev = (gx_device_printer *) pdev; + int retCode = gdev_prn_open_printer(pdev, true); - if (retCode < 0) - return (retCode); + if (retCode < 0) + return (retCode); - cdj970_write_trailer (pdev, ppdev->file); + cdj970_write_trailer(pdev, ppdev->file); - return gdev_prn_close(pdev); + return gdev_prn_close(pdev); } diff -Nru ghostscript-9.10~dfsg/contrib/gdevgdi.c ghostscript-9.25~dfsg+1/contrib/gdevgdi.c --- ghostscript-9.10~dfsg/contrib/gdevgdi.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevgdi.c 2018-09-13 10:02:01.000000000 +0000 @@ -175,7 +175,8 @@ int dots_per_inch = (int)pdev->y_pixels_per_inch; int raster = gx_device_raster((gx_device *)pdev, true); int real_line_width; - long ul_band_size, ul_comp_size, ul_tiff_size, ul_min_size; + long ul_band_size, ul_comp_size; + /* long ul_tiff_size, ul_min_size; */ byte *ibp=NULL, *obp=NULL, *tmp=NULL; byte paper_type=0, compression_type; @@ -242,7 +243,7 @@ /*ul_tiff_size = FrameTiffComp(obp, ibp, band_height, band_width_bytes, GDI_PRE_COMP);*/ /*ul_scan_size = (unsigned long)bmp2run(obp, ibp, band_height, band_width_bytes, GDI_PRE_COMP);*/ /*ul_min_size = (ul_scan_size > ul_tiff_size) ? ul_tiff_size : ul_scan_size;*/ - ul_min_size = ul_tiff_size; + /* ul_min_size = ul_tiff_size; */ compression_type = GDI_COMP_MODITIFF; /*compression_type = (ul_scan_size > ul_tiff_size) ? GDI_COMP_MODITIFF : GDI_COMP_SCANLINE;*/ switch (compression_type) { @@ -268,7 +269,7 @@ band_height, band_width_bytes, GDI_REAL_COMP); if (ul_comp_size > MAXBAND-8) { - int f, g, h; + int f; if (!fudge) { ASSERT(use_band == ibp); use_band = (byte*)gs_malloc(pdev->memory->non_gc_memory, ul_band_size, 1, "gdi_print_page/fudge"); @@ -296,7 +297,6 @@ } } } while (ul_comp_size > MAXBAND-8); - oh_well: if (fudge > 1) { ASSERT(use_band != ibp); gs_free(pdev->memory->non_gc_memory, use_band, ul_band_size, 1, "gdi_print_page/fudge"); @@ -331,7 +331,7 @@ FILE *WritePJLHeaderData(gx_device_printer *pdev, FILE *fp) { unsigned long ulSize; - unsigned char buffer[300]; + char buffer[300]; int dots_per_inch = (int)pdev->y_pixels_per_inch; strcpy(buffer, "\033%-12345X"); @@ -467,10 +467,6 @@ } else { - if(i == 0x253) - { - i = i; - } usLineSize = PreTiffComp(SrcPtr, usBytesPerLine); } SrcPtr += usBytesPerLine; diff -Nru ghostscript-9.10~dfsg/contrib/gdevhl12.c ghostscript-9.25~dfsg+1/contrib/gdevhl12.c --- ghostscript-9.10~dfsg/contrib/gdevhl12.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevhl12.c 2018-09-13 10:02:01.000000000 +0000 @@ -213,7 +213,7 @@ typedef unsigned short u16; /* The printer expects 16-bit data words in big endian order. */ -#if arch_is_big_endian +#if ARCH_IS_BIG_ENDIAN #define cpu_to_be16(x) (x) #else static u16 diff -Nru ghostscript-9.10~dfsg/contrib/gdevlx32.c ghostscript-9.25~dfsg+1/contrib/gdevlx32.c --- ghostscript-9.10~dfsg/contrib/gdevlx32.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevlx32.c 2018-09-13 10:02:01.000000000 +0000 @@ -18,8 +18,13 @@ * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, write to: + * + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 + * USA + * * * -------------------------------------------------------------------- * @@ -1081,7 +1086,8 @@ { int len, offs1, startabs; int endabs, select, fwd; - int back, nabspos, sep; + int back, nabspos; + /* int sep;*/ byte *header; header = gendata->header; @@ -1104,11 +1110,11 @@ */ if(head == LEFT) { - sep = (gendata->bwsep * 2) / gendata->xrmul; + /* sep = (gendata->bwsep * 2) / gendata->xrmul;*/ } else { - sep = (gendata->colsep * 2) / gendata->xrmul; + /* sep = (gendata->colsep * 2) / gendata->xrmul; */ select |= 0x80; } diff -Nru ghostscript-9.10~dfsg/contrib/gdevlx7.c ghostscript-9.25~dfsg+1/contrib/gdevlx7.c --- ghostscript-9.10~dfsg/contrib/gdevlx7.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevlx7.c 2018-09-13 10:02:01.000000000 +0000 @@ -361,18 +361,22 @@ /* ------ Driver procedures ------ */ /*** THIS NEED TO BE REWORKED SOON ***/ -static const int LEFT_MARGIN=50; -static const int VERTSIZE=LX7_BSW_H; +enum { + LEFT_MARGIN=50, + VERTSIZE=LX7_BSW_H +}; /* offsets to print line sequence (defined in outbuf) */ -static const int IDX_SEQLEN=5; -static const int IDX_HORRES=8; -static const int IDX_PACKETS=13; -static const int IDX_5700DIF=12; -static const int IDX_HSTART=15; -static const int IDX_HEND=17; -static const int IDX_DATA=26; -static const int IDX_CARTRIDGE=10; +enum { + IDX_SEQLEN=5, + IDX_HORRES=8, + IDX_PACKETS=13, + IDX_5700DIF=12, + IDX_HSTART=15, + IDX_HEND=17, + IDX_DATA=26, + IDX_CARTRIDGE=10 +}; #define DIV8(x) ( (x) >> 3 ) #define MOD8(x) ( (x) & 0x7 ) diff -Nru ghostscript-9.10~dfsg/contrib/gdevmd2k.c ghostscript-9.25~dfsg+1/contrib/gdevmd2k.c --- ghostscript-9.10~dfsg/contrib/gdevmd2k.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevmd2k.c 2018-09-13 10:02:01.000000000 +0000 @@ -140,7 +140,7 @@ static int alps_get_params(gx_device *pdev, gs_param_list *plist) { - gs_param_string mediaType = { "", 1, false }; + gs_param_string mediaType = { (unsigned char *)"", 1, false }; int code = gdev_prn_get_params(pdev, plist); if (code < 0 || (code = param_write_bool(plist, "Color", &dev_alps->color)) < 0 || @@ -223,7 +223,7 @@ code = alps_put_param_int (plist, "Yellow", &yellow, 0, 2048, code); code = alps_put_param_int (plist, "Black", &black, 0, 2048, code); -#define mediaTypeCmp(mname) strncmp(mediaType.data, mname, mediaType.size) +#define mediaTypeCmp(mname) strncmp((const char *)mediaType.data, mname, mediaType.size) if (param_read_string(plist, "MediaType", &mediaType) == 0) { dev_alps->mediaType = (! mediaTypeCmp("PlainPaper" ) ? 0 @@ -568,7 +568,8 @@ int xskip = 0; /* Count pre print skip octets */ - for( ; len > 0 && *dp == 0; len --, dp ++, xskip ++); + for( ; len > 0 && *dp == 0; len --, dp ++, xskip ++) + {} alps_cmd("\033\052\142", len, 0124, prn_stream); write_short(xskip, prn_stream); diff -Nru ghostscript-9.10~dfsg/contrib/gdevop4w.c ghostscript-9.25~dfsg+1/contrib/gdevop4w.c --- ghostscript-9.10~dfsg/contrib/gdevop4w.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gdevop4w.c 2018-09-13 10:02:01.000000000 +0000 @@ -237,13 +237,9 @@ "oki4w_print_page"); word *data_words, - *out_row_words, - *out_row_alt_words, - *prev_row_words; + *out_row_words; #define data ((byte *)data_words) #define out_row ((byte *)out_row_words) -#define out_row_alt ((byte *)out_row_alt_words) -#define prev_row ((byte *)prev_row_words) byte *out_data; int x_dpi = pdev->x_pixels_per_inch; int y_dpi = pdev->y_pixels_per_inch; @@ -261,8 +257,6 @@ return_error(gs_error_VMerror); data_words = storage; out_row_words = data_words + (line_size_words * 2); - out_row_alt_words = out_row_words + (line_size_words * 2); - prev_row_words = out_row_alt_words + (line_size_words * 2); /* Clear temp storage */ memset(data, 0, storage_size_words * W); diff -Nru ghostscript-9.10~dfsg/contrib/gomni.c ghostscript-9.25~dfsg+1/contrib/gomni.c --- ghostscript-9.10~dfsg/contrib/gomni.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/gomni.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2098 +0,0 @@ -/* - * IBM Omni driver - * Copyright (c) International Business Machines Corp., 2000 - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Portions of this file are used with permission granted by Aladdin - * Enterprises - * - * - * - * - * Copyright (C) 1998, 1999, 2000 Aladdin Enterprises. - * - * The program in this file is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 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 Lesser - * General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -/************************************************************************/ -/* FILE: gomni.c */ -/* */ -/* */ -/* Change History */ -/* ============= */ -/* */ -/* @@08162000 Changed device PageCount value so that we could */ -/* print multiple pages. The PageCount value was */ -/* not being updated internal to Ghostscript */ -/* */ -/* @@10172000 changed to flip coordinates from zero based top */ -/* to actual top of page */ -/* */ -/* @@10192000 adjusted dot size correction values for */ -/* monochrome mode */ -/* */ -/* @@10252000 added code to make sure that we have a full band */ -/* of data. Rendering high res is slow. */ -/* */ -/* @@10312000 correct line decrement and get_bits of a line */ -/* */ -/* 04062001 rewrote module to allow for sync and async */ -/* function since GS does not handle async at the */ -/* moment */ -/* */ -/* @@04062001 removed mono dither routines and support from */ -/* this module into the core omni code */ -/* */ -/* @@04162001 Added support for newFrame */ -/* */ -/* @@04252001 Added support for GS mono output */ -/* -smonodither=GSMONO on the command line */ -/* */ -/* @@05092001 Added the ability to have a client server */ -/* interaction instead of writing the data */ -/* directly to a file */ -/* */ -/* @@05052001A Update mulitplier for .0001 mm vs. .001 mm */ -/* */ -/* 1/28/2002 changed code to utilize a core omni structure */ -/* to allow for management of devices linked */ -/* to servers and allow device code re-entrancy */ -/* */ -/* @@01302002 Changed code to utilize -sserver from the */ -/* command line instead of having to provide a */ -/* file name along with the server */ -/* */ -/************************************************************************/ - -#include "std.h" -#ifdef OMNI_USE_GLIB -/* Include these first. Ghostscript redefines printf */ -#include -#include -#else -#include -#define GModule void -#define GModuleFlags int -typedef void* gpointer; -#define g_module_open dlopen -#define g_module_close dlclose -int dlsym_wrapper(void *lib, char const *name, void **symbol) -{ - *symbol=dlsym(lib, name); - return *symbol != 0; -} -#define g_module_symbol dlsym_wrapper -#define g_module_error dlerror -#endif -#ifdef HAVE_STDINT_H -# include -#endif /* HAVE_STDINT_H */ - -#include "gdevprna.h" -#include "gdevpccm.h" -#include "gdevprn.h" -#include "gsparam.h" -#include "gdevbmp.h" -#include "gserrors.h" -#include "stdio_.h" -#include "gserrors.h" -#include "gpsync.h" - -#include "defs.h" - -#define MAX_LENGTH 65 - -#define Signature "OMNI" - -const static int fDebugOutput = 0; - -#define DEVICES_DEFINED - -typedef struct _HWMAR { - float fLeftClip; - float fBottomClip; - float fRightClip; - float fTopClip; - float fxWidth; - float fyHeight; -} HWMARGINS; - -typedef struct _HWRES { - float xRes; - float yRes; - float fScanDots; /* number of dots in scan line */ -} HWRESOLUTION; - -typedef struct _PRTMODE { - int iBitCount; - int iPlanes; -} PRINTMODE; - -long DiffusionDither (PDDI pdi, PIMAGEINFO pimg_infos, PBYTE *pBuffer, ULONG ulFlgs); - -/* - * Prototypes for routines that we will be calling into the core Omni code - * to resolve - */ -typedef bool (*PFNGIINIT) (void *pDev); -typedef bool (*PFNGITERM) (void *pDev); -typedef bool (*PFNGETPRINTMODEINFO) (void *pDev, - PRINTMODE *pPrtMode); -typedef bool (*PFNGETRESOLUTIONINFO) (void *pDev, - HWRESOLUTION *hwRes); -typedef bool (*PFNGETMARGININFO) (void *pDev, - HWMARGINS *hwMargins); -typedef void (*PFNBEGINJOB) (void *pOmni, - FILE *pfpOut); -typedef void (*PFNNEWFRAME) (void *pDev); /*@@04162001*/ -typedef void (*PFNENDJOB) (void *pDev); -typedef void (*PFNRASTERIZE) (void *pcoreOmni, - PBYTE pbBits, - PBITMAPINFO2 pbmi, - PSIZEL psizelPage, - PRECTL prectlPageLocation, - BITBLT_TYPE eType); -typedef void * (*PFNCREATEDEVICE) (void *pOmni, - void **vhDevice, - int iUsePDC); -typedef void * (*PFNDELETEDEVICE) (void *pOmni); -typedef long (*PFNMONODITHER) (PDDI pdi, /*@@04062001*/ - PIMAGEINFO pimg_infos, - PBYTE *pBuffer, - ULONG ulFlgs); - -ULONG FindBandSize (ULONG ulYHeight, - ULONG ulXWidth, - ULONG ulBitsPerPel, - ULONG ulNumPlanes, - ULONG ulModulus, - ULONG ulMemoryLimit); - -typedef int (*PFNGETOMNIJOBPROPERTIES) (char *pszDriverName, - char **pJobProperties); -typedef int (*PFNFREEOMNIJOBPROPERTIES) (char **pJobProperties); - -#define uint32 unsigned long -#define int32 long - -#define strcmpi strcasecmp - -/* ------ The device descriptors ------ */ - -typedef struct omni_dev_struct { - char cSignature[4]; - int cbSize; /* length of the structure */ - char cVersion[10]; - char cOmniVersion[10]; - bool bPDCDevice; /* boolean to tell if this is a PDC device or not */ - void *pDevice; /* pointer to a device */ - FILE *pfpOut; /* pointer to the output handle from beginjob */ - FILE *pfpErr; - char *pszJobOptions; /* pointer to the job options */ - char cDebugFile[MAX_LENGTH]; /* debug file name */ - char cDeviceName[MAX_LENGTH]; - char cServer[64]; - void *pvReserved; -} core_omni, core_omni_device; - -/* All omni specific data */ -typedef struct _DevStruct { - char cAsyncOpt[MAX_LENGTH]; /* text value for dither */ - char cMonoDither[MAX_LENGTH]; - char cServerFile[256]; /*@@05092001 */ - core_omni_device *pcoreOmni; - void *pCallPtr; - - GModule *hmodOmni; /* handle to libomni.so */ - GModule *hmodDevice; /* handle to libDeviceXXX.so */ - PFNGETPRINTMODEINFO pfnGetPrintModeInfo; - PFNGETRESOLUTIONINFO pfnGetResolutionInfo; - PFNGETMARGININFO pfnGetMarginInfo; - PFNBEGINJOB pfnBeginJob; - PFNNEWFRAME pfnNewFrame; /*@@04162001*/ - PFNENDJOB pfnEndJob; - PFNRASTERIZE pfnRasterize; - PFNCREATEDEVICE pfnCreateDevice; - PFNDELETEDEVICE pfnDeleteDevice; - PFNMONODITHER pfnMonoDither; /*@@04162001*/ - PFNGIINIT pfnGIInit; - PFNGITERM pfnGITerm; - unsigned long ulPelSizeCorrection; - - int iVertDots; - int width; - int height; - int iSync; - int iPageNumber; /*@@04162001 */ - int iGSMono; /*@@04252001 */ - int iUseServer; /*@@05092001 */ - int iUseDialog; - FILE *ProxyFile; /*@@05092001 */ - - byte *outbuf; /* Output-Buffer */ - - int iPage; - int iSetup; -} Omni_Dev, - *PDEVSTRUCT; /** Type & Pointer of device-specifics */ - -/* Define data type for this device based on prn_device */ -typedef struct gx_device_omni_s { - gx_device_common; - gx_prn_device_common; - int buffered_page_exists; - long file_offset_to_data; - int copies_printed; - PDEVSTRUCT pDev; /** Omni specific extensions */ -} gx_device_omni; -typedef gx_device_omni omni_device; - -/* Define initializer for device */ -#define omni_device(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\ -{ prn_device_std_margins_body(gx_device_omni, procs, dname,\ - w10, h10, xdpi, ydpi, lm, tm, lm, bm, rm, tm, color_bits, print_page),\ - 0, 0L\ -} - -static int PrintPage (gx_device_printer *pgx_prt_dev, - FILE *prn_stream, - int num_copies); -static int omni_print_page (gx_device_printer *pdev, - FILE *prn_stream); -static int SetupDevice (gx_device *pgxdev, - gs_param_list *plist); -static int OpenDevice (gx_device *pdev); -static int CloseDevice (gx_device *pdev); -static int GetDeviceParams (gx_device *pgxdev, - gs_param_list *plist); -static int BufferPage (gx_device_printer *pgx_prt_dev, - FILE *file, - int num_copies); -static void RenderThread (void *params); -static int StartRenderThread (gdev_prn_start_render_params *params); -static int OpenRenderDevice (gx_device_printer *ppdev); -static void GetSpaceParams (const gx_device_printer *pgx_prt_dev, - gdev_prn_space_params *space_params); - -/* Print-page, parameters and miscellaneous procedures */ -static dev_proc_print_page_copies (PrintPage); -static prn_dev_proc_buffer_page (BufferPage); -static prn_dev_proc_start_render_thread (StartRenderThread); -static dev_proc_open_device (OpenDevice); -static dev_proc_print_page (omni_print_page); -static dev_proc_close_device (CloseDevice); -static dev_proc_get_params (GetDeviceParams); -static dev_proc_put_params (SetupDevice); -static dev_proc_output_page (PrintPageMultiple); -static prn_dev_proc_get_space_params (GetSpaceParams); - -/* 24-bit color. only want 16M colors */ - -static gx_device_procs omni16m_procs = { - OpenDevice, /* open_device */ - NULL, /* get_initial_matrix */ - NULL, /* sync_output */ - gdev_prn_output_page, /* output_page */ - CloseDevice, /* close_device */ - NULL, /* bmp_map_16m_rgb_color,*/ /* map_rgb_color @@04252001 */ - NULL, /* bmp_map_16m_color_rgb,*/ /* map_color_rgb @@04252001 */ - NULL, /** fill_rectangle */ - NULL, /** tile_rectangle */ - NULL, /** copy_mono */ - NULL, /** copy_color */ - NULL, /** draw_line */ - gx_default_get_bits, /* Reads scan lines */ - GetDeviceParams, /** Export parameters, special */ - SetupDevice /** Import parameters, special */ -}; - -gx_device_omni far_data gs_omni_device = - omni_device (omni16m_procs, - "omni", - DEFAULT_WIDTH_10THS, /* 85 x 110 - page physical area non clipped */ - DEFAULT_HEIGHT_10THS, - X_DPI, Y_DPI, /* std resolution - 72 dpi */ - 0,0,0,0, /* margins - need defaults */ - 1, /* Bpp value */ - omni_print_page); /* sync routine for output of raster data */ - -/* ------------------------------------------------------*/ -/* ------------------------------------------------------*/ - -/* Colour mapping code copied from gdevbmpc.c to ensure that - * this driver does not depend on on other, optional source - * files. - */ - -/* Map a r-g-b color to a color index. */ -static gx_color_index -omni_map_16m_rgb_color(gx_device * dev, const gx_color_value cv[]) -{ - - gx_color_value r, g, b; - r = cv[0]; g = cv[1]; b = cv[2]; - return gx_color_value_to_byte(r) + - ((uint) gx_color_value_to_byte(g) << 8) + - ((ulong) gx_color_value_to_byte(b) << 16); -} - -/* Map a color index to a r-g-b color. */ -static int -omni_map_16m_color_rgb(gx_device * dev, gx_color_index color, - gx_color_value prgb[3]) -{ - prgb[2] = gx_color_value_from_byte(color >> 16); - prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff); - prgb[0] = gx_color_value_from_byte(color & 0xff); - return 0; -} - -/* ------------------------------------------------------*/ - -/* Generic routine to send the page to the printer. */ -static int -PrintPageMultiple (gx_device *pDev, int iCopies, int flush) -{ - /* - * HACK: open the printer page with the positionable attribute since - * we need to seek back & forth to support partial rendering. - */ - if ( iCopies > 0 - || !flush - ) - { - int iRet = gdev_prn_open_printer_positionable (pDev, 1, 1); - - if (iRet < 0) - return iRet; - } - - return gdev_prn_output_page(pDev, iCopies, flush); -} - -/* ------------ Writer Instance procedures ---------- */ - -/* Writer's open procedure */ -static int -OpenDevice (gx_device *pdev /* Driver instance to open */) -{ - gx_device_omni * const pwdev = (gx_device_omni *)pdev; - PDEVSTRUCT pDev = pwdev->pDev; - int max_width; - int max_raster; - int min_band_height; - int max_src_image_row; - - if (fDebugOutput) dprintf2 ("OpenDevice: pDev = %p, pDev->hmodOmni = %p\n", pDev, pDev->hmodOmni); - - if (!pDev) - { - eprintf ("\n<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: No pDev in OpenDevice.\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return gs_error_Fatal; - } - - if (!pDev->hmodOmni) - { - eprintf ("\n<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Could not load libomni.so\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return gs_error_Fatal; - } - - if (!pDev->pcoreOmni->cDeviceName[0]) - { - eprintf ("\n<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: -sDeviceName=XXX was not defined\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return gs_error_Fatal; - } - - pDev->iUseServer = 0; - pDev->iPageNumber = 0; - pDev->iUseDialog = 0; - - /* - * Set up device's printer proc vector to point to this driver, since - * there are no convenient macros for setting them up in static template. - */ - if (pDev->iSync) - { - init_async_render_procs (pwdev, - StartRenderThread, - BufferPage, - PrintPage); - } - else - { - /* don't really think this needs to be done but we'll do it anyway */ - set_dev_proc (pdev, sync_output, gx_default_sync_output); - } - - set_dev_proc (pdev, put_params, SetupDevice); - set_dev_proc (pdev, get_params, GetDeviceParams); - - if (!pDev->iGSMono) - { - if (fDebugOutput) dprintf("Remapping color pointers\n"); - - set_dev_proc(pdev, map_rgb_color, omni_map_16m_rgb_color); - set_dev_proc(pdev, map_color_rgb, omni_map_16m_color_rgb); - } - - if (pDev->iSync) - { - set_dev_proc(pdev, output_page, PrintPageMultiple); - pwdev->printer_procs.get_space_params = GetSpaceParams; - pwdev->printer_procs.open_render_device = OpenRenderDevice; - } - - /* - * Determine MAXIMUM parameters this device will have to support over - * lifetime. See comments for GetSpaceParams(). - */ - max_width = DEFAULT_WIDTH_10THS * 60 * 16; /* figure max wid = default @ 600dpi */ - /* multiplied by 2 for 1200 dpi */ - min_band_height = max(1, (DEFAULT_HEIGHT_10THS * 60) / 100); - max_raster = (max_width * pwdev->color_info.depth) / 8; /* doesn't need to be super accurate */ - max_src_image_row = max_width * 3 * 2; - -#ifdef OMNI_ASYNC - if (pDev->iSync) - { - return gdev_prn_async_write_open ((gx_device_printer *)pdev, - max_raster, - min_band_height, - max_src_image_row); - - } - else -#endif - { - return gdev_prn_open (pdev); - } -} - -static int -CloseDevice (gx_device * pdev) -{ - gx_device_omni * const pwdev = (gx_device_omni *)pdev; - PDEVSTRUCT pDev = pwdev->pDev; - - if (fDebugOutput) dprintf2 ("CloseDevice: pDev = %p, pDev->pcoreOmni->pDevice = %p\n", pDev, pDev->pcoreOmni->pDevice); - - if (!pDev) - { - eprintf ("\n<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: No device handle in CloseDevice\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_Fatal); /* handle no pDev */ - } - - if ( pDev->pcoreOmni - && pDev->pcoreOmni->pDevice - && pDev->pfnEndJob - ) - { - pDev->pfnEndJob ((void*)pDev->pCallPtr); - } - - if ( pDev->pcoreOmni - && pDev->pcoreOmni->pszJobOptions - ) - { - gs_free (pDev->memory->non_gc_memory, pDev->pcoreOmni->pszJobOptions, strlen (pDev->pcoreOmni->pszJobOptions) + 1, 1, "Option String"); - } - - if ( pDev->pcoreOmni - && pDev->pcoreOmni->pDevice - && pDev->pfnDeleteDevice - ) - { - pDev->pfnDeleteDevice (pDev->pcoreOmni->pDevice); - pDev->pcoreOmni->pDevice = 0; - } - - if (pDev->pfnGITerm) - { - pDev->pfnGITerm (pDev->pcoreOmni); - } - - if (pDev->pcoreOmni) - { - gs_free (pDev->memory->non_gc_memory, pDev->pcoreOmni, sizeof (core_omni_device), 1, "omni/device"); - pDev->pcoreOmni = 0; - } - - if (pDev->hmodDevice) - { - g_module_close (pDev->hmodDevice); - pDev->hmodDevice = 0; - } - - if (pDev->hmodOmni) - { - g_module_close (pDev->hmodOmni); - pDev->hmodOmni = 0; - } - - return gdev_prn_close (pdev); -} - -/* -------------------------------------------------------------------------*/ -/* */ -/* Function: GetDeviceParams */ -/* */ -/* This function calls back into Ghostscript to set the string values */ -/* so that next time Ghostscript calls SetupDevice, the correct */ -/* values can be pulled back out again */ -/* */ -/* -------------------------------------------------------------------------*/ - -static int -GetDeviceParams (gx_device *pgxdev, gs_param_list *plist) -{ - omni_device *const odev = (omni_device *) pgxdev; - PDEVSTRUCT pDev = odev->pDev; - int iReturnCode = 0; - gs_param_string strdata; - - const char *pszDeviceName = ""; - const char *pszDebug = ""; - const char *pszOther = ""; - const char *pszAsync = ""; - const char *pszMonoDither = ""; - const char *pszServer = ""; - char pszTemp[3]; - unsigned long ulPelSizeCorrection = 100; - bool bPersist = false; - - if (fDebugOutput) dprintf1 ("GetDeviceParams: pDev = %p\n", pDev); - - iReturnCode = gdev_prn_get_params (pgxdev, plist); - - if (pDev) - { - bPersist = true; - pszDeviceName = pDev->pcoreOmni->cDeviceName; - pszDebug = pDev->pcoreOmni->cDebugFile; - pszOther = pDev->pcoreOmni->pszJobOptions; - pszAsync = pDev->cAsyncOpt; - ulPelSizeCorrection = pDev->ulPelSizeCorrection; - pszMonoDither = pDev->cMonoDither; - pszServer = pDev->pcoreOmni->cServer; - } - - if (fDebugOutput) dprintf1 ("GetDeviceParams: pszDeviceName = %s\n", pszDeviceName); - if (fDebugOutput) dprintf1 ("GetDeviceParams: pszDebug = %s\n", pszDebug); - if (fDebugOutput) dprintf1 ("GetDeviceParams: pszOther = %s\n", pszOther); - if (fDebugOutput) dprintf1 ("GetDeviceParams: pszAsync = %s\n", pszAsync); - if (fDebugOutput) dprintf1 ("GetDeviceParams: ulPelSizeCorrection = %ld\n", ulPelSizeCorrection); - if (fDebugOutput) dprintf1 ("GetDeviceParams: pszMonoDither = %s\n", pszMonoDither); - if (fDebugOutput) dprintf1 ("GetDeviceParams: pszServer = %s\n", pszServer); - - strdata.data = pszDeviceName; - strdata.size = strlen(pszDeviceName); - strdata.persistent = bPersist; - iReturnCode = param_write_string(plist,"DeviceName",&strdata); - - strdata.data = pszDebug; - strdata.size = strlen(pszDebug); - strdata.persistent = bPersist; - iReturnCode = param_write_string(plist,"dbgout",&strdata); - - if ( pDev - && pDev->pcoreOmni->pszJobOptions - ) - { - strdata.size = strlen (pszOther); - strdata.data = pszOther; - } - else - { - pszTemp[0] = '\0'; - strdata.size = 0; - strdata.data = pszTemp; - } - - strdata.persistent = bPersist; - iReturnCode = param_write_string(plist,"properties",&strdata); - - strdata.data = pszAsync; - strdata.size = strlen(pszAsync); - strdata.persistent = bPersist; - iReturnCode = param_write_string(plist,"async",&strdata); - - strdata.data = pszMonoDither; - strdata.size = strlen(pszMonoDither); - strdata.persistent = bPersist; - iReturnCode = param_write_string(plist,"monodither",&strdata); - - strdata.data = pszServer; - strdata.size = strlen(pszServer); - strdata.persistent = bPersist; - iReturnCode = param_write_string(plist,"server",&strdata); - - strdata.data = pszServer; - strdata.size = strlen(pszServer); - strdata.persistent = bPersist; - iReturnCode = param_write_string(plist,"jobdialog",&strdata); - - iReturnCode = param_write_long(plist,"PelSizeCorrection",&ulPelSizeCorrection); - - if (fDebugOutput) dprintf1 ("GetDeviceParams returning %d\n", iReturnCode); - - return iReturnCode; -} - -/*****************************************************************************/ -/* */ -/* FUNCTION: SetupDevice */ -/* */ -/* We need to set up our device and job specific information here */ -/* */ -/*****************************************************************************/ - -/* Put device parameters. */ -/* IMPORTANT: async drivers must NOT CLOSE the device while doing put_params.*/ - -static int -SetupDevice (gx_device *pgxdev, gs_param_list *plist) -{ - int iReturnCode, - i; - BOOL bRet; - HWMARGINS hwMargins; - HWRESOLUTION hwRes; - gx_device_omni * const prgxdev = (gx_device_omni *)pgxdev; - PDEVSTRUCT pDev = prgxdev->pDev; - char *pszDeviceLib = 0; - static char cOmnilib[] = "libomni.so"; - static char cDialogName[] = "libomnijobdialog.so"; - static const char *apszLibraryPaths[] = { -#if __WORDSIZE == 64 - "/usr/lib64/ghostscript/", -#else - "/usr/lib/ghostscript/", -#endif - "/usr/lib/Omni/", - "/opt/Omni/bin/", - "/opt/Omni/lib/", - "./", - "" /* give a chance for $LD_LIBRARY_PATH to work*/ - }; - PRINTMODE prtMode; /* definition of printed output Bpp ..*/ - gs_param_string fname; - - if (fDebugOutput) dprintf1 ("SetupDevice: pDev = %p\n", pDev); - - /* Do we have a handle? */ - if (pDev == NULL) - { - PDEVSTRUCT p; - - p = (PDEVSTRUCT)gs_malloc (pgxdev->memory->non_gc_memory, 1, sizeof (Omni_Dev), "omni/instance"); - if (!p) - { - dprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - dprintf ("Error: Failed allocation in SetupDevice\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_VMerror); - } - - pDev = prgxdev->pDev = p; - - memset (pDev, 0, sizeof (Omni_Dev)); - - pDev->pcoreOmni = (core_omni_device *)gs_malloc (pgxdev->memory->non_gc_memory, 1, sizeof (core_omni_device), "omni/device"); - - if (!pDev->pcoreOmni) - { - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Failed allocation in SetupDevice\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_VMerror); - } - - memset (pDev->pcoreOmni, 0, sizeof (core_omni_device)); - - memcpy ((void *)pDev->pcoreOmni->cSignature, (const void *)Signature, 4); - - pDev->pcoreOmni->cbSize = sizeof (core_omni_device); - } - - if (fDebugOutput) dprintf1 ("SetupDevice: pDev->hmodOmni = %p\n", pDev->hmodOmni); - - /* Is the handle initialized? */ - if (!pDev->hmodOmni) - { - #define dimof(a) (sizeof (a)/sizeof (a[0])) - typedef struct _EntryPointList { - char *pszEntryPoint; - gpointer *pfnEntryPoint; - } ENTRYPOINTLIST, *PENTRYPOINTLIST; - ENTRYPOINTLIST aeplEntryPoints[] = { - { "GetPrintModeInfo", (gpointer *)&pDev->pfnGetPrintModeInfo }, - { "GetResolutionInfo", (gpointer *)&pDev->pfnGetResolutionInfo }, - { "GetMarginInfo", (gpointer *)&pDev->pfnGetMarginInfo }, - { "BeginJob", (gpointer *)&pDev->pfnBeginJob }, - { "NewFrame", (gpointer *)&pDev->pfnNewFrame }, - { "EndJob", (gpointer *)&pDev->pfnEndJob }, - { "Rasterize", (gpointer *)&pDev->pfnRasterize }, - { "CreateDevice", (gpointer *)&pDev->pfnCreateDevice }, - { "DeleteDevice", (gpointer *)&pDev->pfnDeleteDevice }, - { "DiffusionDither", (gpointer *)&pDev->pfnMonoDither }, - { "GhostscriptInferfaceInit", (gpointer *)&pDev->pfnGIInit }, - { "GhostscriptInferfaceTerm", (gpointer *)&pDev->pfnGITerm } - }; - bool fFailure = FALSE; - int i; - - pDev->ulPelSizeCorrection = 100; - - for (i = 0; i < sizeof (apszLibraryPaths)/sizeof (apszLibraryPaths[0]) && !pDev->hmodOmni; i++) - { - pszDeviceLib = (char *)gs_malloc (pDev->memory->non_gc_memory, 1, - strlen (cOmnilib) - + strlen (apszLibraryPaths[i]) - + 1, - "Devicestring"); - if (pszDeviceLib) - { - gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); - - pDev->hmodOmni = g_module_open (pszDeviceLib, (GModuleFlags)0); - - if (fDebugOutput) dprintf2 ("SetupDevice: Trying to load %s = %p\n", pszDeviceLib, pDev->hmodOmni); - } - gs_free (pDev->memory->non_gc_memory, pszDeviceLib, strlen (pszDeviceLib) + 1, 1, "Devicestring"); - } - - if (!pDev->hmodOmni) - { - GModule *pModule = 0; - - /* Failure! */ - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Could not load libomni.so\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - for (i = 0; i < sizeof (apszLibraryPaths)/sizeof (apszLibraryPaths[0]) && !pDev->hmodOmni; i++) - { - pszDeviceLib = (char *)gs_malloc (pDev->memory->non_gc_memory, 1, - strlen (cOmnilib) - + strlen (apszLibraryPaths[i]) - + 1, - "Devicestring"); - if (pszDeviceLib) - { - gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cOmnilib); - - pModule = g_module_open (pszDeviceLib, (GModuleFlags)0); - - if (!pModule) - { - eprintf2 ("Error: Loading \"%s\" returns \"%s\"\n", pszDeviceLib, g_module_error ()); - } - else - { - g_module_close (pModule); - } - } - gs_free (pDev->memory->non_gc_memory, pszDeviceLib, strlen (pszDeviceLib) + 1, 1, "Devicestring"); - } - - return 1; - } - - for (i = 0; i < (int)dimof (aeplEntryPoints); i++) - { - g_module_symbol (pDev->hmodOmni, - aeplEntryPoints[i].pszEntryPoint, - aeplEntryPoints[i].pfnEntryPoint); - - if (!*aeplEntryPoints[i].pfnEntryPoint) - { - if (!fFailure) - { - eprintf ("\n<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - } - - eprintf1 ("Error: Could not load required entry point \"%s\" from libomni.so\n", aeplEntryPoints[i].pszEntryPoint); - - fFailure = TRUE; - } - - if (fDebugOutput) - dprintf2 ("SetupDevice: g_module_symbol (%s) = %p\n", - aeplEntryPoints[i].pszEntryPoint, - *aeplEntryPoints[i].pfnEntryPoint); - } - - if ( !pDev->pfnCreateDevice - || !pDev->pfnBeginJob - || !pDev->pfnNewFrame - || !pDev->pfnEndJob - || !pDev->pfnRasterize - || !pDev->pfnGetPrintModeInfo - || !pDev->pfnGetResolutionInfo - || !pDev->pfnGetMarginInfo - || !pDev->pfnMonoDither - ) - { - /* Failure! */ - g_module_close (pDev->hmodOmni); - pDev->hmodOmni = 0; - - return 1; - } - } - - /* device name in structure*/ - if (!pDev->pcoreOmni->cDeviceName[0]) - { - memset (&fname, 0, sizeof (fname)); - iReturnCode = param_read_string (plist, "DeviceName", &fname); - if (fDebugOutput) dprintf2 ("param_read_string of DeviceName = %d, fname.size = %d\n", iReturnCode, fname.size); - - if ( (iReturnCode < 1) - && (fname.size > 0) - ) - { - memcpy (pDev->pcoreOmni->cDeviceName, fname.data, fname.size); - pDev->pcoreOmni->cDeviceName[fname.size] = '\0'; - } - } - - /* set debugging file name */ - if (!pDev->pcoreOmni->cDebugFile[0]) - { - memset (&fname, 0, sizeof (fname)); - iReturnCode = param_read_string (plist, "dbgout", &fname); - if (fDebugOutput) dprintf2 ("param_read_string of dbgout = %d, fname.size = %d\n", iReturnCode, fname.size); - - if ( (iReturnCode < 1) - && (fname.size > 0) - ) - { - memcpy (pDev->pcoreOmni->cDebugFile, fname.data, fname.size); - pDev->pcoreOmni->cDebugFile[fname.size] = '\0'; - } - } - - /* set Async option */ - if (!pDev->cAsyncOpt[0]) - { - memset (&fname, 0, sizeof (fname)); - iReturnCode = param_read_string (plist, "async", &fname); - if (fDebugOutput) dprintf2 ("param_read_string of async = %d, fname.size = %d\n", iReturnCode, fname.size); - if ( (iReturnCode < 1) - && (fname.size > 0) - ) - { - memcpy (pDev->cAsyncOpt, fname.data, fname.size); - pDev->cAsyncOpt[fname.size] = '\0'; - if ( !strcmp (pDev->cAsyncOpt, "TRUE") - || !strcmp (pDev->cAsyncOpt, "true") - ) - { - pDev->iSync = 1; - } - else - { - pDev->iSync = 0; - } - } - } - - iReturnCode = param_read_long (plist, "PelSizeCorrection", &pDev->ulPelSizeCorrection); - if (fDebugOutput) dprintf2 ("param_read_long of PelSizeCorrection = %d, ulPelSizeCorrection = %ld\n", iReturnCode, pDev->ulPelSizeCorrection); - - /* - * Set user options for the job - */ - if (!pDev->pcoreOmni->pszJobOptions) - { - memset (&fname, 0, sizeof (fname)); - iReturnCode = param_read_string (plist, "properties", &fname); - if (fDebugOutput) dprintf2 ("param_read_string of properties = %d, fname.size = %d\n", iReturnCode, fname.size); - - if ( (iReturnCode < 1) - && (fname.size > 0) - ) - { - if (!pDev->pcoreOmni->pszJobOptions) - pDev->pcoreOmni->pszJobOptions = (char *)gs_malloc (pDev->memory->non_gc_memory, 1, fname.size + 1, "Option String"); - memcpy (pDev->pcoreOmni->pszJobOptions, fname.data, fname.size); - pDev->pcoreOmni->pszJobOptions[fname.size] = '\0'; - } - } - - /* Set user options for monodither by GS */ - if (!pDev->cMonoDither[0]) - { - memset (&fname, 0, sizeof (fname)); - iReturnCode = param_read_string (plist, "monodither", &fname); - if (fDebugOutput) dprintf2 ("param_read_string of monodither = %d, fname.size = %d\n", iReturnCode, fname.size); - - if ( (iReturnCode < 1) - && (fname.size > 0) - ) - { - memcpy (pDev->cMonoDither, fname.data, fname.size); - pDev->cMonoDither[fname.size] = '\0'; - - if (!strcmp (pDev->cMonoDither, "GSMONO")) - { - if (fDebugOutput) dprintf ("turning on GSMONO dither\n"); - - pDev->iGSMono = 1; - } - else - { - pDev->iGSMono = 0; - } - } - } - - /* Set user options for client / server function */ - if (!pDev->pcoreOmni->cServer[0]) - { - memset (&fname, 0, sizeof (fname)); - iReturnCode = param_read_string (plist, "server", &fname); - if (fDebugOutput) dprintf2 ("param_read_string of server = %d, fname.size = %d\n", iReturnCode, fname.size); - - if ( (iReturnCode < 1) - && (fname.size > 0) - ) - { - memcpy (pDev->pcoreOmni->cServer, fname.data, fname.size); - - pDev->pcoreOmni->cServer[fname.size] = '\0'; - - dprintf1 ("Utilizing Server - %s \n", pDev->pcoreOmni->cServer);; - - pDev->iUseServer = 1; - } - } - - /* - * Set user options for dialog function - */ - if (!pDev->iUseDialog) - { - memset (&fname, 0, sizeof (fname)); - iReturnCode = param_read_string (plist, "jobdialog", &fname); - if (fDebugOutput) dprintf2 ("param_read_string of jobdialog = %d, fname.size = %d\n", iReturnCode, fname.size); - - if (!iReturnCode) - { - if (fDebugOutput) dprintf ("Utilizing dialog\n"); - - pDev->iUseDialog = 1; - } - } - - if ( pDev->pcoreOmni->cDeviceName[0] - && pDev->iSetup != 1 - ) - { - /* create a device based on the user supplied inputs */ - if (fDebugOutput) dprintf ("setting following options on CreateDevice\n"); - if (fDebugOutput) dprintf1 ("DeviceName = %s\n", pDev->pcoreOmni->cDeviceName ); - if (fDebugOutput) dprintf1 ("pszJobOptions = %s\n", pDev->pcoreOmni->pszJobOptions); - if (fDebugOutput) dprintf1 ("debug parameter = %s \n", pDev->pcoreOmni->cDebugFile ); - - if (pDev->iUseDialog) - { - int iLength = 0; - char *pszSelectedJobProperties; - PFNGETOMNIJOBPROPERTIES pfnJobDialog; - PFNFREEOMNIJOBPROPERTIES pfnFreeDialogMemory; - GModule *pModule = 0; - - for (i = 0; i < sizeof (apszLibraryPaths)/sizeof (apszLibraryPaths[0]) && !pModule; i++) - { - pszDeviceLib = (char *)gs_malloc (pDev->memory->non_gc_memory, 1, - strlen (cDialogName) - + strlen (apszLibraryPaths[i]) - + 1, - "Devicestring"); - pszDeviceLib[0] = '\0'; - - if (pszDeviceLib) - { - gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); - - if (fDebugOutput) dprintf1 ("attempting to load - %s\n", pszDeviceLib); - - pModule = g_module_open (pszDeviceLib, (GModuleFlags)0); - } - gs_free (pDev->memory->non_gc_memory, pszDeviceLib, strlen (pszDeviceLib) + 1, 1, "Devicestring"); - } - - if (!pModule) - { - /* Print the error messages! */ - eprintf ("\n<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf1 ("Error: Could not load %s\n", cDialogName); - - for (i = 0; i < sizeof (apszLibraryPaths)/sizeof (apszLibraryPaths[0]) && !pModule; i++) - { - pszDeviceLib = (char *)gs_malloc (pDev->memory->non_gc_memory, 1, - strlen (cDialogName) - + strlen (apszLibraryPaths[i]) - + 1, - "Devicestring"); - pszDeviceLib[0] = '\0'; - - if (pszDeviceLib) - { - gs_sprintf (pszDeviceLib, "%s%s", apszLibraryPaths[i], cDialogName); - - pModule = g_module_open (pszDeviceLib, (GModuleFlags)0); - - if (!pModule) - { - eprintf2 ("Error: Loading \"%s\" returns \"%s\"\n", pszDeviceLib, g_module_error ()); - } - else - { - g_module_close (pModule); - } - } - gs_free (pDev->memory->non_gc_memory, pszDeviceLib, strlen (pszDeviceLib) + 1, 1, "Devicestring"); - } - } - else - { - g_module_symbol (pModule, "GetOmniJobProperties", (gpointer *)&pfnJobDialog); - - if (pfnJobDialog) - { - pszSelectedJobProperties = pDev->pcoreOmni->pszJobOptions; - - pfnJobDialog (pDev->pcoreOmni->cDeviceName, &pszSelectedJobProperties); - - if (pDev->pcoreOmni->pszJobOptions) - { - gs_free (pDev->memory->non_gc_memory, pDev->pcoreOmni->pszJobOptions, strlen (pDev->pcoreOmni->pszJobOptions) + 1, 1, "Option String"); - pDev->pcoreOmni->pszJobOptions = 0; - } - - iLength = strlen (pszSelectedJobProperties); - - pDev->pcoreOmni->pszJobOptions = (char *)gs_malloc (pDev->memory->non_gc_memory, 1, iLength + 1, "Option String"); - - strcpy (pDev->pcoreOmni->pszJobOptions, pszSelectedJobProperties); - - if (fDebugOutput) dprintf1 ("options = %s\n", pDev->pcoreOmni->pszJobOptions); - - g_module_symbol (pModule, "FreeOmniJobProperties", (gpointer *)&pfnFreeDialogMemory); - - if (pfnFreeDialogMemory) - { - pfnFreeDialogMemory (&pszSelectedJobProperties); - - if (fDebugOutput) dprintf ("Freeing Dialog Memory\n"); - } - } - else - { - eprintf1 ("Error: Unable to find <> in <<%s>>.\n", cDialogName); - } - - g_module_close (pModule); - } - } - - if (pDev->iUseServer) - { - pDev->pcoreOmni->bPDCDevice = true; - } - - /* get the omni version in case we need it */ - if (pDev->pfnGIInit) - { - pDev->pfnGIInit ((void*)pDev->pcoreOmni); - - if (fDebugOutput) dprintf1 ("core_omni_device size = %d\n",pDev->pcoreOmni->cbSize); - if (fDebugOutput) dprintf1 ("GI version = %s\n",pDev->pcoreOmni->cVersion); - - pDev->pCallPtr = (void *)pDev->pcoreOmni; - } - else - { - pDev->pCallPtr = (void *)pDev->pcoreOmni->pDevice; - } - - pDev->pcoreOmni->pDevice = pDev->pfnCreateDevice (pDev->pcoreOmni, - (void **)&pDev->hmodDevice, - pDev->iUseServer); - - if (!pDev->pcoreOmni->pDevice) - { - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Unable create a omni device\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_Fatal); /* fail if no device was created */ - } - - if (fDebugOutput) dprintf1 ("Device = %p\n", pDev->pcoreOmni->pDevice); - if (fDebugOutput) dprintf1 ("Omni version = %s\n", pDev->pcoreOmni->cOmniVersion); - if (fDebugOutput) dprintf1 ("Device = \"%s\"\n", pDev->pcoreOmni->cDeviceName); - - bRet = pDev->pfnGetPrintModeInfo ((void*)pDev->pCallPtr, &prtMode); - - if (fDebugOutput) dprintf1 ("GetPrintModeInfo returns %d\n", bRet); - if (fDebugOutput) dprintf1 ("GetPrintModeInfo.iBitCount = %d\n", prtMode.iBitCount); - if (fDebugOutput) dprintf1 ("GetPrintModeInfo.iPlanes = %d\n", prtMode.iPlanes); - - if (bRet) - { - /* turn off Ghostscript mono if we are not in mono mode */ - if ( (prtMode.iBitCount > 1) - && pDev->iGSMono - ) - { - if (fDebugOutput) dprintf1 ("Turning off GSMONO - prtMode.iBitCount = %d\n", prtMode.iBitCount); - pDev->iGSMono = 0; - } - } - /* this routine is called multiple times */ - pDev->iSetup = 1; /* don't go setting up new devices */ - - /* get the hardware resolution information */ - - bRet = pDev->pfnGetResolutionInfo ((void*)pDev->pCallPtr, &hwRes); - - if (!bRet) - { - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Failed GetResolutionInfo in SetupDevice\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_Fatal); - } - - /* get the hardware page margins information */ - - bRet = pDev->pfnGetMarginInfo ((void*)pDev->pCallPtr, &hwMargins); - - if (!bRet) - { - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Failed GetMarginInfo in SetupDevice\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_Fatal); - } - - if (fDebugOutput) dprintf1 ("GetMarginInfo returns %d\n", bRet); - if (fDebugOutput) dprintf1 ("GetMarginInfo.fLeftClip = %f\n", hwMargins.fLeftClip); - if (fDebugOutput) dprintf1 ("GetMarginInfo.fBottomClip = %f\n", hwMargins.fBottomClip); - if (fDebugOutput) dprintf1 ("GetMarginInfo.fRightClip = %f\n", hwMargins.fRightClip); - if (fDebugOutput) dprintf1 ("GetMarginInfo.fTopClip = %f\n", hwMargins.fTopClip); - if (fDebugOutput) dprintf1 ("GetMarginInfo.fxWidth = %f\n", hwMargins.fxWidth); - if (fDebugOutput) dprintf1 ("GetMarginInfo.fyHeight = %f\n", hwMargins.fyHeight); - - /* - * We have to let GS know about our page and resolution parameters - */ - - /* setup the width and height of the page */ - prgxdev->width = (int)hwMargins.fxWidth; - prgxdev->height = (int)hwMargins.fyHeight; - prgxdev->MediaSize[1] = (hwMargins.fyHeight/(float)hwRes.yRes)*72.0; - prgxdev->MediaSize[0] = (hwMargins.fxWidth/(float)hwRes.xRes)*72.0; - - /* does not seem like pels works correctly for margins so lets set the margins */ - /* using points instead */ - - /* left margin */ - prgxdev->HWMargins[0] = (float)hwMargins.fLeftClip/25400.0 *72.0; - - /* bottom margin */ - prgxdev->HWMargins[1] = (float)hwMargins.fBottomClip/25400.0 *72.0; - - /* right margin */ - prgxdev->HWMargins[2] = (float)hwMargins.fRightClip/25400.0 *72.0; - - /* top margin */ - prgxdev->HWMargins[3] = (float)hwMargins.fTopClip/25400.0 *72.0; - - /* set x resolution */ - prgxdev->HWResolution[0] = (float)hwRes.xRes; - - /* set y resolution */ - prgxdev->HWResolution[1] = (float)hwRes.yRes; - - prgxdev->pDev->iVertDots = (float)hwRes.fScanDots; /* fill in the scan line */ - - if (fDebugOutput) dprintf1 ("left margin pts = %f \n", prgxdev->HWMargins[0]); - if (fDebugOutput) dprintf1 ("bottom margin pts = %f \n", prgxdev->HWMargins[1]); - if (fDebugOutput) dprintf1 ("right margin pts = %f \n", prgxdev->HWMargins[2]); - if (fDebugOutput) dprintf1 ("top margin pts = %f \n", prgxdev->HWMargins[3]); - - if (!pDev->iGSMono) - { - /* 1,1,1,0,2,0 - mono */ - /* 3, 24,255,255,5,5 - color */ - if (fDebugOutput) dprintf1 ("depth = %d \n", prgxdev->color_info.depth ); - if (fDebugOutput) dprintf1 ("num_comp = %d \n", prgxdev->color_info.num_components ); - if (fDebugOutput) dprintf1 ("max_gray = %d \n", prgxdev->color_info.max_gray ); - if (fDebugOutput) dprintf1 ("max_color = %d \n", prgxdev->color_info.max_color ); - if (fDebugOutput) dprintf1 ("dither_grays = %d \n", prgxdev->color_info.dither_grays ); - if (fDebugOutput) dprintf1 ("dither_colors = %d \n", prgxdev->color_info.dither_colors ); - - prgxdev->color_info.depth = 24; - prgxdev->color_info.num_components = 3; - prgxdev->color_info.max_gray = 255; - prgxdev->color_info.max_color = 255; - prgxdev->color_info.dither_grays = 5; - prgxdev->color_info.dither_colors = 5; - } - } - - iReturnCode = gdev_prn_put_params ((gx_device *)prgxdev, plist); - - if (fDebugOutput) dprintf1 ("SetupDevice returning %d\n", iReturnCode); - - return iReturnCode; /* likely not be a failure */ -} - -static int -omni_print_page (gx_device_printer *pdev, FILE *prn_stream) -{ - return PrintPage (pdev, prn_stream, 1); -} - -/* ------------------------------------------------------*/ -/* ------------------------------------------------------*/ - -static int -PrintPage (gx_device_printer *pgx_prt_dev, FILE *prn_stream, int num_copies) -{ - gx_device_omni * const pasyncDev = (gx_device_omni *)pgx_prt_dev; - gx_device * const pgx_dev = (gx_device *)pgx_prt_dev; - uint uiLineSize = gdev_prn_raster (pgx_prt_dev); /* Raster line size in bytes*/ - - /* BMP scan lines need to be padded to 32 bits. */ - - /* - * The following variables are uses for outputting the bitmap information - */ - uint uiBytesPerLine = uiLineSize + (-uiLineSize & 3); /*actual raster line size used for row */ - - byte *pBitmapMem = NULL; /* bitmap memory for the bitmap band */ - bool bRet; - RECTL rectPageLocation; - SIZEL sizelPage; - ULONG ulBandLength; /* number of scan-lines to match the memory threshold for a band */ - int iBytesToAlloc; - - int iYBand; - int code = 0; - int y, - iNumColors; - byte *pGSData = 0; - byte *raster_data; - - /* MONO */ - byte *pMonoData = NULL; - DIFFUSIONDITHERINFO DiffInfo; - byte *pBuffer = NULL; - IMAGEINFOS ImageInfo; - POINTL ptlBounds; - POINTL ptlTrgBounds; - - PRINTMODE prtMode; /* definition of printed output Bpp .. */ - - /* Get things setup to call into the driver code */ - BITMAPINFO2 *pbmi; - - PDEVSTRUCT pDev = pasyncDev->pDev; - - ptlBounds.x = 0; - ptlBounds.y = 0; - ptlTrgBounds.x = 0; - ptlTrgBounds.y = 0; - - if ( !pDev - || !pDev->pcoreOmni->pDevice - ) - { - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: -sDeviceName=XXX is not specified\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_Fatal); - } - - pDev->iPage++; - pDev->iPageNumber++; /*keep track of the page @@04162001 */ - - bRet = pDev->pfnGetPrintModeInfo ((void*)pasyncDev->pDev->pCallPtr, &prtMode); - - iNumColors = 1 << prtMode.iBitCount; - - /* Allocate a full bitmapinfo2 and bitmap header message */ - iBytesToAlloc = sizeof (BITMAPINFO2); - if (256 >= iNumColors) - { - iBytesToAlloc += (iNumColors - 1) * sizeof (RGB2); - } - - pbmi = (PBITMAPINFO2)gs_malloc (pDev->memory->non_gc_memory, 1, iBytesToAlloc, "Bmpi Memory"); - if (!pbmi) - { - eprintf("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf("Error: Failed allocation of pbmi in PrintPage\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_VMerror); - } - - pbmi->cbFix = sizeof(BITMAPINFO2); /* Length of fixed portion of structure?? */ - - if (256 >= iNumColors) /* must be 16 or 24 bit */ - { - if (iNumColors == 2) - { - memset (&DiffInfo, 0xFF, sizeof (DiffInfo)); - memset (&ImageInfo, 0xFF, sizeof (ImageInfo)); - - DiffInfo.ulLength = sizeof (DiffInfo); - DiffInfo.ulType = GDM_MATRIX_DITHER; - DiffInfo.fOptions = 0; - DiffInfo.ulIntensity = 80; - DiffInfo.bRedWt = 30; /*25 */ - DiffInfo.bGreenWt = 50; /*60 */ - DiffInfo.bBlueWt = 20; /*15 */ - DiffInfo.bPad = 0; - - if (!pDev->iGSMono) - { - pbmi->argbColor[0].bBlue = 0xFF; /* background */ - pbmi->argbColor[0].bRed = 0xFF; - pbmi->argbColor[0].bGreen = 0xFF; - pbmi->argbColor[1].bBlue = 0x00; /* foreground */ - pbmi->argbColor[1].bRed = 0x00; - pbmi->argbColor[1].bGreen = 0x00; - } - else - { - pbmi->argbColor[1].bBlue = 0xFF; /* background */ - pbmi->argbColor[1].bRed = 0xFF; - pbmi->argbColor[1].bGreen = 0xFF; - pbmi->argbColor[0].bBlue = 0x00; /* foreground */ - pbmi->argbColor[0].bRed = 0x00; - pbmi->argbColor[0].bGreen = 0x00; - } - - ImageInfo.pptlSrc = &ptlBounds; /* rectangle extents */ - ImageInfo.pptlDst = &ptlTrgBounds; /* rectangle extents */ - ImageInfo.ulSrcBpp = 24; - ImageInfo.ulSrcBytesPerLine = uiBytesPerLine; /* src bytes per line */ - ImageInfo.ulcSrcClrs = 0; - ImageInfo.ulSrcClrType = 0; - ImageInfo.pargb2Src = 0; /* if srcBPP != 24 */ - ImageInfo.ulTrgBpp = 1; - ImageInfo.ulTrgBytesPerLine = pasyncDev->width + (-pasyncDev->width & 31); - ImageInfo.ulTrgBytesPerLine /= 8; - ImageInfo.ulcTrgClrs = 2; - ImageInfo.ulTrgClrType = 0; - ImageInfo.pargb2Trg = NULL; - ImageInfo.ulOptions = 0; /* options */ - ImageInfo.ulPelSizeCorrection = pDev->ulPelSizeCorrection; - - ptlBounds.x = pasyncDev->width; /* Bounding rectangle for input bitmap */ - ptlTrgBounds.x = pasyncDev->width; /* Bounding rectangle for output bitmap */ - } - else - { - /* - * add for 256 color support -- @TBD ... - */ - } - } - /* set the bitmap width to match the page */ - - pbmi->cx = pgx_prt_dev->width; - - if (fDebugOutput) dprintf ("***************************************************************\n"); - if (fDebugOutput) dprintf1 ("ulTrgBytesPerLine = %ld\n", ImageInfo.ulTrgBytesPerLine); - if (fDebugOutput) dprintf1 ("ulBytesPerLine = %d\n", uiBytesPerLine); - if (fDebugOutput) dprintf1 ("ulLineSize = %d\n", uiLineSize); - if (fDebugOutput) dprintf1 ("width = %d\n", pgx_prt_dev->width); - if (fDebugOutput) dprintf1 ("height = %d\n", pgx_prt_dev->height); - if (fDebugOutput) dprintf ("***************************************************************\n"); - - pbmi->cPlanes = prtMode.iPlanes; /* Number of bit planes */ - pbmi->cBitCount = prtMode.iBitCount; /* number of bits per pel */ - - /* - * BMP format is single page, so discard all but 1st printable page - * This logic isn't quite right, since we can't truncate file if - * num_pages == 0. - */ - if (pasyncDev->copies_printed > 0) - return 0; - - if (pDev->iSync) - { - /* If there's data in buffer, need to process w/overlays */ - if (pasyncDev->buffered_page_exists) - { - code = BufferPage(pgx_prt_dev, prn_stream, num_copies); - goto done; - } - } - - pGSData = (byte *)gs_malloc (pDev->memory->non_gc_memory, uiBytesPerLine, 1, "bmp file buffer"); - - if (pGSData == 0) - /* can't allocate row buffer */ - return_error (gs_error_VMerror); - - /* seek to the file's end */ - if (pDev->iPage == 1) - { - fseek (prn_stream, 0L, SEEK_SET); - } - - /* need to calculate the correct bandsize needed for the device */ - ulBandLength = FindBandSize (pasyncDev->height, - pasyncDev->width, - 24, /* always use 24 bits for source bitmap */ - pbmi->cPlanes, - pasyncDev->pDev->iVertDots, - 8000*1024); /*eight meg buffer */ - - pBitmapMem = (byte *) gs_malloc (pDev->memory->non_gc_memory, 1, uiBytesPerLine * ulBandLength, "Bitmap Memory"); - - if(!pBitmapMem) - { - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Failed allocation of pBitmapMem in PrintPage\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_VMerror); - } - - /* is the band bigger than the page ? */ - - sizelPage.cx = pasyncDev->width; - sizelPage.cy = pasyncDev->height; - - ulBandLength = ulBandLength >=sizelPage.cy ? sizelPage.cy : ulBandLength; - - if (pBitmapMem) - { - memset (pBitmapMem, 0xFF, uiBytesPerLine * ulBandLength ); /* memset the memory to white? maybe zero */ - } - else - { - eprintf("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf("Error: Bitmap memory alloc Failed\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_VMerror); - } - - /* Do initial setup for Rasterize for dithering work on the page. */ - - rectPageLocation.xLeft = 0; - rectPageLocation.xRight = pasyncDev->width; - - if (pDev->iPageNumber == 1) - { - pDev->pcoreOmni->pfpOut = prn_stream; - - pDev->pfnBeginJob ((void*)pasyncDev->pDev->pCallPtr, prn_stream); - } - else - { - pDev->pfnNewFrame ((void*)pasyncDev->pDev->pCallPtr); - } - -/* rectPageLocation.yTop = rectPageLocation.yBottom = 0; @@10172000 */ - rectPageLocation.yTop = pasyncDev->height-1; /* @@10172000 */ - - /* - * Banding Implementation based on bandsize - need to put bits in place so that we can - * tell if this is a top to down or bottom to top printer. - */ - { - /*BEGIN BLOCK for Banding code */ - -/* int iCurTop = 0, iCurBot = 0; @@10172000 */ - - /* - * Since this band needs to be flipped, we need to get a pointer to the top of memory - * so that we can copy from the top down into the band - * We also need to seek to the end of the file because this type of printer needs the - * last lines in the bitmap sent first - */ - - byte * pBitmapTop = pBitmapMem + ((ulBandLength-1) * uiBytesPerLine); - - iYBand = 0; - - /* Call DiffusionDither to setup pBuffer - quick in and out @@04062001 */ - if (!pDev->iGSMono) - pDev->pfnMonoDither (&DiffInfo, - &ImageInfo, - &pBuffer, - (unsigned long)GDM_DITHER_BEGIN); - - /* Go through the bitmap that we have been given */ - for (y = pasyncDev->height - 1; y >= 0; y--) - { - if ( (iYBand < ulBandLength) - && ((code = dev_proc(pgx_dev, get_bits)(pgx_dev, pasyncDev->height - 1 - y, pGSData, &raster_data)) >= 0) - && (y != 0) - ) - { - memcpy (pBitmapTop - (iYBand * uiBytesPerLine), raster_data, uiBytesPerLine); - - iYBand++; /* keep track of lines in the band */ - } - else - { - if ( (code < 0) - && (y > 0) - ) /* add back in the line we failed to get if an error was returned from get_bits */ - { - if (iYBand != ulBandLength) - { - y++; - continue; - } - } - - /* we always decrement y when we come through here even if this is just a complete band */ - if (iYBand == ulBandLength) - y++; - - /* we currently support 24bit or mono so if this is the mono case, allocate memory to be */ - /* used for the gray-scaled bitmap buffer */ - if (!pDev->iGSMono) - { - if (prtMode.iBitCount < 16) - { - pMonoData = (byte *)gs_malloc (pDev->memory->non_gc_memory, 1, iYBand * ImageInfo.ulTrgBytesPerLine, "Mono Memory"); - - if (pMonoData) - { - memset (pMonoData, 0xFF, iYBand * ImageInfo.ulTrgBytesPerLine ); - } - else - { - eprintf ("<<<<<<<<<<<<<<<<<<<<<< ERROR >>>>>>>>>>>>>>>>>>>>>>>\n\n"); - eprintf ("Error: Failed allocation of pMonoData in PrintPage\n"); - if (fDebugOutput) lprintf ("error was here.\n"); - - return_error (gs_error_VMerror); - } - - ImageInfo.pptlSrc->y = ImageInfo.pptlDst->y = iYBand; /* exclusive?? */ - ImageInfo.pbSrcBits = pBitmapTop - ((iYBand-1) * uiBytesPerLine); /* pointer to src image data */ - ImageInfo.pbTrgBits = pMonoData; /* pointer to dst image data */ - - /* Call DiffusionDither to generate a gray-scaled image from our 24bit bitmap */ - - pDev->pfnMonoDither (&DiffInfo, &ImageInfo, &pBuffer, (unsigned long) 0); - } - } - - pbmi->cy = iYBand; - - /* set the page location to account for the new band size (cy) */ - - rectPageLocation.yBottom = rectPageLocation.yTop - pbmi->cy ; /* @@10172000 */ - - /* If this in a mono device, we need to send the mono data to the device and */ - /* not the color */ - - if ( pMonoData - && !pDev->iGSMono - ) - { - pDev->pfnRasterize ((void*)pasyncDev->pDev->pCallPtr, - pMonoData, - pbmi, - &sizelPage, - &rectPageLocation, - BITBLT_BITMAP); - - /* We're done with the mono band */ - /* now free up the mono buffer so we can get clean data buffer if more lines are to be */ - /* gray-scaled */ - gs_free (pDev->memory->non_gc_memory, (char *)pMonoData, iYBand * ImageInfo.ulTrgBytesPerLine, 1, "Mono Memory"); - - pMonoData = NULL; - } - else - { /* non-mono device -- Send the rgb bitmap to the dither and rasterize routines */ - if (fDebugOutput) dprintf3 ("rendering band lines %d - %d w/%d \n", (int)rectPageLocation.yTop, (int)rectPageLocation.yBottom, iYBand); - - if (fDebugOutput) dprintf ("***************************************************************\n"); - if (fDebugOutput) dprintf ("***************************************************************\n"); - if (fDebugOutput) dprintf1 ("Number of lines in band = %d\n", iYBand); - if (fDebugOutput) dprintf1 ("rectPageLocation - Top = %ld\n", rectPageLocation.yTop); - if (fDebugOutput) dprintf1 ("rectPageLocation - Bot = %ld\n", rectPageLocation.yBottom); - if (fDebugOutput) dprintf ("***************************************************************\n"); - if (fDebugOutput) dprintf ("***************************************************************\n"); - - pDev->pfnRasterize ((void*)pasyncDev->pDev->pCallPtr, - pBitmapTop - ((iYBand-1) * uiBytesPerLine), - pbmi, - &sizelPage, - &rectPageLocation, - BITBLT_BITMAP); - /* memset the memory to white */ - memset (pBitmapMem, 0xFF, uiBytesPerLine * ulBandLength); - } - - /* - * implemented based on the number of lines sent to the - * printer and not based on the bandsize - */ - - rectPageLocation.yTop -= iYBand; - - iYBand = 0; - } - } - - if (!pDev->iGSMono) - pDev->pfnMonoDither (&DiffInfo, - &ImageInfo, - &pBuffer, - (unsigned long)GDM_DITHER_END); - - pBuffer = NULL; - } /*END BLOCK*/ - -done: - - gs_free (pDev->memory->non_gc_memory, (char *) pBitmapMem, uiBytesPerLine * ulBandLength, 1, "Bitmap Memory"); - dprintf ("Page Completed\n"); - - gs_free (pDev->memory->non_gc_memory, (char *)pGSData, uiBytesPerLine, 1, "bmp file buffer"); - gs_free (pDev->memory->non_gc_memory, (char *)pbmi, uiBytesPerLine, 1, "Bpmi Memory"); - - /******************************************************************/ - /* Note: @@08162000 */ - /* GS has at least two threads for doing output on async devices.*/ - /* There is a writer and a render thread running at one time and */ - /* each have their own PageCount values. The PageCount on the */ - /* writer thread gets updated but the render thread (us) does */ - /* not receive the update. It looks like there needs to be a */ - /* way to update the thread's device structure that is doing the */ - /* output with the new value when PageCount is changed. */ - /* If the thread doing the rasterizing queries the PageCount */ - /* value (calling put_params from inside of gxclrast.c) it will */ - /* stop rendering the page -- BAD.... */ - /* There needs to be a way to synchronize the two threads so that*/ - /* when the writer's thread actually updates the PageCount value */ - /* in both threads device structures get updated so we don't */ - /* stop rasterizing the page. */ - /* */ - /* | | | | */ - /* V V V V */ - /******************************************************************/ - pgx_prt_dev->PageCount = pDev->iPage - 1; - - if (pasyncDev->copies_printed > 0) - { - pasyncDev->copies_printed = num_copies; - } - - pasyncDev->buffered_page_exists = 0; - - return code; -} - -/* -------------- Renderer instance procedures ----------*/ - -/* Thread to do rendering, started by StartRenderThread */ -static void -RenderThread (void *params) -{ -#ifdef OMNI_ASYNC - gdev_prn_async_render_thread ((gdev_prn_start_render_params *)params); -#endif -} - -/* ------------------------------------------------------*/ -/* ------------------------------------------------------*/ - -static int /* rets 0 ok, -ve error if couldn't start thread */ -StartRenderThread (gdev_prn_start_render_params *params) -{ - return gp_create_thread(RenderThread, params); -} - -/* ------------------------------------------------------*/ -/* ------------------------------------------------------*/ - -static int -OpenRenderDevice (gx_device_printer *ppdev) -{ - gx_device_omni * const pasyncDev = (gx_device_omni *)ppdev; - - /* Do anything that needs to be done at open time here... */ - pasyncDev->copies_printed = 0; - - /* Cascade down to the default handler */ -#ifdef OMNI_ASYNC - return gdev_prn_async_render_open(ppdev); -#else - return gs_note_error(gs_error_undefined); -#endif -} - -/* ------------------------------------------------------*/ -/* ------------------------------------------------------*/ - -/* Buffer a (partial) rasterized page & optionally print result multiple times. */ -static int -BufferPage (gx_device_printer *pgx_prt_dev, FILE *file, int num_copies) -{ -#ifndef OMNI_ASYNC - - /* locate_overlay_buffer is gone, so for now async printing is disabled */ - return gs_note_error (gs_error_undefined); - -#else - gx_device_omni * const pasyncDev = (gx_device_omni *)pgx_prt_dev; - gx_device * const pgx_dev = (gx_device *)pgx_prt_dev; - int code = 0; - - /* BMP format is single page, so discard all but 1st page */ - if (pasyncDev->copies_printed > 0) - return 0; - - /* If there's no data in buffer, no need to do any overlays */ - if (!pasyncDev->buffered_page_exists) - { - code = PrintPage(pgx_prt_dev, file, num_copies); - - goto done; - } - - /* - * Overlay file's bits on top of existing file There are two choices for - * doing this: get_overlay_bits vs. the combination of - * locate_overlay_buffer and get_bits. If you already have a buffer in a - * format compatible with GS's format, use get_overlay_bits. If you'd - * rather use the buffer already in the device, use - * locate_overlay_buffer, copy the bits into the returned buffer, then - * get_bits. - * - * Either way, try to do entire bands at a shot for much greater - * efficiency. - */ - - /* Seek to beginning of data portion of file */ - if (fseek (file, pasyncDev->file_offset_to_data, SEEK_SET)) - { - code = gs_note_error (gs_error_ioerror); - - goto done; - } - - { - byte *raster_data; - int raster = gx_device_raster (pgx_dev, 1); - ulong bmp_raster = raster + (-raster & 3); /* BMP scan lines are padded to 32 bits. */ - int max_band_height = (*pgx_prt_dev->printer_procs.locate_overlay_buffer) (pgx_prt_dev, 0, &raster_data); - int band; - int file_raster_good = min (raster, bmp_raster); - long file_raster_slop = bmp_raster - file_raster_good; - - /* - * iterate thru bands from top to bottom. - * Do this an entire band at a time for efficiency. - */ - for (band = (pgx_prt_dev->height - 1) / max_band_height; band >= 0; --band) - { - int band_base_line = max_band_height * band; - int band_height = (*pgx_prt_dev->printer_procs.locate_overlay_buffer) (pgx_prt_dev, band_base_line, &raster_data); - int line; - - /* Fill in overlay buffer with a band from the BMP file. */ - /* Need to do this backward since BMP is top to bottom */ - for (line = band_height - 1; line >= 0; --line) - { - if ( fread (raster_data + line * bmp_raster, - file_raster_good, - 1, - file) < 1 - || fseek (file, file_raster_slop, SEEK_CUR) - ) - { - code = gs_note_error (gs_error_ioerror); - - goto done; - } - } - - /* Rewind & write out buffer with contents of get_bits */ - if (fseek (file, - -(file_raster_good + file_raster_slop) * band_height, - SEEK_CUR)) - { - code = gs_note_error(gs_error_ioerror); - - goto done; - } - - for (line = band_height - 1; line >= 0; --line) - { - if ((code = dev_proc (pgx_dev, get_bits) (pgx_dev, line + band_base_line, 0, &raster_data)) < 0 ) - goto done; - - if ( fwrite (raster_data, file_raster_good, 1, file) < 1 - || fseek(file, file_raster_slop, SEEK_CUR) - ) - { - code = gs_note_error(gs_error_ioerror); - - goto done; - } - } - } - } - -done: - if ( code >= 0 - && pasyncDev->copies_printed > 0 - ) - pasyncDev->copies_printed = num_copies; - - pasyncDev->buffered_page_exists = (code >= 0); - - return code; - -#endif -} - -/* ------------------------------------------------------*/ -/*------------ Procedures common to writer & renderer -------- */ -/* ------------------------------------------------------*/ - -/* Compute space parameters */ -static void -GetSpaceParams (const gx_device_printer *pgx_prt_dev, - gdev_prn_space_params *space_params) -{ - /* Plug params into device before opening it - * - * You ask "How did you come up with these #'s?" You asked, so... - * - * To answer clearly, let me begin by recapitulating how command list - * (clist) device memory allocation works in the non-overlapped case: - * When the device is opened, a buffer is allocated. How big? For - * starters, it must be >= PRN_MIN_BUFFER_SPACE, and as we'll see, must - * be sufficient to satisfy the rest of the band params. If you don't - * specify a size for it in space_params.band.BandBufferSpace, the open - * routine will use a heuristic where it tries to use PRN_BUFFER_SPACE, - * then works its way down by factors of 2 if that much memory isn't - * available. - * - * The device proceeds to divide the buffer into several parts: one of - * them is used for the same thing during writing & rasterizing; the - * other parts are redivided and used differently writing and - * rasterizing. The limiting factor dictating memory requirements is the - * rasterizer's render buffer. This buffer needs to be able to contain - * a bitmap that covers an entire band. Memory consumption is whatever - * is needed to hold N rows of data aligned on word boundaries, + - * sizeof(pointer) for each of N rows. Whatever is left over in the - * rasterized is allocated to a tile cache. You want to make sure that - * cache is at least 50KB. - * - * For example, take a 600 dpi b/w device at 8.5 x 11 inches. For the - * whole device, that's 6600 rows @ 638 bytes = ~4.2 MB total. If the - * device is divided into 100 bands, each band's rasterizer buffer is - * 62K. Add on a 50K tile cache, and you get a 112KB (+ add a little - * slop) total device buffer size. - * - * Now that we've covered the rasterizer, let's switch back to the - * writer. The writer must have a tile cache *exactly* the same size as - * the reader. This means that the space to divide up for the writer is - * equal is size to the rasterizer's band buffer. This space is divided - * into 2 sections: per-band bookeeping info and a command buffer. The - * bookeeping info currently uses ~72 bytes for each band. The rest is - * the command buffer. - * - * To continue the same 112KB example, we have 62KB to slice up. - * We need 72 bytes * 100 bands = 7.2KB, leaving a 55K command buffer. - * - * A larger command buffer has some performance (see gxclmem.c comments) - * advantages in the general case, but is critical in one special case: - * high-level images. Whenever possible, images are transmitted across - * the band buffer in their original resolution and bits/pixel. The - * alternative fallback behavior can be very slow. Here, the relevant - * restriction is that at least one entire source image row must fit - * into the command buffer. This means that, in our example, an RGB - * source image would have to be <= 18K pixels wide. If the image is - * sampled at the same resolution as the hardware (600 dpi), that means - * the row would be limited to a very reasonable 30 inches. However, if - * the source image is sampled at 2400 dpi, that limit is only 7.5 - * inches. The situation gets worse as bands get smaller, but the - * implementor must decide on the tradeoff point. - * - * The moral of the story is that you should never make a band - * so small that its buffer limits the command buffer excessively. - * Again, Max image row bytes = band buffer size - # bands * 72. - * - * In the overlapped case, everything is exactly as above, except that - * two identical devices, each with an identical buffer, are allocated: - * one for the writer, and one for the rasterizer. Because it's critical - * to allocate identical buffers, I *strongly* recommend setting these - * params in the writer's open routine: - * space_params.band.BandBufferSpace, .BandWidth and .BandHeight. If - * you don't force these values to a known value, the memory allocation - * heuristic may not come to the same result for both copies of the - * device, since the first allocation will diminish the amount of free - * memory. - * - * There is room for an important optimization here: allocate the - * writer's space with enough memory for a generous command buffer, but - * allocate the reader with only enough memory for a band rasterization - * buffer and the tile cache. To do this, observe that the space_params - * struct has two sizes: BufferSpace vs. BandBufferSpace. To start, - * BandBufferSpace is always <= BufferSpace. On the reader side, - * BandBufferSpace is divided between the tile cache and the rendering - * buffer -- that's all the memory that's needed to rasterize. On the - * writer's side, BandBufferSpace is divided the same way: the tile - * cache (which must be identical to the reader's) is carved out, and - * the space that would have been used for a rasterizing buffer is used - * as a command buffer. However, you can further increase the cmd buf - * further by setting BufferSize (not BandBufferSize) to a higher number - * than BandBufferSize. In that case, the command buffer is increased by - * the difference (BufferSize - BandBufferSize). There is logic in the - * memory allocation for printers that will automatically use BufferSize - * for writers (or non-async printers), and BandBufferSize for readers. - * - * Note: per the comments in gxclmem.c, the banding logic will perform - * better with 1MB or better for the command list. - */ - - /* This will give us a very "ungenerous" buffer. */ - /* Here, my arbitrary rule for min image row is: twice the dest width */ - /* in full RGB. */ - ulong render_space = 0; - ulong writer_space; - const int tile_cache_space = 50 * 1024; - const int min_image_rows = 2; - int min_row_space = min_image_rows * (3 * (pgx_prt_dev->width + sizeof (int) - 1)); - int min_band_count = max (1, pgx_prt_dev->height / 100); /* make bands >= 1% of total */ - - space_params->band.BandWidth = pgx_prt_dev->width; - space_params->band.BandHeight = (pgx_prt_dev->height + min_band_count - 1) / min_band_count; - - gdev_mem_data_size ((const gx_device_memory *)pgx_prt_dev, space_params->band.BandWidth, - space_params->band.BandHeight, &render_space); - - /* need to include minimal writer requirements to satisfy rasterizer init */ - writer_space = 5000 /* add 5K slop for good measure */ - + (72 + 8) * ((pgx_prt_dev->height / space_params->band.BandHeight) + 1); - - space_params->band.BandBufferSpace = max (render_space, writer_space) + tile_cache_space; - space_params->BufferSpace = max (render_space, writer_space + min_row_space) + tile_cache_space; -} - -/*-----------------------------------------------------------------------------*/ -/* */ -/* Function: FindBandSize */ -/* This function figures out the appropriate band size based on the amount */ -/* of memory that can be occupied by the band and bitmap information. */ -/* bitmap, and the specifics of the hardware */ -/* */ -/*-----------------------------------------------------------------------------*/ -ULONG -FindBandSize (ULONG ulYHeight, - ULONG ulXWidth, - ULONG ulBitsPerPel, - ULONG ulNumPlanes, - ULONG ulModulus, - ULONG ulMemoryLimit) -{ - ULONG ulSizeScanLine; - ULONG ulMemoryNeeded; - ULONG ulNumLinesFit; - - if (0 == ulModulus) - { - ulModulus = 1; - } - - /* figure out how much memory is needed fore each line */ - ulSizeScanLine = ((ulBitsPerPel*ulXWidth+31)/32)*ulNumPlanes*4; - - /* Figure out how much memory is needed for the page */ - ulMemoryNeeded = ulYHeight * ulSizeScanLine; - - /* How many lines can fit in the size given? */ - ulNumLinesFit = ulMemoryLimit / ulSizeScanLine; - - if (0 == ulNumLinesFit) - /* Minimum of 1 scan line */ - ulNumLinesFit = 1; - - if (ulNumLinesFit <= ulModulus) - /* Not enough lines... Promote it to a modulus. */ - ulNumLinesFit = ulModulus; - else - /* Bump down the number of lines so that it is a modulus. */ - ulNumLinesFit -= ulNumLinesFit % ulModulus; - - if ((ulYHeight % ulNumLinesFit) * 100 / ulYHeight <= 15) - { - USHORT usBumpUp; - - usBumpUp = ulYHeight % ulNumLinesFit; - usBumpUp += ulModulus - 1; - usBumpUp /= ulModulus; - usBumpUp *= ulModulus; - ulNumLinesFit += usBumpUp; - } - - return ulNumLinesFit ; /* return the number of lines we want for the band */ -} diff -Nru ghostscript-9.10~dfsg/contrib/japanese/doc/djgpp.txt ghostscript-9.25~dfsg+1/contrib/japanese/doc/djgpp.txt --- ghostscript-9.10~dfsg/contrib/japanese/doc/djgpp.txt 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/doc/djgpp.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,510 +0,0 @@ - - Ghostscript 2.6.1 DJ's GPP ѥå - version 1.3 - - Copyright (C) 1993,1994 ɻŵ - TPM03937@pcvan.or.jp - GHF01532@niftyserve.or.jp - - -======================================================================== - ѥå -======================================================================== - - ΥѥåˤϰʲΥե롢ǥ쥯ȥ꤬ޤޤƤޤ -ˤϡOS ˰¸˻ȤեޤޤƤޤ () - - COPYING GNU General Public License (GNU GPL) - djgpp.sj Υե - djgpp.mak Makefile - djgpp.dif Ghostscript 2.6.1ꥸʥΥɤФ뺹ʬ - gp_djgpp.c DJ's GPPĶ¸Υ - djgpp.h Ʊ - gp_djgpp.h Ʊ - gp_pc98.c NEC PC-9801/PC-H98¸Υ - gp_pcat.c IBM PC/ATߴ¸Υ - gs_djgpp.tr ѤΥ쥹ݥ󥹥ե - gp_djgpp.ps DJ's GPPĶνPSե - gp_site.ps DJ's GPPĶδĶե - gssetdjg.bat Makefile ƤӽФХåե - gdevgppr.h ץ󥿥ɥ饤ФDJ's GPPб뤿Υإå - zkfpc98.c NEC PC-9801/PC-H98 ROMեȥɥ饤ФΥ - zkfvflib.c VFlibѤեȥɥ饤 - zkfvflib.mak Ʊ - kfvflib.sj VFlibѤΥեȥɥ饤ФΥɥ - drivers/ ƼǥХɥ饤Фǥ쥯ȥ - |---gdev10v/ ܸ첽ѥå° Canon BJ10V ɥ饤Фؤ - | ʬ - |---gdev98hf/ ǥ륢ļ Hyper-Frame+ ѥե륫顼ǥ - | ץ쥤ɥ饤 - |---gdevcdj/ ꥸʥѥå° HP DeskJet꡼ - | Υɥ饤Ф DeskJet 505J б뤿κʬ - |---gdevdjgp/ IBM PC / ATߴ Υǥץ쥤ɥ饤 - |---gdevdmpr/ ѥץ󥿥ɥ饤 - |---gdevlips/ ܸ첽ѥå° LIPS ץ󥿥ɥ饤Фؤ - | ʬ - |---gdevmag/ եޥåȤβǡϤ뤿Υɥ饤 - |---gdevp201/ ܸ첽ѥå° NEC PC-PR 201 ɥ饤Ф - | PC-PR 150 / PC-PR 1000 / PC-PR 1000/4 б - | κʬ - +---gdevpc98/ NEC PC-9801 / H98 Υǥץ쥤ɥ饤 - kanji/ DJ's GPPǸͭδե뤬ǥ쥯ȥ - - -======================================================================== - Ϥ -======================================================================== - - Υѥå Ghostscript version 2.6.1 DJ's GPP ǥѥ뤷 -NEC PC-9801/PC-H98IBM PC/AT ߴѤǤ褦ˤ뤿Υѥå -Ǥ - - Хʥﶦ̤ǤϼưȽ̤ޤ (桼ľ -ܵꤹ뤳ȤǽǤ) - - ޤһˤܸ첽ѥå 1.0 ʻѤ뤳ȤȤ -ƤޤMakefile 񤭴ܸ첽ƤʤΤ⥳ѥ -ǽǤ - - -======================================================================== - OS¸˴ؤ -======================================================================== - - Υѥå˴ޤޤƤΤΤʲΤΤƵ OS -طʤΤޤ޻Ѥ뤳Ȥޤ - - gp_djgpp.c gp_pc98.c gp_pcat.c gp_djgpp.h djgpp.h - ϥץåȥե¸Υ (Ǥ DJ's GPP+GO32 ) - եǤGhostscript ΥꥸʥѥåˤϳƴĶ - ΤΤѰդƤޤΤǡGO32 ĶʳΤϤѤ - - djgpp.mak djgpp.dif - DJ's GPP ǥѥ뤹뤿κʬ makefile Ǥ - gp_djgpp.ps gp_site.ps - ΥѥåȤä DJ's GPP ǥѥ뤷¹ԷΤν - եǤ - gdevdjgp/ gdevpc98/ gdev98hf/ - ǥץ쥤ɥ饤гƼ¸Ǥ - - -======================================================================== - ѥˡ -======================================================================== - - μǥѥ뤷Ƥ - -(1) ꥸʥΥΥ֤Ÿ롣ʲκȤϡκȤˤ - äƺ./gs261 Ȥǥ쥯ȥ˰ܤäƹԤޤ - -(2) ХեʬƤޤ - -(3) Υѥå˴ޤޤƤեڤܸ첽ѥåΥե - 򤳤Υǥ쥯ȥ˥ԡޤ - -(4) ѥå djgpp.difڤܸ첽ʬ򤢤Ƥޤ (ʤ) - djgpp.dif genconf.c ps2epsi.ps Ф뺹ʬǤ - - ܸ첽Ԥʤˤ djgpp.dif ŬѤƤ - - patch < gs261j.dif - patch < djgpp.dif - - - ѥåޤʤ硣 - - Ghostscript ꥸʥΥե (Хʬޤ)ܸ - ѥå (gs261j.diff)DJ's GPP бѥå (djgpp.dif) - UN*X βԥ (Line Feed Τ) ǤMS-DOS Ǥ - patch.exe ǤϡΥݡƥ󥰤ˤäƤϤޤѥå - ʤȤ뤫⤷ޤ - - Τ褦ʾϡƤΥեβԥɤ MS-DOS - (Carriage Return + Line Feed) ѹƤ patch.exe Ȥ - 뤤 UN*X ǥѥåƤȤޤǤκȤԤäƤ - 줫 MS-DOS ˥եäƤưʲκȤԤʤäƤ - - -(5) ܸ첽ѥåޤϤΥѥå°ƤǥХɥ饤 - ФȤ߹ˤϡ򥫥ȥǥ쥯ȥ˥ԡ ( - ΥǥХɥ饤Фϥǥ쥯ȥ drivers ˤޤ) - - ܸ첽ѥå°Υץ󥿥ɥ饤ФΤʤˤϤ˺ʬ - ɬפΤޤޤꥸʥΥѥå°Υץ - ɥ饤ФȤ߹िˤɬפǤ - - ܤϤΥɥȤΡ֥ץ󥿥ɥ饤Фȹߡפ - - ʤΥѥå°Υץ󥿥ɥ饤Сǥץ쥤ɥ饤Ф - ʤǤΤޤȤ߹ޤ - -(6) djgpp.mak Խ롣 - - DJ's gpp Ķ Makefile djgpp.mak ȤեǤΰ - Υޥ񤭴ޤ - - (A) - DJGPP_PLATFORMS= ... - - ץ󥿽ϥ롼ʤɤε¸ɤɤεѤΤΤȤ - फꤷޤ˥ץ󥿽ϴطΥɤǤǥץ - Ϥ˴ؤƤϤȤ̤ DEVICE_DEVS ǻꤷޤNEC - PC-9801IBM PC/AT ߴѤΥץ󥿽ϥ롼ѰդƤ - ޤ - - pc98_pcat_ Ӥޤξꤹ뤳ȤǽǤΥ - å˴ޤޤƤ djgpp.mak ǤξȤ߹褦ˤƤ - ޤ - - λˤƤȵ¸ɤȤ߹ޤƤΥץ - ɤɸץ󥿽 ("PRN") ͳǽϤ褦ˤʤޤ - - (B) - FEATURE_DEVS= ... - - եȥɥ饤ФɲäˤϤ˽񤭲äޤ - - Υѥå˴ޤޤ djgpp.mak ǤϡζեȡJG - եȡNEC PC-9801 ROM եȡѤեȥɥ饤 - ФȤ߹褦ˤʤäƤޤ - - VFlib ver 2.13 ʹߤʻѤ뤳Ȥˤ TrueType եȤ - ѤǤ褦ˤʤޤܤ kfvflib.sj - - ޤܸ첽Ԥʤˤϡkanji.dev ʹ߹ޤǤ - Ƥ - - (C) - DEVICE_DEVS= ... - DEVICE_DEVS1= - : - : - DEVICE_DEVS9= - - ץӥ塼ץ󥿥ɥ饤Фʤɤνϥɥ饤Ф򤳤˶ʸ - ǶڤäƤʤ٤ޤ - - DEVICE_DEVSDEVICE_DEVS1DEVICE_DEVS9 10 ĤΥޥʬ - Τ MS-DOS Υޥɥ饤ŤΤǤΥ - Хɥ饤ФȤ߹ˤϡĤΥޥĹʤꤹ - ʤ褦 10 ĤŬ˿ʬƤ - - Υѥå˴ޤޤƤ djgpp.mak ǤϲȤ߹ޤʤ褦 - ˤʤäƤޤ - - ̾ϥǥץ쥤ɥ饤ФȤ߹ɬפޤ - - ǥХ̾ ɤǥ쥯ȥ - PC-9801/PC-H98 pc98.dev drivers/gdevpc98/ - IBM PC/AT djgpp.dev drivers/gdevdjgp/ - - ܸ첽ѥåڤӤΥѥå°ΥǥХɥ饤Ф - Ȥ߹ˤϡ줾Υץ¾ Ghostscript - ΥץΤǥ쥯ȥ˥ԡˤ줾 - ɥ饤Ф° Makefile Ƥ djgpp.mak ɲáޤ - !include " ե̾ " ȤƼǤ - - DJ's GPP 1.12 ʹߤȤˤϡdjgpp.mak Υޥ AOUT2EXE - 'coff2exe' ˽񤭴ƤǥեȤǤ 'aout2exe' - ˤʤäƤޤ - -(7) djgpp.mak Makefile Ȥ make ¹Ԥ롣 - - make -f djgpp.mak - - djgpp.mak Borland make ѤǤ¾ make Ȥˤϡ - Υѥå° tarcat.pl Ȥä !include " ե̾ " - ʬ򤽤̣֤ơ Makefile ȤƻȤäƤ - perl ץȤǤʲΤ褦ˤƻȤޤΥץȤǤ - !include ҤˤʤäƤƤǤޤ - - jperl tarcat.pl djgpp.mak > merged.mak - - make ѤΥХåե (gsaddmod.bat ʤ) ϥꥸʥΥѥå - ˴ޤޤ Turbo C++/Borland C++ ѤΤΤ򤽤ΤޤѤޤ - ѥåǤϤ˥ꥸʥΥѥåΤΤ˲ä - gssetdjg.bat ȤХåե뤬ɲäƤޤȥǥ - ȥ (gs261) ˤΥХåե뤬뤳ȤǧƤ - - Υѥå˴ޤޤƤʤǥХɥ饤Ф PC-9801 PC/AT - ߴб뤿ˡܥɥȤκǸ˵Ƥޤ - - -======================================================================== - ˡ -======================================================================== - - ǤϡDJ's GPP ͭΤȤˤĤƤΤ߽Ҥ٤ޤGhostscript -ȡˡˤĤƤϥꥸʥΥɥȤ - ------------ - 5.1 ------------ - -(1) Υѥå kanji ǥ쥯ȥˤ PostScript ե - 첽ѥå kanji ǥ쥯ȥ겼ΥեƱǥ쥯ȥ - ԡ롣 - -(2) Υѥå˴ޤޤ gp_djgpp.ps gp_site.ps Ghostscript - 饤֥֤ǥ쥯ȥ (gs_init.ps ʤɤ֤ǥ쥯ȥ) - ԡ롣 - -(3) ɬפǤ gp_site.ps εʬʤɤԽ롣 - - ܥСǤϵ (98/PC/ ¾) ϼưȽ̤ޤäơ - 褱äԤʤɬפϤʤΤޤ޻Ȥޤ - - ˤäƤȽ뤫⤷ޤ󡣤ξˤϡ - gp_site.ps ʲΤ褦ԽơŪˡ׵ꤷƤ - - Ūˤϡ° gp_site.ps ˤϲǽ꤬ ('%' ʹ߲ - Ԥޤ) ƤޤΤǡΤҤȤĤ Uncomment Ƥ - - - % /Name (PC-AT) % ... - % /Name (PC-9801) % ... - % /Name (OTHER) % ... - - ιƬ '%' ΤҤȤĤޤ - - ʤưȽ̤ԤʤäˤϡưŪˤε /Name - ޤ - - - ʲϥץʥʤΤ̾ɬפޤ󡣥ǥեȤ - ǤޤʤǥեȤʤȤˤ - ԤʤäƤ - -(4) ץ󥿽Ϥˡλ (/PrintTarget) -(5) ץ󥿽ϥХåեΥλ (/PrintBufferSize) -(6) ץ󥿽Ϥ®λ (/PrintWait) -(7) ǥեȤΥǥХɥ饤Фλ (/DefaultDevice) - - /Name Ԥȡ - - ץ󥿽Ϥˡ (/PrintTarget ʤ) - ǥեȤΥǥХɥ饤 (/DefaultDevice) - -ƵˤäΤ˼ưŪꤵޤ - - ǡΰ̣ϰʲΤ褦ˤʤäƤޤ - - /PrintTarget - ץ󥿽Ϥ򡢥ץ󥿥ݡȡץ BIOSɸץ󥿽ϡ - ΤΤɤѤƹԤꤷޤ - (PORT),(PORT1),(PORT2),(PORT3),(BIOS),(STDPRN) Τɤ줫ͤȤ - ޤ(PORT) (PORT1) Ǥ - - ǥեȤ PC-9801IBM PC/AT ߴǤ (BIOS)ʳǤ - (STDPRN) Ǥ - - /PrintBufferSize - ץ󥿽ѤΥХåեΥХȿǤץ󥿤ǡ - öΥХåե졢ХåեäѤˤʤäȤˤޤȤ - ץ󥿤ޤ64 ʾ 32767 ʲǤǥեȤǤ - 1024(bytes) Ǥ - - /PrintWait - ץ󥿽ϻΡԤפǤͤ礭ۤɤäȽ - ޤԤפ /PrintBufferSize ֤ΥǡϤ뤴Ȥ - ꡢԤ֤ͤˤۤ㤷ޤ - - LAN Ķץ󥿥סǥץ BIOS եåƤ˥ - 󥿥ɤȤꤳܤƤޤ褦ʤȤˤϤͤ礭ꤹ - ͤ򤢤٤礭ꤷƤ /PrintBufferSize ͤ - ޤ - - /PrintBufferSize ͤۤˤˡԤפȯ뤳Ȥˤ - ꡢ/PrintWait ͤ礭ۤɰ󤢤ΡԤפĹʤ뤳Ȥ - ʤޤ - - Ǥͤ 0 ʾ 2048 ʲǤǥեȤǤ 0(Ԥ - ) Ǥ - - /DefaultDevice - Ghostscript -sDEVICE= ץꤻˡĴĶ - ѿ GS_DEVICE ꤻΩ夲˻ѤǥХɥ饤 - Ǥ̾ϵˤäǥץ쥤ɥ饤ФꤷƤޤ - - ޥɥ饤 - - gs -h - - Ghostscript Ω夲Ȥˡ - - Available devices: - - Ȥʬ˽Ϥ椫Ӥޤ - - /Name γƥǥեͤϡ - - +---------+-----------------------------------------+ - |/Name |/PrintTarget /DefaultDevice | - +---------+-----------------------------------------+ - |(PC-AT) |ݡ1 (djgpp) -sDEVICE=djgpp | - |(PC-9801)|ݡ (pc98) -sDEVICE=pc98 | - |(OTHER) |ɸץ󥿽 nulldevice -dNODISPLAY | - +---------+-----------------------------------------+ - -ǡ/Name ξ /PrintWait 0/PrintBufferSize 1024 - - - ϥ桼 gp_site.ps /PrintTarget/DefaultDevice ʤɤ -Ū˻ꤹ뤳Ȥˤäѹ뤳Ȥޤ - - ˡϡ - - /DefaultDevice (pc98) - -Τ褦ˡ - - / - -Ȥޤgp_site.ps 򥳥ȤȤƵҤƤޤΤǻͤ -Ƥ - - '%' ʹߡޤǤϥȤǤ - - /Name (OTHER) ꤷȤˤϡ¸ưԤޤ -NEC PC-9801 IBM PC/AT ߴʳεѤˤϤꤷ -Ƥץ󥿽Ϥɸץ󥿽ϤȤǥեȤΥǥХ -nulldevice (եå̤ؤνϤڹԤʤǥХޥɥ饤 - -dNODISPLAY ꤷ) ˤʤޤ - - -======================================================================== - ץ󥿥ɥ饤Фȹ -======================================================================== ------------------------------------------ - 6.1 ܥѥå°Υץ󥿥ɥ饤 ------------------------------------------ - - ƥץ󥿥ɥ饤ФΥɥȤˤäȤ߹Ǥ - - ------------------------------------------------ - 6.2 ܸ첽ѥå°Υץ󥿥ɥ饤 ------------------------------------------------ - - drivers ǥ쥯ȥβγƥ֥ǥ쥯ȥ˳ĥ.dif Υե뤬 -ˤϡ gs 2.6.1 ܸ첽ѥå°Υץ󥿥ɥ饤 -Ф뺹ʬǤκʬ򤢤Ƥ뤳Ȥˤܸ첽ѥå°Υ -󥿥ɥ饤ФȤ褦ˤʤޤ - - ܸ첽ʬ°Υץ󥿥ɥ饤ФϤϤᤫ NEC PC-9801 б -Ƥ⤢ޤNEC PC-H98 IBM PC/AT ߴб뤿 -ϤΥѥå°κʬ򤢤ƤƤPC-9801 ǻѤˤ⡢ -BIOS ϤʤɤεǽȤˤϺʬ򤢤Ƥɬפޤ - - ޤܸ첽ѥå°Υץ󥿥ɥ饤ФǤΥѥå -äбʬޤޤƤʤΤϼˤäƺȤ뤳Ȥˤ - PC-9801 PC/AT ѤǤ褦ˤʤޤ - - -------------------------------- - 6.3 ¾Υץ󥿥ɥ饤 -------------------------------- - - СǤϥץ󥿽ϤΤΥ롼 gp_djgpp.c Ѱդ -ƤޤΤǥХɥ饤ФΥɤ߹إåե -ɲäǤޤ PC-9801 ʤɤбƤʤäץ󥿥ɥ饤 -ФѤ뤳Ȥ褦ˤʤޤ - - ˡбǤץ󥿥ɥ饤ФϡɤνϤ -putc(),fputc(),fputs(),fwrite(),fprintf(),vfprintf(),fflush() Υȥ꡼ -ϴؿȤäƹԤʤäƤΤǤwrite() ʤɤϴؿ -ΤбǤޤ - - ޤץ󥿤Υץ gp_printer_open() -gp_printer_close() ȤäƤʤФʤޤgdevprn.c -ؿѤƤɥ饤 (gdevprn.h Ǥɥ饤) Ǥ -дְ㤤ʤξƤޤ - - ʲμ () ѥ뤷Ƥ - -(1) Υѥå° gdevgppr.h ɥ饤ФΥեǥ - 롼ɤ롣 - - #include "gdevgppr.h" - -(2) () ѥ뤹롣 - - -======================================================================== - С󤫤ѹ -======================================================================== - - DJ's GPP бѥåС (1.2) ʲѹƤ -ޤ - - Զν - 桼ƥƥ ps2epsi ưʤäԶ - VFlib ɥ饤Фǡȥǥ쥯ȥ vfontcap - ưʤäԶ - dmprt ɥ饤ФǰΥץ󥿤ưʤäԶ - ˡ˴ؤ뵡ǽĥѹ - IBM PC/AT ߴΥץ BIOS ͳνϤб - ץ󥿽ϤΥǥեȤ BIOS ѹ - ץ󥿽Ϥ®٤ĴǤ褦ѹ - ץ󥿽ϥХåեΥĴǤ褦ѹ - ǥХɥ饤Фεǽĥ - dmprt ɥ饤Ф dviprt 2.42 ʹߤΥץեб - ǥХɥ饤Фɲ - HP DeskJet 505J - Hyper-Frame+ - եޥåȥǡ - ¾ - ưȽ̤褦ˤ - PC-9801, IBM PC/AT ߴ бƤʤץ󥿥ɥ饤ФȤ - ߤѹ (djdriver.pl gp_print.h gdevgppr.h - ɲá) - ե gp_djgpp.ps 顢桼Խʬ̥ե - gp_site.ps ʬΥ񼰤㴳ѹ - - -======================================================================== - ռ -======================================================================== -GO32 ǤΥѥåˤꡢ¿ˤäˤʤޤ - - ؤһˤϡΤ¥ƥǤܸ - ѥå󶡤򤷤Ƥޤ - - PC-VAN SSCIENCE ΤȤˤϡIBM PC/AT ߴǤưǧƥ - ȥХʥκʤѤäˤʤޤ - - PC-VAN SSCIENCE OkI ˤϡNEC H98 бưǧѤ - ˤʤޤ - - PC-VAN SSCIENCE SOLITON ϡIBM PC/AT ߴѤΥǥץ쥤 - ɥ饤ФƤޤޤɥ饤Фνˤä¿ - Τ򤤤ޤ - - Nifty Serve FLABO KEN ˤ IBM PC/AT ߴѤΥǥץ쥤 - 饤ФԶ罤ˤäơŤʤ򤤤ޤ - - hero.h ˤϡIBM PC/AT ߴѤΥץ󥿽ϥɤƤ - ޤ - - VFlib Υȥ饤ؿμΤǴ TrueType եȤ - ݡȤ뤳ȤǤޤVFlib κԤǤ빭ؤγ͵ - VFlib δ TrueType бԤäƤä PC-VAN SSCIENCE - İϺϤȤ VFlib ȯˤäƤä˴ - դޤ - - ǸˤʤޤLouis IX ϤȤ PC-VAN SSCIENCE Τߤʤ - ˤϴ٤ˤϤưƥȡ𡢤ԤäƤޤ꤬ - ޤ - - -======================================================================== - ۡݾ -======================================================================== - - DJ's GPP бʬ˴ؤƤ GNU General Public License (GPL) ˽ -GNU GPL ˤĤƤ COPYING Ȥե˵Ƥޤ - - ƼǥХɥ饤Сեȥɥ饤ФˤĤƤϤ줾Υɥȡ -ե˵Ƥ˽ޤ - -=========================== End of Document ============================ diff -Nru ghostscript-9.10~dfsg/contrib/japanese/doc/gdevmag.txt ghostscript-9.25~dfsg+1/contrib/japanese/doc/gdevmag.txt --- ghostscript-9.10~dfsg/contrib/japanese/doc/gdevmag.txt 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/doc/gdevmag.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ - - եޥåȥɥ饤 version 1.0 - Copyright (C) 1994 ɻŵ - - -======================================================================== - -======================================================================== - -ޤ (.mag) եޥåȤβǡϤ뤿Υɥ饤ФǤ -16 256 бƤޤ - -======================================================================== - Ȥ߹ -======================================================================== - -gdevmag.c ¾ΥץƱǥ쥯ȥ֤Makefile -DEVICE_DEVS (ޤϡDEVICE_DEVS19) mag16.dev (16 ) -mag256.dev(256 ) ɲäMakefile gdevmag.mak Ƥɲä -make ¹ԤƤ - -======================================================================== - Ȥ -======================================================================== - -BMP PCX ʤɤ¾βեޥåȥɥ饤ФƱͤǤgs ư - -sDEVICE=mag16-sDEVICE=mag256 ȤץդƤ - - () gs -dNOPAUSE -sDEVICE=mag16 -sOutputFile=golfer.mag -- golfer.ps - - Ĥ *.mag եˤϰĤβޤ뤳Ȥޤ󤫤顢 - ʣڡ PostScirpt ɤѴˤ - -sOutputFile ץʣΥե˽Ϥ褦˻ꤷƤ - - - () gs -dNOPAUSE -sDEVICE=mag256 -sOutputFile=lines%d.mag -- lines.ps - - ɻ ŵ (ASAYAMA Kazunori) - TPM03937@pcvan.or.jp - GHF01532@niftyserve.or.jp diff -Nru ghostscript-9.10~dfsg/contrib/japanese/doc/gs261j.euc ghostscript-9.25~dfsg+1/contrib/japanese/doc/gs261j.euc --- ghostscript-9.10~dfsg/contrib/japanese/doc/gs261j.euc 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/doc/gs261j.euc 1970-01-01 00:00:00.000000000 +0000 @@ -1,559 +0,0 @@ -Ghostscript version 2.6.1 ܸ첽ѥå gs261j -Version 1.0 Jan.11,1994 by һ (katayama@nacsis.ac.jp) -Copyright (C) 1991,1992,1993,1994 Norio Katayama. - - -ǽ - - 1. Ghostscriptܸؤγĥ - a. ʣեȤΥݡ - b. ʸȥå(Metrics, Metrics2, CDevProc)Υݡ - c. Ľ񤭥⡼ɤΥݡ - - 2. եȤΥݡ - a. X11R5 PCFեȥե뤫ɽФ - b. X11R4 SNFեȥե뤫ɽФ - c. Sony(TM)٥եȥե뤫ɽФ - d. Zeit(TM)եޥåȥեȥե뤫ɽФ - : (Ext)󡢰幯(K-ras) - e Zeit(TM) JG եޥåȥեȥե뤫ɽФ - : ɻŵ - f. ܸTeX PKեȥե뤫ɽФ - - 3. ǥХɥ饤 - a. gdevnwp (Sony NWP-533/537 ץ) - b. gdevlips (Canon LIPS-II/II+/III ץ) - : 縲 - c. gdevp201 (NEC PC-PR201 ץ) - d. gdevp150 (NEC PC-PR150 ץ) - : 餵 - e. gdevepag (ESC/Page) - : - f. gdevj100 (Star JJ-100 ץ) - : ͳ - g. gdev10v (Canon BJ10v ץ) - : 浱ˤػʤ󡢾湧ͺ - - - -ưǧ - - +--------------+-----------------+-----------------+-------------+ - | OS | Machine | Compiler | Device | - +--------------+-----------------+-----------------+-------------+ - | SunOS 4.1.3 | SPARC Station 2 | cc -O / gcc -O | X11 | - +--------------+-----------------+-----------------+-------------+ - - - - - - DJ's GPP Ȥäƥѥ뤹ˤϡɻŵ󤬺줿 -Ghostscript 2.6.1 DJ's GPP ѥå٤Ѥ뤳ȤDzǽǤ -PC-VAN Υ SIG (SSCIENCE) Nifty Serve Υեȥ˼ -(FLABO) Ǥ褦ˤʤ뤽Ǥ - ɻΥ᡼륢ɥ쥹ϡNIFTY: GHF01532, PC-VAN: TPM03937 Ǥ - - zkfjtex.c ʤɰΥץ char signed char Ǥ뤳 -ȤƤޤΤᡢMIPS ϤΥѥʤ char unsigned -char Ȥƽ륳ѥˤĤƤ -signed ץ󤫲Ѥ - char signed char Ȥƽ褦ꤷƲ - - X11R5 PCFեȤޤX11R4 SNFեȤѤݡX11Ķ( -Сͭ饤֥ʤ)ɬפޤ󡣥եȡե뤵ɤ߹ -ळȤǤдɽ뤳ȤǤޤ - - 䡢˾ХݡȡɰƤʤɴޤޤ - JUNET: katayama@nacsis.ac.jp NIFTY: NBB01613 - - - - - -ܸ첽ѥåˤϡΤδեȥեΥǡɽ -ǽޤޤƤޤѤݤˤ丵Υ饤󥹵 -ˤդ̤褦ղ( ءեȤΥ饤󥹤ˤĤơ) - -ܸ첽ѥåϡեʤΤǤϤޤ󤫤顢 -ʥΥХååפäƤȤԤʤäƲ - -ΥѥåλѤˤ˴ؤƤϡǤϰǤ -ͤޤΤǤ餫ᤴλꤤޤ - -Υѥåʣ̡ۤϡŪǤʤ˸¤꼫ͳ -Ԥʤäƹޤ - - - -󥹥ȡˡ(UNIX) - -[1] GhostscriptΥѥȥ󥹥ȡ - -(1) Ghostscript version 2.6.1 ΥեѰդƲ - ΥѥåϰʲΥѥå򤢤ƤեˤƤޤ - ghostscript-2.6.1.fix-01.gz - ghostscript-2.6.1.fix-02.gz - ghostscript-2.6.1.fix-03.gz - ghostscript-2.6.1.fix-04.gz - -(2) եѰդǥ쥯ȥǡΥѥåŸƲ - - -(3) ѥåե`gs261j.diff'򥪥ꥸʥ륽եˤƤƲ - -(4) unix-cc.mak, unix-gcc.mak, unix-ansi.mak Τ줫 Makefile -ԡƥȤδĶ˹碌ԽƲäˡλͤĤ -ԤʤäƲ - - 1. prefix, exec_prefix, bindir, datadir, gsdatadir ޥˤäơ - Ghostscript 򥤥󥹥ȡ뤹ǥ쥯ȥꤷƲ - - ) ɸξ - - prefix = /usr/local - exec_prefix = $(prefix) - bindir = $(exec_prefix)/bin - datadir = $(prefix)/lib - gsdatadir = $(datadir)/ghostscript - - - 2. ƥȤδĶ˹碌 CFLAGS, LDFLAGS, EXTRALIBS, XINCLUDE, - XLIBDIRS ޥꤷƲ - - - 3. FEATURE_DEVS ˡȤեȤ˹碌ưʲ̾ä - - - kfpcf.dev X11R5 PCFեȥե - kfsnf.dev X11R4 SNFեȥե - kfsony.dev Sony٥եȥե - kfzeit.dev Zeitեޥåȥեȥե - kfztbez.dev Zeit JG եޥåȥեȥե - kfjtex.dev ܸTeX PKեȥե - - ) PCFեȥե롢SNFեȥե롢Zeitեޥåȥե - ȥե롢Zeit JG եޥåȥեȥե롢ܸTeX PKե - ȥեȤ褦ˤ - - FEATURE_DEVS=filter.dev dps.dev level2.dev kanji.dev \ - kfpcf.dev kfsnf.dev kfzeit.dev kfztbez.dev kfjtex.dev - - Sony٥եȥեΤߤѤ - - FEATURE_DEVS=filter.dev dps.dev level2.dev kanji.dev \ - kfsony.dev - - PCFեȥե롢SNFեȥե롢Zeitեޥåȥե - ȥե롢Zeit JG եޥåȥեȥե롢ܸTeX PKե - ȥե롢Sony٥եȥեȤ褦ˤ - - FEATURE_DEVS=filter.dev dps.dev level2.dev kanji.dev \ - kfpcf.dev kfsnf.dev kfzeit.dev kfztbez.dev kfjtex.dev \ - kfsony.dev - - - 4. DEVICE_DEVS ˡȤǥХɥ饤Ф¤٤Ʋ - - ) X11ѤΥǥХɥ饤ФȤȤ - - DEVICE_DEVS=x11.dev - - Υѥå˴ޤޤƤǥХɥ饤ФѤȤˤϡ - drivers ǥ쥯ȥˤƥɥ饤ФΥɥȤ򻲾ȤƲ - - -(5) make ޥɤ gs 򥳥ѥ뤷make install ǥ󥹥ȡ뤷 - - -(6) Makefile gsdatadir ޥˤäƻꤷǥ쥯ȥβ -ghostscript-fonts-2.6.1.tar.gz ŸƲ - - ) gsdatadir ɸ /usr/local/lib/ghostscript ǤȤ - - % cd /usr/local/lib/ghostscript - % gunzip < ghostscript-fonts-2.6.1.tar.gz | tar xvf - - - -[2] եȤΥե졼 - -(1) Makefile gsdatadir ޥˤäƻꤷǥ쥯ȥβ -kanji Ȥ֥ǥ쥯ȥ꤬ΤǡΥǥ쥯ȥ˰ưƲ - - ) gsdatadir ɸ /usr/local/lib/ghostscript ǤȤ - - % cd /usr/local/lib/ghostscript - % cd kanji - - -(2) 󤷤ƥץ졼ȥե椫ȤեȤ˱ơ -줫򥳥ԡ kconfig.ps ĤäƲ - - pcf.ps X11R5 PCFեȥե - snf.ps X11R4 SNFեȥե - sony.ps Sony٥եȥե - zeit.ps Zeitեޥåȥեȥե - ztbez.ps Zeit JG եޥåȥեȥե - jtex.ps ܸTeX PKեȥե - -(3) kconfig.ps ƥȤδĶ˹碌ԽƲ̾ѹ -ʤФʤʤΤϥեȥե̾Ǥ - - kconfig.ps ξܺ٤ˤĤƤϡ֡ե졼ե -Ĥơפ򻲾ȤƲ - - -[3] եȤɽƥ - - ץץ gs ˼¹ԤեȤɽ뤳 -ȤΤƲ - - hankaku.ps Ⱦʸΰɽޤ - allkanji.ps Ѵΰɽޤ - fmaptype.ps ʣեȤΥեȥޥåԥ󥰤ΥƥȤǤ - vchars.ps Ľʸΰɽޤ - article9.ps ܹˡǤ - - ץץϡեȥǥ쥯ȥˤΤǥǥ쥯ȥ -ѥꤹɬפϤޤ - - ) % gs hankaku.ps - -() ޥ¤󶡤ƤSNFեѤ硢ʸ - ɽʤȤޤϡbdftosnf.h Υǥե - #define DEFAULTGLPAD 1 - #define DEFAULTBITORDER MSBFirst - #define DEFAULTBYTEORDER MSBFirst - #define DEFAULTSCANUNIT 1 - SNFեΥեޥåȤȰפƤʤȤȹͤޤ - ⤷ʸɽʤˤϡzkfsnf.c 37Ԥ53Ԥ - Ƥߤ뤳Ȥ򤪴ᤷޤ - - - -ե졼եˤĤ - - ΥեϴեȤ뤿ΤΤǤǥեȤǤϡ -kconfig.ps Ȥ̾Υե뤬Ȥޤޥɡץ -äѹ뤳ȤǤޤ - - -[1] եȤ - - եȤϼΥեޥåȤˤäƹԤʤޤ - - ե̾ ˡID [ եȥե̾ ] ޥ - - ե̾ - եȤ̾ǤɸŪ̾ϡ/Ryumin-Light - /GothicBBB-Medium ĤǤ - - ˡID - եȤ̤뤿ֹǤ괺 - 4300000椫200˻ꤹФ褤Ǥ礦 - - եȥե̾ - Ѥեȥե̾ǤΥեɤϡޥ - ˤäƽ񼰤ۤʤޤƥץ졼ȥեΥȤ򻲾Ȥ - Ʋ - - ޥ - եȤ뤿ΥޥɤǤ - - 㤨С"/usr/lib/X11/fonts/misc/k24.pcf"Ȥ̾X11R5 PCFե -ȥեѤ /Ryumin-Light ȤեȤȤ -ϡʸե졼ե˽񤤤Ƥޤ - - /Ryumin-Light 4300000 (/usr/lib/X11/fonts/misc/k24.pcf) pcfkanji - - ʸ񤯤ȤˤäơʲδեȤѤǤ褦ˤʤ - - - /Ryumin-Light.r## (## = 217E) JISɴ - /Ryumin-Light.r##v (## = 21, 22, 24, 25) ĽJISɴ - /Ryumin-Light.sr## (## = 819F, E0EA) 񤭥եJIS - /Ryumin-Light.sr##v (## = 8183) Ľ񤭥եJIS - - /Ryumin-Light.Roman Ⱦѱѿ - /Ryumin-Light.Hiragana ȾѤҤ餬 - /Ryumin-Light.Katakana Ⱦѥ - /Ryumin-Light.Hankaku ȾѱѿҤ餬ʡ - /Ryumin-Light.SuppK եJISȾѥ - - /Ryumin-Light-H JISɴ - /Ryumin-Light-V ĽJISɴ - /Ryumin-Light-Ext-H 񤭳ĥJISɴ - /Ryumin-Light-Ext-V Ľ񤭳ĥJISɴ - /Ryumin-Light-EUC-H EUCɴ - /Ryumin-Light-EUC-V ĽEUCɴ - /Ryumin-Light-RKSJ-H ȾѱѿҲ̾եJIS - /Ryumin-Light-RKSJ-V ĽȾѱѿҲ̾եJIS - /Ryumin-Light-83pv-RKSJ-H ȾѱѿҲ̾եJIS - - ĥJISѤδեȤޤϤʸ -եȥեƤˤäƷޤޤäơեȥե -˴ޤޤʤʸɽޤ󤷡JIS-78ˤʤ뤫JIS-83ˤʤ뤫ե -ȥե˰¸ޤ - - -[2] եȤ̾ - - եȤ̾Ȥˤϡcopyfont Ȥڥ졼Ȥ -ޤcopyfont ΥեޥåȤϼ̤Ǥ - - ¸Υե̾ ̾ copyfont - -㤨С/GothicBBB-Medium-83pv-RKSJ-H ̾Ȥ /ChuGothicBBB-Medium -Ȥˤϡե졼ե˼Τ褦˽񤭤ޤ - - /GothicBBB-Medium-83pv-RKSJ-H /ChuGothicBBB-Medium copyfont - - - -ޥɥץ - -gs ޥɤΥץȤưʲΤΤȤޤ - - -dNOKANJI եȤʤʤޤ - -sKCONFIG=pcf.ps ե졼եꤷޤ - - - -եȤΥ饤󥹤ˤĤ - -ʲϴեȤΥ饤󥹤ˤĤƤξǤͤˤƲ - - - Zeitֽζ - - ZeitեѤΥץ줿ܤ䤤碌Ʋä -֥եȥǡɽФϡ桼ζե꡼ -ˤäɽФΤǤйʤפȤäǤ - - - ܰJTeXѥեȡ - - ؤܹ뤵ܰ䤤碌ƲäȤ֤ -ȤΥ饤󥹷TeXѤȤʤäƤΤǡʷ֤ǻѤ -ܰϢɬפפȤäǤ - -ʲϡܤΥ᡼뤫ΰѤǤ - -ܰΥեȤȤˤäƤϡ ----- ---- - -TeX ΥեȤ GhostScript ΥեȥǻȤ -ޤ -ȤݤΥ򡢲äƤФǤ - -162-01 ɶԥëòĮ 1-1-1 -ܰʳ CTS CTS ȯƥ೫ȯ 1 -ƣ - - СʤǤܰμ긵ˤ˻ѵ -źդƤȤΤȤǤ - ʤǤ˥饤󥹤äƤȸä򤷤ޤ - PK ѴƻȤGhostScript PK б -ȤȤȤˤĤƤ⡢Υ˼ºݤλѷ֤ -񤱤ФɤǤ⤫ޤʤǤ - ----- ޤ ---- - - - -ռ - -ΥѥåˤäƤϰʲˤϤĺޤ -ξ򤫤Ƥ鿽夲ޤ꤬Ȥޤ - -gs23j10 γȯ˶ϤƲä - IMAGICAΰ - 칩α - ˭縫Ź - ŲŹ绳ů蘆 - 縲 - ηԤ - ıݹ - ٻ̹ݸϤ -  - -ZeitեޥåȥեѤδեȥץ줿 - 幯 - Ŵ󤵤 - -Zeit JG եޥåȥեѤδեȥץ줿 - ɻ ŵ - -Canon LIPS-II/II+/III ץѥɥ饤Ф줿 - ŵ縲 - -NEC PC-PR150 ץѥɥ饤Ф줿 - ؤι餵 - -ESC/Page ѥɥ饤Ф줿 - ŵޥ󥳥󥷥ƥ彣LSIȯ󥿡 - -Star JJ-100 ץѥɥ饤Ф줿 - ͳ - -Canon BJ10v ץѥɥ饤Ф줿 - ıؤδ浱ˤػʤ󡢾湧ͺ - - - -ե롦ꥹ - -gs261j.doc ɥ(Ѹ) -gs261j.jis ɥ(JIS) -gs261j.sj ɥ(եJIS) -gs261j.euc ɥ(EUC) - -gs261j.diff Ghostscript Ver. 2.6.1 ʬե - -zcomp.c ʣեȥڥ졼ץ -kfutil.c եȥ桼ƥƥץ -zkfimpath.c ᡼ѥڥ졼ץ - -zkfpcf.c PCFեѥڥ졼ץ -zkfsnf.c SNFեѥڥ졼ץ -zkfsony.c Sony(TM)٥եѥڥ졼ץ -zkfzeit.c Zeit(TM)եѥڥ졼ץ -zkfztbez.c Zeit(TM) JG եѥڥ졼ץ -zkfjtex.c ܸTeX PKեѥڥ졼ץ - -drivers/ - gdevnwp/ Sony NWP-533/537 ץѥɥ饤 - gdevlips/ Canon LIPS-II/II+/III ץѥɥ饤 - gdevp201/ NEC PC-PR201 ץѥɥ饤 - gdevp150/ NEC PC-PR150 ץѥɥ饤 - gdevepag/ ESC/Page ѥɥ饤 - gdevj100/ Star JJ-100 ץѥɥ饤 - gdev10v/ Canon BJ10v ץѥɥ饤 - -kanji/ - kinit.ps ѥץ - metrics2.ps Ľѥץ - kbitmap.ps ӥåȥޥå״եѥץ - koutline.ps ȥ饤եѥץ - kbase.ps ١եѥץ - kcomp.ps ʣեѥץ - kmapping.ps JISɥޥåԥѥץ - - kfpcf.ps X11R5 PCFեѥץ - kfsnf.ps X11R4 SNFեѥץ - kfsony.ps Sony(TM)٥եѥץ - kfzeit.ps Zeit(TM)եѥץ - kfztbez.ps Zeit(TM) JG եѥץ - kfjtex.ps ܸTeX PKեѥץ - - pcf.ps X11R5 PCFեѥƥץ졼ȥե - snf.ps X11R4 SNFեѥƥץ졼ȥե - sony.ps Sony(TM)٥եѥƥץ졼ȥե - zeit.ps Zeit(TM)٥եѥƥץ졼ȥե - ztbez.ps Zeit(TM) JG եѥƥץ졼ȥե - jtex.ps ܸTeX PKեѥƥץ졼ȥե - - hankaku.ps Ⱦʸɽץ - allkanji.ps ɽץ - fmaptype.ps ʣեȥޥåԥ󥰥ץ - vchars.ps ĽʸΥץ - article9.ps ĽʸϤΥץ - -include.pcf/ PCFեѥإåեǼǥ쥯ȥ -include.snf/ SNFեѥإåեǼǥ쥯ȥ - - - -СˤĤ - -gs23j10 (Oct. 4, 1991) - Ghostscript ver. 2.3 ܸ첽ѥå - -gs23j11 (Dec.24, 1991) - եȥե̾򸡺ϥå롼ΥХ - ѿ̾ index ȴؿ̾ index Ȥͤ򤷤 - -gs23j12 (Jan.17, 1992) - եȥȥåñοͤǻꤷȤ顼Х - - - -gs24j10 (May.15, 1992) - Ghostscript ver. 2.4.1 ܸ첽ѥå - -gs241j11 (Jul. 1, 1992) - gs24j10 ΥХ - - -gs261j01b (Aug.20, 1993) - Ghostscript ver. 2.6.1 ܸ첽ѥå ¥С - -gs261j10 (Jan.11, 1994) - Ghostscript ver. 2.6.1 ܸ첽ѥå - - - -ʬˤĤ - -bfont.h - make_composite_font(), make_descender_fonts()Υץȥɲá - -gs_init.ps - ꥸʥΥեȥڥ졼ʣեȥڥ졼ִ - kinit.ps metrics2.ps ɤ߹Ѥѹ - -gs_fonts.ps - QUIET ⡼ɤǡġեȥե뤬ĤʤȤե̾ - å˻ĤƤޤȤԶν - -gschar.c - gs_setcachedevice2 Ľ񤭥ե(WMode=1)б - gs_setrootfont(), gs_currentrootfont() - -gschar.h - gs_setrootfont(), gs_currentrootfont()Υץȥɲá - -gsfont.c - å奵硣 - UniqueID ʤϤʣեȤ򡢥١եƱͥå -ƤޤȤԶν - -gzstate.h - ֤Ȥơrootfont ɲá - -zchar2.c - zrootfont() gs_currentrootfont() Ȥ褦ѹ - -zfont.c - 롼ȥեȤб뤿ᡢzsetfontѹ - ʣեȤФ makefont Ԥʤݡmake_composite_font() -֤褦ѹ - make_composite_font() - -zfont0.c - zbuildfont0κǸǡmake_descender_fonts()Ƥ֤褦ѹ - make_descender_fonts() - -zfont2.c - makefontåθΨΤᵶUniqueID褦ѹ - -gs.mak - ʣեȵǽեȵǽɲá - -cc-head.mak -gcc-head.mak -ansihead.mak - GS_LIB_DEFAULT $(gsdatadir)/kanji ɲá - ѥ롦ץ -DCOMPFONT -DWMODE -DKANJI ɲá - FEATURE_DEVS kanji.dev kfpcf.dev kfsnf.dev kfzeit.dev kfztbez.dev - kfjtex.dev ɲá - -unixhead.mak - ۤΥ롼 `.c.o' ΰ¸ե $(AK) - -unixtail.mak - Ϥ¹ԥե̾ `gs' $(GS)$(XE) ѹ - -unix-cc.mak -unix-gcc.mak -unix-ansi.mak - gs.mak, cc-head.mak, gcc-head.mak, ansihead.mak ˹碌ѹ diff -Nru ghostscript-9.10~dfsg/contrib/japanese/doc/gs261j.txt ghostscript-9.25~dfsg+1/contrib/japanese/doc/gs261j.txt --- ghostscript-9.10~dfsg/contrib/japanese/doc/gs261j.txt 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/doc/gs261j.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,494 +0,0 @@ -Ghostscript Kanji Package gs261j -Version 1.0 Jan.11,1994 by Norio KATAYAMA (katayama@nacsis.ac.jp) -Copyright (C) 1991,1992,1993,1994 Norio Katayama. -This document is translated into English on Jan.11,1994. - - -Features -======== - - 1. Support for Japanese. - a. composite fonts. - b. font metrics (Metrics, Metrics2, CDevProc). - c. vertical writing (WMode). - - 2. Support for Kanji font files. - a. X11R5 PCF font files. - b. X11R4 SNF font files. - c. Sony(TM) vector font files. - d. Zeit(TM) format font files. - Authors: Takuji KAWAMOTO, and Yasunari INOUE. - e. Zeit(TM) JG format font files. - Author: Kazunori ASAYAMA - f. JTeX PK font files. - - 3. Device drivers. - a. gdevnwp (Sony NWP-533/537 printer) - b. gdevlips (Canon LIPS-II/II+/III printer) - Author: Akihisa KURASHIMA - c. gdevp201 (NEC PC-PR201 printer) - d. gdevp150 (NEC PC-PR150 printer) - Author: Takuya KOUMOTO - e. gdevepag (ESC/Page) - Author: Hiroshi NARIMATSU - f. gdevj100 (Star JJ-100 printer) - Author: Caz Yokoyama - g. gdev10v (Canon BJ10v printer) - Authors: Teruo IWAI, Atusi MAEDA, Takao MATUI - - -Tested Environments -=================== - - +--------------+-----------------+-----------------+-------------+ - | OS | Machine | Compiler | Device | - +--------------+-----------------+-----------------+-------------+ - | SunOS 4.1.3 | SPARC Station 2 | cc -O / gcc -O | X11 | - +--------------+-----------------+-----------------+-------------+ - - - -Notes -===== - -Any questions, requests, and bug reports are welcomed. - JUNET: katayama@nacsis.ac.jp NIFTY: NBB01613 - - - -Notices -======= - -Sony vector font files, Zeit format font files, and JTeX PK font files -are commercial products. Please be careful not to violate their -licenses. - -This Kanji package is not an official patch. Therefore you should keep -the original distribution. - -No author takes responsibility for the consequences of using this -package. - -Everyone is permitted to copy, modify and redistribute this package -only for nonprofit use. - - -How to install (UNIX) -===================== - -[1] Building Ghostscript - -(1) Extract source files from the original distribution of Ghostscript - version 2.6.1. - This package is based on the source files to which the following - patches are applied. - ghostscript-2.6.1.fix-01.gz - ghostscript-2.6.1.fix-02.gz - ghostscript-2.6.1.fix-03.gz - ghostscript-2.6.1.fix-04.gz - -(2) Extract the contents of this package in the directory containing - the original source files. - -(3) Apply a patch file `gs261j.diff' to the original source files. - -(4) Copy unix-cc.mak, unix-gcc.mak or unix-ansi.mak onto Makefile, and - edit it appropriately. At least four configurations described - below must be done. - - 1. Set prefix, exec_prefix, bindir, datadir, and gsdatadir macros to - specify the directory to which Ghostscript will be installed. - - - 2. Set CFLAGS, LDFLAGS, EXTRALIBS, XINCLUDE, and XLIBDIRS macros to - configure compilation options. - - 3. Choose the features of Kanji font files to be included and add - some of the symbols listed below to FEATURE_DEVS. - - kfpcf.dev X11R5 PCF font files. - kfsnf.dev X11R4 SNF font files. - kfsony.dev Sony vector font files. - kfzeit.dev Zeit format font files. - kfztbez.dev Zeit JG format font files. - kfjtex.dev JTeX PK font files. - - Examples) - To include the features of PCF font files, SNF font files, Zeit - format font files, Zeit JG format font files, and JTeX PK font files. - - FEATURE_DEVS=filter.dev dps.dev level2.dev kanji.dev \ - kfpcf.dev kfsnf.dev kfzeit.dev kfztbez.dev kfjtex.dev - - To include the feature of Sony vector font files only. - - FEATURE_DEVS=filter.dev dps.dev level2.dev kanji.dev \ - kfsony.dev - - To include the features of PCF font files, SNF font files, Zeit - format font files, Zeit JG format font files, JTeX PK font files, - and Sony vector font files. - - FEATURE_DEVS=filter.dev dps.dev level2.dev kanji.dev \ - kfpcf.dev kfsnf.dev kfzeit.dev kfztbez.dev kfjtex.dev \ - kfsony.dev - - - 4. Choose the devices to be included and add the symbols for them to - DEVICE_DEVS. - - Example) - To include the device driver of X11. - - DEVICE_DEVS=x11.dev - - If you want to use the device drivers contained in this package, - see documents in the `drivers' subdirectory. - - -(5) MAKE and install Ghostscript. - -(6) Extract font files from ghostscript-fonts-2.6.1.tar.gz into the - directory specified by the gsdatadir macro in Makefile. - - Example) - When gsdatadir is the default value (/usr/local/lib/ghostscript) : - - % cd /usr/local/lib/ghostscript - % gunzip < ghostscript-fonts-2.6.1.tar.gz | tar xvf - - - -[2] Configuring Kanji Fonts - -(1) Change the working directory to the `kanji' directory which is a - subdirectory of the directory specified by the gsdatadir macro in - Makefile. - - Example) - When gsdatadir is the default value (/usr/local/lib/ghostscript) : - - % cd /usr/local/lib/ghostscript - % cd kanji - -(2) Copy one of the following template files onto `kconfig.ps'. - - pcf.ps for X11R5 PCF font files. - snf.ps for X11R4 SNF font files. - sony.ps for Sony vector font files. - zeit.ps for Zeit format font files. - ztbez.ps for Zeit JG format font files. - jtex.ps for JTeX PK font files. - -(3) Edit `kconfig.ps' appropriately. Normally, you have only to change - the names of font files. - - The details of `kconfig.ps' are described in the section ``Kanji - Configuration File''. - - -[3] Testing Kanji fonts. - - Execute the following sample programs with gs and verify Kanji fonts - are displayed correctly. - - hankaku.ps A list of half-width Kanji characters. - allkanji.ps A list of Kanji characters. - fmaptype.ps A test program of the composite font mapping. - vchars.ps A list of characters for vertical writing. - article9.ps Article 9 of the Constitution of Japan. - - Because sample programs are contained in the Kanji library directory, - you need not specify a directory path. - - Example) - % gs hankaku.ps - -Note ----- - If you use X11R4 SNF font files which are provided by manufactures - (i.e. not made from the MIT distribution), it is possible that - Kanji characters are not displayed correctly. This is because the - SNF format is dependent on X server and the default values defined - in bdftosnf.h is not appropriate to the server. Edit lines from 37 - to 53 in zkfsnf.c to solve this problem. - - - -Kanji Configuration File -======================== - - Kanji fonts for Ghostscript are defined in the Kanji configuration - file. The name of this file is `kconfig.ps' by default, but it can - be changed by -sKCONFIG switch (see the section `Command switches'). - -[1] Definition of Kanji Fonts - - Kanji fonts are defined in the following format. - - FontName UniqueID [ FileName ] Operator - - FontName - is a name of the Kanji font to be defined. - `/Ryumin-Light' and `/GothicBBB-Medium' are standard Kanji fonts. - - UniqueID - is a unique identifier of the font. - Normally, the identifiers may be set from 4300000 with 200 - differences. - - FileName - is the name of the font file to be used. - The rule of this field is determined by `Operator', so see - comments in the template files for details - - Operator - is a Ghostscript operator to define Kanji font. - - For example, if you want to define a Kanji font with a name - `/Ryumin-Light' using a X11R5 PCF font file whose path name is - "/usr/lib/X11/fonts/misc/k24.pcf", you will write the following line - in the Kanji configuration file. - - /Ryumin-Light 4300000 (/usr/lib/X11/fonts/misc/k24.pcf) pcfkanji - - With this line, the following Kanji fonts will be available. - - /Ryumin-Light.r## (## = 21 - 7E) horizontal JIS base Kanji - /Ryumin-Light.r##v (## = 21, 22, 24, 25) vertical JIS base Kanji - /Ryumin-Light.sr## (## = 81 - 9F, E0 - EA) horizontal SJIS base Kanji - /Ryumin-Light.sr##v (## = 81 - 83) vertical SJIS base Kanji - - /Ryumin-Light.Roman half-width alphanumeric characters - /Ryumin-Light.Hiragana half-width Hiragana - /Ryumin-Light.Katakana half-width Katakana - /Ryumin-Light.Hankaku half-width alphanumerics, Hiragana, Katakana - /Ryumin-Light.SuppK half-width Katakana for SJIS - - /Ryumin-Light-H horizontal JIS Kanji - /Ryumin-Light-V vertical JIS Kanji - /Ryumin-Light-Ext-H horizontal Extended JIS Kanji - /Ryumin-Light-Ext-V vertical Extended JIS Kanji - /Ryumin-Light-EUC-H horizontal EUC Kanji - /Ryumin-Light-EUC-V vertical EUC Kanji - /Ryumin-Light-RKSJ-H horizontal Roman, Katakana, SJIS Kanji - /Ryumin-Light-RKSJ-V vertical Roman, Katakana, SJIS Kanji - /Ryumin-Light-83pv-RKSJ-H horizontal Roman, Katakana, SJIS Kanji - - Although Kanji fonts in Extended JIS Encoding are defined, - characters to be displayed are determined by the contents of font - files. For the same reason, the Kanji encoding such as JIS-78 and - JIS-83 are also determined by font files. - -[2] Definition of Aliases - - An operator `copykanji' can be used to define aliases of Kanji fonts. - The following is the format of `copykanji'. - - FontName NewName copykanji - - For example, the following line defines an alias `/ChuGothicBBB-Medium' - for the font `/GothicBBB-Medium-83pv-RKSJ-H'. - - /GothicBBB-Medium-83pv-RKSJ-H /ChuGothicBBB-Medium copykanji - - -Command Switches -================ - -New command switches are available. - - -dNOKANJI Suppress installing Kanji fonts. - -sKCONFIG=foo.ps Define the name of the Kanji configuration file. - - -Acknowledgements -================ - -In developing this package I obtained cooperation from the following -persons. I make my acknowledgement with thanks to them. - -Cooperators in developing gs23j10. - IKAWA, Takanori UGAI, Yoshihiro OHMI, Tetsuya OHYAMA, - Akihisa KURASHIMA, Masayuki KUWADA, NAKAMARU, NORO, - and Hisashi MINAMINO - -Authors of the feature of Zeit format font files. - Takuji KAWAMOTO, and Yasunari INOUE - -Author of the feature of Zeit JG format font files. - Kazunori ASAYAMA - -Author of the Canon LIPS-II/II+/III printer driver. - Akihisa KURASHIMA - -Author of the NEC PC-PR150 printer printer driver. - Takuya KOUMOTO - -Author of the ESC/Page printer driver. - Hiroshi NARIMATSU - -Author of the Star JJ-100 printer driver. - Caz Yokoyama - -Author of the Canon BJ10v printer driver. - Teruo IWAI, Atusi MAEDA, Takao MATUI - - -File List -========= - -gs261j.doc Document of this package (English) -gs261j.jis Document of this package (Japanese in JIS Kanji) -gs261j.sj Document of this package (Japanese in SJIS Kanji) -gs261j.euc Document of this package (Japanese in EUC Kanji) - -gs261j.diff Patch file for Ghostscript version 2.4.1 - -zcomp.c C program defining composite font operators. -kfutil.c C program defining Kanji font utilities. -zkfimpath.c C program defining imagepath operator. - -zkfpcf.c C program defining PCF font file operator. -zkfsnf.c C program defining SNF font file operator. -zkfsony.c C program defining Sony vector font file operator. -zkfzeit.c C program defining Zeit font file operator. -zkfztbez.c C program defining Zeit JG font file operator. -zkfjtex.c C program defining JTeX PK font file operator. - -drivers/ - gdevnwp/ Sony NWP-533/537 printer driver - gdevlips/ Canon LIPS-II/II+/III printer driver - gdevp201/ NEC PC-PR201 printer driver - gdevp150/ NEC PC-PR150 printer driver - gdevpag/ ESC/Page printer driver - gdevj100/ Star JJ-100 printer driver - gdev10v/ Canon BJ10v printer - -kanji/ - kinit.ps GS program for Kanji environment. - metrics2.ps GS program for vertical writing. - kbitmap.ps GS program for bitmap Kanji fonts. - koutline.ps GS program for outline Kanji fonts. - kbase.ps GS program for defining Kanji base fonts. - kcomp.ps GS program for defining Kanji composite fonts. - kmapping.ps GS program for the mapping from symbols to JIS codes. - - kfpcf.ps GS program for X11R5 PCF font files. - kfsnf.ps GS program for X11R4 SNF font files. - kfsony.ps GS program for Sony vector font files. - kfzeit.ps GS program for Zeit format font files. - kfztbez.ps GS program for Zeit JG format font files. - kfjtex.ps GS program for JTeX PK font files. - - pcf.ps Template file for X11R5 PCF font files. - snf.ps Template file for X11R4 SNF font files. - sony.ps Template file for Sony vector font files. - zeit.ps Template file for Zeit format font files. - ztbez.ps Template file for Zeit JG format font files. - jtex.ps Template file for JTeX PK font files. - - hankaku.ps Sample of half-width Kanji characters. - allkanji.ps Sample of Kanji characters. - fmaptype.ps Sample of the composite font mapping. - vchars.ps Sample of characters for vertical writing. - article9.ps Sample of vertical writing. - -include.pcf/ Directory containing header files for PCF fonts. -include.snf/ Directory containing header files for SNF fonts. - - -History -======= - -gs23j10 (Oct. 4, 1991) - Kanji package for Ghostscript version 2.3. - -gs23j11 (Dec.24, 1991) - -gs23j12 (Jan.17, 1992) - - -gs24j10 (May.15, 1992) - Kanji package for Ghostscript version 2.4.1. - -gs241j11 (Jul. 1, 1992) - - -gs261j01b (Aug.20, 1993) - Kanji package for Ghostscript version 2.6.1. (beta version) - -gs261j10 (Jan.11, 1994) - Kanji package for Ghostscript version 2.6.1. - - -Patches -======= - -bfont.h - The prototype declaration of make_composite_font() and - make_descender_fonts() are added. - -gs_init.ps - Base font operators are replaced with composite font operators. - `kinit.ps' and `metrics2.ps' are invoked. - -gs_fonts.ps - The problem is fixed that the findfont operator leaves a font name - in the stack when it is in QUIET mode and the font file is not found. - -gschar.c - gs_setcachedevice2() is adapted to the vertical writing. - The vertical writing feature is implemented. - gs_setrootfont() and gs_currentrootfont() are defined. - -gschar.h - The prototype declaration of gs_setrootfont() and gs_currentrootfont() - are added. - -gsfont.c - The font cache is enlarged for the efficiency of Kanji fonts. - The problem is fixed that composite fonts, which have no UniqueID, - are cached by makefont. - -gzstate.h - rootfont is added into the graphics state. - -zchar.c - zrootfont() is changed to call gs_currentrootfont(). - -zfont.c - zsetfont() is adapted to rootfont. - make_font() calls make_composite_font() when it transforms composite - fonts. - make_composite_font() is defined. - -zfont0.c - zbuildfont0() is changed to call make_descender_fonts(). - make_descender_fonts() is defined. - -zfont2.c - A `fake UniqueID' facility is implemented to enhance the efficiency - of the `makefont' cache. - -gs.mak - The features of composite fonts and Kanji fonts are added. - -cc-head.mak -gcc-head.mak -ansihead.mak - `$(gsdatadir)/kanji' is added to the GS_LIB_DEFAULT macro. - `-DCOMPFONT -DWMODE -DKANJI' is added to the compilation flags. - `kanji.dev kfpcf.dev kfsnf.dev kfzeit.dev kfztbez.dev kfjtex.dev' is - added to the FEATURE_DEVS macro. - -unixhead.mak - The dependency `$(AK)' is removed from the implicit rule `.c.o'. - -unixtail.mak - The name of the output file is changed from `gs' to` $(GS)$(XE)'. - -unix-cc.mak -unix-gcc.mak -unix-ansi.mak - These files are updated according to the changes of gs.mak, - cc-head.mak, gcc-head.mak, and ansihead.mak. diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdev10v.c ghostscript-9.25~dfsg+1/contrib/japanese/gdev10v.c --- ghostscript-9.10~dfsg/contrib/japanese/gdev10v.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdev10v.c 2018-09-13 10:02:01.000000000 +0000 @@ -183,7 +183,7 @@ static void bj10v_output_run(byte *data, int dnum, int bytes, - char *mode, gx_device_printer *pdev) + const char *mode, gx_device_printer *pdev) { prn_putc(pdev, '\033'); prn_puts(pdev, mode); @@ -198,7 +198,7 @@ { int line_size = gdev_prn_raster((gx_device *)pdev); int xres = pdev->x_pixels_per_inch; int yres = pdev->y_pixels_per_inch; - char *mode = (yres == 180 ? + const char *mode = (yres == 180 ? (xres == 180 ? "\052\047" : "\052\050") : "|*"); int bits_per_column = 24 * (yres / 180); @@ -223,7 +223,6 @@ { byte *out_beg; byte *out_end; byte *outl, *outp; - byte *zp; int count, bnum; /* Copy 1 scan line and test for all zero. */ diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevalps.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevalps.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevalps.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevalps.c 2018-09-13 10:02:01.000000000 +0000 @@ -201,6 +201,8 @@ memset(data, 0, LINE_SIZE); n = gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size); + if (n != 1) + return n; /* Remove trailing 0s. */ while ( end_data > data && end_data[-1] == 0 ) diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevdmpr.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevdmpr.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevdmpr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevdmpr.c 2018-09-13 10:02:01.000000000 +0000 @@ -32,7 +32,7 @@ #include "gdevprn.h" #include "gp.h" -#include "errors.h" +#include "gserrors.h" #include "gsparam.h" #include "gsstate.h" #include "math_.h" @@ -435,7 +435,7 @@ code = param_read_int_array(plist, "MaxSize", &vaint); if (code < 0) return code; if (code == 0) { - if (vaint.size != 2) return e_typecheck; + if (vaint.size != 2) return_error(gs_error_typecheck); pddev->dmprt.max_width = vaint.data[0]; pddev->dmprt.max_height = vaint.data[1]; } @@ -443,7 +443,7 @@ code = param_read_int_array(plist, "Offsets", &vaint); if (code < 0) return code; if (code == 0) { - if (vaint.size != 2) return e_typecheck; + if (vaint.size != 2) return_error(gs_error_typecheck); pddev->dmprt.x_offset = vaint.data[0]; pddev->dmprt.y_offset = vaint.data[1]; } @@ -452,7 +452,7 @@ if (code < 0) return code; if (code == 0) { int i; - if (vaint.size != 4) return e_typecheck; + if (vaint.size != 4) return_error(gs_error_typecheck); for (i=0;i<4;i++) pddev->dmprt.dev_margin[i] = vaint.data[i]; } @@ -475,7 +475,7 @@ char *filename = gs_malloc(pdev->memory->non_gc_memory, vstr.size + 1, 1, "gdev_dmprt_put_props(filename)"); int ccode; - if (filename == 0) return e_VMerror; + if (filename == 0) return_error(gs_error_VMerror); strncpy(filename, (const char*)vstr.data, vstr.size); filename[vstr.size] = '\0'; ccode = gdev_dmprt_get_printer_props(pddev,filename); @@ -566,7 +566,7 @@ } } if (gdev_dmprt_encode_list[i].name == 0) - return e_rangecheck; + return_error(gs_error_rangecheck); } return code; @@ -582,9 +582,9 @@ if (code == 0) { int ccode = gdev_dmprt_check_code_props(vstr.data, vstr.size); byte *pbyte; - if (ccode < 0) return e_rangecheck; + if (ccode < 0) return_error(gs_error_rangecheck); pbyte = (byte *)malloc(vstr.size+1); - if (pbyte == 0) return e_VMerror; + if (pbyte == 0) return_error(gs_error_VMerror); memcpy(pbyte, vstr.data, vstr.size); pbyte[vstr.size] = 0; pprt->prtcode[idx] = pbyte; @@ -604,7 +604,7 @@ if (code == 0) { byte *pbyte; pbyte = (byte *)malloc(vstr.size+1); - if (pbyte == 0) return e_VMerror; + if (pbyte == 0) return_error(gs_error_VMerror); memcpy(pbyte, vstr.data, vstr.size); pbyte[vstr.size] = 0; pprt->strings[idx] = pbyte; @@ -686,7 +686,7 @@ /* get work buffer */ in = (byte *)gs_malloc(pdev->memory->non_gc_memory, 1, i_buf_size ,"gdev_dmprt_print_page(in)"); if ( in == 0 ) - return e_VMerror; + return_error(gs_error_VMerror); /* Initialize this printer driver */ if (pdev->file_is_new) { @@ -760,19 +760,19 @@ if (fmt & CFG_FMT_BIT) { int s = *str++; str += s; - if (str > end) return e_rangecheck; + if (str > end) return_error(gs_error_rangecheck); if ((fmt & CFG_FMT_FORMAT_BIT) == CFG_FMT_STRINGS) { s = *str++; str += s; - if (str > end) return e_rangecheck; + if (str > end) return_error(gs_error_rangecheck); } } else { str += fmt; - if (str > end) return e_rangecheck; + if (str > end) return_error(gs_error_rangecheck); } } - return str == end ? 0 : e_rangecheck; + return str == end ? 0 : gs_error_rangecheck; } static void @@ -803,19 +803,19 @@ char *fname; fname = gs_malloc(pdev->memory->non_gc_memory, 256,1,"dviprt_lib_fname"); - if (fname == NULL) return e_VMerror; + if (fname == NULL) return_error(gs_error_VMerror); fp = gdev_dmprt_dviprt_lib_fopen(fnamebase,fname); if (fp == NULL) { - return e_undefinedfilename; + return_error(gs_error_undefinedfilename); } if (fseek(fp,18,0) < 0) - return e_ioerror; + return_error(gs_error_ioerror); code = fgetc(fp); fclose(fp); if (code == EOF) - code = e_ioerror; + code = gs_error_ioerror; else if (code == 0xff) { code = dviprt_readcfg(fname,&cfg,NULL,0,NULL,0); } @@ -865,10 +865,10 @@ { switch (code) { case CFG_ERROR_MEMORY: - return e_VMerror; + return_error(gs_error_VMerror); case CFG_ERROR_FILE_OPEN: case CFG_ERROR_OUTPUT: - return e_ioerror; + return gs_errpr_ioerror; default: return -1; } diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevespg.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevespg.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevespg.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevespg.c 2018-09-13 10:02:01.000000000 +0000 @@ -60,7 +60,7 @@ #define ppdev ((gx_device_printer *)pdev) -static char *epson_remote_start = "\033\001@EJL \r\n"; +static const char *epson_remote_start = "\033\001@EJL \r\n"; /* Open the printer. */ static int diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevfmpr.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevfmpr.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevfmpr.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevfmpr.c 2018-09-13 10:02:01.000000000 +0000 @@ -50,13 +50,13 @@ } static int -prn_puts(gx_device_printer *pdev, char *ptr) +prn_puts(gx_device_printer *pdev, const char *ptr) { return fputs(ptr, pdev->file); } static int -prn_write(gx_device_printer *pdev, char *ptr, int size) +prn_write(gx_device_printer *pdev, const char *ptr, int size) { return fwrite(ptr, 1, size, pdev->file); } @@ -192,7 +192,7 @@ size = out_end - out_beg + 1; gs_sprintf(prn_buf, "\033Q%d W", size / bytes_per_column); prn_puts(pdev, prn_buf); - prn_write(pdev, out_beg, size); + prn_write(pdev, (const char *)out_beg, size); prn_putc(pdev, '\n'); } diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevlbp3.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevlbp3.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevlbp3.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevlbp3.c 2018-09-13 10:02:01.000000000 +0000 @@ -72,7 +72,7 @@ lbp310PrintPage(gx_device_printer *pDev, FILE *fp) { int i; - byte Buf[10]; + char Buf[10]; long DataSize; struct bounding Box; @@ -81,7 +81,7 @@ DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.r"); /* ----==== Set size ====---- */ - gs_sprintf((char *)Buf, "0%ld", DataSize); + gs_sprintf(Buf, "0%ld", DataSize); i = (DataSize+strlen(Buf)+1)&1; /* ----==== escape to LIPS ====---- */ fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); @@ -94,7 +94,7 @@ lbp320PrintPage(gx_device_printer *pDev, FILE *fp) { int i; - byte Buf[16]; + char Buf[16]; long DataSize; struct bounding Box; @@ -110,7 +110,7 @@ DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.&r"); /* ----==== Set size ====---- */ - gs_sprintf((char *)Buf, "000%ld", DataSize); + gs_sprintf(Buf, "000%ld", DataSize); i = (DataSize+strlen(Buf)+1)&3; /* ----==== escape to LIPS ====---- */ fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); @@ -181,7 +181,7 @@ int x, y, i, count = 255; int Xres = (int)pDev->x_pixels_per_inch; int LineSize = gdev_mem_bytes_per_scan_line((gx_device *)pDev); - byte *Buf, oBuf[128], c_prev, c_cur, c_tmp; + byte *Buf, oBuf[128], c_prev = 0, c_cur, c_tmp; long DataSize = 0; /* ----==== Printer initialize ====---- */ diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevmag.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevmag.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevmag.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevmag.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,335 +0,0 @@ -/* Copyright (C) 1992, 1993 Aladdin Enterprises. All rights reserved. - -This file is part of Ghostscript. - -Ghostscript is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY. No author or distributor accepts responsibility -to anyone for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. Refer -to the Ghostscript General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute -Ghostscript, but only under the conditions described in the Ghostscript -General Public License. A copy of this license is supposed to have been -given to you along with Ghostscript so you can know your rights and -responsibilities. It should be in a file named COPYING. Among other -things, the copyright notice and this notice must be preserved on all -copies. */ - -/* gdevmag.c */ -/* .MAG file format devices for Ghostscript */ -#include "gdevprn.h" -#include "gdevpccm.h" -#include - -/* ------ The device descriptors ------ */ - -/* - * Default X and Y resolution. - */ -#define HEIGHT_10THS 117 -#define DPI (8000.0/HEIGHT_10THS) -#define WIDTH_10THS (6400.0 / DPI) - -static dev_proc_print_page(mag_4bit_print_page); -static dev_proc_open_device(gdev_mag_4bit_open); -static dev_proc_print_page(mag_8bit_print_page); -static dev_proc_open_device(gdev_mag_8bit_open); - -/* internal routines. */ -static int mag_make_flag(gx_device_printer *,int ,int ,byte **, byte *,byte *); -static int mag_comp_flag(gx_device_printer *,int ,byte * ,byte *,byte *, int, byte *); -static int mag_write_palette(gx_device_printer * ,int ); -static int mag_print_page(gx_device_printer * , int , FILE * ); - -/* 4-bit planar (PC-9801 style) color. */ - -static gx_device_procs mag16_procs = - prn_color_procs(gdev_mag_4bit_open, gdev_prn_output_page, gdev_prn_close, - pc_4bit_map_rgb_color, pc_4bit_map_color_rgb); -gx_device_printer far_data gs_mag16_device = - prn_device(mag16_procs, "mag16", - (int)WIDTH_10THS, (int)HEIGHT_10THS, - DPI, DPI, - 0,0,0,0, /* margins */ - 4, mag_4bit_print_page); - -/* 8-bit planar color. */ - -static gx_device_procs mag256_procs = - prn_color_procs(gdev_mag_8bit_open, gdev_prn_output_page, gdev_prn_close, - pc_8bit_map_rgb_color, pc_8bit_map_color_rgb); -gx_device_printer far_data gs_mag256_device = - prn_device(mag256_procs, "mag256", - (int)WIDTH_10THS, (int)HEIGHT_10THS, - DPI, DPI, - 0,0,0,0, /* margins */ - 8, mag_8bit_print_page); - -/* ------ Private definitions ------ */ - -static int -gdev_mag_4bit_open(gx_device *dev) -{ - dev->width = (dev->width + 7) / 8 * 8; - return gdev_prn_open(dev); -} - -static int -gdev_mag_8bit_open(gx_device *dev) -{ - dev->width = (dev->width + 3) / 4 * 4; - return gdev_prn_open(dev); -} - -static int -mag_4bit_print_page(gx_device_printer *pdev,FILE *file) -{ return mag_print_page(pdev,4,file); -} - -static int -mag_8bit_print_page(gx_device_printer *pdev,FILE *file) -{ return mag_print_page(pdev,8,file); -} - -/* Write out a page in MAG format. */ -/* This routine is used for all formats. */ -static int -mag_print_page(gx_device_printer *pdev, int depth, FILE *file) -{ - int code = 0; /* return code */ - const char *magic = "MAKI02 gs "; - char *user = getenv("USER"); - char check[256]; - byte header[32] = "\000\000\000\000" - "\000\000\000\000" - "\000\000\000\000"; - byte *flag; - byte *flag_prev; - byte *flag_a,*flag_b; - byte *row_buffer; - byte *row[17]; - byte *pixel; - int raster = gdev_prn_raster(pdev); - int height = pdev->height; - int width = pdev->width; - int width_pixel = width / ((depth == 4) ? 4 : 2 ); - int flag_size = width_pixel / 2; - int flag_a_bytes = (flag_size + 7)/8 + 1; - int flag_b_size = flag_size; - long flag_b_bytes; - long pixel_bytes; - int y; - - row_buffer = (byte *)gs_malloc(pdev->memory->non_gc_memory, raster,17,"mag_row"); - flag = (byte *)gs_malloc(pdev->memory->non_gc_memory, flag_size,2,"mag_flag"); - flag_prev = flag + flag_size; - flag_a = (byte *)gs_malloc(pdev->memory->non_gc_memory, flag_a_bytes,1,"mag_flag_a"); - flag_b = (byte *)gs_malloc(pdev->memory->non_gc_memory, flag_b_size,1,"mag_flag_b"); - pixel = (byte *)gs_malloc(pdev->memory->non_gc_memory, width,1,"mag_pixel"); - if (row_buffer == 0 || flag == 0 || - flag_a == 0 || flag_b == 0 || pixel == 0) { - code = -1; - goto mag_done; - } - for (y=0;y<17;y++) - row[y] = row_buffer + raster*y; - - if (user == 0) user = "Unknown"; - strcpy(check,magic); - gs_sprintf(check+strlen(check),"%-18s",user); - gs_sprintf(check+31," Ghostscript with %s driver\x1a", pdev->dname); - - /* check sizes of flag and pixel data. */ - pixel_bytes = 0; - flag_b_bytes = 0; - { - byte *f0=flag_prev,*f1=flag; - memset(f0,0,flag_size); - for (y=0;y>8)&0xff) -#define put_dword(b,w) (put_word(b,w),put_word((b)+2,(w)>>16)) - header[3] = depth == 4 ? 0 : 0x80; - put_word(header+8,width-1); - put_word(header+10,height-1); - offset = 32 + (1 << depth) * 3; - put_dword(header+12,offset); - offset += (flag_size * height + 7) / 8; - put_dword(header+16,offset); - put_dword(header+20,flag_b_bytes); - offset += flag_b_bytes; - put_dword(header+24,offset); - put_dword(header+28,pixel_bytes); -#undef put_word -#undef put_dword - } - - /* write magic number, header, palettes. */ - fputs(check,file); - fwrite(header,32,1,file); - mag_write_palette(pdev,depth); - - /* write image */ - { int count; - int next_bit; - byte *f0=flag_prev,*f1=flag; - - /* flag A */ - memset(f0,0,flag_size); - next_bit = 0; - for (y=0;ymemory->non_gc_memory, (char *)row_buffer, raster, 17, "mag_row"); - if (flag) gs_free(pdev->memory->non_gc_memory, (char *)flag,flag_size,2,"mag_flag"); - if (flag_a) gs_free(pdev->memory->non_gc_memory, (char *)flag_a,flag_a_bytes,1,"mag_flag_a"); - if (flag_b) gs_free(pdev->memory->non_gc_memory, (char *)flag_b,flag_b_size,1,"mag_flag_b"); - if (pixel) gs_free(pdev->memory->non_gc_memory, (char *)pixel,width,1,"mag_pixel"); - - fflush(file); - - return code; -} - -/* make flag and pixel data */ -static int -mag_make_flag(gx_device_printer *pdev,int line_no, int depth, - byte **row, byte *flag,byte *pixel) -{ - int x; - int raster = gdev_prn_raster(pdev); - byte *ppixel = pixel; - - { byte *prow = row[16]; - for (x=16;x>0;x--) - row[x] = row[x-1]; - row[0] = prow; - } - gdev_prn_copy_scan_lines(pdev,line_no,row[0],raster); - - if (depth == 4) { - for (x=0;x= (a) && line_no >= (b) && \ - *(row[0]+x) == *(row[b] + (x - (a))) && \ - *(row[0]+x+1) == *(row[b] + (x+1 - (a)))) -#define set_flag(v) \ - ((x & 2) ? (flag[x>>2] |= (v)) : (flag[x>>2] = (v)<<4)) - - for (x=0; x>next_bit; - byte *pflag_b = flag_b; - - for ( ;size>0 ; size--) { - byte b = *f0 ^ *f1; - if (mask == 0x80) { - *flag_a = 0; - } - if (b) { - *flag_a |= mask; - *pflag_b++ = b; - } - mask >>= 1; - f0++; - f1++; - if (mask == 0) { - mask = 0x80; - flag_a++; - } - } - - return pflag_b - flag_b; -} - -/* write palette */ -static int -mag_write_palette(gx_device_printer *pdev,int depth) -{ - uint i; - gx_color_value rgb[3]; - int max_index = 1 << depth; - - for ( i = 0; i < max_index; i++ ) { - byte grb[3]; - (pdev->orig_procs.map_color_rgb)((gx_device *)pdev, (gx_color_index)i, rgb); - grb[0] = rgb[1] >> (gx_color_value_bits - 8); - grb[1] = rgb[0] >> (gx_color_value_bits - 8); - grb[2] = rgb[2] >> (gx_color_value_bits - 8); - fwrite(grb, 3,1,pdev->file); - } - return 0; -} diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevmjc.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevmjc.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevmjc.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevmjc.c 2018-09-13 10:02:01.000000000 +0000 @@ -141,6 +141,8 @@ /* Colour mapping procedures */ static dev_proc_map_rgb_color (gdev_mjc_map_rgb_color); static dev_proc_map_color_rgb (gdev_mjc_map_color_rgb); +static dev_proc_encode_color(gdev_mjc_encode_color); +static dev_proc_decode_color(gdev_mjc_decode_color); /* Print-page, properties and miscellaneous procedures */ static dev_proc_open_device(mj700v2c_open); @@ -221,7 +223,45 @@ NULL, /* draw_line */\ gx_default_get_bits,\ proc_get_params,\ - proc_put_params\ + proc_put_params,\ + NULL, /* map_cmyk_color */\ + NULL, /* get_xfont_procs */\ + NULL, /* get_xfont_device */\ + NULL, /* map_rgb_alpha_color */\ + NULL, /* get_page_device */\ + NULL, /* get_alpha_bits */\ + NULL, /* copy_alpha */\ + NULL, /* get_band */\ + NULL, /* copy_rop */\ + NULL, /* fill_path */\ + NULL, /* stroke_path */\ + NULL, /* fill_mask */\ + NULL, /* fill_trapezoid */\ + NULL, /* fill_parallelogram */\ + NULL, /* fill_triangle */\ + NULL, /* draw_thin_line */\ + NULL, /* begin_image */\ + NULL, /* image_data */\ + NULL, /* end_image */\ + NULL, /* strip_tile_rectangle */\ + NULL, /* strip_copy_rop, */\ + NULL, /* get_clipping_box */\ + NULL, /* begin_typed_image */\ + NULL, /* get_bits_rectangle */\ + NULL, /* map_color_rgb_alpha */\ + NULL, /* create_compositor */\ + NULL, /* get_hardware_params */\ + NULL, /* text_begin */\ + NULL, /* finish_copydevice */\ + NULL, /* begin_transparency_group */\ + NULL, /* end_transparency_group */\ + NULL, /* begin_transparency_mask */\ + NULL, /* end_transparency_mask */\ + NULL, /* discard_transparency_layer */\ + NULL, /* get_color_mapping_procs */\ + NULL, /* get_color_comp_index */\ + gdev_mjc_encode_color,\ + gdev_mjc_decode_color\ } static gx_device_procs mj700v2c_procs = @@ -503,8 +543,9 @@ #define FSDline(scan, i, j, plane_size, cErr, mErr, yErr, kErr, cP, mP, yP, kP, n)\ {\ - unsigned short *mat = matrix2 + (lnum & 127)*128;\ - int x;\ + unsigned short *mat = matrix2 + (lnum & 127)*128;\ + int x;\ + (void)cErr; /* Stop compiler warning */\ if (scan == 0) { /* going_up */\ x = 0;\ for (i = 0; i < plane_size; i++) {\ @@ -932,7 +973,7 @@ int scan = 0; int *errors[2]; byte *data[4], *plane_data[4][4], *out_data; - byte *out_row, *out_row_alt; + byte *out_row; word *storage; uint storage_size_words; uint mj_tmp_buf_size; @@ -1046,7 +1087,6 @@ byte *p = out_data = out_row = (byte *)storage; data[0] = data[1] = data[2] = p; data[3] = p + databuff_size; - out_row_alt = out_row + plane_size * 2; if (bits_per_pixel > 1) { p += databuff_size; } @@ -1066,7 +1106,6 @@ } if (bits_per_pixel == 1) { out_data = out_row = p; /* size is outbuff_size * 4 */ - out_row_alt = out_row + plane_size * 2; data[1] += databuff_size; /* coincides with plane_data pointers */ data[3] += databuff_size; } @@ -1209,7 +1248,6 @@ register byte *mP = plane_data[scan + 2][1]; register byte *yP = plane_data[scan + 2][0]; register byte *dp = data[scan + 2]; - int zero_row_count; int i, j; byte *odp; @@ -1340,19 +1378,18 @@ * in the order (K), C, M, Y. */ switch (mj->colorcomp) { case 1: - zero_row_count = 0; out_data = (byte*) plane_data[scan][0]; /* 3 for balck */ mj_raster_cmd(3, plane_size, out_data, mj_tmp_buf, pdev, prn_stream); break; case 3: - for (zero_row_count = 0, i = 3 - 1; i >= 0; i--) { + for (i = 3 - 1; i >= 0; i--) { out_data = (byte*) plane_data[scan][i]; mj_raster_cmd(i, plane_size, out_data, mj_tmp_buf, pdev, prn_stream); } break; default: - for (zero_row_count = 0, i = num_comps - 1; i >= 0; i--) { + for (i = num_comps - 1; i >= 0; i--) { out_data = (byte*) plane_data[scan][i]; mj_raster_cmd(i, plane_size, out_data, mj_tmp_buf, pdev, prn_stream); } @@ -1614,6 +1651,24 @@ } /* +* Encode a list of colorant values into a gx_color_index_value. +*/ +static gx_color_index +gdev_mjc_encode_color(gx_device *dev, const gx_color_value colors[]) +{ + return gdev_mjc_map_rgb_color(dev, colors); +} + +/* +* Decode a gx_color_index value back to a list of colorant values. +*/ +static int +gdev_mjc_decode_color(gx_device * dev, gx_color_index color, gx_color_value * out) +{ + return gdev_mjc_map_color_rgb(dev, color, out); +} + +/* * Convert and expand scanlines: * * (a) 16 -> 24 bit (1-stage) diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevml6.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevml6.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevml6.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevml6.c 2018-09-13 10:02:01.000000000 +0000 @@ -158,9 +158,7 @@ rmask = (byte)(0xff << (-pdev->width & 7)); /* right edge */ for (lnum = 0; lnum < pdev->height; lnum++) { - int s; - - s = gdev_prn_copy_scan_lines(pdev, lnum, data[current], + (void)gdev_prn_copy_scan_lines(pdev, lnum, data[current], line_size); /* Mask right edge bits */ *(data[current] + line_size - 1) &= rmask; diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevp201.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevp201.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevp201.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevp201.c 2018-09-13 10:02:01.000000000 +0000 @@ -143,6 +143,7 @@ case PR150: head_pins=48; lr_pitch=18; x_dpi=320; break; case PR1K4: + default: head_pins=60; lr_pitch=18; x_dpi=400; break; } diff -Nru ghostscript-9.10~dfsg/contrib/japanese/gdevrpdl.c ghostscript-9.25~dfsg+1/contrib/japanese/gdevrpdl.c --- ghostscript-9.10~dfsg/contrib/japanese/gdevrpdl.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/japanese/gdevrpdl.c 2018-09-13 10:02:01.000000000 +0000 @@ -22,6 +22,7 @@ #include "gdevlprn.h" #include "gdevlips.h" +#include #define DPI 240 @@ -230,7 +231,10 @@ static void rpdl_paper_set(gx_device_printer * pdev, FILE * prn_stream) { - int width, height, w, h, wp, hp; + int width, height, w, h; + + /* Page size match tolerance in points */ + #define TOL 5 width = pdev->MediaSize[0]; height = pdev->MediaSize[1]; @@ -238,54 +242,47 @@ if (width < height) { w = width; h = height; - wp = width / 72.0 * pdev->x_pixels_per_inch; - hp = height / 72.0 * pdev->y_pixels_per_inch; } else { w = height; h = width; - wp = height / 72.0 * pdev->y_pixels_per_inch; - hp = width / 72.0 * pdev->x_pixels_per_inch; } - if (w == 1684 && h == 2380) /* A1 */ + if (abs(w - 1684) <= TOL && abs(h - 2380) <= TOL) /* A1 */ fprintf(prn_stream, "\033\02251@A1R\033 "); - else if (w == 1190 && h == 1684) { /* A2 */ + else if (abs(w - 1190) <= TOL && abs(h - 1684) <= TOL) { /* A2 */ fprintf(prn_stream, "\033\02251@A2R\033 "); fprintf(prn_stream, "\033\02251@A2\033 "); - } else if (w == 842 && h == 1190) { /* A3 */ + } else if (abs(w - 842) <= TOL && abs(h - 1190) <= TOL) { /* A3 */ fprintf(prn_stream, "\033\02251@A3R\033 "); fprintf(prn_stream, "\033\02251@A3\033 "); - } else if (w == 595 && h == 842) { /* A4 */ - fprintf(prn_stream, "\033\02251@A4R\033 "); - fprintf(prn_stream, "\033\02251@A4\033 "); - } else if (w == 597 && h == 842) { /* A4 */ + } else if (abs(w - 595) <= TOL && abs(h - 842) <= TOL) { /* A4 */ fprintf(prn_stream, "\033\02251@A4R\033 "); fprintf(prn_stream, "\033\02251@A4\033 "); - } else if (w == 421 && h == 595) { /* A5 */ + } else if (abs(w - 421) <= TOL && abs(h - 595) <= TOL) { /* A5 */ fprintf(prn_stream, "\033\02251@A5R\033 "); fprintf(prn_stream, "\033\02251@A5\033 "); - } else if (w == 297 && h == 421) { /* A6 */ + } else if (abs(w - 297) <= TOL && abs(h - 421) <= TOL) { /* A6 */ fprintf(prn_stream, "\033\02251@A6R\033 "); fprintf(prn_stream, "\033\02251@A6\033 "); - } else if (w == 729 && h == 1032) { /* B4 */ + } else if (abs(w - 729) <= TOL && abs(h - 1032) <= TOL) { /* B4 */ fprintf(prn_stream, "\033\02251@B4R\033 "); fprintf(prn_stream, "\033\02251@B4\033 "); - } else if (w == 516 && h == 729) { /* B5 */ + } else if (abs(w - 516) <= TOL && abs(h - 729) <= TOL) { /* B5 */ fprintf(prn_stream, "\033\02251@B5R\033 "); fprintf(prn_stream, "\033\02251@B5\033 "); - } else if (w == 363 && h == 516) { /* B6 */ + } else if (abs(w - 363) <= TOL && abs(h - 516) <= TOL) { /* B6 */ fprintf(prn_stream, "\033\02251@A6R\033 "); fprintf(prn_stream, "\033\02251@A6\033 "); - } else if (w == 612 && h == 792) { /* Letter */ + } else if (abs(w - 612) <= TOL && abs(h - 792) <= TOL) { /* Letter */ fprintf(prn_stream, "\033\02251@LTR\033 "); fprintf(prn_stream, "\033\02251@LT\033 "); - } else if (w == 612 && h == 1008) { /* Legal */ + } else if (abs(w - 612) <= TOL && abs(h - 1008) <= TOL) { /* Legal */ fprintf(prn_stream, "\033\02251@LGR\033 "); fprintf(prn_stream, "\033\02251@LG\033 "); - } else if (w == 396 && h == 612) { /* Half Letter */ + } else if (abs(w - 396) <= TOL && abs(h - 612) <= TOL) { /* Half Letter */ fprintf(prn_stream, "\033\02251@HLR\033 "); fprintf(prn_stream, "\033\02251@HLT\033 "); - } else if (w == 792 && h == 1224) { /* Ledger */ + } else if (abs(w - 792) <= TOL && abs(h - 1224) <= TOL) { /* Ledger */ fprintf(prn_stream, "\033\02251@DLT\033 "); fprintf(prn_stream, "\033\02251@DLR\033 "); } else { /* Free Size (mm) */ diff -Nru ghostscript-9.10~dfsg/contrib/lips4/gdevl4r.c ghostscript-9.25~dfsg+1/contrib/lips4/gdevl4r.c --- ghostscript-9.10~dfsg/contrib/lips4/gdevl4r.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/lips4/gdevl4r.c 2018-09-13 10:02:01.000000000 +0000 @@ -505,11 +505,11 @@ ecode = gs_error_limitcheck; goto pmediae; } else { /* Check the validity of ``MediaType'' characters */ - if (strcmp(pmedia.data, "PlainPaper") != 0 && - strcmp(pmedia.data, "OHP") != 0 && - strcmp(pmedia.data, "TransparencyFilm") != 0 && /* same as OHP */ - strcmp(pmedia.data, "GlossyFilm") != 0 && - strcmp(pmedia.data, "CardBoard") != 0 + if (strcmp((const char *)pmedia.data, "PlainPaper") != 0 && + strcmp((const char *)pmedia.data, "OHP") != 0 && + strcmp((const char *)pmedia.data, "TransparencyFilm") != 0 && /* same as OHP */ + strcmp((const char *)pmedia.data, "GlossyFilm") != 0 && + strcmp((const char *)pmedia.data, "CardBoard") != 0 ) { ecode = gs_error_rangecheck; goto pmediae; diff -Nru ghostscript-9.10~dfsg/contrib/lips4/gdevl4v.c ghostscript-9.25~dfsg+1/contrib/lips4/gdevl4v.c --- ghostscript-9.10~dfsg/contrib/lips4/gdevl4v.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/lips4/gdevl4v.c 2018-09-13 10:02:01.000000000 +0000 @@ -81,10 +81,9 @@ #else #include "spprint.h" #endif -#include "ghost.h" + #include "gzstate.h" -#include "imemory.h" -#include "igstate.h" + #include "gdevlips.h" /* ---------------- Device definition ---------------- */ @@ -229,34 +228,34 @@ /* Vector device implementation */ #if GS_VERSION_MAJOR >= 8 static int lips4v_beginpage(gx_device_vector * vdev); -static int lips4v_setfillcolor(gx_device_vector * vdev, const gs_imager_state * pis, +static int lips4v_setfillcolor(gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); -static int lips4v_setstrokecolor(gx_device_vector * vdev, const gs_imager_state * pis, +static int lips4v_setstrokecolor(gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); static int lips4v_setdash(gx_device_vector * vdev, const float *pattern, - uint count, floatp offset); -static int lips4v_setflat(gx_device_vector * vdev, floatp flatness); + uint count, double offset); +static int lips4v_setflat(gx_device_vector * vdev, double flatness); static int lips4v_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop, gs_logical_operation_t diff); -static int lips4v_can_handle_hl_color(gx_device_vector * vdev, const gs_imager_state * pis, +static int lips4v_can_handle_hl_color(gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc); static int lips4v_beginpath(gx_device_vector * vdev, gx_path_type_t type); static int -lips4v_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, - floatp y, gx_path_type_t type); +lips4v_moveto(gx_device_vector * vdev, double x0, double y0, double x, + double y, gx_path_type_t type); static int -lips4v_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, - floatp y, gx_path_type_t type); +lips4v_lineto(gx_device_vector * vdev, double x0, double y0, double x, + double y, gx_path_type_t type); static int -lips4v_curveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x1, - floatp y1, floatp x2, floatp y2, floatp x3, floatp y3, +lips4v_curveto(gx_device_vector * vdev, double x0, double y0, double x1, + double y1, double x2, double y2, double x3, double y3, gx_path_type_t type); static int -lips4v_closepath(gx_device_vector * vdev, floatp x, floatp y, floatp x_start, - floatp y_start, gx_path_type_t type); +lips4v_closepath(gx_device_vector * vdev, double x, double y, double x_start, + double y_start, gx_path_type_t type); static int lips4v_endpath(gx_device_vector * vdev, gx_path_type_t type); #else @@ -266,8 +265,8 @@ static int lips4v_setstrokecolor(P2(gx_device_vector * vdev, const gx_drawing_color * pdc)); static int lips4v_setdash(P4(gx_device_vector * vdev, const float *pattern, - uint count, floatp offset)); -static int lips4v_setflat(P2(gx_device_vector * vdev, floatp flatness)); + uint count, double offset)); +static int lips4v_setflat(P2(gx_device_vector * vdev, double flatness)); static int lips4v_setlogop(P3 @@ -278,28 +277,28 @@ lips4v_beginpath(P2(gx_device_vector * vdev, gx_path_type_t type)); static int lips4v_moveto(P6 - (gx_device_vector * vdev, floatp x0, floatp y0, floatp x, - floatp y, gx_path_type_t type)); + (gx_device_vector * vdev, double x0, double y0, double x, + double y, gx_path_type_t type)); static int lips4v_lineto(P6 - (gx_device_vector * vdev, floatp x0, floatp y0, floatp x, - floatp y, gx_path_type_t type)); + (gx_device_vector * vdev, double x0, double y0, double x, + double y, gx_path_type_t type)); static int lips4v_curveto(P10 - (gx_device_vector * vdev, floatp x0, floatp y0, floatp x1, - floatp y1, floatp x2, floatp y2, floatp x3, floatp y3, + (gx_device_vector * vdev, double x0, double y0, double x1, + double y1, double x2, double y2, double x3, double y3, gx_path_type_t type)); static int lips4v_closepath(P6 - (gx_device_vector * vdev, floatp x, floatp y, floatp x_start, - floatp y_start, gx_path_type_t type)); + (gx_device_vector * vdev, double x, double y, double x_start, + double y_start, gx_path_type_t type)); static int lips4v_endpath(P2(gx_device_vector * vdev, gx_path_type_t type)); #endif -static int lips4v_setlinewidth(gx_device_vector * vdev, floatp width); +static int lips4v_setlinewidth(gx_device_vector * vdev, double width); static int lips4v_setlinecap(gx_device_vector * vdev, gs_line_cap cap); static int lips4v_setlinejoin(gx_device_vector * vdev, gs_line_join join); -static int lips4v_setmiterlimit(gx_device_vector * vdev, floatp limit); +static int lips4v_setmiterlimit(gx_device_vector * vdev, double limit); static const gx_device_vector_procs lips4v_vector_procs = { /* Page management */ lips4v_beginpage, @@ -488,7 +487,7 @@ uint width_bytes = (w + 7) >> 3; uint size = width_bytes * h; int i, j; - uint ccode; + uint ccode = 0; char cset_sub[9], cset[64], cset_number[8], text_color[15]; int cell_length = (POINT * (int)dev->x_pixels_per_inch) / 72; bool download = TRUE; @@ -951,14 +950,14 @@ } static int -lips4v_setlinewidth(gx_device_vector * vdev, floatp width) +lips4v_setlinewidth(gx_device_vector * vdev, double width) { stream *s = gdev_vector_stream(vdev); gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev; #if 0 /* Scale ݤƤΤ, Ghostscript 5.10/5.50 ΥХΤ */ - floatp xscale, yscale; + double xscale, yscale; xscale = fabs(igs->ctm.xx); yscale = fabs(igs->ctm.xy); @@ -998,6 +997,7 @@ pdev->TextMode = FALSE; } switch (cap) { + default: case 0: case 3: line_cap = 0; /* butt */ @@ -1035,6 +1035,7 @@ } switch (join) { + default: case 0: lips_join = 2; /* miter */ break; @@ -1057,11 +1058,11 @@ } static int -lips4v_setmiterlimit(gx_device_vector * vdev, floatp limit) +lips4v_setmiterlimit(gx_device_vector * vdev, double limit) { stream *s = gdev_vector_stream(vdev); gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev; - floatp lips_miterlimit; + double lips_miterlimit; if (pdev->TextMode) { sputc(s, LIPS_CSI); @@ -1079,7 +1080,7 @@ #if GS_VERSION_MAJOR >= 8 static int -lips4v_setfillcolor(gx_device_vector * vdev, const gs_imager_state * pis, const gx_drawing_color * pdc) +lips4v_setfillcolor(gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc) #else static int lips4v_setfillcolor(gx_device_vector * vdev, const gx_drawing_color * pdc) @@ -1092,8 +1093,8 @@ stream *s = gdev_vector_stream(vdev); gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev; gx_color_index color = gx_dc_pure_color(pdc); - int drawing_color; - float r, g, b; + int drawing_color = 0; + float r = 0.0F, g = 0.0F, b = 0.0F; if (vdev->color_info.depth == 8) { drawing_color = vdev->color_info.max_gray - color; @@ -1147,7 +1148,7 @@ #if GS_VERSION_MAJOR >= 8 static int -lips4v_setstrokecolor(gx_device_vector * vdev, const gs_imager_state * pis, const gx_drawing_color * pdc) +lips4v_setstrokecolor(gx_device_vector * vdev, const gs_gstate * pgs, const gx_drawing_color * pdc) #else static int lips4v_setstrokecolor(gx_device_vector * vdev, const gx_drawing_color * pdc) @@ -1159,7 +1160,7 @@ stream *s = gdev_vector_stream(vdev); gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev; gx_color_index color = gx_dc_pure_color(pdc); - float r, g, b; + float r = 0.0F, g = 0.0F, b = 0.0F; if (vdev->color_info.depth == 24) { r = (color >> 16) * 1000 / 255.0; @@ -1190,12 +1191,14 @@ /* ̿ */ static int lips4v_setdash(gx_device_vector * vdev, const float *pattern, uint count, - floatp offset) + double offset) { stream *s = gdev_vector_stream(vdev); gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev; int i; +#if 0 float scale, xscale, yscale; +#endif if (pdev->TextMode) { sputc(s, LIPS_CSI); @@ -1260,7 +1263,7 @@ /* ѥʿٻ */ static int -lips4v_setflat(gx_device_vector * vdev, floatp flatness) +lips4v_setflat(gx_device_vector * vdev, double flatness) { stream *s = gdev_vector_stream(vdev); gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev; @@ -1288,7 +1291,7 @@ #if GS_VERSION_MAJOR >= 8 /*--- added for Ghostscritp 8.15 ---*/ static int -lips4v_can_handle_hl_color(gx_device_vector * vdev, const gs_imager_state * pis1, +lips4v_can_handle_hl_color(gx_device_vector * vdev, const gs_gstate * pgs1, const gx_drawing_color * pdc) { return false; /* High level color is not implemented yet. */ @@ -1318,8 +1321,8 @@ } static int -lips4v_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, - floatp y, gx_path_type_t type) +lips4v_moveto(gx_device_vector * vdev, double x0, double y0, double x, + double y, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); @@ -1333,8 +1336,8 @@ } static int -lips4v_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, - floatp y, gx_path_type_t type) +lips4v_lineto(gx_device_vector * vdev, double x0, double y0, double x, + double y, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev; @@ -1355,9 +1358,9 @@ } static int -lips4v_curveto(gx_device_vector * vdev, floatp x0, floatp y0, - floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, - floatp y3, gx_path_type_t type) +lips4v_curveto(gx_device_vector * vdev, double x0, double y0, + double x1, double y1, double x2, double y2, double x3, + double y3, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); @@ -1375,8 +1378,8 @@ } static int -lips4v_closepath(gx_device_vector * vdev, floatp x, floatp y, - floatp x_start, floatp y_start, gx_path_type_t type) +lips4v_closepath(gx_device_vector * vdev, double x, double y, + double x_start, double y_start, gx_path_type_t type) { stream *s = gdev_vector_stream(vdev); @@ -1649,11 +1652,11 @@ ecode = gs_error_limitcheck; goto pmediae; } else { /* Check the validity of ``MediaType'' characters */ - if (strcmp(pmedia.data, "PlainPaper") != 0 && - strcmp(pmedia.data, "OHP") != 0 && - strcmp(pmedia.data, "TransparencyFilm") != 0 && /* same as OHP */ - strcmp(pmedia.data, "GlossyFilm") != 0 && - strcmp(pmedia.data, "CardBoard") != 0) { + if (strcmp((const char *)pmedia.data, "PlainPaper") != 0 && + strcmp((const char *)pmedia.data, "OHP") != 0 && + strcmp((const char *)pmedia.data, "TransparencyFilm") != 0 && /* same as OHP */ + strcmp((const char *)pmedia.data, "GlossyFilm") != 0 && + strcmp((const char *)pmedia.data, "CardBoard") != 0) { ecode = gs_error_rangecheck; goto pmediae; } @@ -1864,7 +1867,7 @@ int dpi = dev->x_pixels_per_inch; gx_drawing_color color; int code = 0; - floatp r, g, b; + double r, g, b; if (id != gs_no_id && zero == gx_no_color_index && one != gx_no_color_index && data_x == 0) { @@ -2200,7 +2203,7 @@ /* Start processing an image. */ static int lips4v_begin_image(gx_device * dev, - const gs_imager_state * pis, const gs_image_t * pim, + const gs_gstate * pgs, const gs_image_t * pim, gs_image_format_t format, const gs_int_rect * prect, const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, gs_memory_t * mem, @@ -2212,7 +2215,7 @@ gs_alloc_struct(mem, gdev_vector_image_enum_t, &st_vector_image_enum, "lips4v_begin_image"); const gs_color_space *pcs = pim->ColorSpace; - gs_color_space_index index; + gs_color_space_index index = 0; int num_components = 1; bool can_do = prect == 0 && (pim->format == gs_image_format_chunky || @@ -2224,7 +2227,7 @@ if (pie == 0) return_error(gs_error_VMerror); pie->memory = mem; - code = gdev_vector_begin_image(vdev, pis, pim, format, prect, + code = gdev_vector_begin_image(vdev, pgs, pim, format, prect, pdcolor, pcpath, mem, &lips4v_image_enum_procs, pie); if (code < 0) @@ -2264,7 +2267,7 @@ } } if (!can_do) - return gx_default_begin_image(dev, pis, pim, format, prect, + return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, mem, &pie->default_info); else if (index == gs_color_space_index_DeviceGray) { @@ -2299,7 +2302,7 @@ pdev->TextMode = FALSE; } gs_matrix_invert(&pim->ImageMatrix, &imat); - gs_matrix_multiply(&imat, &ctm_only(pis), &imat); + gs_matrix_multiply(&imat, &ctm_only(pgs), &imat); /* [xx xy yx yy tx ty] LIPS κɸϤѴԤʤ diff -Nru ghostscript-9.10~dfsg/contrib/opvp/gdevopvp.c ghostscript-9.25~dfsg+1/contrib/opvp/gdevopvp.c --- ghostscript-9.10~dfsg/contrib/opvp/gdevopvp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/opvp/gdevopvp.c 2018-09-13 10:02:01.000000000 +0000 @@ -11,8 +11,12 @@ 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. + with this program; if not, write to: + + Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor + Boston, MA 02110-1301 + USA */ @@ -40,7 +44,7 @@ #include "string_.h" #include "math_.h" #include "gx.h" -#include "ghost.h" + #include "gscdefs.h" #include "gsexit.h" #include "gsstruct.h" @@ -56,21 +60,7 @@ #include "spprint.h" #include "ghost.h" #include "gzstate.h" -#include "ialloc.h" -#include "iddict.h" -#include "dstack.h" -#include "ilevel.h" -#include "iinit.h" -#include "iname.h" -#include "imemory.h" -#include "igstate.h" -#include "interp.h" -#include "ipacked.h" -#include "iparray.h" -#include "iutil.h" -#include "ivmspace.h" -#include "opdef.h" -#include "store.h" + #include "gspath.h" #include "gzpath.h" #include "gzcpath.h" @@ -137,8 +127,8 @@ /* point (internal) */ typedef struct { - floatp x; - floatp y; + double x; + double y; } _fPoint; /* ----- private function prototypes ----- */ @@ -198,10 +188,10 @@ static int _put_params(gs_param_list *); static int opvp_put_params(gx_device *, gs_param_list *); static int oprp_put_params(gx_device *, gs_param_list *); -static int opvp_fill_path(gx_device *, const gs_imager_state *, gx_path *, +static int opvp_fill_path(gx_device *, const gs_gstate *, gx_path *, const gx_fill_params *, const gx_device_color *, const gx_clip_path *); -static int opvp_stroke_path(gx_device *, const gs_imager_state *, gx_path *, +static int opvp_stroke_path(gx_device *, const gs_gstate *, gx_path *, const gx_stroke_params *, const gx_drawing_color *, const gx_clip_path *); static int opvp_fill_mask(gx_device *, const byte *, int, int, gx_bitmap_id, @@ -223,18 +213,18 @@ /* vector driver procs */ static int opvp_beginpage(gx_device_vector *); -static int opvp_setlinewidth(gx_device_vector *, floatp); +static int opvp_setlinewidth(gx_device_vector *, double); static int opvp_setlinecap(gx_device_vector *, gs_line_cap); static int opvp_setlinejoin(gx_device_vector *, gs_line_join); -static int opvp_setmiterlimit(gx_device_vector *, floatp); -static int opvp_setdash(gx_device_vector *, const float *, uint, floatp); -static int opvp_setflat(gx_device_vector *, floatp); +static int opvp_setmiterlimit(gx_device_vector *, double); +static int opvp_setdash(gx_device_vector *, const float *, uint, double); +static int opvp_setflat(gx_device_vector *, double); static int opvp_setlogop(gx_device_vector *, gs_logical_operation_t, gs_logical_operation_t); #if GS_VERSION_MAJOR >= 8 -static int opvp_can_handle_hl_color(gx_device_vector *, const gs_imager_state *, const gx_drawing_color *); -static int opvp_setfillcolor(gx_device_vector *, const gs_imager_state *, const gx_drawing_color *); -static int opvp_setstrokecolor(gx_device_vector *, const gs_imager_state *,const gx_drawing_color *); +static int opvp_can_handle_hl_color(gx_device_vector *, const gs_gstate *, const gx_drawing_color *); +static int opvp_setfillcolor(gx_device_vector *, const gs_gstate *, const gx_drawing_color *); +static int opvp_setstrokecolor(gx_device_vector *, const gs_gstate *,const gx_drawing_color *); #else static int opvp_setfillcolor(gx_device_vector *, const gx_drawing_color *); static int opvp_setstrokecolor(gx_device_vector *, const gx_drawing_color *); @@ -244,13 +234,13 @@ static int opvp_vector_dorect(gx_device_vector *, fixed, fixed, fixed, fixed, gx_path_type_t); static int opvp_beginpath(gx_device_vector *, gx_path_type_t); -static int opvp_moveto(gx_device_vector *, floatp, floatp, floatp, floatp, +static int opvp_moveto(gx_device_vector *, double, double, double, double, gx_path_type_t); -static int opvp_lineto(gx_device_vector *, floatp, floatp, floatp, floatp, +static int opvp_lineto(gx_device_vector *, double, double, double, double, gx_path_type_t); -static int opvp_curveto(gx_device_vector *, floatp, floatp, floatp, floatp, - floatp, floatp, floatp, floatp, gx_path_type_t); -static int opvp_closepath(gx_device_vector *, floatp, floatp, floatp, floatp, +static int opvp_curveto(gx_device_vector *, double, double, double, double, + double, double, double, double, gx_path_type_t); +static int opvp_closepath(gx_device_vector *, double, double, double, double, gx_path_type_t); static int opvp_endpath(gx_device_vector *, gx_path_type_t); @@ -499,7 +489,7 @@ }; /* color space mapping 1.0 to 0.2 */ -static opvp_cspace_t cspace_1_0_to_0_2[] = { +static OPVP_ColorSpace cspace_1_0_to_0_2[] = { OPVP_cspaceBW, OPVP_cspaceDeviceGray, OPVP_cspaceDeviceCMY, @@ -511,7 +501,7 @@ }; /* image format mapping 1.0 to 0.2 */ -static opvp_imageformat_t iformat_1_0_to_0_2[] = { +static OPVP_ImageFormat iformat_1_0_to_0_2[] = { OPVP_iformatRaw, OPVP_iformatRaw, /* OPVP_IFORMAT_MASK use iformat raw in 0.2 */ OPVP_iformatRLE, @@ -630,7 +620,7 @@ *ErrorNo = OPVP_NOTSUPPORTED_0_2; return -1; } - if (cspace + if ((int)cspace >= sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) { /* unknown color space */ *ErrorNo = OPVP_PARAMERROR_0_2; @@ -674,7 +664,7 @@ /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */ return OPVP_NOTSUPPORTED; } - if (brush->colorSpace + if ((int)brush->colorSpace >= sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) { /* unknown color space */ *ErrorNo = OPVP_PARAMERROR_0_2; @@ -701,7 +691,7 @@ /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */ return OPVP_NOTSUPPORTED; } - if (brush->colorSpace + if ((int)brush->colorSpace >= sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) { /* unknown color space */ *ErrorNo = OPVP_PARAMERROR_0_2; @@ -729,7 +719,7 @@ *ErrorNo = OPVP_NOTSUPPORTED_0_2; return -1; } - if (brush->colorSpace + if ((int)brush->colorSpace >= sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) { /* unknown color space */ *ErrorNo = OPVP_PARAMERROR_0_2; @@ -1171,6 +1161,7 @@ FastImageReverseAngle, FastImageAll } FastImageSupportMode; + static char *fastImage = NULL; static FastImageSupportMode FastImageMode = FastImageDisable; static bool begin_image = false; @@ -1840,7 +1831,6 @@ { int ecode = 0; int code; - opvp_result_t r = -1; opvp_api_procs_t *api_entry; int dumFD = -1; opvp_dc_t dumContext = -1; @@ -1910,7 +1900,7 @@ } /* call GetColorSpace */ if (apiEntry->opvpGetColorSpace) { - r = apiEntry->opvpGetColorSpace(dumContext, &cspace); + (void)apiEntry->opvpGetColorSpace(dumContext, &cspace); } if (cspace == OPVP_CSPACE_BW) { /* mono-color */ @@ -2054,6 +2044,11 @@ ecode = code; return ecode; } + while (dev->child) { + dev = dev->child; + } + rdev = (gx_device_oprp *)(dev); + pdev = (gx_device_opvp *)(dev); #if GS_VERSION_MAJOR >= 8 if (pdev->bbox_device != NULL) { if (pdev->bbox_device->memory == NULL) { @@ -2066,22 +2061,24 @@ /* open printer device */ code = gdev_prn_open(dev); if (code < 0) { - ecode = ecode; - return ecode; + return code; + } + while (dev->child) { + dev = dev->child; } + rdev = (gx_device_oprp *)(dev); + pdev = (gx_device_opvp *)(dev); /* open output stream */ code = gdev_prn_open_printer_seekable(dev, true, false); if (code < 0) { - ecode = code; - return ecode; + return code; } outputFD = fileno(rdev->file); } /* RE-load vector driver */ if ((code = opvp_load_vector_driver())) { - ecode = code; - return ecode; + return code; } /* call opvpOpenPrinter */ @@ -2131,7 +2128,7 @@ int i; for (i = 0;i < nn;i++) { - if (p[i] < sizeof(cspace_available)) { + if ((unsigned int)p[i] < sizeof(cspace_available)) { cspace_available[p[i]] = 1; } } @@ -3487,7 +3484,7 @@ static int opvp_fill_path( gx_device *dev, - const gs_imager_state *pis, + const gs_gstate *pgs, gx_path *ppath, const gx_fill_params *params, const gx_device_color *pdevc, @@ -3498,7 +3495,7 @@ /* check if paths are too complex */ if (!checkPath(ppath) || !checkCPath(pxpath)) { - return gx_default_fill_path(dev, pis, ppath, params, pdevc, pxpath); + return gx_default_fill_path(dev, pgs, ppath, params, pdevc, pxpath); } /* check clippath support */ if (!(apiEntry->opvpSetClipPath)) { @@ -3514,10 +3511,10 @@ } if (!vector || draw_image) { - return gx_default_fill_path(dev, pis, ppath, params, pdevc, pxpath); + return gx_default_fill_path(dev, pgs, ppath, params, pdevc, pxpath); } - return gdev_vector_fill_path(dev, pis, ppath, params, pdevc, pxpath); + return gdev_vector_fill_path(dev, pgs, ppath, params, pdevc, pxpath); } /* @@ -3526,7 +3523,7 @@ static int opvp_stroke_path( gx_device *dev, - const gs_imager_state *pis, + const gs_gstate *pgs, gx_path *ppath, const gx_stroke_params *params, const gx_drawing_color *pdcolor, @@ -3537,7 +3534,7 @@ /* check if paths are too complex */ if (!checkPath(ppath) || !checkCPath(pxpath)) { - return gx_default_stroke_path(dev, pis, ppath, + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pxpath); } /* check clippath support */ @@ -3554,11 +3551,11 @@ } if (!vector || draw_image) { - return gx_default_stroke_path(dev, pis, ppath, + return gx_default_stroke_path(dev, pgs, ppath, params, pdcolor, pxpath); } - return gdev_vector_stroke_path(dev, pis, ppath, + return gdev_vector_stroke_path(dev, pgs, ppath, params, pdcolor, pxpath); } @@ -3601,7 +3598,7 @@ static int opvp_begin_image( gx_device *dev, - const gs_imager_state *pis, + const gs_gstate *pgs, const gs_image_t *pim, gs_image_format_t format, const gs_int_rect *prect, @@ -3628,7 +3625,7 @@ /* check if paths are too complex */ if (!checkCPath(pcpath)) { return gx_default_begin_image( - dev, pis, pim, format, + dev, pgs, pim, format, prect, pdcolor, pcpath, mem, pinfo); } @@ -3642,7 +3639,7 @@ if (vinfo) { memcpy(imageDecode,pim->Decode,sizeof(pim->Decode)); vinfo->memory =mem; - code = gdev_vector_begin_image(vdev, pis, pim, format, prect, + code = gdev_vector_begin_image(vdev, pgs, pim, format, prect, pdcolor, pcpath, mem, &opvp_image_enum_procs, vinfo); @@ -3663,7 +3660,7 @@ if (((pcs->params.indexed.hival + 1) > 256) || (bits_per_pixel != 8 && bits_per_pixel != 1)) { return gx_default_begin_image( - dev, pis, pim, format, + dev, pgs, pim, format, prect, pdcolor, pcpath, mem, pinfo); } else if (base_color_index @@ -3683,9 +3680,9 @@ byte2frac((*(p + 2 + (count * 4)))), byte2frac((*(p + 3 + (count * 4)))), #if GS_VERSION_MAJOR >= 9 - pis, rgb, mem); + pgs, rgb, mem); #else - pis, rgb); + pgs, rgb); #endif *(palette + 0 + (count * 3)) = frac2byte(rgb[0]); *(palette + 1 + (count * 3)) = frac2byte(rgb[1]); @@ -3710,7 +3707,7 @@ } else { /* except CMYK and RGB */ return gx_default_begin_image( - dev, pis, pim, format, + dev, pgs, pim, format, prect, pdcolor, pcpath, mem, pinfo); } @@ -3725,7 +3722,7 @@ /* adjust matrix */ reverse_image = false; gs_matrix_invert(&pim->ImageMatrix, &mtx); - gs_matrix_multiply(&mtx, &ctm_only(pis), &mtx); + gs_matrix_multiply(&mtx, &ctm_only(pgs), &mtx); switch (FastImageMode) { case FastImageNoCTM: if ((mtx.xy==0)&&(mtx.yx==0)&& (mtx.yy>=0)) { @@ -3958,7 +3955,7 @@ if(apiEntry->opvpResetCTM) { apiEntry->opvpResetCTM(printerContext); /* reset CTM */ } - return gx_default_begin_image(dev, pis, pim, format, + return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, mem, pinfo); } } @@ -3970,7 +3967,7 @@ return ecode; } - return gx_default_begin_image(dev, pis, pim, format, prect, + return gx_default_begin_image(dev, pgs, pim, format, prect, pdcolor, pcpath, mem, pinfo); } @@ -4000,7 +3997,7 @@ byte *ptr; bbox_image_enum *pbe; gx_image_enum *tinfo; - const gs_imager_state *pis; + const gs_gstate *pgs; vinfo = (gdev_vector_image_enum_t *)info; @@ -4025,7 +4022,7 @@ /* Adjust image data gamma */ pbe = (bbox_image_enum *)vinfo->bbox_info; tinfo = (gx_image_enum *)pbe->target_info; - pis = tinfo->pis; + pgs = tinfo->pgs; if (vinfo->num_planes == 1) { for (h = 0; h < height; h++) { @@ -4340,11 +4337,11 @@ for (i = 0; i < height; i++) { ptr = buf + raster_length * i; for (j = 0; j < vinfo->width; j++) { - ptr[j*3] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j*3] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j*3]), effective_transfer[0]))); - ptr[j*3+1] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j*3+1] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j*3+1]), effective_transfer[1]))); - ptr[j*3+2] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j*3+2] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j*3+2]), effective_transfer[2]))); } } @@ -4352,7 +4349,7 @@ for (i = 0; i < height; i++) { ptr = buf + raster_length * i; for (j=0; j < vinfo->width; j++) { - ptr[j] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j]), effective_transfer[3]))); } } @@ -4362,11 +4359,11 @@ for (i = 0; i < height; i++) { ptr = buf + raster_length * i; for (j = 0; j < vinfo->width; j++) { - ptr[j*3] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j*3] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j*3]), effective_transfer.colored.red))); - ptr[j*3+1] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j*3+1] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j*3+1]), effective_transfer.colored.green))); - ptr[j*3+2] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j*3+2] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j*3+2]), effective_transfer.colored.blue))); } } @@ -4374,7 +4371,7 @@ for (i = 0; i < height; i++) { ptr = buf + raster_length * i; for (j = 0; j < vinfo->width; j++) { - ptr[j] = min(255, frac2cv(gx_map_color_frac(pis, + ptr[j] = min(255, frac2cv(gx_map_color_frac(pgs, cv2frac(ptr[j]), effective_transfer.colored.gray))); } } @@ -4487,7 +4484,7 @@ * set line width */ static int -opvp_setlinewidth(gx_device_vector *vdev, floatp width) +opvp_setlinewidth(gx_device_vector *vdev, double width) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; opvp_result_t r = -1; @@ -4596,7 +4593,7 @@ * set miter limit */ static int -opvp_setmiterlimit(gx_device_vector *vdev, floatp limit) +opvp_setmiterlimit(gx_device_vector *vdev, double limit) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; opvp_result_t r = -1; @@ -4626,7 +4623,7 @@ gx_device_vector *vdev, const float *pattern, uint count, - floatp offset) + double offset) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; opvp_result_t r = -1; @@ -4693,7 +4690,7 @@ * set flat */ static int -opvp_setflat(gx_device_vector *vdev, floatp flatness) +opvp_setflat(gx_device_vector *vdev, double flatness) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; int ecode = 0; @@ -4723,7 +4720,7 @@ /*--- added for Ghostscritp 8.15 ---*/ static int opvp_can_handle_hl_color(gx_device_vector * vdev, - const gs_imager_state * pis1, const gx_drawing_color * pdc) + const gs_gstate * pgs1, const gx_drawing_color * pdc) { return false; /* High level color is not implemented yet. */ } @@ -4736,7 +4733,7 @@ static int opvp_setfillcolor( gx_device_vector *vdev, - const gs_imager_state *pis, /* added for gs 8.15 */ + const gs_gstate *pgs, /* added for gs 8.15 */ const gx_drawing_color *pdc) #else static int @@ -4777,7 +4774,7 @@ static int opvp_setstrokecolor( gx_device_vector *vdev, - const gs_imager_state *pis, /* added for gs 8.15 */ + const gs_gstate *pgs, /* added for gs 8.15 */ const gx_drawing_color *pdc) #else static int @@ -4838,7 +4835,6 @@ _fPoint *points = NULL; opvp_point_t *opvp_p = NULL; _fPoint current; - _fPoint check_p; #else _fPoint points[4]; #endif @@ -5002,8 +4998,6 @@ case gs_pe_curveto: #ifdef OPVP_OPT_MULTI_PATH /* curve to */ - check_p.x = fixed2float(vs[0]) / scale.x; - check_p.y = fixed2float(vs[1]) / scale.y; i = npoints; npoints += 3; @@ -5173,10 +5167,10 @@ static int opvp_moveto( gx_device_vector *vdev, - floatp x0, - floatp y0, - floatp x1, - floatp y1, + double x0, + double y0, + double x1, + double y1, gx_path_type_t type) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; @@ -5206,10 +5200,10 @@ static int opvp_lineto( gx_device_vector *vdev, - floatp x0, - floatp y0, - floatp x1, - floatp y1, + double x0, + double y0, + double x1, + double y1, gx_path_type_t type) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; @@ -5241,28 +5235,25 @@ static int opvp_curveto( gx_device_vector *vdev, - floatp x0, - floatp y0, - floatp x1, - floatp y1, - floatp x2, - floatp y2, - floatp x3, - floatp y3, + double x0, + double y0, + double x1, + double y1, + double x2, + double y2, + double x3, + double y3, gx_path_type_t type) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; opvp_result_t r = -1; int ecode = 0; - int npoints[2]; opvp_point_t points[4]; /* check page-in */ if (opvp_check_in_page(pdev)) return -1; /* points */ - npoints[0] = 4; - npoints[1] = 0; OPVP_F2FIX(x0, points[0].x); OPVP_F2FIX(y0, points[0].y); OPVP_F2FIX(x1, points[1].x); @@ -5292,10 +5283,10 @@ static int opvp_closepath( gx_device_vector *vdev, - floatp x, - floatp y, - floatp x_start, - floatp y_start, + double x, + double y, + double x_start, + double y_start, gx_path_type_t type) { gx_device_opvp *pdev = (gx_device_opvp *)vdev; diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/eprnfs.c ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/eprnfs.c --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/eprnfs.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/eprnfs.c 2018-09-13 10:02:01.000000000 +0000 @@ -22,12 +22,6 @@ ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: eprnfs.c,v 1.6 2001/05/01 07:02:01 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -255,7 +249,7 @@ /* Distribute the approximation over the bit planes */ for (plane = 0; plane < planes; plane++) { - *ptr[plane] = (*ptr[plane] << 1) | approx & 0x01; + *ptr[plane] = (*ptr[plane] << 1) | (approx & 0x01); approx >>= 1; } @@ -527,7 +521,7 @@ plane = 0; for (colorant = last_colorant; colorant >= 0; colorant--) { while (plane < next_plane[colorant]) { - *ptr[plane] = (*ptr[plane] << 1) | approx[colorant] & 0x01; + *ptr[plane] = (*ptr[plane] << 1) | (approx[colorant] & 0x01); approx[colorant] >>= 1; plane++; } diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/eprnparm.c ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/eprnparm.c --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/eprnparm.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/eprnparm.c 2018-09-13 10:02:01.000000000 +0000 @@ -32,12 +32,6 @@ ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: eprnparm.c,v 1.24 2001/08/18 17:42:34 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -65,6 +59,8 @@ #include "gdeveprn.h" #include "gp.h" +#include "gscoord.h" /* for gs_setdefaultmatrix() */ + /*****************************************************************************/ #define ERRPREF "? eprn: " @@ -201,6 +197,35 @@ } #endif /* EPRN_TRACE */ + +/****************************************************************************** + + Function: eprn_fillpage + This is just a "call-through" to the default, so we can grab the gs_gstate + +******************************************************************************/ +int +eprn_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) +{ + eprn_Eprn *eprn = &((eprn_Device *)dev)->eprn; + + eprn->pgs = pgs; + + return (*eprn->orig_fillpage)(dev, pgs, pdevc); +} + + +static void eprn_replace_fillpage(gx_device *dev) +{ + eprn_Eprn *eprn = &((eprn_Device *)dev)->eprn; + + if (dev->procs.fillpage != eprn_fillpage) { + eprn->orig_fillpage = dev->procs.fillpage; + dev->procs.fillpage = eprn_fillpage; + } +} + + /****************************************************************************** Function: eprn_get_params @@ -222,6 +247,8 @@ if_debug0(EPRN_TRACE_CHAR, "! eprn_get_params()...\n"); #endif + eprn_replace_fillpage(device); + /* Base class parameters */ rc = gdev_prn_get_params(device, plist); if (rc < 0) return rc; @@ -737,8 +764,8 @@ /* Search for a match. Successful exits are in the middle of the loop. */ for (entry = list; entry->info[0] != NULL; entry++) if (entry->colour_model == *model || - entry->colour_model == eprn_DeviceCMYK && - *model == eprn_DeviceCMY_plus_K) { + (entry->colour_model == eprn_DeviceCMYK && + *model == eprn_DeviceCMY_plus_K)) { const eprn_ResLev *rl; unsigned int levels = (entry->colour_model == eprn_DeviceRGB || entry->colour_model == eprn_DeviceCMY? *non_black_levels: @@ -759,8 +786,8 @@ for (rl2 = entry->info[1]; rl2->levels != NULL; rl2++) if (reslev_supported(rl2, *hres, *vres, *non_black_levels)) break; } - if (entry->info[1] == NULL && *black_levels == *non_black_levels || - entry->info[1] != NULL && rl2->levels != NULL) + if ((entry->info[1] == NULL && *black_levels == *non_black_levels) || + (entry->info[1] != NULL && rl2->levels != NULL)) return 0; } } @@ -902,6 +929,8 @@ } #endif /* EPRN_TRACE */ + eprn_replace_fillpage(dev); + /* Remember initial page size */ for (temp = 0; temp < 2; temp++) mediasize[temp] = dev->MediaSize[temp]; @@ -928,7 +957,7 @@ if (rc != 0) { \ if (rc != gs_error_VMerror) { \ eprintf1("%s" ERRPREF "Unknown colour model: `", epref); \ - errwrite(dev->memory, string_value.data, sizeof(char)*string_value.size); \ + errwrite(dev->memory, (const char *)string_value.data, sizeof(char)*string_value.size); \ eprintf("'.\n"); \ } \ last_error = rc; \ @@ -984,11 +1013,11 @@ /* BlackLevels. Various depending values will be adjusted below. */ if ((rc = param_read_int(plist, (pname = "BlackLevels"), &temp)) == 0) { - if (temp == 0 && (eprn->colour_model == eprn_DeviceRGB || - eprn->colour_model == eprn_DeviceCMY) || - 2 <= temp && temp <= 256 && - eprn->colour_model != eprn_DeviceRGB && - eprn->colour_model != eprn_DeviceCMY) { + if ((temp == 0 && (eprn->colour_model == eprn_DeviceRGB || + eprn->colour_model == eprn_DeviceCMY)) || + (2 <= temp && temp <= 256 && + eprn->colour_model != eprn_DeviceRGB && + eprn->colour_model != eprn_DeviceCMY)) { if (eprn->black_levels != temp && dev->is_open) gs_closedevice(dev); eprn->black_levels = temp; } @@ -1004,8 +1033,8 @@ /* CMYLevels */ if ((rc = param_read_int(plist, (pname = "CMYLevels"), &temp)) == 0) { - if (temp == 0 && eprn->colour_model == eprn_DeviceGray || - 2 <= temp && temp <= 256 && eprn->colour_model != eprn_DeviceGray) { + if ((temp == 0 && eprn->colour_model == eprn_DeviceGray) || + (2 <= temp && temp <= 256 && eprn->colour_model != eprn_DeviceGray)) { if (eprn->non_black_levels != temp && dev->is_open) gs_closedevice(dev); eprn->non_black_levels = temp; } @@ -1043,7 +1072,7 @@ else { eprintf1("%s" ERRPREF "Invalid method for IntensityRendering: `", epref); - errwrite(dev->memory, string_value.data, sizeof(char)*string_value.size); + errwrite(dev->memory, (const char *)string_value.data, sizeof(char)*string_value.size); eprintf("'.\n"); last_error = gs_error_rangecheck; param_signal_error(plist, pname, last_error); @@ -1161,7 +1190,7 @@ /* RGBLevels */ if ((rc = param_read_int(plist, (pname = "RGBLevels"), &temp)) == 0) { - if (temp == 0 || 2 <= temp && temp <= 256) { + if (temp == 0 || (2 <= temp && temp <= 256)) { if (eprn->non_black_levels != temp && dev->is_open) gs_closedevice(dev); eprn->non_black_levels = temp; } @@ -1211,7 +1240,8 @@ /* Process parameters defined by base classes (should occur after treating parameters defined for the derived class, see gsparam.h) */ - if ((rc = gdev_prn_put_params(dev, plist)) < 0 || rc > 0 && last_error >= 0) + rc = gdev_prn_put_params(dev, plist); + if (rc < 0 || (rc > 0 && last_error >= 0)) last_error = rc; if (last_error < 0) return_error(last_error); diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/eprnrend.c ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/eprnrend.c --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/eprnrend.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/eprnrend.c 2018-09-13 10:02:01.000000000 +0000 @@ -44,12 +44,6 @@ ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: eprnrend.c,v 1.15 2001/08/01 05:12:56 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -166,7 +160,6 @@ gx_color_value red = cv[0], green = cv[1], blue = cv[2]; static const gx_color_value half = gx_max_color_value/2; gx_color_index value = 0; - const eprn_Device *dev = (eprn_Device *)device; #ifdef EPRN_TRACE if_debug3(EPRN_TRACE_CHAR, @@ -174,7 +167,7 @@ red, green, blue); #endif - assert(dev->eprn.colour_model == eprn_DeviceRGB); + assert(((eprn_Device *)device)->eprn.colour_model == eprn_DeviceRGB); if (red > half) value |= RED_BIT; if (green > half) value |= GREEN_BIT; @@ -211,10 +204,10 @@ red, green, blue); #endif - assert(dev->eprn.colour_model == eprn_DeviceGray && red == green && - green == blue && (blue == 0 || blue == gx_max_color_value) || - dev->eprn.colour_model == eprn_DeviceCMY || - dev->eprn.colour_model == eprn_DeviceCMY_plus_K); + assert((dev->eprn.colour_model == eprn_DeviceGray && red == green && + green == blue && (blue == 0 || blue == gx_max_color_value)) || + dev->eprn.colour_model == eprn_DeviceCMY || + dev->eprn.colour_model == eprn_DeviceCMY_plus_K); /* Map to CMY */ if (red > half) value &= ~CYAN_BIT; @@ -730,13 +723,13 @@ */ comp = pixel & comp_mask; /* black */ for (j = 0; j < black_planes; j++) { - *ptr[j] = (*ptr[j] << 1) | comp & 1; + *ptr[j] = (*ptr[j] << 1) | (comp & 1); comp >>= 1; } if (non_black_planes > 0) for (l = 1; l < 4; l++) { comp = (pixel >> l*dev->eprn.bits_per_colorant) & comp_mask; for (m = 0; m < non_black_planes; m++, j++) { - *ptr[j] = (*ptr[j] << 1) | comp & 1; + *ptr[j] = (*ptr[j] << 1) | (comp & 1); comp >>= 1; } } @@ -819,13 +812,13 @@ /* Split and distribute over planes */ comp = pixel & comp_mask; /* black */ for (j = 0; j < black_planes; j++) { - *ptr[j] = (*ptr[j] << 1) | comp & 1; + *ptr[j] = (*ptr[j] << 1) | (comp & 1); comp >>= 1; } for (l = 1; l < 4; l++) { comp = (pixel >> l*dev->eprn.bits_per_colorant) & comp_mask; for (m = 0; m < non_black_planes; m++, j++) { - *ptr[j] = (*ptr[j] << 1) | comp & 1; + *ptr[j] = (*ptr[j] << 1) | (comp & 1); comp >>= 1; } } @@ -953,9 +946,9 @@ pixel = line[k]; /* Split and distribute over planes */ - *ptr[0] = (*ptr[0] << 1) | pixel & 0x01; + *ptr[0] = (*ptr[0] << 1) | (pixel & 0x01); #define assign_bit(index) \ - *ptr[index] = (*ptr[index] << 1) | (pixel >> index) & 0x01 + *ptr[index] = (*ptr[index] << 1) | ((pixel >> index) & 0x01) assign_bit(1); assign_bit(2); assign_bit(3); diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/gdeveprn.c ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/gdeveprn.c --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/gdeveprn.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/gdeveprn.c 2018-09-13 10:02:01.000000000 +0000 @@ -33,12 +33,6 @@ ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: gdeveprn.c,v 1.25 2001/04/30 05:15:51 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -108,6 +102,7 @@ /* Prefix for error messages */ #define ERRPREF "? eprn: " + /****************************************************************************** Function: eprn_get_initial_matrix @@ -661,9 +656,9 @@ best_cmatch->code: best_cdmatch->code); if (best_dmatch == NULL || - best_cmatch != NULL && - better_flag_match(desired, eprn->optional_flags, best_dmatch->code, - custom_code)) { + (best_cmatch != NULL && + better_flag_match(desired, eprn->optional_flags, best_dmatch->code, + custom_code))) { if (flag_match(desired, eprn->optional_flags, custom_code)) { if (eprn->media_overrides == NULL) { eprn->code = best_cmatch->code; @@ -1035,6 +1030,13 @@ /* Open the "prn" device part */ if ((rc = gdev_prn_open(device)) != 0) return rc; + /* if device has been subclassed (FirstPage/LastPage device) then make sure we use + * the subclassed device. + */ + while (device->child) + device = device->child; + eprn = &((eprn_Device *)device)->eprn; + /* Just in case a previous open call failed in a derived device (note that 'octets_per_line' is still the same as then): */ if (eprn->scan_line.str != NULL) @@ -1107,14 +1109,11 @@ ******************************************************************************/ -static void eprn_forget_defaultmatrix(gs_memory_t *memory) +static void eprn_forget_defaultmatrix(gx_device *device) { -#if EPRN_USE_GSTATE - /* Old ghostscript versions */ - gs_setdefaultmatrix(igs, NULL); -#else - gs_setdefaultmatrix(get_minst_from_memory(memory)->i_ctx_p->pgs, NULL); -#endif + eprn_Eprn *eprn = &((eprn_Device *)device)->eprn; + + gs_setdefaultmatrix((gs_gstate *)eprn->pgs, NULL); return; } @@ -1177,7 +1176,7 @@ /* If soft tumble has been demanded, ensure the get_initial_matrix procedure is consulted for the next page */ - if (eprn->soft_tumble) eprn_forget_defaultmatrix(dev->memory->non_gc_memory); + if (eprn->soft_tumble) eprn_forget_defaultmatrix(dev); #ifdef EPRN_TRACE if_debug1(EPRN_TRACE_CHAR, "! eprn_output_page() terminates after %f s.\n", diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/gdeveprn.h ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/gdeveprn.h --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/gdeveprn.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/gdeveprn.h 2018-09-13 10:02:01.000000000 +0000 @@ -173,9 +173,6 @@ #ifndef _gdeveprn_h /* Inclusion protection */ #define _gdeveprn_h -/* Configuration management identification */ -#pragma ident "@(#)$Id: gdeveprn.h,v 1.23 2001/04/30 05:15:51 Martin Rel $" - /*****************************************************************************/ /* Special Aladdin header, must be included before on some @@ -489,6 +486,8 @@ /* If this field is set, every second page will have its default user coordinate system rotated by 180 degrees. */ + dev_proc_fillpage((*orig_fillpage)); + /* Colour */ eprn_ColourModel colour_model; /* Colour model selected */ @@ -528,6 +527,7 @@ eprn_IR_FloydSteinberg, the next scan line to return is actually already present in 'next_scan_line' with its device coordinate being "next_y - 1", unless 'next_y' is zero in which case we have finished. */ + gs_gstate * pgs; } eprn_Eprn; /* Macro for device structure type definitions. Note that in contrast to @@ -542,6 +542,10 @@ gx_eprn_device_common; } eprn_Device; +#define private_st_device_EPRN(eprn_enum, eprn_reloc) \ + gs_private_st_composite(st_eprn_Device, eprn_Device, \ + "eprn_Device", eprn_enum, eprn_reloc); + /* Macro for initializing device structure instances (device prototypes) This macro corresponds to the prn_device*() macros which are used when @@ -605,6 +609,7 @@ 0.0, /* down_shift */ \ false, /* keep_margins */ \ false, /* soft_tumble */ \ + NULL, /* orig_fillpage */ \ eprn_DeviceGray, /* colour_model */ \ 2, /* black_levels */ \ 0, /* non_black_levels */ \ @@ -619,7 +624,8 @@ {NULL, 0}, /* next_scan_line */ \ 0, /* octets_per_line */ \ 0, /* output_planes */ \ - 0 /* next_y */ \ + 0, /* next_y */ \ + NULL /* pgs */ \ } /* For the calling conventions of the following functions consult the comments @@ -658,6 +664,7 @@ extern dev_proc_map_cmyk_color(eprn_map_cmyk_color_flex); extern dev_proc_map_cmyk_color(eprn_map_cmyk_color_max); extern dev_proc_map_cmyk_color(eprn_map_cmyk_color_glob); +extern dev_proc_fillpage(eprn_fillpage); /* Macro for initializing device procedure tables @@ -693,7 +700,49 @@ NULL, /* get_xfont_procs */ \ NULL, /* get_xfont_device */ \ NULL, /* map_rgb_alpha_color */ \ - gx_page_device_get_page_device /* get_page_device */ + gx_page_device_get_page_device, /* get_page_device */ \ + NULL, /* get_alpha_bits */ \ + NULL, /* copy_alpha */ \ + NULL, /* get_band */ \ + NULL, /* copy_rop */ \ + NULL, /* fill_path */ \ + NULL, /* stroke_path */ \ + NULL, /* fill_mask */ \ + NULL, /* fill_trapezoid */ \ + NULL, /* fill_parallelogram */ \ + NULL, /* fill_triangle */ \ + NULL, /* draw_thin_line */ \ + NULL, /* begin_image */ \ + NULL, /* image_data */ \ + NULL, /* end_image */ \ + NULL, /* strip_tile_rectangle */ \ + NULL, /* strip_copy_rop */ \ + NULL, /* get_clipping_box */ \ + NULL, /* begin_typed_image */ \ + NULL, /* get_bits_rectangle */ \ + NULL, /* map_color_rgb_alpha */ \ + NULL, /* create_compositor */ \ + NULL, /* get_hardware_params */ \ + NULL, /* text_begin */ \ + NULL, /* finish_copydevice */ \ + NULL, /* begin_transparency_group */ \ + NULL, /* end_transparency_group */ \ + NULL, /* begin_transparency_mask */ \ + NULL, /* end_transparency_mask */ \ + NULL, /* discard_transparency_layer */\ + NULL, /* get_color_mapping_procs */ \ + NULL, /* get_color_comp_index */ \ + NULL, /* encode_color */ \ + NULL, /* decode_color */ \ + NULL, /* pattern_manage */ \ + NULL, /* fill_rectangle_hl_color */ \ + NULL, /* include_color_space */ \ + NULL, /* fill_linear_color_scanline */\ + NULL, /* fill_linear_color_trapezoid */ \ + NULL, /* fill_linear_color_triangle */\ + NULL, /* update_spot_equivalent_colors */\ + NULL, /* ret_devn_params */ \ + eprn_fillpage /* fillpage */ /* The remaining fields should be NULL. */ /*****************************************************************************/ diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/mediasize.c ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/mediasize.c --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/mediasize.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/mediasize.c 2018-09-13 10:02:01.000000000 +0000 @@ -11,12 +11,6 @@ * * ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: mediasize.c,v 1.11 2001/04/12 18:35:26 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -171,8 +165,8 @@ assert(list[j].dimen[0] <= list[j].dimen[1]); assert(strlen(list[j].name) < LONGER_THAN_NAMES); assert(list[j].dimen[0] == 0.0 || list[j-1].dimen[0] < list[j].dimen[0] || - list[j-1].dimen[0] == list[j].dimen[0] && - list[j-1].dimen[1] <= list[j].dimen[1]); + (list[j-1].dimen[0] == list[j].dimen[0] && + list[j-1].dimen[1] <= list[j].dimen[1])); } /* Check that the highest accepted value does not collide with the flags */ @@ -408,9 +402,9 @@ code = ms_flags(code); /* Substrings */ - if (user_flag_list != NULL && - add_substrings(buffer, &length, &code, user_flag_list) != 0 || - add_substrings(buffer, &length, &code, substrings) != 0) return -1; + if ((user_flag_list != NULL && + add_substrings(buffer, &length, &code, user_flag_list) != 0) || + add_substrings(buffer, &length, &code, substrings) != 0) return -1; /* Transverse qualifier */ if (code & MS_TRANSVERSE_FLAG) { diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/mediasize.h ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/mediasize.h --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/mediasize.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/mediasize.h 2018-09-13 10:02:01.000000000 +0000 @@ -14,9 +14,6 @@ #ifndef _mediasize_h /* Inclusion protection */ #define _mediasize_h -/* Configuration management identification */ -#pragma ident "@(#)$Id: mediasize.h,v 1.11 2001/04/12 18:35:26 Martin Rel $" - /*****************************************************************************/ /* Macros for conversion between units. diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/pagecount.c ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/pagecount.c --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/pagecount.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/pagecount.c 2018-09-13 10:02:01.000000000 +0000 @@ -16,12 +16,6 @@ int dummy; #else -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: pagecount.c,v 1.6 2000/10/07 17:48:49 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/eprn/pagecount.h ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/pagecount.h --- ghostscript-9.10~dfsg/contrib/pcl3/eprn/pagecount.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/eprn/pagecount.h 2018-09-13 10:02:01.000000000 +0000 @@ -18,9 +18,6 @@ #define EPRN_NO_PAGECOUNTFILE #else -/* Configuration management identification */ -#pragma ident "@(#)$Id: pagecount.h,v 1.3 2000/11/19 07:05:17 Martin Rel $" - /*****************************************************************************/ /* The following two functions are used to read and write a "page count file". diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/ppd/fonts.ppd ghostscript-9.25~dfsg+1/contrib/pcl3/ppd/fonts.ppd --- ghostscript-9.10~dfsg/contrib/pcl3/ppd/fonts.ppd 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/ppd/fonts.ppd 2018-09-13 10:02:01.000000000 +0000 @@ -14,78 +14,78 @@ *% The following list has been derived from the gnu-gs-fonts-std-5.50.tar *% archive. -*Font URWGothicL-Book: Standard "(1.05)" Standard Disk -*Font URWGothicL-Demi: Standard "(1.05)" Standard Disk -*Font URWGothicL-BookObli: Standard "(1.05)" Standard Disk -*Font URWGothicL-DemiObli: Standard "(1.05)" Standard Disk -*Font URWBookmanL-Ligh: Standard "(1.05)" Standard Disk -*Font URWBookmanL-DemiBold: Standard "(1.05)" Standard Disk -*Font URWBookmanL-LighItal: Standard "(1.05)" Standard Disk -*Font URWBookmanL-DemiBoldItal: Standard "(1.05)" Standard Disk -*Font CenturySchL-Roma: Standard "(1.05)" Standard Disk -*Font CenturySchL-Bold: Standard "(1.05)" Standard Disk -*Font CenturySchL-Ital: Standard "(1.05)" Standard Disk -*Font CenturySchL-BoldItal: Standard "(1.05)" Standard Disk +*Font URWGothicL-Book: Standard "(1.10)" Standard Disk +*Font URWGothicL-Demi: Standard "(1.10)" Standard Disk +*Font URWGothicL-BookObli: Standard "(1.10)" Standard Disk +*Font URWGothicL-DemiObli: Standard "(1.10)" Standard Disk +*Font URWBookmanL-Ligh: Standard "(1.10)" Standard Disk +*Font URWBookmanL-DemiBold: Standard "(1.10)" Standard Disk +*Font URWBookmanL-LighItal: Standard "(1.10)" Standard Disk +*Font URWBookmanL-DemiBoldItal: Standard "(1.10)" Standard Disk +*Font CenturySchL-Roma: Standard "(1.10)" Standard Disk +*Font CenturySchL-Bold: Standard "(1.10)" Standard Disk +*Font CenturySchL-Ital: Standard "(1.10)" Standard Disk +*Font CenturySchL-BoldItal: Standard "(1.10)" Standard Disk *Font Dingbats: Special "(001.005)" Unknown Disk -*Font NimbusSanL-Regu: Standard "(1.05)" Standard Disk -*Font NimbusSanL-Bold: Standard "(1.05)" Standard Disk -*Font NimbusSanL-ReguItal: Standard "(1.05)" Standard Disk -*Font NimbusSanL-BoldItal: Standard "(1.05)" Standard Disk -*Font NimbusSanL-ReguCond: Standard "(1.05)" Standard Disk -*Font NimbusSanL-BoldCond: Standard "(1.05)" Standard Disk -*Font NimbusSanL-ReguCondItal: Standard "(1.05)" Standard Disk -*Font NimbusSanL-BoldCondItal: Standard "(1.05)" Standard Disk -*Font NimbusRomNo9L-Regu: Standard "(1.05)" Standard Disk -*Font NimbusRomNo9L-Medi: Standard "(1.05)" Standard Disk -*Font NimbusRomNo9L-ReguItal: Standard "(1.05)" Standard Disk -*Font NimbusRomNo9L-MediItal: Standard "(1.05)" Standard Disk -*Font NimbusMonL-Regu: Standard "(1.05)" Standard Disk -*Font NimbusMonL-Bold: Standard "(1.05)" Standard Disk -*Font NimbusMonL-ReguObli: Standard "(1.05)" Standard Disk -*Font NimbusMonL-BoldObli: Standard "(1.05)" Standard Disk -*Font URWPalladioL-Roma: Standard "(1.05)" Standard Disk -*Font URWPalladioL-Bold: Standard "(1.05)" Standard Disk -*Font URWPalladioL-Ital: Standard "(1.05)" Standard Disk -*Font URWPalladioL-BoldItal: Standard "(1.05)" Standard Disk +*Font NimbusSanL-Regu: Standard "(1.10)" Standard Disk +*Font NimbusSanL-Bold: Standard "(1.10)" Standard Disk +*Font NimbusSanL-ReguItal: Standard "(1.10)" Standard Disk +*Font NimbusSanL-BoldItal: Standard "(1.10)" Standard Disk +*Font NimbusSanL-ReguCond: Standard "(1.10)" Standard Disk +*Font NimbusSanL-BoldCond: Standard "(1.10)" Standard Disk +*Font NimbusSanL-ReguCondItal: Standard "(1.10)" Standard Disk +*Font NimbusSanL-BoldCondItal: Standard "(1.10)" Standard Disk +*Font NimbusRomNo9L-Regu: Standard "(1.10)" Standard Disk +*Font NimbusRomNo9L-Medi: Standard "(1.10)" Standard Disk +*Font NimbusRomNo9L-ReguItal: Standard "(1.10)" Standard Disk +*Font NimbusRomNo9L-MediItal: Standard "(1.10)" Standard Disk +*Font NimbusMonL-Regu: Standard "(1.10)" Standard Disk +*Font NimbusMonL-Bold: Standard "(1.10)" Standard Disk +*Font NimbusMonL-ReguObli: Standard "(1.10)" Standard Disk +*Font NimbusMonL-BoldObli: Standard "(1.10)" Standard Disk +*Font URWPalladioL-Roma: Standard "(1.10)" Standard Disk +*Font URWPalladioL-Bold: Standard "(1.10)" Standard Disk +*Font URWPalladioL-Ital: Standard "(1.10)" Standard Disk +*Font URWPalladioL-BoldItal: Standard "(1.10)" Standard Disk *Font StandardSymL: Special "(001.005)" Unknown Disk -*Font URWChanceryL-MediItal: Standard "(1.05)" Standard Disk +*Font URWChanceryL-MediItal: Standard "(1.10)" Standard Disk *% The following list is the same as the previous one, using standard font name *% substitutions from the GNU gs 5.50 Fontmap file. -*Font AvantGarde-Book: Standard "(1.05)" Standard Disk -*Font AvantGarde-Demi: Standard "(1.05)" Standard Disk -*Font AvantGarde-BookObli: Standard "(1.05)" Standard Disk -*Font AvantGarde-DemiObli: Standard "(1.05)" Standard Disk -*Font Bookman-Light: Standard "(1.05)" Standard Disk -*Font Bookman-Demi: Standard "(1.05)" Standard Disk -*Font Bookman-LightItal: Standard "(1.05)" Standard Disk -*Font Bookman-DemiItal: Standard "(1.05)" Standard Disk -*Font NewCenturySchlbk-Roman: Standard "(1.05)" Standard Disk -*Font NewCenturySchlbk-Bold: Standard "(1.05)" Standard Disk -*Font NewCenturySchlbk-Italic: Standard "(1.05)" Standard Disk -*Font NewCenturySchlbk-BoldItal: Standard "(1.05)" Standard Disk +*Font AvantGarde-Book: Standard "(1.10)" Standard Disk +*Font AvantGarde-Demi: Standard "(1.10)" Standard Disk +*Font AvantGarde-BookObli: Standard "(1.10)" Standard Disk +*Font AvantGarde-DemiObli: Standard "(1.10)" Standard Disk +*Font Bookman-Light: Standard "(1.10)" Standard Disk +*Font Bookman-Demi: Standard "(1.10)" Standard Disk +*Font Bookman-LightItal: Standard "(1.10)" Standard Disk +*Font Bookman-DemiItal: Standard "(1.10)" Standard Disk +*Font NewCenturySchlbk-Roman: Standard "(1.10)" Standard Disk +*Font NewCenturySchlbk-Bold: Standard "(1.10)" Standard Disk +*Font NewCenturySchlbk-Italic: Standard "(1.10)" Standard Disk +*Font NewCenturySchlbk-BoldItal: Standard "(1.10)" Standard Disk *Font ZapfDingbats: Special "(001.005)" Unknown Disk -*Font Helvetica: Standard "(1.05)" Standard Disk -*Font Helvetica-Bold: Standard "(1.05)" Standard Disk -*Font HelveticaItal: Standard "(1.05)" Standard Disk -*Font Helvetica-BoldItal: Standard "(1.05)" Standard Disk -*Font HelveticaCond: Standard "(1.05)" Standard Disk -*Font Helvetica-BoldCond: Standard "(1.05)" Standard Disk -*Font HelveticaCondItal: Standard "(1.05)" Standard Disk -*Font Helvetica-BoldCondItal: Standard "(1.05)" Standard Disk -*Font Times-Roman: Standard "(1.05)" Standard Disk -*Font Times-Bold: Standard "(1.05)" Standard Disk -*Font Times-RomanItal: Standard "(1.05)" Standard Disk -*Font Times-BoldItal: Standard "(1.05)" Standard Disk -*Font Courier: Standard "(1.05)" Standard Disk -*Font Courier-Bold: Standard "(1.05)" Standard Disk -*Font CourierObli: Standard "(1.05)" Standard Disk -*Font Courier-BoldObli: Standard "(1.05)" Standard Disk -*Font Palatino-Roman: Standard "(1.05)" Standard Disk -*Font Palatino-Bold: Standard "(1.05)" Standard Disk -*Font Palatino-Italic: Standard "(1.05)" Standard Disk -*Font Palatino-BoldItal: Standard "(1.05)" Standard Disk +*Font Helvetica: Standard "(1.10)" Standard Disk +*Font Helvetica-Bold: Standard "(1.10)" Standard Disk +*Font HelveticaItal: Standard "(1.10)" Standard Disk +*Font Helvetica-BoldItal: Standard "(1.10)" Standard Disk +*Font HelveticaCond: Standard "(1.10)" Standard Disk +*Font Helvetica-BoldCond: Standard "(1.10)" Standard Disk +*Font HelveticaCondItal: Standard "(1.10)" Standard Disk +*Font Helvetica-BoldCondItal: Standard "(1.10)" Standard Disk +*Font Times-Roman: Standard "(1.10)" Standard Disk +*Font Times-Bold: Standard "(1.10)" Standard Disk +*Font Times-RomanItal: Standard "(1.10)" Standard Disk +*Font Times-BoldItal: Standard "(1.10)" Standard Disk +*Font Courier: Standard "(1.10)" Standard Disk +*Font Courier-Bold: Standard "(1.10)" Standard Disk +*Font CourierObli: Standard "(1.10)" Standard Disk +*Font Courier-BoldObli: Standard "(1.10)" Standard Disk +*Font Palatino-Roman: Standard "(1.10)" Standard Disk +*Font Palatino-Bold: Standard "(1.10)" Standard Disk +*Font Palatino-Italic: Standard "(1.10)" Standard Disk +*Font Palatino-BoldItal: Standard "(1.10)" Standard Disk *Font Symbol: Special "(001.005)" Unknown Disk -*Font ZapfChancery-MediumItalic: Standard "(1.05)" Standard Disk +*Font ZapfChancery-MediumItalic: Standard "(1.10)" Standard Disk *% **************************************************************************** diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/gdevpcl3.c ghostscript-9.25~dfsg+1/contrib/pcl3/src/gdevpcl3.c --- ghostscript-9.10~dfsg/contrib/pcl3/src/gdevpcl3.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/gdevpcl3.c 2018-09-13 10:02:01.000000000 +0000 @@ -23,12 +23,6 @@ ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: gdevpcl3.c,v 1.32 2001/08/14 15:22:35 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -127,7 +121,7 @@ /*****************************************************************************/ /* Forward declaration */ -static void pcl3_flag_mismatch_reporter(FILE *err, +static void pcl3_flag_mismatch_reporter( const struct s_eprn_Device *eprn, bool no_match); /* Macro for creating device structure instances */ @@ -428,7 +422,7 @@ ******************************************************************************/ -static void pcl3_flag_mismatch_reporter(FILE *err, +static void pcl3_flag_mismatch_reporter( const struct s_eprn_Device *eprn, bool no_match) { const char *epref = eprn->CUPS_messages? CUPS_ERRPREF: ""; @@ -908,7 +902,8 @@ else { eprintf1("%s" ERRPREF "Unknown subdevice name: `", epref); errwrite(dev->memory, - string_value.data, sizeof(char)*string_value.size); + (const char *)string_value.data, + sizeof(char)*string_value.size); eprintf("'.\n"); last_error = gs_error_rangecheck; param_signal_error(plist, pname, last_error); @@ -1018,7 +1013,8 @@ else { eprintf1("%s" ERRPREF "Invalid duplex capability: `", epref); errwrite(dev->memory, - string_value.data, sizeof(char)*string_value.size); + (const char *)string_value.data, + sizeof(char)*string_value.size); eprintf("'.\n"); last_error = gs_error_rangecheck; param_signal_error(plist, pname, last_error); @@ -1074,7 +1070,8 @@ if (rc != gs_error_VMerror) { eprintf1("%s" ERRPREF "Unknown medium: `", epref); errwrite(dev->memory, - string_value.data, sizeof(char)*string_value.size); + (const char *)string_value.data, + sizeof(char)*string_value.size); eprintf("'.\n"); } last_error = rc; @@ -1144,7 +1141,8 @@ if (rc != gs_error_VMerror) { eprintf1("%s" ERRPREF "Unknown print quality: `", epref); errwrite(dev->memory, - string_value.data, sizeof(char)*string_value.size); + (const char *)string_value.data, + sizeof(char)*string_value.size); eprintf("'.\n"); } last_error = rc; @@ -1232,8 +1230,9 @@ /* Process parameters defined by base classes (should occur after treating parameters defined for the derived class, see gsparam.h) */ - if ((rc = eprn_put_params(device, plist)) < 0 || - rc > 0 && last_error >= 0) last_error = rc; + rc = eprn_put_params(device, plist); + if (rc < 0 || (rc > 0 && last_error >= 0)) + last_error = rc; /* Act if the colour model was changed */ if (previous_colour_model != dev->eprn.colour_model) set_palette(dev); @@ -1298,6 +1297,14 @@ /* Open the "eprn" device part */ if ((rc = eprn_open_device(device)) != 0) return rc; + /* if device has been subclassed (FirstPage/LastPage device) then make sure we use + * the subclassed device. + */ + while (device->child) + device = device->child; + + dev = (pcl3_Device *)device; + /* Fill the still unassigned parts of 'file_data' from the other data */ { pcl_FileData *data = &dev->file_data; @@ -1347,10 +1354,10 @@ just as fast, provided the compiler is sufficiently intelligent. */ dev->eprn.soft_tumble = dev->duplex_capability != Duplex_both && - (same_leading_edge && - dev->duplex_capability != Duplex_sameLeadingEdge || - !same_leading_edge && - dev->duplex_capability != Duplex_oppositeLeadingEdge); + ((same_leading_edge && + dev->duplex_capability != Duplex_sameLeadingEdge) || + (!same_leading_edge && + dev->duplex_capability != Duplex_oppositeLeadingEdge)); if (dev->eprn.soft_tumble) same_leading_edge = !same_leading_edge; /* I am assuming here that the values 1 and 2, specified by HP in @@ -1473,8 +1480,8 @@ if (pcl_cm_is_differential(dev->file_data.compression)) rd.previous = (pcl_OctetString *)malloc(planes*sizeof(pcl_OctetString)); if (lengths == NULL || rd.next == NULL || - pcl_cm_is_differential(dev->file_data.compression) && - rd.previous == NULL) { + (pcl_cm_is_differential(dev->file_data.compression) && + rd.previous == NULL)) { free(lengths); free(rd.next); free(rd.previous); eprintf1("%s" ERRPREF "Memory allocation failure from malloc().\n", epref); diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pcl3opts.c ghostscript-9.25~dfsg+1/contrib/pcl3/src/pcl3opts.c --- ghostscript-9.10~dfsg/contrib/pcl3/src/pcl3opts.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pcl3opts.c 2018-09-13 10:02:01.000000000 +0000 @@ -13,12 +13,6 @@ * * ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static char - cm_id[] = "@(#)$Id: pcl3opts.c,v 1.17 2001/05/31 15:19:16 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclcap.c ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclcap.c --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclcap.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclcap.c 2018-09-13 10:02:01.000000000 +0000 @@ -11,12 +11,6 @@ * * ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: pclcap.c,v 1.17 2001/03/08 09:17:51 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclcap.h ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclcap.h --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclcap.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclcap.h 2018-09-13 10:02:01.000000000 +0000 @@ -14,9 +14,6 @@ #ifndef _pclcap_h /* Inclusion protection */ #define _pclcap_h -/* Configuration management identification */ -#pragma ident "@(#)$Id: pclcap.h,v 1.10 2000/11/19 07:05:17 Martin Rel $" - /*****************************************************************************/ #include "gdeveprn.h" diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclcomp.c ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclcomp.c --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclcomp.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclcomp.c 2018-09-13 10:02:01.000000000 +0000 @@ -16,12 +16,6 @@ ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: pclcomp.c,v 1.11 2000/10/07 17:51:57 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -162,7 +156,7 @@ last = *in; in++; /* Fetch one octet and remember it. */ /* to state2 */ - state2: + /* state2: */ /* One octet to be treated is in 'last', 'in' points to the next. */ if (*in != last) { if (available < 3) return -1; @@ -696,7 +690,7 @@ /* Test macro for an argument of type "pcl_OctetString *" */ #define is_valid(s) \ - (s != NULL && ((s)->length == 0 || (s)->length > 0 && (s)->str != NULL)) + (s != NULL && ((s)->length == 0 || ((s)->length > 0 && (s)->str != NULL))) int pcl_compress(pcl_Compression method, const pcl_OctetString *in, const pcl_OctetString *prev, pcl_OctetString *out) @@ -704,8 +698,8 @@ int result = -1; /* Prevent silly mistakes with the arguments */ - assert(is_valid(in) && is_valid(out) && - (method != pcl_cm_delta && method != pcl_cm_crdr || is_valid(prev))); + assert((is_valid(in) && is_valid(out) && + method != pcl_cm_delta && method != pcl_cm_crdr) || is_valid(prev)); /* Treat zero-length case for the "purely horizontal" methods */ if (in->length == 0 && method != pcl_cm_delta && method != pcl_cm_crdr) { diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclgen.c ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclgen.c --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclgen.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclgen.c 2018-09-13 10:02:01.000000000 +0000 @@ -49,12 +49,6 @@ ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: pclgen.c,v 1.21 2001/04/29 10:37:08 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -82,7 +76,7 @@ /* Macro to check whether an octet is an ASCII letter. Note that we can't use the isalpha() function because we might be operating in an internationalized environment. */ -#define is_letter(c) (0x41 <= (c) && (c) <= 0x5A || 0x61 <= (c) && (c) <= 0x7A) +#define is_letter(c) ((0x41 <= (c) && (c) <= 0x5A) || (0x61 <= (c) && (c) <= 0x7A)) /* Same for digits */ #define is_digit(c) (0x30 <= (c) && (c) <= 0x39) @@ -308,7 +302,7 @@ /* Permissible characters are HT and the octets 32-255 with the exception of '"' (PJLTRM, with some corrections). */ - while (*s != '\0' && (*s == '\t' || 32 <= *s && *s != '"')) s++; + while (*s != '\0' && (*s == '\t' || (32 <= *s && *s != '"'))) s++; if (*s != '\0') { fprintf(stderr, ERRPREF "Illegal character in PJL job name (code 0x%02X).\n", *s); @@ -578,8 +572,8 @@ invalid = j < global->number_of_bitplanes; if (!invalid && pcl_cm_is_differential(global->compression)) { invalid = (data->previous == NULL || - global->compression == pcl_cm_delta && - data->workspace[1] == NULL); + (global->compression == pcl_cm_delta && + data->workspace[1] == NULL)); if (!invalid) { for (j = 0; j < global->number_of_bitplanes && @@ -1107,8 +1101,8 @@ data->depletion = 2; /* 25 % */ data->raster_graphics_quality = 0; /* use current control panel setting */ if (data->media_type == 3 || - data->media_type == 4 && data->palette != pcl_CMY && - data->palette != pcl_RGB) + (data->media_type == 4 && data->palette != pcl_CMY && + data->palette != pcl_RGB)) data->shingling = 2; /* 4 passes (25 % each pass) */ else data->shingling = 1; /* 2 passes (50 % each pass) */ } diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclgen.h ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclgen.h --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclgen.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclgen.h 2018-09-13 10:02:01.000000000 +0000 @@ -22,9 +22,6 @@ #ifndef _pclgen_h /* Inclusion protection */ #define _pclgen_h -/* Configuration management identification */ -#pragma ident "@(#)$Id: pclgen.h,v 1.25 2001/08/18 17:41:29 Martin Rel $" - /*****************************************************************************/ /* Standard headers */ diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclscan.c ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclscan.c --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclscan.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclscan.c 2018-09-13 10:02:01.000000000 +0000 @@ -11,12 +11,6 @@ * * ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: pclscan.c,v 1.8 2000-10-22 11:05:34+02 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclscan.h ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclscan.h --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclscan.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclscan.h 2018-09-13 10:02:01.000000000 +0000 @@ -14,13 +14,6 @@ #ifndef _pclscan_h /* Inclusion protection */ #define _pclscan_h -/* Configuration management identification */ -#ifdef __GNUC__ -#ident "@(#)$Id: pclscan.h,v 1.6 2000-10-22 11:05:34+02 Martin Rel $" -#else -#pragma ident "@(#)$Id: pclscan.h,v 1.6 2000-10-22 11:05:34+02 Martin Rel $" -#endif - /*****************************************************************************/ /* Standard headers */ diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclsize.c ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclsize.c --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclsize.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclsize.c 2018-09-13 10:02:01.000000000 +0000 @@ -11,12 +11,6 @@ * * ******************************************************************************/ -/* Configuration management identification */ -#ifndef lint -static const char - cm_id[] = "@(#)$Id: pclsize.c,v 1.10 2001/08/18 17:41:49 Martin Rel $"; -#endif - /*****************************************************************************/ #ifndef _XOPEN_SOURCE @@ -126,7 +120,7 @@ initialized = TRUE; } - key.mc = ms_without_flags(code) | code & PCL_CARD_FLAG; + key.mc = ms_without_flags(code) |( code & PCL_CARD_FLAG); result = (const CodeEntry *)bsearch(&key, code_map, array_size(code_map), sizeof(CodeEntry), cmp_by_size); diff -Nru ghostscript-9.10~dfsg/contrib/pcl3/src/pclsize.h ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclsize.h --- ghostscript-9.10~dfsg/contrib/pcl3/src/pclsize.h 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pcl3/src/pclsize.h 2018-09-13 10:02:01.000000000 +0000 @@ -15,9 +15,6 @@ #ifndef _pclsize_h /* Inclusion protection */ #define _pclsize_h -/* Configuration management identification */ -#pragma ident "@(#)$Id: pclsize.h,v 1.7 2000/11/19 07:05:17 Martin Rel $" - /*****************************************************************************/ #include "mediasize.h" diff -Nru ghostscript-9.10~dfsg/contrib/pscolor/test.c ghostscript-9.25~dfsg+1/contrib/pscolor/test.c --- ghostscript-9.10~dfsg/contrib/pscolor/test.c 2013-08-30 10:37:28.000000000 +0000 +++ ghostscript-9.25~dfsg+1/contrib/pscolor/test.c 2018-09-13 10:02:01.000000000 +0000 @@ -333,7 +333,7 @@ fclose(black_fd); fclose(temp_fd); - if ((code == 0) || (code == e_Quit)) + if ((code == 0) || (code == gs_error_Quit)) return 0; return 1; } diff -Nru ghostscript-9.10~dfsg/cups/cups.mak ghostscript-9.25~dfsg+1/cups/cups.mak --- ghostscript-9.10~dfsg/cups/cups.mak 2013-08-30 10:37:29.000000000 +0000 +++ ghostscript-9.25~dfsg+1/cups/cups.mak 2018-09-13 10:02:01.000000000 +0000 @@ -21,7 +21,7 @@ # # define the name of this makefile -CUPS_MAK=$(LCUPSSRCDIR)$(D)cups.mak +CUPS_MAK=$(LCUPSSRCDIR)$(D)cups.mak $(TOP_MAKEFILES) ### ----------------- CUPS Ghostscript Driver ---------------------- ### diff -Nru ghostscript-9.10~dfsg/cups/gdevcups.c ghostscript-9.25~dfsg+1/cups/gdevcups.c --- ghostscript-9.10~dfsg/cups/gdevcups.c 2013-08-30 10:37:29.000000000 +0000 +++ ghostscript-9.25~dfsg+1/cups/gdevcups.c 2018-09-13 10:02:01.000000000 +0000 @@ -70,6 +70,7 @@ #include "std.h" /* to stop stdlib.h redefining types */ #include "gdevprn.h" #include "gsparam.h" +#include "gxdevsop.h" #include "arch.h" #include "gsicc_manage.h" @@ -99,6 +100,70 @@ int old_width, int old_height, bool old_page_uses_transparency); +/* Strings for cups_put/get_params */ +static const char * const cups_Integer_strings[] = +{ + "cupsInteger0", + "cupsInteger1", + "cupsInteger2", + "cupsInteger3", + "cupsInteger4", + "cupsInteger5", + "cupsInteger6", + "cupsInteger7", + "cupsInteger8", + "cupsInteger9", + "cupsInteger10", + "cupsInteger11", + "cupsInteger12", + "cupsInteger13", + "cupsInteger14", + "cupsInteger15", + NULL +}; + +static const char * const cups_Real_strings[] = +{ + "cupsReal0", + "cupsReal1", + "cupsReal2", + "cupsReal3", + "cupsReal4", + "cupsReal5", + "cupsReal6", + "cupsReal7", + "cupsReal8", + "cupsReal9", + "cupsReal10", + "cupsReal11", + "cupsReal12", + "cupsReal13", + "cupsReal14", + "cupsReal15", + NULL +}; + +static const char * const cups_String_strings[] = +{ + "cupsString0", + "cupsString1", + "cupsString2", + "cupsString3", + "cupsString4", + "cupsString5", + "cupsString6", + "cupsString7", + "cupsString8", + "cupsString9", + "cupsString10", + "cupsString11", + "cupsString12", + "cupsString13", + "cupsString14", + "cupsString15", + NULL +}; + /* * Check if we are compiling against CUPS 1.2. If so, enable * certain extended attributes and use a different page header @@ -109,10 +174,17 @@ # define cups_page_header_t cups_page_header2_t # define cupsRasterWriteHeader cupsRasterWriteHeader2 #else -/* The RGBW colorspace is not defined until CUPS 1.2... */ +/* The RGBW, SW, SRGB, and ADOBERGB colorspaces is not defined until + CUPS 1.2... */ # define CUPS_CSPACE_RGBW 17 +# define CUPS_CSPACE_SW 18 +# define CUPS_CSPACE_SRGB 19 +# define CUPS_CSPACE_ADOBERGB 20 #endif /* CUPS_RASTER_SYNCv1 */ +#if !defined(CUPS_RASTER_WRITE_PWG) + #define CUPS_RASTER_WRITE_PWG 3 +#endif /* * CIE XYZ color constants... @@ -181,6 +253,7 @@ private int cups_set_color_info(gx_device *); private dev_proc_sync_output(cups_sync_output); private prn_dev_proc_get_space_params(cups_get_space_params); +private int cups_spec_op(gx_device *dev_, int op, void *data, int datasize); #ifdef dev_t_proc_encode_color private cm_map_proc_gray(cups_map_gray); @@ -321,7 +394,7 @@ NULL, /* push_transparency_state */ NULL, /* pop_transparency_state */ NULL, /* put_image */ - + cups_spec_op }; #define prn_device_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_pages)\ @@ -336,109 +409,118 @@ ),\ prn_device_body_copies_rest_(print_pages) -gx_device_cups gs_cups_device = -{ - prn_device_body_copies(gx_device_cups,/* type */ - cups_procs, /* procedures */ - "cups", /* device name */ - 85, /* initial width */ - 110, /* initial height */ - 100, /* initial x resolution */ - 100, /* initial y resolution */ - 0, /* initial left offset */ - 0, /* initial top offset */ - 0, /* initial left margin */ - 0, /* initial bottom margin */ - 0, /* initial right margin */ - 0, /* initial top margin */ - 1, /* number of color components */ - 1, /* number of color bits */ - 1, /* maximum gray value */ - 0, /* maximum color value */ - 2, /* number of gray values */ - 0, /* number of color values */ - cups_print_pages), - /* print procedure */ - 0, /* page */ - NULL, /* stream */ - { /* header */ - "", /* MediaClass */ - "", /* MediaColor */ - "", /* MediaType */ - "", /* OutputType */ - 0, /* AdvanceDistance */ - CUPS_ADVANCE_NONE, /* AdvanceMedia */ - CUPS_FALSE, /* Collate */ - CUPS_CUT_NONE, /* CutMedia */ - CUPS_FALSE, /* Duplex */ - { 100, 100 }, /* HWResolution */ - { 0, 0, 612, 792 }, /* ImagingBoundingBox */ - CUPS_FALSE, /* InsertSheet */ - CUPS_JOG_NONE, /* Jog */ - CUPS_EDGE_TOP, /* LeadingEdge */ - { 0, 0 }, /* Margins */ - CUPS_FALSE, /* ManualFeed */ - 0, /* MediaPosition */ - 0, /* MediaWeight */ - CUPS_FALSE, /* MirrorPrint */ - CUPS_FALSE, /* NegativePrint */ - 1, /* NumCopies */ - CUPS_ORIENT_0, /* Orientation */ - CUPS_FALSE, /* OutputFaceUp */ - { 612, 792 }, /* PageSize */ - CUPS_FALSE, /* Separations */ - CUPS_FALSE, /* TraySwitch */ - CUPS_FALSE, /* Tumble */ - 850, /* cupsWidth */ - 1100, /* cupsHeight */ - 0, /* cupsMediaType */ - 1, /* cupsBitsPerColor */ - 1, /* cupsBitsPerPixel */ - 107, /* cupsBytesPerLine */ - CUPS_ORDER_CHUNKED, /* cupsColorOrder */ - CUPS_CSPACE_K, /* cupsColorSpace */ - 0, /* cupsCompression */ - 0, /* cupsRowCount */ - 0, /* cupsRowFeed */ - 0 /* cupsRowStep */ + + #ifdef CUPS_RASTER_SYNCv1 - , - 1, /* cupsNumColors */ - 1.0, /* cupsBorderlessScalingFactor */ - { 612.0, 792.0 }, /* cupsPageSize */ - { 0.0, 0.0, 612.0, 792.0 }, /* cupsImagingBBox */ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* cupsInteger */ - { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, /* cupsReal */ - { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, - /* cupsString */ - "", /* cupsMarkerType */ - "", /* cupsRenderingIntent */ +#define RASTER_SYNCv1_ENTRIES \ + ,\ + 1, /* cupsNumColors */\ + 1.0, /* cupsBorderlessScalingFactor */\ + { 612.0, 792.0 }, /* cupsPageSize */\ + { 0.0, 0.0, 612.0, 792.0 }, /* cupsImagingBBox */\ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* cupsInteger */\ + { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, /* cupsReal */\ + { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },\ + /* cupsString */\ + "", /* cupsMarkerType */\ + "", /* cupsRenderingIntent */\ "" /* cupsPageSizeName */ +#else +#define RASTER_SYNCv1_ENTRIES #endif /* CUPS_RASTER_SYNCv1 */ - }, - 0, /* landscape */ - 0, /* lastpage */ - 0, /* HaveProfile */ - NULL, /* Profile */ - NULL, /* PPD */ - { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, - 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f },/* RevLower1 */ - { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 },/* RevUpper1 */ - { 0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, - 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f },/* RevLower2 */ - { 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0, - 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0 },/* RevUpper2 */ - {0x00}, /* DecodeLUT */ - {0x00}, /* EncodeLUT */ - {0x00}, /* Density */ - {{{0x00},{0x00},{0x00}}, - {{0x00},{0x00},{0x00}}, - {{0x00},{0x00},{0x00}}}, /* Matrix */ - 0, /* user_icc */ + +#define gs_xxx_device(dname, mediaclass)\ + prn_device_body_copies(gx_device_cups,/* type */\ + cups_procs, /* procedures */\ + dname, /* device name */\ + 85, /* initial width */\ + 110, /* initial height */\ + 100, /* initial x resolution */\ + 100, /* initial y resolution */\ + 0, /* initial left offset */\ + 0, /* initial top offset */\ + 0, /* initial left margin */\ + 0, /* initial bottom margin */\ + 0, /* initial right margin */\ + 0, /* initial top margin */\ + 1, /* number of color components */\ + 1, /* number of color bits */\ + 1, /* maximum gray value */\ + 0, /* maximum color value */\ + 2, /* number of gray values */\ + 0, /* number of color values */\ + cups_print_pages),\ + /* print procedure */\ + 0, /* page */\ + NULL, /* stream */\ + { /* header */\ + mediaclass, /* MediaClass */\ + "", /* MediaColor */\ + "", /* MediaType */\ + "", /* OutputType */\ + 0, /* AdvanceDistance */\ + CUPS_ADVANCE_NONE, /* AdvanceMedia */\ + CUPS_FALSE, /* Collate */\ + CUPS_CUT_NONE, /* CutMedia */\ + CUPS_FALSE, /* Duplex */\ + { 100, 100 }, /* HWResolution */\ + { 0, 0, 612, 792 }, /* ImagingBoundingBox */\ + CUPS_FALSE, /* InsertSheet */\ + CUPS_JOG_NONE, /* Jog */\ + CUPS_EDGE_TOP, /* LeadingEdge */\ + { 0, 0 }, /* Margins */\ + CUPS_FALSE, /* ManualFeed */\ + 0, /* MediaPosition */\ + 0, /* MediaWeight */\ + CUPS_FALSE, /* MirrorPrint */\ + CUPS_FALSE, /* NegativePrint */\ + 1, /* NumCopies */\ + CUPS_ORIENT_0, /* Orientation */\ + CUPS_FALSE, /* OutputFaceUp */\ + { 612, 792 }, /* PageSize */\ + CUPS_FALSE, /* Separations */\ + CUPS_FALSE, /* TraySwitch */\ + CUPS_FALSE, /* Tumble */\ + 850, /* cupsWidth */\ + 1100, /* cupsHeight */\ + 0, /* cupsMediaType */\ + 1, /* cupsBitsPerColor */\ + 1, /* cupsBitsPerPixel */\ + 107, /* cupsBytesPerLine */\ + CUPS_ORDER_CHUNKED, /* cupsColorOrder */\ + CUPS_CSPACE_K, /* cupsColorSpace */\ + 0, /* cupsCompression */\ + 0, /* cupsRowCount */\ + 0, /* cupsRowFeed */\ + 0 /* cupsRowStep */\ + RASTER_SYNCv1_ENTRIES, /* See above */\ + },\ + 0, /* landscape */\ + 0, /* lastpage */\ + 0, /* HaveProfile */\ + NULL, /* Profile */\ + NULL, /* PPD */\ + { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,\ + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f },/* RevLower1 */\ + { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,\ + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 },/* RevUpper1 */\ + { 0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d,\ + 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f },/* RevLower2 */\ + { 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0,\ + 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0 },/* RevUpper2 */\ + {0x00}, /* DecodeLUT */\ + {0x00}, /* EncodeLUT */\ + {0x00}, /* Density */\ + {{{0x00},{0x00},{0x00}},\ + {{0x00},{0x00},{0x00}},\ + {{0x00},{0x00},{0x00}}}, /* Matrix */\ + 0, /* user_icc */\ 3 /* cupsRasterVersion */ -}; + +gx_device_cups gs_cups_device = { gs_xxx_device("cups", "") }; +gx_device_cups gs_pwgraster_device = { gs_xxx_device("pwgraster", + "PwgRaster") }; /* * Local functions... @@ -622,6 +704,7 @@ return -1; /* Indicate that the component name is "unknown" */ break; case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : case CUPS_CSPACE_WHITE : if (compare_color_names(pname, name_size, "White") || compare_color_names(pname, name_size, "Luminance") || @@ -636,6 +719,7 @@ compare_color_names(pname, name_size, "Transparent") || compare_color_names(pname, name_size, "Transparency")) return 3; + /* fall through */ case CUPS_CSPACE_RGBW : if (compare_color_names(pname, name_size, "Red")) return 0; @@ -649,6 +733,8 @@ return -1; break; case CUPS_CSPACE_RGB : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : if (compare_color_names(pname, name_size, "Red")) return 0; if (compare_color_names(pname, name_size, "Green")) @@ -678,6 +764,7 @@ # endif /* CUPS_RASTER_HAVE_COLORIMETRIC */ if (compare_color_names(pname, name_size, "Black")) return 3; + /* fall through */ case CUPS_CSPACE_CMY : if (compare_color_names(pname, name_size, "Cyan")) return 0; @@ -692,13 +779,16 @@ if (compare_color_names(pname, name_size, "Silver") || compare_color_names(pname, name_size, "Silver Foil")) return 3; + /* fall through */ case CUPS_CSPACE_GMCK : if (compare_color_names(pname, name_size, "Gold") || compare_color_names(pname, name_size, "Gold Foil")) return 0; + /* fall through */ case CUPS_CSPACE_YMCK : if (compare_color_names(pname, name_size, "Black")) return 3; + /* fall through */ case CUPS_CSPACE_YMC : if (compare_color_names(pname, name_size, "Yellow")) return 0; @@ -851,13 +941,12 @@ cups_get_params(gx_device *pdev, /* I - Device info */ gs_param_list *plist) /* I - Parameter list */ { -#ifdef CUPS_RASTER_SYNCv1 - int i; /* Looping var */ - char name[255]; /* Attribute name */ -#endif /* CUPS_RASTER_SYNCv1 */ int code; /* Return code */ gs_param_string s; /* Temporary string value */ bool b; /* Temporary boolean value */ +#ifdef CUPS_RASTER_SYNCv1 + int i; /* Looping var */ +#endif /* CUPS_RASTER_SYNCv1 */ #ifdef CUPS_DEBUG2 @@ -873,7 +962,7 @@ #endif /* CUPS_DEBUG2 */ if ((code = gdev_prn_get_params(pdev, plist)) < 0) - return (code); + goto done; #ifdef CUPS_DEBUG2 dmprintf(pdev->memory, "DEBUG2: after gdev_prn_get_params()\n"); @@ -883,193 +972,192 @@ * Then write the CUPS parameters... */ - param_string_from_string(s, cups->header.MediaClass); + param_string_from_transient_string(s, cups->header.MediaClass); if ((code = param_write_string(plist, "MediaClass", &s)) < 0) - return (code); + goto done; - param_string_from_string(s, cups->header.MediaColor); + param_string_from_transient_string(s, cups->header.MediaColor); if ((code = param_write_string(plist, "MediaColor", &s)) < 0) - return (code); + goto done; - param_string_from_string(s, cups->header.MediaType); + param_string_from_transient_string(s, cups->header.MediaType); if ((code = param_write_string(plist, "MediaType", &s)) < 0) - return (code); + goto done; - param_string_from_string(s, cups->header.OutputType); + param_string_from_transient_string(s, cups->header.OutputType); if ((code = param_write_string(plist, "OutputType", &s)) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "AdvanceDistance", (int *)&(cups->header.AdvanceDistance))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "AdvanceMedia", (int *)&(cups->header.AdvanceMedia))) < 0) - return (code); + goto done; b = cups->header.Collate; if ((code = param_write_bool(plist, "Collate", &b)) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "CutMedia", (int *)&(cups->header.CutMedia))) < 0) - return (code); + goto done; b = cups->header.Duplex; if ((code = param_write_bool(plist, "Duplex", &b)) < 0) - return (code); + goto done; b = cups->header.InsertSheet; if ((code = param_write_bool(plist, "InsertSheet", &b)) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "Jog", (int *)&(cups->header.Jog))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "LeadingEdge", (int *)&(cups->header.LeadingEdge))) < 0) - return (code); + goto done; b = cups->header.ManualFeed; if ((code = param_write_bool(plist, "ManualFeed", &b)) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "MediaPosition", (int *)&(cups->header.MediaPosition))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "MediaWeight", (int *)&(cups->header.MediaWeight))) < 0) - return (code); + goto done; b = cups->header.MirrorPrint; if ((code = param_write_bool(plist, "MirrorPrint", &b)) < 0) - return (code); + goto done; b = cups->header.NegativePrint; if ((code = param_write_bool(plist, "NegativePrint", &b)) < 0) - return (code); + goto done; b = cups->header.OutputFaceUp; if ((code = param_write_bool(plist, "OutputFaceUp", &b)) < 0) - return (code); + goto done; b = cups->header.Separations; if ((code = param_write_bool(plist, "Separations", &b)) < 0) - return (code); + goto done; b = cups->header.TraySwitch; if ((code = param_write_bool(plist, "TraySwitch", &b)) < 0) - return (code); + goto done; b = cups->header.Tumble; if ((code = param_write_bool(plist, "Tumble", &b)) < 0) - return (code); + goto done; #if 0 /* Don't include read-only parameters... */ if ((code = param_write_int(plist, "cupsWidth", (int *)&(cups->header.cupsWidth))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsHeight", (int *)&(cups->header.cupsHeight))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsBitsPerPixel", (int *)&(cups->header.cupsBitsPerPixel))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsBytesPerLine", (int *)&(cups->header.cupsBytesPerLine))) < 0) - return (code); + goto done; #endif /* 0 */ if ((code = param_write_int(plist, "cupsMediaType", (int *)&(cups->header.cupsMediaType))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsBitsPerColor", (int *)&(cups->header.cupsBitsPerColor))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsColorOrder", (int *)&(cups->header.cupsColorOrder))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsColorSpace", (int *)&(cups->header.cupsColorSpace))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsCompression", (int *)&(cups->header.cupsCompression))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsRowCount", (int *)&(cups->header.cupsRowCount))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsRowFeed", (int *)&(cups->header.cupsRowFeed))) < 0) - return (code); + goto done; if ((code = param_write_int(plist, "cupsRowStep", (int *)&(cups->header.cupsRowStep))) < 0) - return (code); + goto done; #ifdef CUPS_RASTER_SYNCv1 #if 0 /* Don't include read-only parameters... */ if ((code = param_write_int(plist, "cupsNumColors", (int *)&(cups->header.cupsNumColors))) < 0) - return (code); + goto done; #endif /* 0 */ if ((code = param_write_float(plist, "cupsBorderlessScalingFactor", &(cups->header.cupsBorderlessScalingFactor))) < 0) - return (code); + goto done; - for (i = 0; i < 16; i ++) + for (i = 0; cups_Integer_strings[i] != NULL; i ++) { - sprintf(name, "cupsInteger%d", i); - if ((code = param_write_int(plist, strdup(name), + if ((code = param_write_int(plist, cups_Integer_strings[i], (int *)(cups->header.cupsInteger + i))) < 0) - return (code); + goto done; } - for (i = 0; i < 16; i ++) + for (i = 0; cups_Real_strings[i] != NULL; i ++) { - sprintf(name, "cupsReal%d", i); - if ((code = param_write_float(plist, strdup(name), + if ((code = param_write_float(plist, cups_Real_strings[i], cups->header.cupsReal + i)) < 0) - return (code); + goto done; } - for (i = 0; i < 16; i ++) + for (i = 0; cups_String_strings[i] != NULL; i ++) { - sprintf(name, "cupsString%d", i); - param_string_from_string(s, cups->header.cupsString[i]); - if ((code = param_write_string(plist, strdup(name), &s)) < 0) - return (code); + param_string_from_transient_string(s, cups->header.cupsString[i]); + if ((code = param_write_string(plist, cups_String_strings[i], &s)) < 0) + goto done; } - param_string_from_string(s, cups->header.cupsMarkerType); + param_string_from_transient_string(s, cups->header.cupsMarkerType); if ((code = param_write_string(plist, "cupsMarkerType", &s)) < 0) - return (code); + goto done; - param_string_from_string(s, cups->header.cupsRenderingIntent); + param_string_from_transient_string(s, cups->header.cupsRenderingIntent); if ((code = param_write_string(plist, "cupsRenderingIntent", &s)) < 0) - return (code); + goto done; - param_string_from_string(s, cups->header.cupsPageSizeName); + param_string_from_transient_string(s, cups->header.cupsPageSizeName); if ((code = param_write_string(plist, "cupsPageSizeName", &s)) < 0) - return (code); + goto done; #endif /* CUPS_RASTER_SYNCv1 */ +done: + #ifdef CUPS_DEBUG2 dmprintf(pdev->memory, "DEBUG2: Leaving cups_get_params()\n"); #endif /* CUPS_DEBUG2 */ - return (0); + return code; } @@ -1181,6 +1269,7 @@ switch (cups->header.cupsColorSpace) { case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : c0 = (c * 31 + m * 61 + y * 8) / 100 + k; if (c0 < 0) @@ -1194,6 +1283,8 @@ out[3] = frac_1; case CUPS_CSPACE_RGB : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : case CUPS_CSPACE_RGBW : c0 = c + k; c1 = m + k; @@ -1232,8 +1323,6 @@ out[3] = frac_1; else if (c3 == frac_1) out[3] = 0; - else - out[3] = frac_1; } break; @@ -1646,7 +1735,7 @@ private void cups_map_rgb(gx_device *pdev, /* I - Device info */ - const gs_imager_state *pis,/* I - Device state */ + const gs_gstate *pgs,/* I - Device state */ frac r, /* I - Red value */ frac g, /* I - Green value */ frac b, /* I - Blue value */ @@ -1659,7 +1748,7 @@ #ifdef CUPS_DEBUG2 dmprintf6(pdev->memory, "DEBUG2: cups_map_rgb(%p, %p, %d, %d, %d, %p)\n", - pdev, pis, r, g, b, out); + pdev, pgs, r, g, b, out); #endif /* CUPS_DEBUG2 */ /* @@ -2000,12 +2089,15 @@ break; case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : prgb[0] = prgb[1] = prgb[2] = cups->DecodeLUT[c3]; break; case CUPS_CSPACE_RGB : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : prgb[0] = cups->DecodeLUT[c1]; prgb[1] = cups->DecodeLUT[c2]; prgb[2] = cups->DecodeLUT[c3]; @@ -2272,10 +2364,13 @@ switch (cups->header.cupsColorSpace) { case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : i = cups->EncodeLUT[(r * 31 + g * 61 + b * 8) / 100]; break; case CUPS_CSPACE_RGB : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : ic = cups->EncodeLUT[r]; im = cups->EncodeLUT[g]; iy = cups->EncodeLUT[b]; @@ -2699,7 +2794,7 @@ break; #ifdef GX_COLOR_INDEX_TYPE case 16 : - i = (((((ic << 16) | im) << 16) | iy) << 16) | ik; + i = (((ic << 16) | im) << 16) | iy; break; #endif /* GX_COLOR_INDEX_TYPE */ } @@ -2744,7 +2839,7 @@ } if ((code = gdev_prn_open(pdev)) != 0) - return (code); + return(code); if (cups->PPD == NULL) cups->PPD = ppdOpenFile(getenv("PPD")); @@ -2881,10 +2976,25 @@ return_error(gs_error_unknownerror); } } + /* NOTE: PWG Raster output is only available with shared CUPS CUPS and + CUPS image libraries as the built-in libraries of Ghostscript do not + contain the new code needed for PWG Raster output. This conditional + is a temporary workaround for the time being until up-to-date CUPS + libraries get included. */ if ((cups->stream = cupsRasterOpen(fileno(cups->file), +#if defined(CUPS_RASTER_HAVE_PWGRASTER) + (strcasecmp(cups->header.MediaClass, + "PwgRaster") == 0 ? + CUPS_RASTER_WRITE_PWG : + (cups->cupsRasterVersion == 3 ? + CUPS_RASTER_WRITE : + CUPS_RASTER_WRITE_COMPRESSED)))) == + NULL) +#else (cups->cupsRasterVersion == 3 ? CUPS_RASTER_WRITE : CUPS_RASTER_WRITE_COMPRESSED))) == NULL) +#endif { perror("ERROR: Unable to open raster stream - "); return_error(gs_error_ioerror); @@ -2953,10 +3063,6 @@ gs_param_list *plist) /* I - Parameter list */ { int i; /* Looping var */ -#ifdef CUPS_RASTER_SYNCv1 - char name[255]; /* Name of attribute */ - float sf; /* cupsBorderlessScalingFactor */ -#endif /* CUPS_RASTER_SYNCv1 */ float margins[4]; /* Physical margins of print */ ppd_size_t *size; /* Page size */ int code; /* Error code */ @@ -2990,6 +3096,9 @@ gs_param_string icc_pro_dummy; int old_cmps = cups->color_info.num_components; int old_depth = cups->color_info.depth; +#ifdef CUPS_RASTER_SYNCv1 + float sf; /* cupsBorderlessScalingFactor */ +#endif /* CUPS_RASTER_SYNCv1 */ #ifdef CUPS_DEBUG dmprintf2(pdev->memory, "DEBUG2: cups_put_params(%p, %p)\n", pdev, plist); @@ -3004,7 +3113,7 @@ { \ dmprintf1(pdev->memory, "ERROR: Error setting %s...\n", sname); \ param_signal_error(plist, sname, code); \ - return (code); \ + goto done; \ } \ else if (code == 0) \ { \ @@ -3018,7 +3127,7 @@ { \ dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n", sname); \ param_signal_error(plist, sname, code); \ - return (code); \ + goto done; \ } \ else if (code == 0) \ { \ @@ -3030,7 +3139,7 @@ { \ dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n", sname); \ param_signal_error(plist, sname, code); \ - return (code); \ + goto done; \ } \ else if (code == 0) \ { \ @@ -3044,7 +3153,7 @@ { \ dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n", sname); \ param_signal_error(plist, sname, code); \ - return (code); \ + goto done; \ } \ if (code == 0) \ cups->header.name = CUPS_FALSE; \ @@ -3061,7 +3170,7 @@ { \ dmprintf1(pdev->memory, "ERROR: Error setting %s...\n", sname); \ param_signal_error(plist, sname, code); \ - return (code); \ + goto done; \ } \ if (code == 0) \ { \ @@ -3090,14 +3199,6 @@ cups->user_icc = param_read_string(plist, "OutputICCProfile", &icc_pro_dummy) == 0; } - /* We set the old dimensions to 1 if we have a color depth change, so - that memory reallocation gets forced. This is perhaps not the correct - approach to prevent crashes like in bug 690435. We keep it for the - time being until we decide finally */ - if (color_set) { - width_old = 1; - height_old = 1; - } /* We also recompute page size and margins if we simply get onto a new page without necessarily having a page size change in the PostScript code, as for some printers margins have to be flipped on the back sides of @@ -3119,7 +3220,6 @@ arrayoption(ImagingBoundingBox, "ImagingBoundingBox", 4) booloption(InsertSheet, "InsertSheet") intoption(Jog, "Jog", cups_jog_t) - intoption(LeadingEdge, "LeadingEdge", cups_edge_t) arrayoption(Margins, "Margins", 2) booloption(ManualFeed, "ManualFeed") intoption(MediaPosition, "cupsMediaPosition", unsigned) /* Compatibility */ @@ -3141,6 +3241,23 @@ intoption(cupsRowFeed, "cupsRowFeed", unsigned) intoption(cupsRowStep, "cupsRowStep", unsigned) + /* Special handling of LeadingEdge to allow null as a valid value type */ + if ((code = param_read_int(plist, "LeadingEdge", &intval)) < 0) + { + if ((code = param_read_null(plist, "LeadingEdge")) < 0) + { + dmprintf(pdev->memory, "ERROR: Error setting LeadingEdge ...\n"); + param_signal_error(plist, "LeadingEdge", code); + goto done; + } + if (code == 0) + cups->header.LeadingEdge = CUPS_EDGE_TOP; + } + else if (code == 0) + { + cups->header.LeadingEdge = (cups_edge_t)intval; + } + #ifdef GX_COLOR_INDEX_TYPE /* * Support cupsPreferredBitsPerColor - basically, allows you to @@ -3155,22 +3272,19 @@ #ifdef CUPS_RASTER_SYNCv1 floatoption(cupsBorderlessScalingFactor, "cupsBorderlessScalingFactor"); - for (i = 0; i < 16; i ++) + for (i = 0; cups_Integer_strings[i] != NULL; i ++) { - sprintf(name, "cupsInteger%d", i); - intoption(cupsInteger[i],strdup(name), unsigned) + intoption(cupsInteger[i], cups_Integer_strings[i], unsigned) } - for (i = 0; i < 16; i ++) + for (i = 0; cups_Real_strings[i] != NULL; i ++) { - sprintf(name, "cupsReal%d", i); - floatoption(cupsReal[i], strdup(name)) + floatoption(cupsReal[i], cups_Real_strings[i]) } - for (i = 0; i < 16; i ++) + for (i = 0; cups_String_strings[i] != NULL; i ++) { - sprintf(name, "cupsString%d", i); - stringoption(cupsString[i], strdup(name)) + stringoption(cupsString[i], cups_String_strings[i]) } stringoption(cupsMarkerType, "cupsMarkerType"); @@ -3181,7 +3295,7 @@ if ((code = param_read_string(plist, "cupsProfile", &stringval)) < 0) { param_signal_error(plist, "cupsProfile", code); - return (code); + goto done; } else if (code == 0) { @@ -3192,7 +3306,7 @@ } if ((code = cups_set_color_info(pdev)) < 0) { - return(code); + goto done; } /* @@ -3200,7 +3314,7 @@ */ if ((code = gdev_prn_put_params(pdev, plist)) < 0) - return (code); + goto done; /* If cups_set_color_info() changed the color model of the device we want to * force the raster memory to be recreated/reinitialized @@ -3452,18 +3566,32 @@ cups->landscape = 0; - margins[0] = best_size->left / 72.0; - margins[1] = best_size->bottom / 72.0; - margins[2] = (best_size->width - best_size->right) / 72.0; - margins[3] = (best_size->length - best_size->top) / 72.0; - if (xflip == 1) +#ifdef CUPS_RASTER_SYNCv1 + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) { - swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; +#endif + margins[0] = best_size->left / 72.0; + margins[1] = best_size->bottom / 72.0; + margins[2] = (best_size->width - best_size->right) / 72.0; + margins[3] = (best_size->length - best_size->top) / 72.0; + if (xflip == 1) + { + swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; + } + if (yflip == 1) + { + swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; + } +#ifdef CUPS_RASTER_SYNCv1 } - if (yflip == 1) + else { - swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; + margins[0] = 0.0; + margins[1] = 0.0; + margins[2] = 0.0; + margins[3] = 0.0; } +#endif } else { @@ -3560,18 +3688,32 @@ cups->landscape = 1; - margins[0] = (best_size->length - best_size->top) / 72.0; - margins[1] = best_size->left / 72.0; - margins[2] = best_size->bottom / 72.0; - margins[3] = (best_size->width - best_size->right) / 72.0; - if (xflip == 1) +#ifdef CUPS_RASTER_SYNCv1 + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) { - swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; +#endif + margins[0] = (best_size->length - best_size->top) / 72.0; + margins[1] = best_size->left / 72.0; + margins[2] = best_size->bottom / 72.0; + margins[3] = (best_size->width - best_size->right) / 72.0; + if (xflip == 1) + { + swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; + } + if (yflip == 1) + { + swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; + } +#ifdef CUPS_RASTER_SYNCv1 } - if (yflip == 1) + else { - swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; + margins[0] = 0.0; + margins[1] = 0.0; + margins[2] = 0.0; + margins[3] = 0.0; } +#endif } else { @@ -3595,32 +3737,62 @@ cups->landscape = 1; - margins[0] = cups->PPD->custom_margins[3] / 72.0; - margins[1] = cups->PPD->custom_margins[0] / 72.0; - margins[2] = cups->PPD->custom_margins[1] / 72.0; - margins[3] = cups->PPD->custom_margins[2] / 72.0; - if (xflip == 1) +#ifdef CUPS_RASTER_SYNCv1 + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) { - swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; +#endif + margins[0] = cups->PPD->custom_margins[3] / 72.0; + margins[1] = cups->PPD->custom_margins[0] / 72.0; + margins[2] = cups->PPD->custom_margins[1] / 72.0; + margins[3] = cups->PPD->custom_margins[2] / 72.0; + if (xflip == 1) + { + swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; + } + if (yflip == 1) + { + swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; + } +#ifdef CUPS_RASTER_SYNCv1 } - if (yflip == 1) + else { - swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; + margins[0] = 0.0; + margins[1] = 0.0; + margins[2] = 0.0; + margins[3] = 0.0; } - } else { +#endif + } + else + { /* Do not rotate */ cups->landscape = 0; - for (i = 0; i < 4; i ++) - margins[i] = cups->PPD->custom_margins[i] / 72.0; - if (xflip == 1) +#ifdef CUPS_RASTER_SYNCv1 + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) { - swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; +#endif + for (i = 0; i < 4; i ++) + margins[i] = cups->PPD->custom_margins[i] / 72.0; + if (xflip == 1) + { + swap = margins[0]; margins[0] = margins[2]; margins[2] = swap; + } + if (yflip == 1) + { + swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; + } +#ifdef CUPS_RASTER_SYNCv1 } - if (yflip == 1) + else { - swap = margins[1]; margins[1] = margins[3]; margins[3] = swap; + margins[0] = 0.0; + margins[1] = 0.0; + margins[2] = 0.0; + margins[3] = 0.0; } +#endif } } } @@ -3630,6 +3802,31 @@ margins[0], margins[1], margins[2], margins[3]); #endif /* CUPS_DEBUG */ } + else + { +#ifdef CUPS_RASTER_SYNCv1 + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) + { +#endif + /* If we do not have a PPD file, make sure that margins given via the + input file or via something like + "-c '<>setpagedevice'" + on the command line are conserved */ + margins[0] = pdev->HWMargins[0] / 72.0; + margins[1] = pdev->HWMargins[1] / 72.0; + margins[2] = pdev->HWMargins[2] / 72.0; + margins[3] = pdev->HWMargins[3] / 72.0; +#ifdef CUPS_RASTER_SYNCv1 + } + else + { + margins[0] = 0.0; + margins[1] = 0.0; + margins[2] = 0.0; + margins[3] = 0.0; + } +#endif + } /* * Set the margins to update the bitmap size... @@ -3664,6 +3861,11 @@ pdev->HWResolution[1] / 72.0f + 0.499f; } + if (width <= 0 || height <= 0) { + dmprintf(pdev->memory, "ERROR: page margins overlap\n"); + return_error(gs_error_rangecheck); + } + #ifdef CUPS_RASTER_SYNCv1 if (cups->header.cupsBorderlessScalingFactor > 1.0) { @@ -3697,7 +3899,7 @@ width_old, height_old, transp_old)) < 0) - return (code); + goto done; #ifdef CUPS_DEBUG dmprintf4(pdev->memory, "DEBUG2: Reallocated memory, [%.0f %.0f] = %dx%d pixels...\n", pdev->MediaSize[0], pdev->MediaSize[1], width, height); @@ -3733,85 +3935,125 @@ cups->header.cupsPageSize[0] = pdev->MediaSize[1]; cups->header.cupsPageSize[1] = pdev->MediaSize[0]; - cups->header.cupsImagingBBox[0] = pdev->HWMargins[1]; - cups->header.cupsImagingBBox[1] = pdev->HWMargins[2]; - cups->header.cupsImagingBBox[2] = pdev->MediaSize[1] - pdev->HWMargins[3]; - cups->header.cupsImagingBBox[3] = pdev->MediaSize[0] - pdev->HWMargins[0]; - if ((sf = cups->header.cupsBorderlessScalingFactor) < 1.0) sf = 1.0; - cups->header.Margins[0] = pdev->HWMargins[1] * sf; - cups->header.Margins[1] = pdev->HWMargins[2] * sf; - - cups->header.PageSize[0] = pdev->MediaSize[1] * sf; - cups->header.PageSize[1] = pdev->MediaSize[0] * sf; + cups->header.PageSize[0] = (pdev->MediaSize[1] * sf) + 0.5; + cups->header.PageSize[1] = (pdev->MediaSize[0] * sf) + 0.5; - cups->header.ImagingBoundingBox[0] = pdev->HWMargins[1] * sf; - cups->header.ImagingBoundingBox[1] = pdev->HWMargins[2] * sf; - cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[1] - - pdev->HWMargins[3]) * sf; - cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[0] - - pdev->HWMargins[0]) * sf; + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) + { + cups->header.Margins[0] = (pdev->HWMargins[1] * sf) + 0.5; + cups->header.Margins[1] = (pdev->HWMargins[2] * sf) + 0.5; + cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[1] * sf) + 0.5; + cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[2] * sf) + 0.5; + cups->header.ImagingBoundingBox[2] = ((pdev->MediaSize[1] - + pdev->HWMargins[3]) * sf) + 0.5; + cups->header.ImagingBoundingBox[3] = ((pdev->MediaSize[0] - + pdev->HWMargins[0]) * sf) + 0.5; + cups->header.cupsImagingBBox[0] = pdev->HWMargins[1]; + cups->header.cupsImagingBBox[1] = pdev->HWMargins[2]; + cups->header.cupsImagingBBox[2] = pdev->MediaSize[1] - pdev->HWMargins[3]; + cups->header.cupsImagingBBox[3] = pdev->MediaSize[0] - pdev->HWMargins[0]; + } + else + { + for (i = 0; i < 2; i ++) + cups->header.Margins[i] = 0; + for (i = 0; i < 4; i ++) + { + cups->header.ImagingBoundingBox[i] = 0; + cups->header.cupsImagingBBox[i] = 0.0; + } + } } else { cups->header.cupsPageSize[0] = pdev->MediaSize[0]; cups->header.cupsPageSize[1] = pdev->MediaSize[1]; - cups->header.cupsImagingBBox[0] = pdev->HWMargins[0]; - cups->header.cupsImagingBBox[1] = pdev->HWMargins[1]; - cups->header.cupsImagingBBox[2] = pdev->MediaSize[0] - pdev->HWMargins[2]; - cups->header.cupsImagingBBox[3] = pdev->MediaSize[1] - pdev->HWMargins[3]; - if ((sf = cups->header.cupsBorderlessScalingFactor) < 1.0) sf = 1.0; - cups->header.Margins[0] = pdev->HWMargins[0] * sf; - cups->header.Margins[1] = pdev->HWMargins[1] * sf; - - cups->header.PageSize[0] = pdev->MediaSize[0] * sf; - cups->header.PageSize[1] = pdev->MediaSize[1] * sf; + cups->header.PageSize[0] = (pdev->MediaSize[0] * sf) + 0.5; + cups->header.PageSize[1] = (pdev->MediaSize[1] * sf) + 0.5; - cups->header.ImagingBoundingBox[0] = pdev->HWMargins[0] * sf; - cups->header.ImagingBoundingBox[1] = pdev->HWMargins[1] * sf; - cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[0] - - pdev->HWMargins[2]) * sf; - cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[1] - - pdev->HWMargins[3]) * sf; + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) + { + cups->header.Margins[0] = (pdev->HWMargins[0] * sf) + 0.5; + cups->header.Margins[1] = (pdev->HWMargins[1] * sf) + 0.5; + cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[0] * sf) + 0.5; + cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[1] * sf) + 0.5; + cups->header.ImagingBoundingBox[2] = ((pdev->MediaSize[0] - + pdev->HWMargins[2]) * sf) + 0.5; + cups->header.ImagingBoundingBox[3] = ((pdev->MediaSize[1] - + pdev->HWMargins[3]) * sf) + 0.5; + cups->header.cupsImagingBBox[0] = pdev->HWMargins[0]; + cups->header.cupsImagingBBox[1] = pdev->HWMargins[1]; + cups->header.cupsImagingBBox[2] = pdev->MediaSize[0] - pdev->HWMargins[2]; + cups->header.cupsImagingBBox[3] = pdev->MediaSize[1] - pdev->HWMargins[3]; + } + else + { + for (i = 0; i < 2; i ++) + cups->header.Margins[i] = 0; + for (i = 0; i < 4; i ++) + { + cups->header.ImagingBoundingBox[i] = 0; + cups->header.cupsImagingBBox[i] = 0.0; + } + } } #else if (cups->landscape) { - cups->header.Margins[0] = pdev->HWMargins[1]; - cups->header.Margins[1] = pdev->HWMargins[2]; + cups->header.PageSize[0] = pdev->MediaSize[1] + 0.5; + cups->header.PageSize[1] = pdev->MediaSize[0] + 0.5; - cups->header.PageSize[0] = pdev->MediaSize[1]; - cups->header.PageSize[1] = pdev->MediaSize[0]; - - cups->header.ImagingBoundingBox[0] = pdev->HWMargins[1]; - cups->header.ImagingBoundingBox[1] = pdev->HWMargins[0]; - cups->header.ImagingBoundingBox[2] = pdev->MediaSize[1] - - pdev->HWMargins[3]; - cups->header.ImagingBoundingBox[3] = pdev->MediaSize[0] - - pdev->HWMargins[2]; + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) + { + cups->header.Margins[0] = (pdev->HWMargins[1]) + 0.5; + cups->header.Margins[1] = (pdev->HWMargins[2]) + 0.5; + cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[1]) + 0.5; + cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[0]) + 0.5; + cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[1] - + pdev->HWMargins[3]) + 0.5; + cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[0] - + pdev->HWMargins[2]) + 0.5; + } + else + { + for (i = 0; i < 2; i ++) + cups->header.Margins[i] = 0; + for (i = 0; i < 4; i ++) + cups->header.ImagingBoundingBox[i] = 0; + } } else { - cups->header.Margins[0] = pdev->HWMargins[0]; - cups->header.Margins[1] = pdev->HWMargins[1]; - - cups->header.PageSize[0] = pdev->MediaSize[0]; - cups->header.PageSize[1] = pdev->MediaSize[1]; + cups->header.PageSize[0] = pdev->MediaSize[0] + 0.5; + cups->header.PageSize[1] = pdev->MediaSize[1] + 0.5; - cups->header.ImagingBoundingBox[0] = pdev->HWMargins[0]; - cups->header.ImagingBoundingBox[1] = pdev->HWMargins[3]; - cups->header.ImagingBoundingBox[2] = pdev->MediaSize[0] - - pdev->HWMargins[2]; - cups->header.ImagingBoundingBox[3] = pdev->MediaSize[1] - - pdev->HWMargins[1]; + if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) + { + cups->header.Margins[0] = (pdev->HWMargins[0]) + 0.5; + cups->header.Margins[1] = (pdev->HWMargins[1]) + 0.5; + cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[0]) + 0.5; + cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[3]) + 0.5; + cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[0] - + pdev->HWMargins[2]) + 0.5; + cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[1] - + pdev->HWMargins[1]) + 0.5; + } + else + { + for (i = 0; i < 2; i ++) + cups->header.Margins[i] = 0; + for (i = 0; i < 4; i ++) + cups->header.ImagingBoundingBox[i] = 0; + } } #endif /* CUPS_RASTER_SYNCv1 */ @@ -3834,7 +4076,8 @@ pdev->HWMargins[2], pdev->HWMargins[3]); #endif /* CUPS_DEBUG */ - return (0); +done: + return code; } /* @@ -3866,6 +4109,7 @@ { default : case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : case CUPS_CSPACE_K : case CUPS_CSPACE_WHITE : case CUPS_CSPACE_GOLD : @@ -3885,6 +4129,8 @@ case CUPS_CSPACE_CMY : case CUPS_CSPACE_YMC : case CUPS_CSPACE_RGB : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : #ifdef CUPS_RASTER_SYNCv1 cups->header.cupsNumColors = 3; #endif /* CUPS_RASTER_SYNCv1 */ @@ -3987,6 +4233,7 @@ break; case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : case CUPS_CSPACE_WHITE : case CUPS_CSPACE_K : case CUPS_CSPACE_GOLD : @@ -4009,8 +4256,11 @@ default : case CUPS_CSPACE_RGBW : case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : case CUPS_CSPACE_WHITE : case CUPS_CSPACE_RGB : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : case CUPS_CSPACE_RGBA : # ifdef CUPS_RASTER_HAVE_COLORIMETRIC case CUPS_CSPACE_CIEXYZ : @@ -4122,8 +4372,14 @@ (int)cups->EncodeLUT[gx_max_color_value]); #endif /* CUPS_DEBUG */ - for (i = 0; i < cups->color_info.dither_grays; i ++) - cups->DecodeLUT[i] = gx_max_color_value * i / max_lut; + for (i = 0; i < cups->color_info.dither_grays; i ++) { + j = i; +#if !ARCH_IS_BIG_ENDIAN + if (max_lut > 255) + j = ((j & 255) << 8) | ((j >> 8) & 255); +#endif /* !ARCH_IS_BIG_ENDIAN */ + cups->DecodeLUT[i] = gx_max_color_value * j / max_lut; + } #ifdef CUPS_DEBUG dmprintf2(pdev->memory, "DEBUG: num_components = %d, depth = %d\n", @@ -4262,6 +4518,8 @@ default : case CUPS_CSPACE_RGBW : case CUPS_CSPACE_RGB : + case CUPS_CSPACE_SRGB : + case CUPS_CSPACE_ADOBERGB : case CUPS_CSPACE_RGBA : case CUPS_CSPACE_CMY : case CUPS_CSPACE_YMC : @@ -4297,6 +4555,7 @@ break; case CUPS_CSPACE_W : + case CUPS_CSPACE_SW : case CUPS_CSPACE_WHITE : case CUPS_CSPACE_K : case CUPS_CSPACE_GOLD : @@ -4371,7 +4630,9 @@ *dstptr; /* Pointer to bits */ int count; /* Count for loop */ int xflip, /* Flip scanline? */ +#ifdef CUPS_DEBUG yflip, /* Reverse scanline order? */ +#endif ystart, yend, ystep; /* Loop control for scanline order */ ppd_attr_t *backside = NULL; @@ -4410,12 +4671,16 @@ (cups->header.Tumble && (backside && !strcasecmp(backside->value, "ManualTumble")))) && !(cups->page & 1)) { +#ifdef CUPS_DEBUG yflip = 1; +#endif ystart = cups->height - 1; yend = -1; ystep = -1; } else { +#ifdef CUPS_DEBUG yflip = 0; +#endif ystart = 0; yend = cups->height; ystep = 1; @@ -4598,7 +4863,9 @@ unsigned char *cptr, *mptr, *yptr, /* Pointer to components */ *kptr, *lcptr, *lmptr; /* ... */ int xflip, /* Flip scanline? */ +#ifdef CUPS_DEBUG yflip, /* Reverse scanline order? */ +#endif ystart, yend, ystep; /* Loop control for scanline order */ ppd_attr_t *backside = NULL; @@ -4637,12 +4904,16 @@ (cups->header.Tumble && (backside && !strcasecmp(backside->value, "ManualTumble")))) && !(cups->page & 1)) { +#ifdef CUPS_DEBUG yflip = 1; +#endif ystart = cups->height - 1; yend = -1; ystep = -1; } else { +#ifdef CUPS_DEBUG yflip = 0; +#endif ystart = 0; yend = cups->height; ystep = 1; @@ -5303,7 +5574,7 @@ { int x; /* Looping var */ int y; /* Looping var */ - int z; /* Looping var */ + unsigned char z; /* Looping var */ unsigned char srcbit; /* Current source bit */ unsigned char dstbit; /* Current destination bit */ unsigned char temp; /* Temporary variable */ @@ -5658,6 +5929,17 @@ return (0); } +private int +cups_spec_op(gx_device *dev_, int op, void *data, int datasize) +{ + /* Although not strictly DeviceN, the range of color models + this device supports presets similar issues. + */ + if (op == gxdso_supports_devn) { + return true; + } + return gx_default_dev_spec_op(dev_, op, data, datasize); +} /* */ diff -Nru ghostscript-9.10~dfsg/debian/changelog ghostscript-9.25~dfsg+1/debian/changelog --- ghostscript-9.10~dfsg/debian/changelog 2018-09-12 15:32:37.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/changelog 2018-09-27 14:00:37.000000000 +0000 @@ -1,3 +1,22 @@ +ghostscript (9.25~dfsg+1-0ubuntu0.14.04.1) trusty-security; urgency=medium + + * SECURITY UPDATE: updated to 9.25 to fix multiple security issues + - Previous security release contained an incomplete fix for + CVE-2018-16510, and there are many other security fixes and + improvements that went into the new upstream version without getting + CVE numbers assigned. + - CVE-2018-16510 + - CVE-2018-17183 + * Packages changes required for new version: + - debian/patches/CVE*: removed, included in new version. + - debian/patches/*: updated from cosmic package. + - debian/copyright*: updated from cosmic package. + - debian/rules, debian/libgs-dev.install: remove static library. + - debian/symbols.common: updated for new version. + - debian/rules: use bundled lcms2 as trusty version is too old. + + -- Marc Deslauriers Thu, 27 Sep 2018 09:46:18 -0400 + ghostscript (9.10~dfsg-0ubuntu10.13) trusty-security; urgency=medium * SECURITY UPDATE: Multiple security issues diff -Nru ghostscript-9.10~dfsg/debian/copyright ghostscript-9.25~dfsg+1/debian/copyright --- ghostscript-9.10~dfsg/debian/copyright 2013-03-13 14:20:47.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/copyright 2018-09-27 11:54:19.000000000 +0000 @@ -1,135 +1,152 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: GPL Ghostscript -Upstream-Contact: Artifex Software, Inc -Source: http://downloads.ghostscript.com/public/ - Repackaged, excluding non-DFSG files and unused external projects +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: GhostPDL +Upstream-Contact: Ghostscript development and discussion +Source: https://github.com/ArtifexSoftware/ghostpdl-downloads/releases + Repackaged, excluding non-DFSG files and convenience code copies: + * non-DFSG fonts + * PCL and PX3 files without license + * XPS document with embedded potentially non-DFSG odttf font + * embedded code copies cluttering authorship/licensing tracking + (Arguably custom build of jpeg code is required - see bug#582521) Files-Excluded: - cups/libs/* - expat/* - freetype/* - ijs/* - jasper/* - jbig2dec/* - jpeg/* - jpegxr/* - lcms/* - lcms2/* - libpng/* - openjpeg/* - tiff/* - zlib/* - Resource/CMap/90ms-RKSJ-UCS2 - Resource/CMap/90pv-RKSJ-UCS2 - Resource/CMap/90pv-RKSJ-UCS2C - Resource/CMap/Adobe-CNS1-B5pc - Resource/CMap/Adobe-CNS1-ETenms-B5 - Resource/CMap/Adobe-CNS1-H-CID - Resource/CMap/Adobe-CNS1-H-Host - Resource/CMap/Adobe-CNS1-H-Mac - Resource/CMap/Adobe-CNS1-UCS2 - Resource/CMap/Adobe-GB1-GBK-EUC - Resource/CMap/Adobe-GB1-GBpc-EUC - Resource/CMap/Adobe-GB1-H-CID - Resource/CMap/Adobe-GB1-H-Host - Resource/CMap/Adobe-GB1-H-Mac - Resource/CMap/Adobe-GB1-UCS2 - Resource/CMap/Adobe-Japan1-90ms-RKSJ - Resource/CMap/Adobe-Japan1-90pv-RKSJ - Resource/CMap/Adobe-Japan1-H-CID - Resource/CMap/Adobe-Japan1-H-Host - Resource/CMap/Adobe-Japan1-H-Mac - Resource/CMap/Adobe-Japan1-PS-H - Resource/CMap/Adobe-Japan1-PS-V - Resource/CMap/Adobe-Japan1-UCS2 - Resource/CMap/Adobe-Korea1-H-CID - Resource/CMap/Adobe-Korea1-H-Host - Resource/CMap/Adobe-Korea1-H-Mac - Resource/CMap/Adobe-Korea1-KSCms-UHC - Resource/CMap/Adobe-Korea1-KSCpc-EUC - Resource/CMap/Adobe-Korea1-UCS2 - Resource/CMap/B5pc-UCS2 - Resource/CMap/B5pc-UCS2C - Resource/CMap/CNS01-RKSJ-H - Resource/CMap/CNS02-RKSJ-H - Resource/CMap/CNS03-RKSJ-H - Resource/CMap/CNS04-RKSJ-H - Resource/CMap/CNS05-RKSJ-H - Resource/CMap/CNS06-RKSJ-H - Resource/CMap/CNS07-RKSJ-H - Resource/CMap/CNS15-RKSJ-H - Resource/CMap/ETen-B5-UCS2 - Resource/CMap/GB-RKSJ-H - Resource/CMap/GBK-EUC-UCS2 - Resource/CMap/GBT-RKSJ-H - Resource/CMap/GBpc-EUC-UCS2 - Resource/CMap/GBpc-EUC-UCS2C - Resource/CMap/HK-RKSJ-H - Resource/CMap/Hojo-RKSJ-H - Resource/CMap/KSC-RKSJ-H - Resource/CMap/KSC2-RKSJ-H - Resource/CMap/KSCms-UHC-UCS2 - Resource/CMap/KSCpc-EUC-UCS2 - Resource/CMap/KSCpc-EUC-UCS2C - Resource/CMap/TCVN-RKSJ-H - Resource/CMap/UCS2-90ms-RKSJ - Resource/CMap/UCS2-90pv-RKSJ - Resource/CMap/UCS2-B5pc - Resource/CMap/UCS2-ETen-B5 - Resource/CMap/UCS2-GBK-EUC - Resource/CMap/UCS2-GBpc-EUC - Resource/CMap/UCS2-KSCms-UHC - Resource/CMap/UCS2-KSCpc-EUC - Resource/CMap/Identity-UTF16-H - Resource/CMap/Identity-UTF16-V + cups/libs/* + expat/* + freetype/* + ijs/* + jbig2dec/* + jpeg/* + jpegxr/* + libpng/* + tiff/* + toolbin/Acrobat2Tiff/* + zlib/* -Files: base/* - psi/* - lib/* - toolbin/* - examples/* - doc/* - man/* +Files: lcms2mt/* +Copyright: 1998-2011, Marti Maria Saguer +License: Expat + +Files: openjpeg/* +Copyright: 2002-2014, Universite catholique de Louvain (UCL), Belgium + 2002-2014, Professor Benoit Macq + 2003-2014, Antonin Descampe + 2003-2009, Francois-Olivier Devaux + 2005, Herve Drolon, FreeImage Team + 2002-2003, Yannick Verschueren + 2001-2003, David Janssens + 2011-2012, Centre National d'Etudes Spatiales (CNES), France + 2012, CS Systemes d'Information, France +License: BSD-2-Clause + +Files: Resource/ColorSpace/* Resource/Decoding/* Resource/Encoding/* Resource/Init/* Resource/SubstCID/* + base/* + devices/* + doc/* + examples/* + gpdl/* + iccprofiles/* + lib/* + man/* + psi/* + toolbin/* Copyright: 1986, Eric Gisin 1989, Berthold K.P. Horn - 1989-2002, 2006-2007, Aladdin Enterprises, Menlo Park, CA - 1990-2012, Artifex Software, Inc. + 1990-2018, Artifex Software, Inc. 1991, Apple Computer, Inc 1991-1994, Free Software Foundation, Inc. 1994, Thomas Merz - 1994-2000, Ghostgum Software Pty Ltd 1995-1996, Yves Arrouye 1998, Ivan Schreter 2001, gs-cjk project 2001, Taiji Yamada - 2001-2006, artofcode LLC + 2001-2004, Raph Levien 2003-2004, Hewlett-Packard Development Company, LP +License-Grant: + GhostPDL and GPL Ghostscript are free software; you can redistribute + and/or modify them under the terms of the GNU Affero General Public + License as published by the Free Software Foundation, either version 3 + of the License, or (at your option) any later version. License: AGPL-3+ +Comments: + The file LICENSE in topmost directory of upstream source covers only + GPL Ghostscript, whereas the file pcl/LICENSE contains above statement. + +Files: Resource/CMap/* +Copyright: 1990-2015, Adobe Systems Incorporated +License: BSD-3-Clause~Adobe Files: Resource/CMap/Identity-UTF16-H -Copyright: 2003 Artifex Software +Copyright: 2003-2018, Artifex Software +License-Grant: + GPL Ghostscript is free software; you can redistribute it and/or modify + it under the terms the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. License: AGPL-3+ -Files: Resource/CMap/* -Copyright: 1990-2010, Adobe Systems Incorporated -License: BSD-3-Clause~Adobe - Files: contrib/pcl3/* Copyright: 1996-2003, Martin Lottermoser -License: LGPL-2.1~pcl3 +License-Grant: + pcl3 is free software and can be used under the terms of the GNU Lesser + General Public License (LGPL), Version 2.1 (February 1999). +License: LGPL-2.1 + +Files: + base/ttcalc.c + base/ttcalc.h + base/ttcommon.h + base/ttconfig.h + base/ttinterp.c + base/ttinterp.h + base/ttload.c + base/ttload.h + base/ttobjs.c + base/ttobjs.h + base/tttables.h + base/tttype.h + base/tttypes.h +Copyright: 1996-1998, David Turner, Robert Wilhelm, and Werner Lemberg + 2001-2018, Artifex Software, Inc. +License: FTL + +Files: contrib/gdevlx7.c +Copyright: 1989-1994,1998-1999, Aladdin Enterprises +License-Grant: + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with this software so you can know your rights and + responsibilities. It should be in a file named COPYING. +License: GPL +Comment: + The referenced file COPYING does not exist in folders belonging to same + code. -Files: icclib/* -Copyright: 1997-2002, Graeme W. Gill -License: icclib +Files: contrib/japanese/* +Copyright: 1989-1993,1995-1997, Aladdin Enterprises +License-Grant: + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have + been given to you along with this software so you can know your rights + and responsibilities. It should be in a file named COPYING. +License: GPL +Comment: + The referenced file COPYING does not exist in folders belonging to same + code. Files: Resource/Font/* -Copyright: 1997, 1999, (URW)++ Design & Development - 2001-2002, Valek Filippov -License: GPL~URW with font exception +Copyright: 1997,2003,2006, (URW)++ Design & Development +License-Grant: + GPL Ghostscript is free software; you can redistribute it and/or modify + it under the terms the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. +License: AGPL-3+ with font exception As a special exception, permission is granted to include this font program in a Postscript or PDF file that consists of a document that contains text to be displayed or printed using this font, regardless of @@ -137,200 +154,229 @@ Files: contrib/lips4/* Copyright: 1998-2000, Norihito Ohmori -License: GPL~LIPS +License-Grant: + Everyone is granted permission to copy, modify and redistribute this + software, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with this software so you can know your rights and + responsibilities. It should be in a file named COPYING. +License: GPL +Comment: + The referenced file COPYING does not exist in folders belonging to same + code. -Files: contrib/japanese/gdevespg.c +Files: + contrib/japanese/gdevespg.c contrib/japanese/gdevrpdl.c Copyright: 1998-2000, Norihito Ohmori -License: GPL~LIPS - -Files: */config.guess - */config.sub - */ltconfig - */missing -Copyright: 1991-2006, Free Software Foundation, Inc. -License: GPL-2+ with Autoconf exception - 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. - -Files: */ltmain.sh -Copyright: 1996-2008, Free Software Foundation, Inc -License: GPL-2+ with Libtool exception - As a special exception to the GNU General Public License, if you - distribute this file as part of a program or library that is built - using GNU Libtool, you may include this file under the same - distribution terms that you use for the rest of that program. - -Files: contrib/japanese/doc/gdevdmpr.txt - toolbin/localcluster/dashboard.html -Copyright: 1997, 1999, (URW)++ Design & Development - 2001-2002, Valek Filippov -License: GPL~URW with font exception - As a special exception, permission is granted to include this font - program in a Postscript or PDF file that consists of a document that - contains text to be displayed or printed using this font, regardless of - the conditions or license applying to the document itself. +License-Grant: + Everyone is granted permission to copy, modify and redistribute this + software, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with this software so you can know your rights and + responsibilities. It should be in a file named COPYING. +License: GPL +Comment: + The referenced file COPYING does not exist in folders belonging to same + code. Files: configure -Copyright: 1992-2008, Free Software Foundation, Inc +Copyright: 1992-2012, Free Software Foundation, Inc License: GAP~configure +Files: contrib/gdevln03.c + contrib/gdevxes.c +Copyright: 1991-1994, Free Software Foundation, Inc. +License-Grant: + This file is part of Ghostscript. + . + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING or COPYLEFT. + Among other things, the copyright notice and this notice must be + preserved on all copies. +License-Grant: + This code is subject to the GNU General Public License +License: GPL-2+ + Files: cups/gdevcups.c - cups/gstoraster.convs - cups/pxlcolor.ppd - cups/pxlmono.ppd Copyright: 1993-2006, Easy Software Products 1997-2005, Easy Software Products -License: GPL~CUPS +License-Grant: + Distribution and use rights are outlined in the file "LICENSE.txt" + which should have been included with this file. [...] + . + This code and any derivative of it may be used and distributed freely + under the terms of the GNU General Public License when used with GNU + Ghostscript or its derivatives. Use of the code (or any derivative of + it) with software other than GNU GhostScript (or its derivatives) is + governed by the CUPS license agreement. +License: GPL +Comment: + The referenced file LICENSE.txt does not exist in folders belonging to + same code. Files: contrib/gdevbjc[_a].[ch] Copyright: 1989, 2000 Aladdin Enterprises, Menlo Park, CA 2000-2002, Gergely Szász -License: GPL-2+ or AFPL~AFPL +License-Grant: + This program may be distributed and/or modified under the terms of the + GNU General Public License as published by the Free Software Foundation + (the "GPL"); either version 2 of the GPL, or (at your option) any later + version. +License: GPL-2+ +Comment: + Also licensed as AFPL, ignored as irrelevant for our redistribution. -Files: base/md5.c - base/md5.h +Files: + base/gsmd5.c + base/gsmd5.h base/md5main.c -Copyright: 1999-2007, Artifex Software, Inc +Copyright: 1999-2018, Artifex Software, Inc. License: ZLIB -Files: base/sha2.c +Files: + base/sha2.c base/sha2.h Copyright: 2000-2001, Aaron D. Gifford License: BSD-3-Clause -Files: base/aes.c +Files: + base/aes.c base/aes.h Copyright: 2006-2007, Christophe Devine License: BSD-3-Clause -Files: base/icc34.h - icclib/icc9809.h +Files: + base/icc34.h toolbin/color/icc_creator/ICC_Creator/icc34.h -Copyright: 1994-1998, SunSoft, Inc +Copyright: 1994-1996, SunSoft, Inc License: Expat~SunSoft with SunSoft exception Except as contained in this notice, the name of SunSoft, Inc. shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without written authorization from SunSoft Inc. -Files: contrib/opvp/opvp_0_2_0.h +Files: + contrib/opvp/opvp_0_2_0.h contrib/opvp/opvp_common.h Copyright: 2003-2004, AXE, Inc. License: Expat -Files: doc/figures/Ghost.eps - doc/figures/Overview.eps -Copyright: 1987-2007, Adobe Systems Incorporated. -License: UNKNOWN - FIXME - Files: doc/Hershey.htm Copyright: None (Public Domain) -License: PD +License: public-domain This file, unlike the rest of Ghostscript, consists entirely of information copied from public sources. It therefore is not covered by the Ghostscript copyright or license: it is in the public domain. -Files: contrib/japanese/doc/gs261j.euc - contrib/japanese/doc/gs261j.txt -Copyright: 1991-1994, Norio Katayama -License: UNKNOWN - FIXME +Files: + base/gsstrtok.c + base/gssprintf.c +Copyright: 2000-2015, The Apache Software Foundation +License-Grant: + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +License: Apache-2.0 +Comment: + Copyright holder indirectly referenced and fetched 2015-09-26 from + https://svn.apache.org/repos/asf/apr/apr/trunk/NOTICE Files: Resource/CIDFSubst/DroidSansFallback.ttf Copyright: 2005-2008, The Android Open Source Project -License: Apache-2.0 +License-Grant: Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. - . - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied. See the License for the specific language governing - permissions and limitations under the License. -Comment: - On Debian systems the 'Apache License' version 2.0 is located in - '/usr/share/common-licenses/Apache-2.0'. - -Files: base/ConvertUTF.c - base/ConvertUTF.h -Copyright: 2001-2004, Unicode, Inc -License: Unicode +License: Apache-2.0 -Files: lib/cbjc600.ppd +Files: + lib/cbjc600.ppd lib/cbjc800.ppd Copyright: 1995, Yves Arrouye -License: GPL-3+ +License-Grant: This file may be distributed as part of GNU Ghostscript and/or AFPL Ghostscript, under the same terms and conditions as Ghostscript. +License: GPL-3+ -Files: contrib/japanese/doc/djgpp.txt - contrib/japanese/doc/gdevmag.txt -Copyright: 1993-1994, 淺山和典 ■ -License: UNKNOWN - FIXME +Files: base/gsstrl.c +Copyright: 1998, Todd C. Miller +License: ISC Files: cups/cups.mak Copyright: 2001-2005, Easy Software Products - 2007, Artifex Software, Inc -License: GPL-2+~you - -Files: cups/gstopxl.in -Copyright: 2001-2005, Easy Software Products -License: GPL-2+~you + 2007, Artifex Software, Inc. +License-Grant: + 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, or (at your option) any + later version. +License: GPL-2+ Files: contrib/gdevdj9.c Copyright: 1999, Aladdin Enterprises, Menlo Park, CA 2000, Rene Harsch -License: GPL-2+~you or AFPL +License-Grant: + 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. +License: GPL-2+ +Comment: + Also licensed as AFPL, ignored as irrelevant for our redistribution. Files: contrib/gdevcd8.c Copyright: 1996-1998, Uli Wortmann 1999, Aladdin Enterprises, Menlo Park, CA 2000, Hewlett-Packard Company -License: GPL-2+~you or AFPL +License-Grant: + 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. +License: GPL-2+ +Comment: + Also licensed as AFPL, ignored as irrelevant for our redistribution. Files: contrib/opvp/gdevopvp.c Copyright: 2003-2004, AXE, Inc. -License: GPL-2+~you +License-Grant: + 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. +License: GPL-2+ Files: contrib/gdevlx32.c Copyright: 2000, Daniel Gordini (dgordin@tin.it) -License: GPL-2+~you +License-Grant: + 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. +License: GPL-2+ Files: lib/afmdiff.awk Copyright: 2000, Nelson H. F. Beebe -License: GPL-2+~you or AFPL~AFPL - -Files: contrib/gomni.c -Copyright: 1998-2000, Aladdin Enterprises, Menlo Park, CA - 2000, International Business Machines Corp. -License: LGPL-2.1+ and LGPL-2.1+~program-in-file - -Files: contrib/defs.h -Copyright: 2000, International Business Machines Corp. -License: LGPL-2.1+ - -Files: cups/colord.* -Files: cups/gstoraster.convs -Files: cups/gstoraster.c -Copyright: 2008, Till Kamppeter - 2011, Richard Hughes - 2011, Tim Waugh -License: Expat +License-Grant: + 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. +License: GPL-2+ +Comment: + Also licensed as AFPL, ignored as irrelevant for our redistribution. Files: lib/ghostpdf.ppd Copyright: 2004-2006, Ghostgum Software Pty Ltd License: Expat~Ghostgum -Files: examples/chess.ps -Copyright: 1989, Adobe Systems Inc. -License: UNKNOWN - FIXME - Files: contrib/opvp/opvp.h Copyright: 2003-2006, AXE Inc 2006, Canon Inc @@ -340,7 +386,7 @@ Files: Resource/Init/pdf_sec.ps Copyright: 1996-1998, Geoffrey Keating - 2001-2008, Artifex Software, Inc + 2001-2018, Artifex Software, Inc. License: other This file may be freely distributed with or without modifications, so long as modified versions are marked as such and copyright notices are @@ -349,208 +395,727 @@ Files: contrib/eplaser/gdevescv.[ch] Copyright: 1999-2000, EPSON SOFTWARE DEVELOPMENT LABORATORY, INC. 2000-2006,2009, SEIKO EPSON CORPORATION -License: GPL~LIPS +License-Grant: + Everyone is granted permission to copy, modify and redistribute this + software, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with this software so you can know your rights and + responsibilities. It should be in a file named COPYING. +License: GPL +Comment: + The referenced file COPYING does not exist in folders belonging to same + code. -Files: base/gdevifno.c +Files: devices/gdevifno.c Copyright: 1998, Lucent Technologies License: NTP~Lucent -Files: base/gdev4693.c +Files: devices/gdev4693.c Copyright: 1992, Washington State University. License: NTP~WSU -Files: base/gdevsgi.h -Copyright: None (Public Domain) -License: PD - This file is distributed with Ghostscript, but its author, Tanmoy - Bhattacharya (tanmoy@qcd.lanl.gov) hereby places it in the public - domain. - Files: lib/fixmswrd.pl Copyright: 1997, Anthony Shipman License: ZLIB Files: debian/* Copyright: 2004-2009, Masayuki Hatta (mhatta) - 2009-2011, Jonas Smedegaard - 2007-2011, Till Kamppeter -License: GPL-2+ + 2009-2017, Jonas Smedegaard +License-Grant: + 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 3, or (at your option) any + later version. +License: GPL-3+ Files: debian/update-gsfontmap Copyright: 2010, Kenshi Muto License: GPL FIXME -License: GPL-3+~Artifex - GPL Ghostscript is free software; you can redistribute it and/or - modify it under the terms the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 - of the License, or (at your option) any later version. +License: AGPL-3 + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + . + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies of this + license document, but changing it is not allowed. + . + Preamble + . + The GNU Affero General Public License is a free, copyleft license for + software and other kinds of works, specifically designed to ensure + cooperation with the community in the case of network server software. + . + The licenses for most software and other practical works are designed + to take away your freedom to share and change the works. By contrast, + our General Public Licenses are intended to guarantee your freedom to + share and change all versions of a program--to make sure it remains + free software for all its users. + . + When we speak of free software, we are referring to freedom, not price. + Our General Public Licenses are designed to make sure that you have the + freedom to distribute copies of free software (and charge for them if + you wish), that you receive source code or can get it if you want it, + that you can change the software or use pieces of it in new free + programs, and that you know you can do these things. + . + Developers that use our General Public Licenses protect your rights + with two steps: (1) assert copyright on the software, and (2) offer you + this License which gives you legal permission to copy, distribute + and/or modify the software. + . + A secondary benefit of defending all users' freedom is that + improvements made in alternate versions of the program, if they receive + widespread use, become available for other developers to incorporate. + Many developers of free software are heartened and encouraged by the + resulting cooperation. However, in the case of software used on + network servers, this result may fail to come about. The GNU General + Public License permits making a modified version and letting the public + access it on a server without ever releasing its source code to the + public. + . + The GNU Affero General Public License is designed specifically to + ensure that, in such cases, the modified source code becomes available + to the community. It requires the operator of a network server to + provide the source code of the modified version running there to the + users of that server. Therefore, public use of a modified version, on + a publicly accessible server, gives the public access to the source + code of the modified version. + . + An older license, called the Affero General Public License and + published by Affero, was designed to accomplish similar goals. This is + a different license, not a version of the Affero GPL, but Affero has + released a new version of the Affero GPL which permits relicensing + under this license. + . + The precise terms and conditions for copying, distribution and + modification follow. + . + TERMS AND CONDITIONS + . + 0. Definitions. + . + "This License" refers to version 3 of the GNU Affero General Public + License. + . + "Copyright" also means copyright-like laws that apply to other kinds of + works, such as semiconductor masks. + . + "The Program" refers to any copyrightable work licensed under this + License. Each licensee is addressed as "you". "Licensees" and + "recipients" may be individuals or organizations. + . + To "modify" a work means to copy from or adapt all or part of the work + in a fashion requiring copyright permission, other than the making of + an exact copy. The resulting work is called a "modified version" of + the earlier work or a work "based on" the earlier work. + . + A "covered work" means either the unmodified Program or a work based on + the Program. + . + To "propagate" a work means to do anything with it that, without + permission, would make you directly or secondarily liable for + infringement under applicable copyright law, except executing it on a + computer or modifying a private copy. Propagation includes copying, + distribution (with or without modification), making available to the + public, and in some countries other activities as well. + . + To "convey" a work means any kind of propagation that enables other + parties to make or receive copies. Mere interaction with a user + through a computer network, with no transfer of a copy, is not + conveying. + . + An interactive user interface displays "Appropriate Legal Notices" to + the extent that it includes a convenient and prominently visible + feature that (1) displays an appropriate copyright notice, and (2) + tells the user that there is no warranty for the work (except to the + extent that warranties are provided), that licensees may convey the + work under this License, and how to view a copy of this License. If the + interface presents a list of user commands or options, such as a menu, + a prominent item in the list meets this criterion. + . + 1. Source Code. + . + The "source code" for a work means the preferred form of the work for + making modifications to it. "Object code" means any non-source form of + a work. + . + A "Standard Interface" means an interface that either is an official + standard defined by a recognized standards body, or, in the case of + interfaces specified for a particular programming language, one that is + widely used among developers working in that language. + . + The "System Libraries" of an executable work include anything, other + than the work as a whole, that (a) is included in the normal form of + packaging a Major Component, but which is not part of that Major + Component, and (b) serves only to enable use of the work with that + Major Component, or to implement a Standard Interface for which an + implementation is available to the public in source code form. A "Major + Component", in this context, means a major essential component (kernel, + window system, and so on) of the specific operating system (if any) on + which the executable work runs, or a compiler used to produce the work, + or an object code interpreter used to run it. + . + The "Corresponding Source" for a work in object code form means all the + source code needed to generate, install, and (for an executable work) + run the object code and to modify the work, including scripts to + control those activities. However, it does not include the work's + System Libraries, or general-purpose tools or generally available free + programs which are used unmodified in performing those activities but + which are not part of the work. For example, Corresponding Source + includes interface definition files associated with source files for + the work, and the source code for shared libraries and dynamically + linked subprograms that the work is specifically designed to require, + such as by intimate data communication or control flow between those + subprograms and other parts of the work. + . + The Corresponding Source need not include anything that users can + regenerate automatically from other parts of the Corresponding Source. + . + The Corresponding Source for a work in source code form is that same + work. + . + 2. Basic Permissions. + . + All rights granted under this License are granted for the term of + copyright on the Program, and are irrevocable provided the stated + conditions are met. This License explicitly affirms your unlimited + permission to run the unmodified Program. The output from running a + covered work is covered by this License only if the output, given its + content, constitutes a covered work. This License acknowledges your + rights of fair use or other equivalent, as provided by copyright law. + . + You may make, run and propagate covered works that you do not convey, + without conditions so long as your license otherwise remains in force. + You may convey covered works to others for the sole purpose of having + them make modifications exclusively for you, or provide you with + facilities for running those works, provided that you comply with the + terms of this License in conveying all material for which you do not + control copyright. Those thus making or running the covered works for + you must do so exclusively on your behalf, under your direction and + control, on terms that prohibit them from making any copies of your + copyrighted material outside their relationship with you. + . + Conveying under any other circumstances is permitted solely under the + conditions stated below. Sublicensing is not allowed; section 10 makes + it unnecessary. + . + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + . + No covered work shall be deemed part of an effective technological + measure under any applicable law fulfilling obligations under article + 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar + laws prohibiting or restricting circumvention of such measures. + . + When you convey a covered work, you waive any legal power to forbid + circumvention of technological measures to the extent such + circumvention is effected by exercising rights under this License with + respect to the covered work, and you disclaim any intention to limit + operation or modification of the work as a means of enforcing, against + the work's users, your or third parties' legal rights to forbid + circumvention of technological measures. + . + 4. Conveying Verbatim Copies. + . + You may convey verbatim copies of the Program's source code as you + receive it, in any medium, provided that you conspicuously and + appropriately publish on each copy an appropriate copyright notice; + keep intact all notices stating that this License and any + non-permissive terms added in accord with section 7 apply to the code; + keep intact all notices of the absence of any warranty; and give all + recipients a copy of this License along with the Program. + . + You may charge any price or no price for each copy that you convey, and + you may offer support or warranty protection for a fee. + . + 5. Conveying Modified Source Versions. + . + You may convey a work based on the Program, or the modifications to + produce it from the Program, in the form of source code under the terms + of section 4, provided that you also meet all of these conditions: + . + a) The work must carry prominent notices stating that you modified it, + and giving a relevant date. + . + b) The work must carry prominent notices stating that it is released + under this License and any conditions added under section 7. This + requirement modifies the requirement in section 4 to "keep intact all + notices". + . + c) You must license the entire work, as a whole, under this License to + anyone who comes into possession of a copy. This License will + therefore apply, along with any applicable section 7 additional terms, + to the whole of the work, and all its parts, regardless of how they are + packaged. This License gives no permission to license the work in any + other way, but it does not invalidate such permission if you have + separately received it. + . + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your work + need not make them do so. + . + A compilation of a covered work with other separate and independent + works, which are not by their nature extensions of the covered work, + and which are not combined with it such as to form a larger program, in + or on a volume of a storage or distribution medium, is called an + "aggregate" if the compilation and its resulting copyright are not used + to limit the access or legal rights of the compilation's users beyond + what the individual works permit. Inclusion of a covered work in an + aggregate does not cause this License to apply to the other parts of + the aggregate. + . + 6. Conveying Non-Source Forms. + . + You may convey a covered work in object code form under the terms of + sections 4 and 5, provided that you also convey the machine-readable + Corresponding Source under the terms of this License, in one of these + ways: + . + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium customarily + used for software interchange. + . + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a written + offer, valid for at least three years and valid for as long as you + offer spare parts or customer support for that product model, to give + anyone who possesses the object code either (1) a copy of the + Corresponding Source for all the software in the product that is + covered by this License, on a durable physical medium customarily used + for software interchange, for a price no more than your reasonable cost + of physically performing this conveying of source, or (2) access to + copy the Corresponding Source from a network server at no charge. + . + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This alternative is + allowed only occasionally and noncommercially, and only if you received + the object code with such an offer, in accord with subsection 6b. + . + d) Convey the object code by offering access from a designated place + (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to copy + the object code is a network server, the Corresponding Source may be on + a different server (operated by you or a third party) that supports + equivalent copying facilities, provided you maintain clear directions + next to the object code saying where to find the Corresponding Source. + Regardless of what server hosts the Corresponding Source, you remain + obligated to ensure that it is available for as long as needed to + satisfy these requirements. + . + e) Convey the object code using peer-to-peer transmission, provided you + inform other peers where the object code and Corresponding Source of + the work are being offered to the general public at no charge under + subsection 6d. + . + A separable portion of the object code, whose source code is excluded + from the Corresponding Source as a System Library, need not be included + in conveying the object code work. + . + A "User Product" is either (1) a "consumer product", which means any + tangible personal property which is normally used for personal, family, + or household purposes, or (2) anything designed or sold for + incorporation into a dwelling. In determining whether a product is a + consumer product, doubtful cases shall be resolved in favor of + coverage. For a particular product received by a particular user, + "normally used" refers to a typical or common use of that class of + product, regardless of the status of the particular user or of the way + in which the particular user actually uses, or expects or is expected + to use, the product. A product is a consumer product regardless of + whether the product has substantial commercial, industrial or + non-consumer uses, unless such uses represent the only significant mode + of use of the product. + . + "Installation Information" for a User Product means any methods, + procedures, authorization keys, or other information required to + install and execute modified versions of a covered work in that User + Product from a modified version of its Corresponding Source. The + information must suffice to ensure that the continued functioning of + the modified object code is in no case prevented or interfered with + solely because modification has been made. + . + If you convey an object code work under this section in, or with, or + specifically for use in, a User Product, and the conveying occurs as + part of a transaction in which the right of possession and use of the + User Product is transferred to the recipient in perpetuity or for a + fixed term (regardless of how the transaction is characterized), the + Corresponding Source conveyed under this section must be accompanied by + the Installation Information. But this requirement does not apply if + neither you nor any third party retains the ability to install modified + object code on the User Product (for example, the work has been + installed in ROM). + . + The requirement to provide Installation Information does not include a + requirement to continue to provide support service, warranty, or + updates for a work that has been modified or installed by the + recipient, or for the User Product in which it has been modified or + installed. Access to a network may be denied when the modification + itself materially and adversely affects the operation of the network or + violates the rules and protocols for communication across the network. + . + Corresponding Source conveyed, and Installation Information provided, + in accord with this section must be in a format that is publicly + documented (and with an implementation available to the public in + source code form), and must require no special password or key for + unpacking, reading or copying. + . + 7. Additional Terms. + . + "Additional permissions" are terms that supplement the terms of this + License by making exceptions from one or more of its conditions. + Additional permissions that are applicable to the entire Program shall + be treated as though they were included in this License, to the extent + that they are valid under applicable law. If additional permissions + apply only to part of the Program, that part may be used separately + under those permissions, but the entire Program remains governed by + this License without regard to the additional permissions. + . + When you convey a copy of a covered work, you may at your option remove + any additional permissions from that copy, or from any part of it. + (Additional permissions may be written to require their own removal in + certain cases when you modify the work.) You may place additional + permissions on material, added by you to a covered work, for which you + have or can give appropriate copyright permission. + . + Notwithstanding any other provision of this License, for material you + add to a covered work, you may (if authorized by the copyright holders + of that material) supplement the terms of this License with terms: + . + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + . + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + . + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + . + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + . + e) Declining to grant rights under trademark law for use of some trade + names, trademarks, or service marks; or + . + f) Requiring indemnification of licensors and authors of that material + by anyone who conveys the material (or modified versions of it) with + contractual assumptions of liability to the recipient, for any + liability that these contractual assumptions directly impose on those + licensors and authors. + . + All other non-permissive additional terms are considered "further + restrictions" within the meaning of section 10. If the Program as you + received it, or any part of it, contains a notice stating that it is + governed by this License along with a term that is a further + restriction, you may remove that term. If a license document contains + a further restriction but permits relicensing or conveying under this + License, you may add to a covered work material governed by the terms + of that license document, provided that the further restriction does + not survive such relicensing or conveying. + . + If you add terms to a covered work in accord with this section, you + must place, in the relevant source files, a statement of the additional + terms that apply to those files, or a notice indicating where to find + the applicable terms. + . + Additional terms, permissive or non-permissive, may be stated in the + form of a separately written license, or stated as exceptions; the + above requirements apply either way. + . + 8. Termination. + . + You may not propagate or modify a covered work except as expressly + provided under this License. Any attempt otherwise to propagate or + modify it is void, and will automatically terminate your rights under + this License (including any patent licenses granted under the third + paragraph of section 11). + . + However, if you cease all violation of this License, then your license + from a particular copyright holder is reinstated (a) provisionally, + unless and until the copyright holder explicitly and finally terminates + your license, and (b) permanently, if the copyright holder fails to + notify you of the violation by some reasonable means prior to 60 days + after the cessation. + . + Moreover, your license from a particular copyright holder is reinstated + permanently if the copyright holder notifies you of the violation by + some reasonable means, this is the first time you have received notice + of violation of this License (for any work) from that copyright holder, + and you cure the violation prior to 30 days after your receipt of the + notice. + . + Termination of your rights under this section does not terminate the + licenses of parties who have received copies or rights from you under + this License. If your rights have been terminated and not permanently + reinstated, you do not qualify to receive new licenses for the same + material under section 10. + . + 9. Acceptance Not Required for Having Copies. + . + You are not required to accept this License in order to receive or run + a copy of the Program. Ancillary propagation of a covered work + occurring solely as a consequence of using peer-to-peer transmission to + receive a copy likewise does not require acceptance. However, nothing + other than this License grants you permission to propagate or modify + any covered work. These actions infringe copyright if you do not + accept this License. Therefore, by modifying or propagating a covered + work, you indicate your acceptance of this License to do so. + . + 10. Automatic Licensing of Downstream Recipients. + . + Each time you convey a covered work, the recipient automatically + receives a license from the original licensors, to run, modify and + propagate that work, subject to this License. You are not responsible + for enforcing compliance by third parties with this License. + . + An "entity transaction" is a transaction transferring control of an + organization, or substantially all assets of one, or subdividing an + organization, or merging organizations. If propagation of a covered + work results from an entity transaction, each party to that transaction + who receives a copy of the work also receives whatever licenses to the + work the party's predecessor in interest had or could give under the + previous paragraph, plus a right to possession of the Corresponding + Source of the work from the predecessor in interest, if the predecessor + has it or can get it with reasonable efforts. + . + You may not impose any further restrictions on the exercise of the + rights granted or affirmed under this License. For example, you may + not impose a license fee, royalty, or other charge for exercise of + rights granted under this License, and you may not initiate litigation + (including a cross-claim or counterclaim in a lawsuit) alleging that + any patent claim is infringed by making, using, selling, offering for + sale, or importing the Program or any portion of it. + . + 11. Patents. + . + A "contributor" is a copyright holder who authorizes use under this + License of the Program or a work on which the Program is based. The + work thus licensed is called the contributor's "contributor version". + . + A contributor's "essential patent claims" are all patent claims owned + or controlled by the contributor, whether already acquired or hereafter + acquired, that would be infringed by some manner, permitted by this + License, of making, using, or selling its contributor version, but do + not include claims that would be infringed only as a consequence of + further modification of the contributor version. For purposes of this + definition, "control" includes the right to grant patent sublicenses in + a manner consistent with the requirements of this License. + . + Each contributor grants you a non-exclusive, worldwide, royalty-free + patent license under the contributor's essential patent claims, to + make, use, sell, offer for sale, import and otherwise run, modify and + propagate the contents of its contributor version. + . + In the following three paragraphs, a "patent license" is any express + agreement or commitment, however denominated, not to enforce a patent + (such as an express permission to practice a patent or covenant not to + sue for patent infringement). To "grant" such a patent license to a + party means to make such an agreement or commitment not to enforce a + patent against the party. + . + If you convey a covered work, knowingly relying on a patent license, + and the Corresponding Source of the work is not available for anyone to + copy, free of charge and under the terms of this License, through a + publicly available network server or other readily accessible means, + then you must either (1) cause the Corresponding Source to be so + available, or (2) arrange to deprive yourself of the benefit of the + patent license for this particular work, or (3) arrange, in a manner + consistent with the requirements of this License, to extend the patent + license to downstream recipients. "Knowingly relying" means you have + actual knowledge that, but for the patent license, your conveying the + covered work in a country, or your recipient's use of the covered work + in a country, would infringe one or more identifiable patents in that + country that you have reason to believe are valid. + . + If, pursuant to or in connection with a single transaction or + arrangement, you convey, or propagate by procuring conveyance of, a + covered work, and grant a patent license to some of the parties + receiving the covered work authorizing them to use, propagate, modify + or convey a specific copy of the covered work, then the patent license + you grant is automatically extended to all recipients of the covered + work and works based on it. + . + A patent license is "discriminatory" if it does not include within the + scope of its coverage, prohibits the exercise of, or is conditioned on + the non-exercise of one or more of the rights that are specifically + granted under this License. You may not convey a covered work if you + are a party to an arrangement with a third party that is in the + business of distributing software, under which you make payment to the + third party based on the extent of your activity of conveying the work, + and under which the third party grants, to any of the parties who would + receive the covered work from you, a discriminatory patent license (a) + in connection with copies of the covered work conveyed by you (or + copies made from those copies), or (b) primarily for and in connection + with specific products or compilations that contain the covered work, + unless you entered into that arrangement, or that patent license was + granted, prior to 28 March 2007. + . + Nothing in this License shall be construed as excluding or limiting any + implied license or other defenses to infringement that may otherwise be + available to you under applicable patent law. + . + 12. No Surrender of Others' Freedom. + . + If conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot convey a + covered work so as to satisfy simultaneously your obligations under + this License and any other pertinent obligations, then as a consequence + you may not convey it at all. For example, if you agree to terms that + obligate you to collect a royalty for further conveying from those to + whom you convey the Program, the only way you could satisfy both those + terms and this License would be to refrain entirely from conveying the + Program. + . + 13. Remote Network Interaction; Use with the GNU General Public + License. + . + Notwithstanding any other provision of this License, if you modify the + Program, your modified version must prominently offer all users + interacting with it remotely through a computer network (if your + version supports such interaction) an opportunity to receive the + Corresponding Source of your version by providing access to the + Corresponding Source from a network server at no charge, through some + standard or customary means of facilitating copying of software. This + Corresponding Source shall include the Corresponding Source for any + work covered by version 3 of the GNU General Public License that is + incorporated pursuant to the following paragraph. + . + Notwithstanding any other provision of this License, you have + permission to link or combine any covered work with a work licensed + under version 3 of the GNU General Public License into a single + combined work, and to convey the resulting work. The terms of this + License will continue to apply to the part which is the covered work, + but the work with which it is combined will remain governed by version + 3 of the GNU General Public License. + . + 14. Revised Versions of this License. + . + The Free Software Foundation may publish revised and/or new versions of + the GNU Affero General Public License from time to time. Such new + versions will be similar in spirit to the present version, but may + differ in detail to address new problems or concerns. + . + Each version is given a distinguishing version number. If the Program + specifies that a certain numbered version of the GNU Affero General + Public License "or any later version" applies to it, you have the + option of following the terms and conditions either of that numbered + version or of any later version published by the Free Software + Foundation. If the Program does not specify a version number of the + GNU Affero General Public License, you may choose any version ever + published by the Free Software Foundation. + . + If the Program specifies that a proxy can decide which future versions + of the GNU Affero General Public License can be used, that proxy's + public statement of acceptance of a version permanently authorizes you + to choose that version for the Program. + . + Later license versions may give you additional or different + permissions. However, no additional obligations are imposed on any + author or copyright holder as a result of your choosing to follow a + later version. + . + 15. Disclaimer of Warranty. + . + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY + APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT + HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT + WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE + OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU + ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + . + 16. Limitation of Liability. + . + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR + CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES + ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT + NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES + SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO + OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY + HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + . + 17. Interpretation of Sections 15 and 16. + . + If the disclaimer of warranty and limitation of liability provided + above cannot be given local legal effect according to their terms, + reviewing courts shall apply local law that most closely approximates + an absolute waiver of all civil liability in connection with the + Program, unless a warranty or assumption of liability accompanies a + copy of the Program in return for a fee. + . + END OF TERMS AND CONDITIONS + . + How to Apply These Terms to Your New Programs + . + If you develop a new program, and you want it to be of the greatest + possible use to the public, the best way to achieve this is to make it + free software which everyone can redistribute and change under these + terms. + . + To do so, attach the following notices to the program. It is safest to + attach them to the start of each source file to most effectively state + the exclusion of warranty; and each file should have at least the + "copyright" line and a pointer to where the full notice is found. + . + + Copyright (C) + . + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. . - GPL Ghostscript 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 + 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 Affero General Public License for more details. . You should have received a copy of the GNU Affero General Public - License along with this program so you can know your rights and - responsibilities. It should be in a file named doc/COPYING. If not, - write to the Free Software Foundation, Inc., 59 Temple Place Suite - 330, Boston, MA 02111-1307, USA. - -License: GPL~LIPS - This software is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY. No author or distributor accepts responsibility - to anyone for the consequences of using it or for whether it serves any - particular purpose or works at all, unless he says so in writing. - Refer to the GNU General Public License for full details. - . - Everyone is granted permission to copy, modify and redistribute this - software, but only under the conditions described in the GNU General - Public License. A copy of this license is supposed to have been given - to you along with this software so you can know your rights and - responsibilities. It should be in a file named COPYING. Among other - things, the copyright notice and this notice must be preserved on all - copies. -Comment: - The referenced file COPYING does not exist in folders belonging to same - code. + License along with this program. If not, see + . . - On Debian systems the 'GNU General Public License' is located in - '/usr/share/common-licenses/GPL'. - -License: GPL-2+ - This program may be distributed and/or modified under the terms of the - GNU General Public License as published by the Free Software Foundation - (the "GPL"); either version 2 of the GPL, or (at your option) any later - version. + Also add information on how to contact you by electronic and paper + mail. . - When distributed under the terms of the GPL, 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 GPL for more details. -Comment: - On Debian systems the 'GNU General Public License' version 2 is located - in '/usr/share/common-licenses/GPL-2'. + If your software can interact with users remotely through a computer + network, you should also make sure that it provides a way for users to + get its source. For example, if your program is a web application, its + interface could display a "Source" link that leads users to an archive + of the code. There are many ways you could offer source, and different + solutions will be better for different programs; see section 13 for the + specific requirements. + . + You should also get your employer (if you work as a programmer) or + school, if any, to sign a "copyright disclaimer" for the program, if + necessary. For more information on this, and how to apply and follow + the GNU AGPL, see . -License: GPL-2+~you - 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. +License: GPL-3+ +License-Reference: /usr/share/common-licenses/GPL-3 -License: GPL~URW - See the file COPYING (GNU General Public License) for license - conditions. -Comment: - The referenced file COPYING does not exist in folders belonging to same - code. +License: GPL-2+ +License-Reference: /usr/share/common-licenses/GPL-2 -License: GPL~CUPS - These coded instructions, statements, and computer programs are the - property of Easy Software Products and are protected by Federal - copyright law. Distribution and use rights are outlined in the file - "LICENSE.txt" which should have been included with this file. If this - file is missing or damaged please contact Easy Software Products at: - . - Attn: CUPS Licensing Information - Easy Software Products - 44141 Airport View Drive, Suite 204 - Hollywood, Maryland 20636 USA - . - Voice: (301) 373-9600 - EMail: cups-info@cups.org - WWW: http://www.cups.org/ - . - This code and any derivative of it may be used and distributed freely - under the terms of the GNU General Public License when used with GNU - Ghostscript or its derivatives. Use of the code (or any derivative of - it) with software other than GNU GhostScript (or its derivatives) is - governed by the CUPS license agreement. -Comment: - The referenced file LICENSE.txt does not exist in folders belonging to - same code. +License: GPL-2 +License-Reference: /usr/share/common-licenses/GPL-2 -License: AFPL - This program may also be distributed as part of Aladdin Ghostscript, - under the terms of the Aladdin Free Public License (the "License"). - . - Every copy of Aladdin Ghostscript must include a copy of the License, - normally in a plain ASCII text file named PUBLIC. The License grants - you the right to copy, modify and redistribute Aladdin Ghostscript, but - only under certain conditions described in the License. Among other - things, the License requires that the copyright notice and this notice - be preserved on all copies. -Comment: - Upstream source do not contain the referenced PUBLIC file (probably due - to no longer being distributed as 'Aladdin Ghostscript'). This should - not matter for Debian, as all AFPL-licenced files are dual-licensed as - GPL-2+ which is then used in Debian. - -License: AFPL~AFPL - This program may also be distributed as part of AFPL Ghostscript, under - the terms of the Aladdin Free Public License (the "License"). - . - AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No - author or distributor accepts any responsibility for the consequences of - using it, or for whether it serves any particular purpose or works at - all, unless he or she says so in writing. Refer to the License for - full details. - . - Every copy of AFPL Ghostscript must include a copy of the License, - normally in a plain ASCII text file named PUBLIC. The License grants - you the right to copy, modify and redistribute AFPL Ghostscript, but - only under certain conditions described in the License. Among other - things, the License requires that the copyright notice and this notice - be preserved on all copies. -Comment: - Upstream source do not contain the referenced PUBLIC file (probably due - to no longer being distributed as 'AFPL Ghostscript'). This should not - matter for Debian, as all AFPL~AFPL-licenced files are dual-licensed as - GPL-2+ which is then used in Debian. - -License: LGPL-2.1+ - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - . - This library 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 - Lesser General Public License for more details. -Comment: - On Debian systems the 'GNU Lesser General Public License' version 2.1 - is located in '/usr/share/common-licenses/LGPL-2.1'. - . - You should have received a copy of the 'GNU Lesser General Public - License' along with this program. If not, see - . +License: GPL +License-Reference: /usr/share/common-licenses/GPL -License: LGPL-2.1+~program-in-file - The program in this file is free software; you can redistribute it - and/or modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either version - 2.1 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 - Lesser General Public License for more details. +License: LGPL-2.1 +License-Reference: /usr/share/common-licenses/LGPL-2.1 -License: LGPL-2.1~pcl3 - pcl3 is free software and can be used under the terms of the GNU Lesser - General Public License (LGPL), Version 2.1 (February 1999). You can - find a copy of the LGPL in the pcl3 distribution, in several software - packages distributed by the Free Software Foundation, and at - http://www.gnu.org/copyleft/lesser.html. - . - This implies in particular that you are using pcl3 AT YOUR OWN RISK! +License: Apache-2.0 +License-Reference: /usr/share/common-licenses/Apache-2.0 License: GAP~configure This configure script is free software; the Free Software Foundation @@ -647,6 +1212,28 @@ MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. +License: BSD-2-Clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + License: BSD-3-Clause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -718,49 +1305,16 @@ 3. This notice may not be removed or altered from any source distribution. -License: icclib - Permission is hereby granted, to use, copy, modify, distribute, and - sell this software and its associated documentation files (the - "Software") for any purpose without fee, provided that: - . - 1) The above copyright notices and this permission notice accompany - all source code copies of the Software and related documentation. - and - . - 2) If executable code based on the Software only is distributed, then - the accompanying documentation must aknowledge that "this software - is based in part on the work of Graeme W. Gill". - and - . - 3) It is accepted that Graeme W. Gill (the "Author") accepts NO - LIABILITY for damages of any kind. The Software is provided - without fee by the Author "AS-IS" and without warranty of any kind, - express, implied or otherwise, including without limitation, any - warranty of merchantability or fitness for a particular purpose. - and - . - 4) These conditions apply to any software derived from or based on the - Software, not just to the unmodified library. - and - . - 5) Except as contained in this notice, or in the required - acknowledgment, the name of the Author, or the name of any - organization or company affiliated with the Author may not be used - in any advertising or publicity relating to the Software, without - the specific, prior written permission of the Author. - -License: Unicode - This source code is provided as is by Unicode, Inc. No claims are made - as to fitness for any particular purpose. No warranties of any kind are - expressed or implied. The recipient agrees to determine applicability - of information provided. If this file has been purchased on magnetic or - optical media from Unicode, Inc., the sole remedy for any claim will be - exchange of defective media within 90 days of receipt. - . - Limitations on Rights to Redistribute This Code - . - Unicode, Inc. hereby grants the right to freely use the information - supplied in this file in the creation of products supporting the - Unicode Standard, and to make copies of this file in any form for - internal or external distribution as long as this notice remains - attached. +License: ISC + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR + BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES + OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + SOFTWARE. diff -Nru ghostscript-9.10~dfsg/debian/copyright-check ghostscript-9.25~dfsg+1/debian/copyright-check --- ghostscript-9.10~dfsg/debian/copyright-check 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/copyright-check 2018-09-06 18:21:03.000000000 +0000 @@ -0,0 +1,34 @@ +#!/bin/sh +# Copyright © 2016-2017 Jonas Smedegaard +# Description: helper script to update copyright_hints +# +# 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 3, 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, see . + +set -eu + +# extract metadata from ICC, PDF, and fonts before copyright check +# - skip main HTML documentation and a spreadsheet +# - skip binary non-metadata-parseable graphics formats (ico pcl xps) +# - skip binary non-metadata-parseable certificate bundle (cat) +export DEB_COPYRIGHT_EXTRACT_EXTS="icc pdf png ttf" +export DEB_COPYRIGHT_EXTRACT_PATHS_EXIF="Resource/Font/" +export DEB_COPYRIGHT_CHECK_IGNORE_EXTS="cat ico xls pcl xps" +export DEB_COPYRIGHT_CHECK_IGNORE_PATHS="doc/.*\.htm" +#export DEB_COPYRIGHT_CHECK_MERGE_SAME_LICENSE=yes + +make -f /usr/share/cdbs/1/rules/utils.mk pre-build || true +make -f /usr/share/cdbs/1/rules/utils.mk clean DEB_COPYRIGHT_CHECK_STRICT=1 + +# unconditionally merge changes - safe to do with git-tracked package +[ ! -f debian/copyright_newhints ] || mv -f debian/copyright_newhints debian/copyright_hints diff -Nru ghostscript-9.10~dfsg/debian/copyright_hints ghostscript-9.25~dfsg+1/debian/copyright_hints --- ghostscript-9.10~dfsg/debian/copyright_hints 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/copyright_hints 2018-02-23 20:04:45.000000000 +0000 @@ -0,0 +1,3447 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: FIXME +Upstream-Contact: FIXME +Source: FIXME +Disclaimer: Autogenerated by CDBS + +Files: Makefile.in + Resource/CIDFont/ArtifexBullet + Resource/ColorSpace/DefaultCMYK + Resource/ColorSpace/DefaultGray + Resource/ColorSpace/DefaultRGB + Resource/ColorSpace/TrivialCMYK + Resource/ColorSpace/sGray + Resource/ColorSpace/sRGB + Resource/Decoding/FCO_Dingbats + Resource/Decoding/FCO_Wingdings + Resource/Decoding/StandardEncoding + Resource/Encoding/CEEncoding + Resource/Encoding/ExpertEncoding + Resource/Encoding/ExpertSubsetEncoding + Resource/Encoding/NotDefEncoding + Resource/Encoding/Wingdings + Resource/Init/FCOfontmap-PCLPS2 + Resource/Init/gs_btokn.ps + Resource/Init/gs_cff.ps + Resource/Init/gs_cidcm.ps + Resource/Init/gs_ciddc.ps + Resource/Init/gs_cidfm.ps + Resource/Init/gs_cidfn.ps + Resource/Init/gs_cidtt.ps + Resource/Init/gs_cmap.ps + Resource/Init/gs_cspace.ps + Resource/Init/gs_dbt_e.ps + Resource/Init/gs_diskf.ps + Resource/Init/gs_diskn.ps + Resource/Init/gs_dpnxt.ps + Resource/Init/gs_dps.ps + Resource/Init/gs_dps1.ps + Resource/Init/gs_dps2.ps + Resource/Init/gs_dscp.ps + Resource/Init/gs_epsf.ps + Resource/Init/gs_fapi.ps + Resource/Init/gs_fntem.ps + Resource/Init/gs_fonts.ps + Resource/Init/gs_frsd.ps + Resource/Init/gs_icc.ps + Resource/Init/gs_il1_e.ps + Resource/Init/gs_init.ps + Resource/Init/gs_l2img.ps + Resource/Init/gs_lev2.ps + Resource/Init/gs_ll3.ps + Resource/Init/gs_mex_e.ps + Resource/Init/gs_mgl_e.ps + Resource/Init/gs_mro_e.ps + Resource/Init/gs_pdf_e.ps + Resource/Init/gs_pdfwr.ps + Resource/Init/gs_resmp.ps + Resource/Init/gs_setpd.ps + Resource/Init/gs_statd.ps + Resource/Init/gs_std_e.ps + Resource/Init/gs_trap.ps + Resource/Init/gs_ttf.ps + Resource/Init/gs_typ32.ps + Resource/Init/gs_typ42.ps + Resource/Init/gs_type1.ps + Resource/Init/gs_wan_e.ps + Resource/Init/pdf_base.ps + Resource/Init/pdf_draw.ps + Resource/Init/pdf_font.ps + Resource/Init/pdf_main.ps + Resource/Init/pdf_ops.ps + Resource/Init/pdf_rbld.ps + Resource/SubstCID/CNS1-WMode + Resource/SubstCID/GB1-WMode + Resource/SubstCID/Japan1-WMode + Resource/SubstCID/Korea1-WMode + arch/arch_autoconf.h.in + arch/windows-arm-msvc.h + arch/windows-x64-msvc.h + arch/windows-x86-msvc.h + base/all-arch.mak + base/assert_.h + base/bobbin.c + base/bobbin.h + base/ctype_.h + base/dirent_.h + base/dos_.h + base/echogs.c + base/errno_.h + base/expat.mak + base/fapi_bs.mak + base/fapi_ft.c + base/fapibstm.c + base/fapiufst.c + base/fcntl_.h + base/freetype.mak + base/gconf.c + base/gconf.h + base/gdbflags.h + base/gdebug.h + base/gdevabuf.c + base/gdevbbox.c + base/gdevbbox.h + base/gdevdbit.c + base/gdevdcrd.c + base/gdevdcrd.h + base/gdevddrw.c + base/gdevddrw.h + base/gdevdevn.c + base/gdevdevn.h + base/gdevdevnprn.h + base/gdevdflt.c + base/gdevdgbr.c + base/gdevdrop.c + base/gdevdsha.c + base/gdevemap.c + base/gdevflp.c + base/gdevflp.h + base/gdevhit.c + base/gdevkrnlsclass.h + base/gdevm1.c + base/gdevm16.c + base/gdevm2.c + base/gdevm24.c + base/gdevm32.c + base/gdevm4.c + base/gdevm64.c + base/gdevm8.c + base/gdevmem.c + base/gdevmem.h + base/gdevmpla.c + base/gdevmpla.h + base/gdevmplt.c + base/gdevmplt.h + base/gdevmr1.c + base/gdevmr2n.c + base/gdevmr8n.c + base/gdevmrop.h + base/gdevmrun.c + base/gdevmrun.h + base/gdevmx.c + base/gdevnfwd.c + base/gdevoflt.c + base/gdevoflt.h + base/gdevp14.c + base/gdevp14.h + base/gdevpccm.c + base/gdevpccm.h + base/gdevpipe.c + base/gdevplnx.c + base/gdevplnx.h + base/gdevppla.c + base/gdevppla.h + base/gdevprn.c + base/gdevprn.h + base/gdevpxat.h + base/gdevpxen.h + base/gdevpxop.h + base/gdevrops.c + base/gdevsclass.c + base/gdevsclass.h + base/gdevvec.c + base/gdevvec.h + base/gen_ordered.c + base/gen_ordered.h + base/genarch.c + base/genconf.c + base/gendev.c + base/genht.c + base/gp.h + base/gp_dosfe.c + base/gp_dosfs.c + base/gp_dvx.c + base/gp_getnv.c + base/gp_mktmp.c + base/gp_msdll.c + base/gp_msdos.c + base/gp_mshdl.c + base/gp_mslib.c + base/gp_mspol.c + base/gp_msprn.c + base/gp_mswin.c + base/gp_mswin.h + base/gp_nsync.c + base/gp_ntfs.c + base/gp_nxpsprn.c + base/gp_os2.c + base/gp_os2.h + base/gp_os2fs.c + base/gp_os2pr.c + base/gp_os9.c + base/gp_paper.c + base/gp_psync.c + base/gp_stdia.c + base/gp_stdin.c + base/gp_strdl.c + base/gp_sysv.c + base/gp_unifn.c + base/gp_unifs.c + base/gp_unix.c + base/gp_upapr.c + base/gp_vms.c + base/gp_wgetv.c + base/gp_win32.c + base/gp_wpapr.c + base/gp_wsync.c + base/gp_wutf8.c + base/gp_wxpsprn.cpp + base/gpcheck.h + base/gpgetenv.h + base/gpmisc.c + base/gpmisc.h + base/gpsync.h + base/gs.mak + base/gs_dll_call.h + base/gs_mgl_e.h + base/gs_mro_e.h + base/gsalloc.c + base/gsalloc.h + base/gsalpha.c + base/gsalpha.h + base/gsalphac.c + base/gsalphac.h + base/gsargs.c + base/gsargs.h + base/gsbitcom.c + base/gsbitmap.h + base/gsbitops.c + base/gsbitops.h + base/gsbittab.c + base/gsbittab.h + base/gsccode.h + base/gsccolor.h + base/gscdef.c + base/gscdefs.h + base/gscdevn.c + base/gscdevn.h + base/gscedata.h + base/gscencs.c + base/gscencs.h + base/gschar.c + base/gschar.h + base/gschar0.c + base/gscicach.c + base/gscicach.h + base/gscie.c + base/gscie.h + base/gsciemap.c + base/gscindex.h + base/gsclipsr.c + base/gsclipsr.h + base/gscms.h + base/gscolor.c + base/gscolor.h + base/gscolor1.c + base/gscolor1.h + base/gscolor2.c + base/gscolor2.h + base/gscolor3.c + base/gscolor3.h + base/gscompt.h + base/gscoord.c + base/gscoord.h + base/gscparam.c + base/gscpixel.c + base/gscpixel.h + base/gscpm.h + base/gscrd.c + base/gscrd.h + base/gscrdp.c + base/gscrdp.h + base/gscrypt1.c + base/gscrypt1.h + base/gscscie.c + base/gscsel.h + base/gscsepr.c + base/gscsepr.h + base/gscspace.c + base/gscspace.h + base/gscssub.c + base/gscssub.h + base/gsdcolor.h + base/gsdevice.c + base/gsdevice.h + base/gsdevmem.c + base/gsdfilt.c + base/gsdfilt.h + base/gsdllwin.h + base/gsdparam.c + base/gsdpnext.h + base/gsdps.c + base/gsdps.h + base/gsdps1.c + base/gsdsrc.c + base/gsdsrc.h + base/gsequivc.c + base/gsequivc.h + base/gserrors.h + base/gsexit.h + base/gsfcid.c + base/gsfcid2.c + base/gsfcmap.c + base/gsfcmap.h + base/gsfcmap1.c + base/gsflip.c + base/gsflip.h + base/gsfname.c + base/gsfname.h + base/gsfont.c + base/gsfont.h + base/gsfont0.c + base/gsfont0c.c + base/gsform1.h + base/gsfunc.c + base/gsfunc.h + base/gsfunc0.c + base/gsfunc0.h + base/gsfunc3.c + base/gsfunc3.h + base/gsfunc4.c + base/gsfunc4.h + base/gsgc.h + base/gsgcache.c + base/gsgcache.h + base/gsgdata.c + base/gsgdata.h + base/gsgstate.c + base/gshsb.c + base/gshsb.h + base/gsht.c + base/gsht.h + base/gsht1.c + base/gsht1.h + base/gshtscr.c + base/gshtx.c + base/gshtx.h + base/gsicc.c + base/gsicc.h + base/gsicc_cache.c + base/gsicc_cache.h + base/gsicc_cms.h + base/gsicc_create.h + base/gsicc_lcms.c + base/gsicc_lcms2.c + base/gsicc_manage.c + base/gsicc_manage.h + base/gsicc_monitorcm.c + base/gsicc_nocm.c + base/gsicc_profilecache.c + base/gsicc_profilecache.h + base/gsicc_replacecm.c + base/gsimage.c + base/gsimage.h + base/gsimpath.c + base/gsinit.c + base/gsio.h + base/gsiodev.c + base/gsiodevs.c + base/gsiodisk.c + base/gsioram.c + base/gsiorom.c + base/gsiorom.h + base/gsipar3x.h + base/gsiparam.h + base/gsiparm2.h + base/gsiparm3.h + base/gsiparm4.h + base/gsjconf.h + base/gsjmorec.h + base/gslib.c + base/gslib.h + base/gslibctx.c + base/gslibctx.h + base/gsline.c + base/gsline.h + base/gslparam.h + base/gsmalloc.c + base/gsmalloc.h + base/gsmatrix.c + base/gsmatrix.h + base/gsmchunk.c + base/gsmchunk.h + base/gsmdebug.h + base/gsmemory.c + base/gsmemory.h + base/gsmemraw.h + base/gsmemret.c + base/gsmemret.h + base/gsmisc.c + base/gsnamecl.c + base/gsnamecl.h + base/gsncdummy.c + base/gsncdummy.h + base/gsnogc.c + base/gsnogc.h + base/gsnotify.c + base/gsnotify.h + base/gsovrc.c + base/gsovrc.h + base/gspaint.c + base/gspaint.h + base/gsparam.c + base/gsparam.h + base/gsparam2.c + base/gsparams.c + base/gsparams.h + base/gsparamx.c + base/gsparamx.h + base/gspath.c + base/gspath.h + base/gspath1.c + base/gspath2.h + base/gspcolor.c + base/gspcolor.h + base/gspenum.h + base/gspmdrv.c + base/gspmdrv.h + base/gsptype1.c + base/gsptype1.h + base/gsptype2.c + base/gsptype2.h + base/gsrect.h + base/gsrefct.h + base/gsromfs0.c + base/gsrop.c + base/gsrop.h + base/gsroprun.c + base/gsroprun1.h + base/gsroprun24.h + base/gsroprun8.h + base/gsropt.h + base/gsroptab.c + base/gsserial.c + base/gsserial.h + base/gsshade.c + base/gsshade.h + base/gssprintf.h + base/gsstate.c + base/gsstate.h + base/gsstrl.h + base/gsstrtok.h + base/gsstruct.h + base/gsstype.h + base/gstext.c + base/gstext.h + base/gstiffio.c + base/gstiffio.h + base/gstparam.h + base/gstrans.c + base/gstrans.h + base/gstrap.c + base/gstrap.h + base/gstype1.c + base/gstype1.h + base/gstype2.c + base/gstypes.h + base/gsuid.h + base/gsutil.c + base/gsutil.h + base/gswin.rc + base/gsxfont.h + base/gx.h + base/gxacpath.c + base/gxalloc.h + base/gxalpha.h + base/gxarith.h + base/gxband.h + base/gxbcache.c + base/gxbcache.h + base/gxbitfmt.h + base/gxbitmap.h + base/gxbitops.h + base/gxblend.c + base/gxblend.h + base/gxblend1.c + base/gxccache.c + base/gxccman.c + base/gxcdevn.h + base/gxchar.c + base/gxchar.h + base/gxchrout.c + base/gxchrout.h + base/gxcht.c + base/gxcid.h + base/gxcie.h + base/gxcindex.h + base/gxclbits.c + base/gxcldev.h + base/gxclfile.c + base/gxclimag.c + base/gxclio.h + base/gxclip.c + base/gxclip.h + base/gxclip2.c + base/gxclip2.h + base/gxclipm.c + base/gxclipm.h + base/gxclipsr.h + base/gxclist.c + base/gxclist.h + base/gxcllzw.c + base/gxclmem.c + base/gxclmem.h + base/gxclpage.c + base/gxclpage.h + base/gxclpath.c + base/gxclpath.h + base/gxclrast.c + base/gxclread.c + base/gxclrect.c + base/gxclthrd.c + base/gxclthrd.h + base/gxclutil.c + base/gxclzlib.c + base/gxcmap.c + base/gxcmap.h + base/gxcolor2.h + base/gxcomp.h + base/gxcoord.h + base/gxcpath.c + base/gxcpath.h + base/gxcspace.h + base/gxctable.c + base/gxctable.h + base/gxcvalue.h + base/gxdcconv.c + base/gxdcconv.h + base/gxdcolor.c + base/gxdcolor.h + base/gxdda.h + base/gxdevbuf.h + base/gxdevcli.h + base/gxdevice.h + base/gxdevmem.h + base/gxdevndi.c + base/gxdevndi.h + base/gxdevrop.h + base/gxdevsop.h + base/gxdht.h + base/gxdhtres.h + base/gxdhtserial.c + base/gxdhtserial.h + base/gxdither.h + base/gxdownscale.c + base/gxdownscale.h + base/gxdtfill.h + base/gxfapi.c + base/gxfapi.h + base/gxfapiu.c + base/gxfapiu.h + base/gxfarith.h + base/gxfcache.h + base/gxfcid.h + base/gxfcmap.h + base/gxfcmap1.h + base/gxfill.c + base/gxfill.h + base/gxfillsl.h + base/gxfilltr.h + base/gxfillts.h + base/gxfixed.h + base/gxfmap.h + base/gxfont.h + base/gxfont0.h + base/gxfont0c.h + base/gxfont1.h + base/gxfont42.h + base/gxfrac.h + base/gxftype.h + base/gxfunc.h + base/gxgetbit.h + base/gxgstate.h + base/gxhintn.c + base/gxhintn.h + base/gxhintn1.c + base/gxhldevc.c + base/gxhldevc.h + base/gxht.c + base/gxht.h + base/gxht_thresh.c + base/gxht_thresh.h + base/gxhtbit.c + base/gxhttile.h + base/gxhttype.h + base/gxi12bit.c + base/gxi16bit.c + base/gxiclass.h + base/gxicolor.c + base/gxidata.c + base/gxifast.c + base/gximag3x.c + base/gximag3x.h + base/gximage.c + base/gximage.h + base/gximage1.c + base/gximage2.c + base/gximage3.c + base/gximage3.h + base/gximage4.c + base/gximask.c + base/gximask.h + base/gximdecode.c + base/gximdecode.h + base/gximono.c + base/gxiodev.h + base/gxiparam.h + base/gxipixel.c + base/gxiscale.c + base/gxline.h + base/gxlum.h + base/gxmatrix.h + base/gxmclip.c + base/gxmclip.h + base/gxobj.h + base/gxoprect.c + base/gxoprect.h + base/gxp1fill.c + base/gxp1impl.h + base/gxpaint.c + base/gxpaint.h + base/gxpath.c + base/gxpath.h + base/gxpath2.c + base/gxpcache.h + base/gxpcmap.c + base/gxpcolor.h + base/gxpcopy.c + base/gxpdash.c + base/gxpflat.c + base/gxrplane.h + base/gxsample.c + base/gxsample.h + base/gxsamplp.h + base/gxscanc.c + base/gxscanc.h + base/gxshade.c + base/gxshade.h + base/gxshade1.c + base/gxshade4.c + base/gxshade4.h + base/gxshade6.c + base/gxstate.h + base/gxstdio.h + base/gxstroke.c + base/gxsync.c + base/gxsync.h + base/gxtext.h + base/gxtmap.h + base/gxttf.h + base/gxttfb.c + base/gxttfb.h + base/gxtype1.c + base/gxtype1.h + base/gxxfont.h + base/gzacpath.h + base/gzcpath.h + base/gzht.h + base/gzline.h + base/gzpath.h + base/gzspotan.c + base/gzspotan.h + base/gzstate.h + base/ijs.mak + base/instcopy + base/jbig2.mak + base/jerror_.h + base/jmemcust.c + base/jmemcust.h + base/jpeg.mak + base/jpegxr.mak + base/lcms2.mak + base/lcups.mak + base/lcupsi.mak + base/ldf_jb2.mak + base/lib.mak + base/locale_.h + base/lwf_jp2.mak + base/malloc_.h + base/math_.h + base/memento.c + base/memento.h + base/memory_.h + base/mkromfs.c + base/msvccmd.mak + base/msvclib.mak + base/msvctail.mak + base/openjpeg.mak + base/openvms.mak + base/openvms.mmk + base/pack_ps.c + base/pcwin.mak + base/pipe_.h + base/png.mak + base/png_.h + base/ramfs.c + base/ramfs.h + base/sa85d.c + base/sa85d.h + base/sa85x.h + base/saes.c + base/saes.h + base/sarc4.c + base/sarc4.h + base/sbcp.c + base/sbcp.h + base/sbtx.h + base/scanchar.h + base/scantab.c + base/scf.h + base/scfd.c + base/scfdgen.c + base/scfdtab.c + base/scfe.c + base/scfetab.c + base/scfparam.c + base/scfx.h + base/scommon.h + base/sdcparam.c + base/sdcparam.h + base/sdct.h + base/sdctc.c + base/sdctd.c + base/sdcte.c + base/sddparam.c + base/sdeparam.c + base/seexec.c + base/setjmp_.h + base/sfilter.h + base/sfilter2.c + base/sfxboth.c + base/sfxcommon.c + base/sfxfd.c + base/sfxstdio.c + base/shc.c + base/shc.h + base/sidscale.c + base/sidscale.h + base/siinterp.c + base/siinterp.h + base/simscale.c + base/simscale.h + base/siscale.c + base/siscale.h + base/sisparam.h + base/sjbig2.c + base/sjbig2.h + base/sjbig2_luratech.c + base/sjbig2_luratech.h + base/sjpeg.h + base/sjpegc.c + base/sjpegd.c + base/sjpege.c + base/sjpx_luratech.c + base/sjpx_luratech.h + base/sjpx_none.c + base/sjpx_openjpeg.c + base/sjpx_openjpeg.h + base/slzwc.c + base/slzwd.c + base/slzwe.c + base/slzwx.h + base/smd5.c + base/smd5.h + base/smtf.h + base/spdiff.c + base/spdiffx.h + base/spngp.c + base/spngpx.h + base/spprint.c + base/spprint.h + base/spsdf.c + base/spsdf.h + base/srdline.h + base/srld.c + base/srle.c + base/srlx.h + base/ssha2.c + base/ssha2.h + base/sstring.c + base/sstring.h + base/stat_.h + base/std.h + base/stdint_.h + base/stdio_.h + base/stream.c + base/stream.h + base/strimpl.h + base/string_.h + base/strmio.c + base/strmio.h + base/stub.mak + base/szlibc.c + base/szlibd.c + base/szlibe.c + base/szlibx.h + base/szlibxx.h + base/tiff.mak + base/time_.h + base/ttconf.h + base/ttfinp.c + base/ttfinp.h + base/ttfmain.c + base/ttfmemd.c + base/ttfmemd.h + base/ttfoutl.h + base/ttmisc.h + base/ugcclib.mak + base/unistd_.h + base/unix-aux.mak + base/unix-dll.mak + base/unix-end.mak + base/unix-gcc.mak + base/unixansi.mak + base/unixhead.mak + base/unixinst.mak + base/unixlink.mak + base/valgrind.h + base/version.mak + base/vms_x_fix.h + base/vmsmath.h + base/windows_.h + base/winlib.mak + base/winplat.mak + base/winrtsup.cpp + base/winrtsup.h + base/wrfont.c + base/wrfont.h + base/write_t1.c + base/write_t1.h + base/write_t2.c + base/write_t2.h + base/x_.h + base/zlib.mak + configure.ac + devices/contrib.mak + devices/devs.mak + devices/gdev3852.c + devices/gdev4081.c + devices/gdev8510.c + devices/gdev8bcm.c + devices/gdev8bcm.h + devices/gdevatx.c + devices/gdevbit.c + devices/gdevbj10.c + devices/gdevbjcl.c + devices/gdevbjcl.h + devices/gdevbmp.c + devices/gdevbmp.h + devices/gdevbmpc.c + devices/gdevccr.c + devices/gdevcfax.c + devices/gdevcif.c + devices/gdevclj.c + devices/gdevcljc.c + devices/gdevcmykog.c + devices/gdevcp50.c + devices/gdevcslw.c + devices/gdevdfax.c + devices/gdevdjet.c + devices/gdevdjtc.c + devices/gdevdljm.c + devices/gdevdljm.h + devices/gdevdm24.c + devices/gdevdsp.c + devices/gdevdsp.h + devices/gdevdsp2.h + devices/gdevepsc.c + devices/gdevepsn.c + devices/gdevescp.c + devices/gdevfax.c + devices/gdevfax.h + devices/gdevfpng.c + devices/gdevgprf.c + devices/gdevhl7x.c + devices/gdevimgn.c + devices/gdevjbig2.c + devices/gdevjpeg.c + devices/gdevjpx.c + devices/gdevl31s.c + devices/gdevlbp8.c + devices/gdevlj56.c + devices/gdevlp8k.c + devices/gdevlxm.c + devices/gdevmeds.c + devices/gdevmeds.h + devices/gdevmgr.c + devices/gdevmgr.h + devices/gdevmiff.c + devices/gdevn533.c + devices/gdevo182.c + devices/gdevokii.c + devices/gdevpbm.c + devices/gdevpcl.c + devices/gdevpcl.h + devices/gdevpcx.c + devices/gdevpe.c + devices/gdevperm.c + devices/gdevphex.c + devices/gdevpjet.c + devices/gdevplan.c + devices/gdevplib.c + devices/gdevplib.h + devices/gdevpm.h + devices/gdevpng.c + devices/gdevpsd.c + devices/gdevpsd.h + devices/gdevpsim.c + devices/gdevpxut.h + devices/gdevrinkj.c + devices/gdevsj48.c + devices/gdevsnfb.c + devices/gdevsppr.c + devices/gdevstc.c + devices/gdevstc.h + devices/gdevstc1.c + devices/gdevstc2.c + devices/gdevstc3.c + devices/gdevstc4.c + devices/gdevtfax.c + devices/gdevtfax.h + devices/gdevtfnx.c + devices/gdevtifs.c + devices/gdevtifs.h + devices/gdevtknk.c + devices/gdevtrac.c + devices/gdevtsep.c + devices/gdevupd.c + devices/gdevwpr2.c + devices/gdevx.c + devices/gdevx.h + devices/gdevxalt.c + devices/gdevxcf.c + devices/gdevxcmp.c + devices/gdevxcmp.h + devices/gdevxini.c + devices/gdevxres.c + devices/gxfcopy.c + devices/gxfcopy.h + devices/minftrsz.c + devices/minftrsz.h + devices/rinkj/evenbetter-rll.c + devices/rinkj/evenbetter-rll.h + devices/rinkj/rinkj-byte-stream.c + devices/rinkj/rinkj-byte-stream.h + devices/rinkj/rinkj-config.c + devices/rinkj/rinkj-config.h + devices/rinkj/rinkj-device.c + devices/rinkj/rinkj-device.h + devices/rinkj/rinkj-dither.c + devices/rinkj/rinkj-dither.h + devices/rinkj/rinkj-epson870.c + devices/rinkj/rinkj-epson870.h + devices/rinkj/rinkj-screen-eb.c + devices/rinkj/rinkj-screen-eb.h + devices/vector/gdevagl.h + devices/vector/gdevpdf.c + devices/vector/gdevpdfb.c + devices/vector/gdevpdfb.h + devices/vector/gdevpdfc.c + devices/vector/gdevpdfc.h + devices/vector/gdevpdfd.c + devices/vector/gdevpdfe.c + devices/vector/gdevpdfg.c + devices/vector/gdevpdfg.h + devices/vector/gdevpdfi.c + devices/vector/gdevpdfj.c + devices/vector/gdevpdfm.c + devices/vector/gdevpdfo.c + devices/vector/gdevpdfo.h + devices/vector/gdevpdfp.c + devices/vector/gdevpdfr.c + devices/vector/gdevpdft.c + devices/vector/gdevpdfu.c + devices/vector/gdevpdfv.c + devices/vector/gdevpdfx.h + devices/vector/gdevpdt.c + devices/vector/gdevpdt.h + devices/vector/gdevpdtb.c + devices/vector/gdevpdtb.h + devices/vector/gdevpdtc.c + devices/vector/gdevpdtd.c + devices/vector/gdevpdtd.h + devices/vector/gdevpdte.c + devices/vector/gdevpdtf.c + devices/vector/gdevpdtf.h + devices/vector/gdevpdti.c + devices/vector/gdevpdti.h + devices/vector/gdevpdts.c + devices/vector/gdevpdts.h + devices/vector/gdevpdtt.c + devices/vector/gdevpdtt.h + devices/vector/gdevpdtv.c + devices/vector/gdevpdtv.h + devices/vector/gdevpdtw.c + devices/vector/gdevpdtw.h + devices/vector/gdevpdtx.h + devices/vector/gdevpsdf.h + devices/vector/gdevpsdi.c + devices/vector/gdevpsdp.c + devices/vector/gdevpsds.c + devices/vector/gdevpsds.h + devices/vector/gdevpsdu.c + devices/vector/gdevpsf.h + devices/vector/gdevpsf2.c + devices/vector/gdevpsfm.c + devices/vector/gdevpsft.c + devices/vector/gdevpsfu.c + devices/vector/gdevpsfx.c + devices/vector/gdevpsu.h + devices/vector/gdevpx.c + devices/vector/gdevtxtw.c + devices/vector/gdevxps.c + devices/vector/opdfread.ps + devices/vector/whitelst.c + devices/vector/whitelst.h + doc/gdevds32.c + gpdl/gpdl.mak + gpdl/psi/gpdlpsi.mak + gpdl/psi/psitop.c + gpdl/pspcl6_gcc.mak + gpdl/pspcl6_msvc.mak + lib/FCOfontmap-PCLPS3 + lib/FCOfontmap-PS3 + lib/Fontmap.ATB + lib/Fontmap.Ult + lib/align.ps + lib/caption.ps + lib/cat.ps + lib/cid2code.ps + lib/docie.ps + lib/gs_ce_e.ps + lib/gs_cmdl.ps + lib/gs_il2_e.ps + lib/gs_kanji.ps + lib/gs_ksb_e.ps + lib/gs_lgo_e.ps + lib/gs_lgx_e.ps + lib/gs_wl1_e.ps + lib/gs_wl2_e.ps + lib/gs_wl5_e.ps + lib/gslp.ps + lib/gsnup.ps + lib/image-qa.ps + lib/jispaper.ps + lib/lines.ps + lib/mkcidfm.ps + lib/pfbtopfa.ps + lib/ppath.ps + lib/pphs.ps + lib/ps2epsi.ps + lib/rollconv.ps + lib/stcinfo.ps + lib/stcolor.ps + lib/stocht.ps + lib/traceimg.ps + lib/traceop.ps + lib/uninfo.ps + lib/viewcmyk.ps + lib/viewgif.ps + lib/viewmiff.ps + lib/viewpbm.ps + lib/viewpcx.ps + lib/viewps2a.ps + lib/viewraw.ps + lib/viewrgb.ps + lib/winmaps.ps + lib/zeroline.ps + pcl/pcl/pcbiptrn.c + pcl/pcl/pcbiptrn.h + pcl/pcl/pccid.c + pcl/pcl/pccid.h + pcl/pcl/pccolor.c + pcl/pcl/pccoord.h + pcl/pcl/pccprint.c + pcl/pcl/pccsbase.c + pcl/pcl/pccsbase.h + pcl/pcl/pcdict.h + pcl/pcl/pcdither.c + pcl/pcl/pcdither.h + pcl/pcl/pcdraw.c + pcl/pcl/pcdraw.h + pcl/pcl/pcfont.c + pcl/pcl/pcfontpg.c + pcl/pcl/pcfontst.h + pcl/pcl/pcfrgrnd.c + pcl/pcl/pcfrgrnd.h + pcl/pcl/pcfsel.c + pcl/pcl/pcfsel.h + pcl/pcl/pcht.c + pcl/pcl/pcht.h + pcl/pcl/pcident.c + pcl/pcl/pcident.h + pcl/pcl/pcimpl.c + pcl/pcl/pcindxed.c + pcl/pcl/pcindxed.h + pcl/pcl/pcjob.c + pcl/pcl/pcl.mak + pcl/pcl/pcl_top.mak + pcl/pcl/pclookup.c + pcl/pcl/pclookup.h + pcl/pcl/pcmacros.c + pcl/pcl/pcmisc.c + pcl/pcl/pcmtx3.c + pcl/pcl/pcmtx3.h + pcl/pcl/pcommand.c + pcl/pcl/pcommand.h + pcl/pcl/pcpage.c + pcl/pcl/pcpage.h + pcl/pcl/pcpalet.c + pcl/pcl/pcpalet.h + pcl/pcl/pcparam.h + pcl/pcl/pcparse.c + pcl/pcl/pcparse.h + pcl/pcl/pcpatrn.c + pcl/pcl/pcpatrn.h + pcl/pcl/pcpattyp.h + pcl/pcl/pcpatxfm.c + pcl/pcl/pcpatxfm.h + pcl/pcl/pcrect.c + pcl/pcl/pcsfont.c + pcl/pcl/pcstate.h + pcl/pcl/pcstatus.c + pcl/pcl/pcsymbol.c + pcl/pcl/pcsymbol.h + pcl/pcl/pctext.c + pcl/pcl/pctop.c + pcl/pcl/pctop.h + pcl/pcl/pctpm.h + pcl/pcl/pcuptrn.c + pcl/pcl/pcuptrn.h + pcl/pcl/pcursor.c + pcl/pcl/pcursor.h + pcl/pcl/pcwhtidx.c + pcl/pcl/pcwhtidx.h + pcl/pcl/pcxfmst.h + pcl/pcl/pgchar.c + pcl/pcl/pgcolor.c + pcl/pcl/pgconfig.c + pcl/pcl/pgdraw.c + pcl/pcl/pgdraw.h + pcl/pcl/pgfdata.c + pcl/pcl/pgfdata.h + pcl/pcl/pgfont.c + pcl/pcl/pgfont.h + pcl/pcl/pgframe.c + pcl/pcl/pggeom.c + pcl/pcl/pggeom.h + pcl/pcl/pginit.c + pcl/pcl/pginit.h + pcl/pcl/pglabel.c + pcl/pcl/pglfill.c + pcl/pcl/pgmand.h + pcl/pcl/pgmisc.c + pcl/pcl/pgmisc.h + pcl/pcl/pgparse.c + pcl/pcl/pgpoly.c + pcl/pcl/pgstate.h + pcl/pcl/pgvector.c + pcl/pcl/rtgmode.c + pcl/pcl/rtgmode.h + pcl/pcl/rtmisc.c + pcl/pcl/rtmisc.h + pcl/pcl/rtraster.c + pcl/pcl/rtraster.h + pcl/pcl/rtrstcmp.c + pcl/pcl/rtrstcmp.h + pcl/pcl/rtrstst.h + pcl/pl/pjparse.c + pcl/pl/pjparse.h + pcl/pl/pjparsei.c + pcl/pl/pjtop.c + pcl/pl/pjtop.h + pcl/pl/pl.mak + pcl/pl/plalloc.c + pcl/pl/plapi.c + pcl/pl/plapi.h + pcl/pl/plchar.c + pcl/pl/plchar.h + pcl/pl/plcursor.c + pcl/pl/plcursor.h + pcl/pl/pldebug.h + pcl/pl/pldict.c + pcl/pl/pldict.h + pcl/pl/pldraw.c + pcl/pl/pldraw.h + pcl/pl/plfapi.c + pcl/pl/plfapi.h + pcl/pl/plfont.c + pcl/pl/plfont.h + pcl/pl/plftable.c + pcl/pl/plftable.h + pcl/pl/plht.c + pcl/pl/plht.h + pcl/pl/plimpl.c + pcl/pl/pllfont.c + pcl/pl/pllfont.h + pcl/pl/plmain.c + pcl/pl/plmain.h + pcl/pl/plparams.c + pcl/pl/plparams.h + pcl/pl/plparse.h + pcl/pl/plromfs.mak + pcl/pl/plsymbol.c + pcl/pl/plsymbol.h + pcl/pl/pltop.c + pcl/pl/pltop.h + pcl/pl/pluchar.c + pcl/pl/plufont.c + pcl/pl/plufstlp.c + pcl/pl/plufstlp.h + pcl/pl/plufstlp1.c + pcl/pl/plulfont.c + pcl/pl/plvalue.c + pcl/pl/plvalue.h + pcl/pl/plvocab.h + pcl/pl/plwimg.c + pcl/pl/plwimg.h + pcl/pl/plwmainc.c + pcl/pl/plwreg.c + pcl/pl/plwreg.h + pcl/pl/plwres.h + pcl/pl/realmain.c + pcl/pxl/pxasm.ps + pcl/pxl/pxattr.h + pcl/pxl/pxbfont.c + pcl/pxl/pxbfont.h + pcl/pxl/pxcet.txt + pcl/pxl/pxdict.h + pcl/pxl/pxenum.h + pcl/pxl/pxerrors.c + pcl/pxl/pxerrors.h + pcl/pxl/pxffont.c + pcl/pxl/pxfont.c + pcl/pxl/pxfont.h + pcl/pxl/pxfts.txt + pcl/pxl/pxgstate.c + pcl/pxl/pxgstate.h + pcl/pxl/pximage.c + pcl/pxl/pximpl.c + pcl/pxl/pxink.c + pcl/pxl/pxl.mak + pcl/pxl/pxlib.txt + pcl/pxl/pxoper.h + pcl/pxl/pxpaint.c + pcl/pxl/pxparse.c + pcl/pxl/pxparse.h + pcl/pxl/pxptable.c + pcl/pxl/pxptable.h + pcl/pxl/pxpthr.c + pcl/pxl/pxpthr.h + pcl/pxl/pxsessio.c + pcl/pxl/pxspec.txt + pcl/pxl/pxstate.c + pcl/pxl/pxstate.h + pcl/pxl/pxstream.c + pcl/pxl/pxsymbol.psh + pcl/pxl/pxtag.h + pcl/pxl/pxtop.c + pcl/pxl/pxvalue.c + pcl/pxl/pxvalue.h + pcl/pxl/pxvendor.c + pcl/pxl/pxvendor.h + pcl/tools/suite.tcl + psi/bfont.h + psi/btoken.h + psi/dmmain.c + psi/dpmain.c + psi/dscparse.c + psi/dscparse.h + psi/dstack.h + psi/dwdll.c + psi/dwdll.h + psi/dwimg.c + psi/dwimg.h + psi/dwmain.c + psi/dwmain.rc + psi/dwmainc.c + psi/dwnodll.c + psi/dwreg.c + psi/dwreg.h + psi/dwres.h + psi/dwtext.c + psi/dwtext.h + psi/dwtrace.c + psi/dwtrace.h + psi/dxmain.c + psi/dxmainc.c + psi/estack.h + psi/files.h + psi/ghost.h + psi/gs.c + psi/gsdll2.rc + psi/gsdll32.rc + psi/gserver.c + psi/gsos2.rc + psi/ialloc.c + psi/ialloc.h + psi/iapi.c + psi/iapi.h + psi/iastate.h + psi/iastruct.h + psi/ibnum.c + psi/ibnum.h + psi/ichar.h + psi/ichar1.h + psi/icharout.h + psi/icid.h + psi/icie.h + psi/icolor.h + psi/iconf.c + psi/iconf.h + psi/icontext.c + psi/icontext.h + psi/icremap.h + psi/icsmap.h + psi/icstate.h + psi/iddict.h + psi/iddstack.h + psi/idebug.c + psi/idebug.h + psi/idict.c + psi/idict.h + psi/idictdef.h + psi/idicttpl.h + psi/idisp.c + psi/idisp.h + psi/idosave.h + psi/idparam.c + psi/idparam.h + psi/idsdata.h + psi/idstack.c + psi/idstack.h + psi/ierrors.h + psi/iesdata.h + psi/iestack.h + psi/ifapi.h + psi/ifcid.h + psi/ifilter.h + psi/ifilter2.h + psi/ifont.h + psi/ifont1.h + psi/ifont2.h + psi/ifont42.h + psi/ifrpred.h + psi/ifunc.h + psi/ifwpred.h + psi/igc.c + psi/igc.h + psi/igcref.c + psi/igcstr.c + psi/igcstr.h + psi/igstate.h + psi/iht.h + psi/iimage.h + psi/iimage2.h + psi/iinit.c + psi/iinit.h + psi/ilevel.h + psi/ilocate.c + psi/imain.c + psi/imain.h + psi/imainarg.c + psi/imainarg.h + psi/imemory.h + psi/iname.c + psi/iname.h + psi/inamedef.h + psi/inameidx.h + psi/inames.h + psi/inamestr.h + psi/inobtokn.c + psi/inouparm.c + psi/int.mak + psi/interp.c + psi/interp.h + psi/iosdata.h + psi/iostack.h + psi/ipacked.h + psi/iparam.c + psi/iparam.h + psi/iparray.h + psi/ipcolor.h + psi/iplugin.c + psi/iplugin.h + psi/ireclaim.c + psi/isave.c + psi/isave.h + psi/iscan.c + psi/iscan.h + psi/iscanbin.c + psi/iscanbin.h + psi/iscannum.c + psi/iscannum.h + psi/isdata.h + psi/isstate.h + psi/istack.c + psi/istack.h + psi/istkparm.h + psi/istream.h + psi/istruct.h + psi/itoken.h + psi/iutil.c + psi/iutil.h + psi/iutil2.c + psi/iutil2.h + psi/ivmem2.h + psi/ivmspace.h + psi/main.h + psi/mkfilelt.cpp + psi/msvc.mak + psi/msvc32.mak + psi/msvc64.mak + psi/nsisinst.nsi + psi/oparc.h + psi/opcheck.h + psi/opdef.h + psi/oper.h + psi/opextern.h + psi/os2.mak + psi/ostack.h + psi/psromfs.mak + psi/sfilter1.c + psi/store.h + psi/winint.mak + psi/zalg.c + psi/zarith.c + psi/zarray.c + psi/zbfont.c + psi/zbseq.c + psi/zcfont.c + psi/zchar.c + psi/zchar1.c + psi/zchar2.c + psi/zchar32.c + psi/zchar42.c + psi/zchar42.h + psi/zcharout.c + psi/zcharx.c + psi/zcid.c + psi/zcie.c + psi/zcie.h + psi/zcolor.c + psi/zcolor.h + psi/zcolor1.c + psi/zcolor2.c + psi/zcolor3.c + psi/zcontext.c + psi/zcontrol.c + psi/zcrd.c + psi/zcsindex.c + psi/zcspixel.c + psi/zcssepr.c + psi/zdevcal.c + psi/zdevice.c + psi/zdevice2.c + psi/zdfilter.c + psi/zdict.c + psi/zdouble.c + psi/zdpnext.c + psi/zdps.c + psi/zdps1.c + psi/zdscpars.c + psi/zfaes.c + psi/zfapi.c + psi/zfarc4.c + psi/zfbcp.c + psi/zfcid.c + psi/zfcid0.c + psi/zfcid1.c + psi/zfcmap.c + psi/zfdctd.c + psi/zfdcte.c + psi/zfdecode.c + psi/zfile.c + psi/zfile.h + psi/zfile1.c + psi/zfileio.c + psi/zfilter.c + psi/zfilter2.c + psi/zfimscale.c + psi/zfjbig2.c + psi/zfjpx.c + psi/zfmd5.c + psi/zfont.c + psi/zfont0.c + psi/zfont1.c + psi/zfont32.c + psi/zfont42.c + psi/zfontenum.c + psi/zform.c + psi/zfproc.c + psi/zfrsd.c + psi/zfrsd.h + psi/zfsample.c + psi/zfsha2.c + psi/zfunc.c + psi/zfunc.h + psi/zfunc0.c + psi/zfunc3.c + psi/zfunc4.c + psi/zfzlib.c + psi/zgeneric.c + psi/zgstate.c + psi/zhsb.c + psi/zht.c + psi/zht1.c + psi/zht2.c + psi/zht2.h + psi/zicc.c + psi/zicc.h + psi/zimage.c + psi/zimage2.c + psi/zimage3.c + psi/ziodev.c + psi/ziodev2.c + psi/ziodevs.c + psi/ziodevsc.c + psi/zmath.c + psi/zmatrix.c + psi/zmedia2.c + psi/zmisc.c + psi/zmisc1.c + psi/zmisc2.c + psi/zmisc3.c + psi/zncdummy.c + psi/zpacked.c + psi/zpaint.c + psi/zpath.c + psi/zpath1.c + psi/zpcolor.c + psi/zpdf_r6.c + psi/zpdfops.c + psi/zrelbit.c + psi/zshade.c + psi/zstack.c + psi/zstring.c + psi/zsysvm.c + psi/ztoken.c + psi/ztrans.c + psi/ztrap.c + psi/ztype.c + psi/zupath.c + psi/zusparam.c + psi/zutf8.c + psi/zvmem.c + psi/zvmem2.c + psi/zwinutf8.c + toolbin/GenSubstCID.ps + toolbin/afmutil.py + toolbin/color/icc_creator/ICC_Creator/CIELAB.h + toolbin/color/icc_creator/ICC_Creator/ICC_Creator.cpp + toolbin/color/icc_creator/ICC_Creator/ICC_Creator.h + toolbin/color/icc_creator/ICC_Creator/ICC_CreatorDlg.cpp + toolbin/color/icc_creator/ICC_Creator/ICC_CreatorDlg.h + toolbin/color/icc_creator/ICC_Creator/icc_create.h + toolbin/color/icc_creator/README.txt + toolbin/errlist.tcl + toolbin/extractFonts.ps + toolbin/extractICCprofiles.ps + toolbin/genfontmap.ps + toolbin/gitlog2changelog.py + toolbin/gsmake.tcl + toolbin/halftone/gen_ordered/README + toolbin/halftone/gen_ordered/gen_ordered_main.c + toolbin/halftone/gen_stochastic/gen_stochastic.c + toolbin/jpxtopdf.c + toolbin/leaks.tcl + toolbin/makehist.tcl + toolbin/memory.py + toolbin/ocheck.py + toolbin/pdf_info.ps + toolbin/pre.tcl + toolbin/precheck.tcl + toolbin/split_changelog.py + toolbin/suite.tcl + toolbin/tests/build_revision.py + toolbin/tests/check_all.py + toolbin/tests/check_comments.py + toolbin/tests/check_dirs.py + toolbin/tests/check_docrefs.py + toolbin/tests/check_source.py + toolbin/tests/cmpi.py + toolbin/tests/compare_checksumdb.py + toolbin/tests/compare_checksums.py + toolbin/tests/dump_checksum.py + toolbin/tests/dump_checksum_plus.py + toolbin/tests/dump_checksum_raw.py + toolbin/tests/fuzzy.c + toolbin/tests/get_baseline_log.py + toolbin/tests/get_baselines.py + toolbin/tests/gscheck_all.py + toolbin/tests/gscheck_fuzzypdf.py + toolbin/tests/gscheck_pdfwrite.py + toolbin/tests/gscheck_raster.py + toolbin/tests/gscheck_testfiles.py + toolbin/tests/gsconf.py + toolbin/tests/gsparamsets.py + toolbin/tests/gssum.py + toolbin/tests/gstestgs.py + toolbin/tests/gstestutils.py + toolbin/tests/gsutil.py + toolbin/tests/make_baselinedb.py + toolbin/tests/make_testdb.py + toolbin/tests/make_two_pdfversions + toolbin/tests/make_two_versions + toolbin/tests/myoptparse.py + toolbin/tests/rasterdb.py + toolbin/tests/revert_baseline + toolbin/tests/revert_pdfbaseline + toolbin/tests/run_nightly.py + toolbin/tests/run_parallel + toolbin/tests/run_regression.py + toolbin/tests/testdiff.py + toolbin/tests/update_baseline.py + toolbin/tests/update_specific + toolbin/tmake.tcl + xps/ghostxps.h + xps/xps.mak + xps/xpsanalyze.c + xps/xpscff.c + xps/xpscolor.c + xps/xpscommon.c + xps/xpscrc.c + xps/xpsdoc.c + xps/xpsfapi.c + xps/xpsfapi.h + xps/xpsfont.c + xps/xpsglyphs.c + xps/xpsgradient.c + xps/xpshash.c + xps/xpsimage.c + xps/xpsjpeg.c + xps/xpsjxr.c + xps/xpsmem.c + xps/xpsopacity.c + xps/xpspage.c + xps/xpspath.c + xps/xpspng.c + xps/xpsresource.c + xps/xpsromfs.mak + xps/xpstiff.c + xps/xpstile.c + xps/xpstop.c + xps/xpsttf.c + xps/xpsutf.c + xps/xpsvisual.c + xps/xpsxml.c + xps/xpszip.c +Copyright: 2001-2006, Artifex Software, Inc. + 2001-2012, Artifex Software, Inc. + 2001-2013, Artifex Software, Inc. + 2001-2014, Artifex Software, Inc. + 2001-2015, Artifex Software, Inc. + 2001-2016, Artifex Software, Inc. + 2001-2017, Artifex Software, Inc. + 2009-2016, Artifex Software, Inc. + 2010-2012, Artifex Software, Inc. + 2013, Artifex Software, Inc. + 2014-2015, Artifex Software, Inc. + 2016, Artifex Software, Inc. + 2017, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: Resource/IdiomSet/Pscript5Idiom + Resource/Init/FAPIcidfmap + Resource/Init/FAPIconfig + Resource/Init/FAPIfontmap + Resource/Init/Fontmap + Resource/Init/cidfmap + Resource/Init/gs_cet.ps + Resource/Init/xlatmap + arch/osx-x86-x86_64-ppc-gcc.h + autogen.sh + base/append_l.com + base/bcc32.cfg + base/catmake + base/claptrap-impl.h + base/copy_one.com + base/cp.bat + base/cp.cmd + base/ets.h + base/ets_tm.h + base/gdevkrnlsclass.c + base/gspmdrv.def + base/gspmdrv.icx + base/gswin.icx + base/gswin16.icx + base/gswin32.rc + base/mv.bat + base/mv.cmd + base/rm.bat + base/rm.cmd + base/rm_all.com + base/rm_one.com + contrib/chp2200/AUTHORS + contrib/chp2200/INSTALL + contrib/epson740/README + contrib/epson740/printerdb_rh5.2 + contrib/epson740/printerdb_rh6.0 + contrib/epson740/ps-to-printer.fpi_rh5.2 + contrib/epson740/upp-HowTo-to-be + contrib/gdevcd8.h + contrib/gdevgdi.c + contrib/japanese/dmp_site.ps + contrib/japanese/doc/Gdevlips.htm + contrib/japanese/doc/dj505j.txt + contrib/japanese/doc/gdevalps.txt + contrib/japanese/doc/gdevj100.txt + contrib/japanese/doc/gdevlbp3.txt + contrib/japanese/doc/gdevmd2k.txt + contrib/japanese/doc/gdevp201.txt + contrib/japanese/escp_24.src + contrib/japanese/gdevlbp3.c + contrib/japanese/gdevmjc.h + contrib/lxm3200-tweaked/README + contrib/lxm3200-tweaked/Z12-Z31-QuickSetup + contrib/md2k_md5k/README.jis + contrib/opvp/opvp_media.def + contrib/pcl3/doc/notes.bbl + contrib/pcl3/pcl3.tar.sig + contrib/pcl3/src/contrib.mak-5.50.add + contrib/pcl3/src/contrib.mak-6.01.add + contrib/pcl3/src/contrib.mak-6.50.add + contrib/pcl3/src/contrib.mak-6.51.add + contrib/pcl3/src/contrib.mak-7.00.add + contrib/pcl3/src/zmedia2.c-5.50.diff + contrib/pcl3/src/zmedia2.c-6.01.diff + contrib/pcl3/src/zmedia2.c-6.50.diff + contrib/pcl3/src/zmedia2.c-6.51.diff + contrib/pcl3/src/zmedia2.c-7.00.diff + contrib/pscolor/Makefile + contrib/pscolor/black.pdf + contrib/pscolor/color.pdf + contrib/pscolor/colorsplit.vcproj + contrib/pscolor/common.mak + contrib/pscolor/instream.yy + contrib/pscolor/test.c + contrib/pscolor/windows.mak + contrib/uniprint/PM760p.upp + contrib/uniprint/PM760pl.upp + contrib/uniprint/PM820p.upp + contrib/uniprint/PM820pl.upp + contrib/uniprint/Stc670p.upp + contrib/uniprint/Stc670pl.upp + contrib/uniprint/Stc680p.upp + contrib/uniprint/Stc680pl.upp + contrib/uniprint/Stc740p.upp + contrib/uniprint/Stc740pl.upp + contrib/uniprint/Stc760p.upp + contrib/uniprint/Stc760pl.upp + contrib/uniprint/Stc777p.upp + contrib/uniprint/Stc777pl.upp + contrib/uniprint/Stp720p.upp + contrib/uniprint/Stp720pl.upp + contrib/uniprint/Stp870p.upp + contrib/uniprint/Stp870pl.upp + contrib/uniprint/bjc6000a1.upp + contrib/uniprint/bjc6000b1.upp + contrib/uniprint/s400a1.upp + contrib/uniprint/s400b1.upp + contrib/uniprint/sharp.upp + contrib/uniprint/sipixa6.upp + contrib/uniprint/stc740ih.upp + debian/README.Debian + debian/README.source + debian/TODO + debian/compat + debian/control + debian/control.in + debian/control.in.in + debian/gbp.conf + debian/ghostscript-doc.doc-base + debian/ghostscript-doc.install + debian/ghostscript-x.install + debian/ghostscript.dirs + debian/ghostscript.install + debian/ghostscript.links + debian/ghostscript.postinst + debian/ghostscript.preinst + debian/ghostscript.prerm + debian/libgs__VER__-common.dirs.in + debian/libgs__VER__-common.install.in + debian/libgs__VER__-common.links.in + debian/patches/2001_docdir_fix_for_debian.patch + debian/patches/2002_gs_man_fix_debian.patch + debian/patches/2003_support_multiarch.patch + debian/patches/2004_remove_non-Debian_paths_from_docs.patch + debian/patches/2005_fix_Debian_paths_in_docs.patch + debian/patches/2006_suggest_install_ghostscript-doc_in_docs.patch + debian/patches/2007_suggest_install_ghostscript-doc_in_code.patch + debian/patches/2008_mention_ghostscript-x_in_docs.patch + debian/patches/2010_add_build_timestamp_setting.patch + debian/patches/README + debian/patches/series + debian/source/format + debian/watch + doc/AUTHORS + doc/GS9_Color_Management.pdf + doc/gs-vms.hlp + doc/gs.css + doc/gsdoc.el + doc/index.html + doc/pclxps/Makefile + doc/pclxps/README + doc/pclxps/ghostpdl.pdf + doc/pscet_status.txt + doc/who_owns_what.txt + examples/alphabet.ps + examples/annots.pdf + examples/cjk/article9.ps + examples/colorcir.ps + examples/doretree.ps + examples/escher.ps + examples/golfer.eps + examples/grayalph.ps + examples/ridt91.eps + examples/snowflak.ps + examples/text_graph_image_cmyk_rgb.pdf + examples/text_graphic_image.pdf + examples/tiger.eps + examples/transparency_example.ps + examples/vasarely.ps + lib/FAPIconfig-FCO + lib/Fontmap.OSF + lib/Info-macos.plist + lib/PDFA_def.ps + lib/PDFX_def.ps + lib/acctest.ps + lib/bj8.rpd + lib/bj8gc12f.upp + lib/bj8hg12f.upp + lib/bj8oh06n.upp + lib/bj8pa06n.upp + lib/bj8pp12f.upp + lib/bj8ts06n.upp + lib/bjc610a0.upp + lib/bjc610a1.upp + lib/bjc610a2.upp + lib/bjc610a3.upp + lib/bjc610a4.upp + lib/bjc610a5.upp + lib/bjc610a6.upp + lib/bjc610a7.upp + lib/bjc610a8.upp + lib/bjc610b1.upp + lib/bjc610b2.upp + lib/bjc610b3.upp + lib/bjc610b4.upp + lib/bjc610b6.upp + lib/bjc610b7.upp + lib/bjc610b8.upp + lib/cdj550.upp + lib/cdj690.upp + lib/cdj690ec.upp + lib/dnj750c.upp + lib/dnj750m.upp + lib/dvipdf + lib/eps2eps + lib/eps2eps.bat + lib/eps2eps.cmd + lib/ghostpdf.README + lib/ghostpdf.inf + lib/gs_l.xbm + lib/gs_l.xpm + lib/gs_l_m.xbm + lib/gs_m.xbm + lib/gs_m.xpm + lib/gs_m_m.xbm + lib/gs_s.xbm + lib/gs_s.xpm + lib/gs_s_m.xbm + lib/gs_t.xbm + lib/gs_t.xpm + lib/gs_t_m.xbm + lib/gsbj + lib/gsbj.bat + lib/gsdj + lib/gsdj.bat + lib/gsdj500 + lib/gsdj500.bat + lib/gslj + lib/gslj.bat + lib/gslp + lib/gslp.bat + lib/gsnd + lib/gsnd.bat + lib/gsndt.bat + lib/gssetgs.bat + lib/gssetgs32.bat + lib/gssetgs64.bat + lib/gst.bat + lib/gstt.bat + lib/jobseparator.ps + lib/landscap.ps + lib/lp386.bat + lib/lp386r2.bat + lib/lpgs.bat + lib/lpr2.bat + lib/lprsetup.sh + lib/necp2x.upp + lib/necp2x6.upp + lib/pdf2dsc + lib/pdf2dsc.bat + lib/pdf2ps + lib/pdf2ps.bat + lib/pdf2ps.cmd + lib/pf2afm + lib/pf2afm.bat + lib/pf2afm.cmd + lib/pfbtopfa + lib/pfbtopfa.bat + lib/pphs + lib/printafm + lib/ps2ascii + lib/ps2ascii.bat + lib/ps2ascii.cmd + lib/ps2epsi + lib/ps2epsi.bat + lib/ps2epsi.cmd + lib/ps2pdf + lib/ps2pdf.bat + lib/ps2pdf.cmd + lib/ps2pdf12 + lib/ps2pdf12.bat + lib/ps2pdf12.cmd + lib/ps2pdf13 + lib/ps2pdf13.bat + lib/ps2pdf13.cmd + lib/ps2pdf14 + lib/ps2pdf14.bat + lib/ps2pdf14.cmd + lib/ps2pdfwr + lib/ps2pdfxx.bat + lib/ps2ps + lib/ps2ps.bat + lib/ps2ps.cmd + lib/ps2ps2 + lib/ps2ps2.bat + lib/ps2ps2.cmd + lib/ras1.upp + lib/ras24.upp + lib/ras3.upp + lib/ras32.upp + lib/ras4.upp + lib/ras8m.upp + lib/rinkj-2200-setup + lib/st640ih.upp + lib/st640ihg.upp + lib/st640p.upp + lib/st640pg.upp + lib/st640pl.upp + lib/st640plg.upp + lib/stc.upp + lib/stc1520h.upp + lib/stc2.upp + lib/stc200_h.upp + lib/stc2_h.upp + lib/stc2s_h.upp + lib/stc300.upp + lib/stc300bl.upp + lib/stc300bm.upp + lib/stc500p.upp + lib/stc500ph.upp + lib/stc600ih.upp + lib/stc600p.upp + lib/stc600pl.upp + lib/stc640p.upp + lib/stc800ih.upp + lib/stc800p.upp + lib/stc800pl.upp + lib/stc_h.upp + lib/stc_l.upp + lib/stcany.upp + lib/stcany_h.upp + lib/unix-lpr.sh + lib/wmakebat.bat + man/de/dvipdf.1 + man/de/font2c.1 + man/de/gsnd.1 + man/de/pdf2dsc.1 + man/de/pdf2ps.1 + man/de/printafm.1 + man/de/ps2ascii.1 + man/de/ps2pdf.1 + man/de/ps2ps.1 + man/de/wftopfa.1 + man/dvipdf.1 + man/eps2eps.1 + man/font2c.1 + man/gs.1 + man/gslp.1 + man/gsnd.1 + man/pdf2dsc.1 + man/pdf2ps.1 + man/pf2afm.1 + man/pfbtopfa.1 + man/printafm.1 + man/ps2ascii.1 + man/ps2epsi.1 + man/ps2pdf.1 + man/ps2pdfwr.1 + man/ps2ps.1 + man/wftopfa.1 + pcl/NEWS + pcl/README.txt + pcl/examples/label.tst + pcl/pcl/Anomalies.txt + pcl/pl/gpcl6dll32.def + pcl/pl/gpcl6dll64.def + pcl/pl/gpdldll32.def + pcl/pl/gpdldll64.def + pcl/pl/gxpsdll32.def + pcl/pl/gxpsdll64.def + pcl/pxl/pxasm.bat + pcl/tools/cat_url.py + pcl/tools/check_deps.py + pcl/tools/docov.pl + pcl/tools/gl2_chars.pl + pcl/tools/make_snapshot.sh + pcl/tools/makeromttf.py + pcl/tools/pcl2pdf + pcl/tools/pcl2pdf.bat + pcl/tools/pcl2pdfwr + pcl/tools/pcl2pdfwr.bat + pcl/tools/plot2pdf.sh + pcl/tools/regress.sh + pcl/tools/revlist.py + pcl/tools/smoke_baseline.txt + pcl/tools/smoke_check.sh + pcl/tools/smoke_update.sh + pcl/tools/tt2pcl.c + psi/apitest.c + psi/dw32c.def + psi/dw64c.def + psi/dwmain32.def + psi/dwmain64.def + psi/dwsetup.def + psi/dwsetup_x64.manifest + psi/dwsetup_x86.manifest + psi/dwuninst.def + psi/dwuninst_x64.manifest + psi/dwuninst_x86.manifest + psi/gsdll2.def + psi/gsdll32.def + psi/gsdll32metro.def + psi/gsdll32w.lnk + psi/gsdll64.def + psi/gsdll64metro.def + psi/gsdllARM32metro.def + psi/gsos2.def + psi/gsos2.icx + toolbin/apitest.pl + toolbin/bmpcmp.c + toolbin/bugsByEngineer.pl + toolbin/checkdeps.pl + toolbin/color/icc_creator/ICC_Creator.sln + toolbin/color/icc_creator/ICC_Creator/ICC_Creator.vcxproj + toolbin/color/icc_creator/ICC_Creator/ICC_Creator.vcxproj.filters + toolbin/color/icc_creator/ICC_Creator/res/ICC_Creator.rc2 + toolbin/color/icc_creator/ICC_Creator/resource.h + toolbin/color/icc_creator/ICC_Creator/stdafx.cpp + toolbin/color/icc_creator/ICC_Creator/stdafx.h + toolbin/color/icc_creator/ICC_Creator/targetver.h + toolbin/color/icc_creator/effects/c_only.txt + toolbin/color/icc_creator/effects/k_only.txt + toolbin/color/icc_creator/effects/m_only.txt + toolbin/color/icc_creator/effects/y_only.txt + toolbin/color/icc_creator/example/README.txt + toolbin/color/icc_creator/example/cielab_values.txt + toolbin/color/icc_creator/example/color_names.txt + toolbin/color/icc_creator/example/duotone.pdf + toolbin/color/icc_creator/example/tritone.pdf + toolbin/color/icc_creator/example/tritone_cielab.txt + toolbin/color/icc_creator/example/tritone_names.txt + toolbin/color/icc_creator/ucr_bg_max_k.txt + toolbin/color/icc_creator/ucr_bg_no_k.txt + toolbin/color/named_color/named_color_table.txt + toolbin/color/named_color/named_colors.pdf + toolbin/color/src_color/objsrc_profiles_example.txt + toolbin/drawafm.ps + toolbin/gitsetup.sh + toolbin/gsmake + toolbin/halftone/ETS/ei03.pdf + toolbin/halftone/ETS/ets.c + toolbin/halftone/ETS/ets.h + toolbin/halftone/ETS/ipview.html + toolbin/halftone/ETS/test_ets.c + toolbin/halftone/ETS/tm.h + toolbin/halftone/ETS/win32/ETS.sln + toolbin/halftone/ETS/win32/ETS.vcproj + toolbin/halftone/README + toolbin/halftone/gen_ordered/Makefile + toolbin/halftone/gen_ordered/gen_ordered.sln + toolbin/halftone/gen_ordered/gen_ordered.vcproj + toolbin/halftone/gen_ordered/gen_ordered_example.ps + toolbin/halftone/gen_stochastic/README + toolbin/halftone/gen_stochastic/gen_stochastic.sln + toolbin/halftone/gen_stochastic/gen_stochastic.vcproj + toolbin/halftone/thresh_remap/README + toolbin/halftone/thresh_remap/thresh_remap.sln + toolbin/halftone/thresh_remap/thresh_remap.vcproj + toolbin/htmldiff.pl + toolbin/localcluster/clusterpush.pl + toolbin/localcluster/clusterpush.txt + toolbin/localcluster/gitpush.sh + toolbin/localcluster/readme + toolbin/performance.pl + toolbin/pre.chk + toolbin/pscet_status.pl + toolbin/search-svn-revs + toolbin/search/README + toolbin/squeeze2html.pl + toolbin/tests/README + toolbin/tests/collate.py + toolbin/tests/find_unique_file.py + toolbin/tests/gsvalidate.py + toolbin/tests/main.py + toolbin/tests/regen_baseline.py + toolbin/tests/regen_filelist.py + toolbin/tests/run_nightly + toolbin/tests/run_series.py + toolbin/tests/testing.cfg.example + toolbin/tests/updatelist.py + toolbin/tests/updatelistpdf.py + toolbin/tests/validate.py + toolbin/vg_bugs.supp + toolbin/vg_okay.supp + windows/All.vcproj + windows/GhostPDL.sln + windows/Ghostscript-winrt.sln + windows/ghostpcl.vcproj + windows/ghostpdl.vcproj + windows/ghostscript-ufst.vcproj + windows/ghostscript.vcproj + windows/ghostscript_rt.vcxproj + windows/ghostxps.vcproj + xps/TODO + xps/tools/xps2tiff/README + xps/tools/xps2tiff/xps2tiff.sln + xps/tools/xps2tiff/xps2tiff/stdafx.cpp + xps/tools/xps2tiff/xps2tiff/stdafx.h + xps/tools/xps2tiff/xps2tiff/xps2tiff.cpp + xps/tools/xps2tiff/xps2tiff/xps2tiff.vcproj +Copyright: NONE +License: UNKNOWN + FIXME + +Files: Resource/CMap/78-EUC-H + Resource/CMap/78-EUC-V + Resource/CMap/78-H + Resource/CMap/78-RKSJ-H + Resource/CMap/78-RKSJ-V + Resource/CMap/78-V + Resource/CMap/78ms-RKSJ-H + Resource/CMap/78ms-RKSJ-V + Resource/CMap/83pv-RKSJ-H + Resource/CMap/90ms-RKSJ-H + Resource/CMap/90ms-RKSJ-V + Resource/CMap/90msp-RKSJ-H + Resource/CMap/90msp-RKSJ-V + Resource/CMap/90pv-RKSJ-H + Resource/CMap/90pv-RKSJ-V + Resource/CMap/Add-H + Resource/CMap/Add-RKSJ-H + Resource/CMap/Add-RKSJ-V + Resource/CMap/Add-V + Resource/CMap/Adobe-CNS1-0 + Resource/CMap/Adobe-CNS1-1 + Resource/CMap/Adobe-CNS1-2 + Resource/CMap/Adobe-CNS1-3 + Resource/CMap/Adobe-CNS1-4 + Resource/CMap/Adobe-CNS1-5 + Resource/CMap/Adobe-CNS1-6 + Resource/CMap/Adobe-GB1-0 + Resource/CMap/Adobe-GB1-1 + Resource/CMap/Adobe-GB1-2 + Resource/CMap/Adobe-GB1-3 + Resource/CMap/Adobe-GB1-4 + Resource/CMap/Adobe-GB1-5 + Resource/CMap/Adobe-Japan1-0 + Resource/CMap/Adobe-Japan1-1 + Resource/CMap/Adobe-Japan1-2 + Resource/CMap/Adobe-Japan1-3 + Resource/CMap/Adobe-Japan1-4 + Resource/CMap/Adobe-Japan1-5 + Resource/CMap/Adobe-Japan1-6 + Resource/CMap/Adobe-Korea1-0 + Resource/CMap/Adobe-Korea1-1 + Resource/CMap/Adobe-Korea1-2 + Resource/CMap/B5-H + Resource/CMap/B5-V + Resource/CMap/B5pc-H + Resource/CMap/B5pc-V + Resource/CMap/CNS-EUC-H + Resource/CMap/CNS-EUC-V + Resource/CMap/CNS1-H + Resource/CMap/CNS1-V + Resource/CMap/CNS2-H + Resource/CMap/CNS2-V + Resource/CMap/ETHK-B5-H + Resource/CMap/ETHK-B5-V + Resource/CMap/ETen-B5-H + Resource/CMap/ETen-B5-V + Resource/CMap/ETenms-B5-H + Resource/CMap/ETenms-B5-V + Resource/CMap/EUC-H + Resource/CMap/EUC-V + Resource/CMap/Ext-H + Resource/CMap/Ext-RKSJ-H + Resource/CMap/Ext-RKSJ-V + Resource/CMap/Ext-V + Resource/CMap/GB-EUC-H + Resource/CMap/GB-EUC-V + Resource/CMap/GB-H + Resource/CMap/GB-V + Resource/CMap/GBK-EUC-H + Resource/CMap/GBK-EUC-V + Resource/CMap/GBK2K-H + Resource/CMap/GBK2K-V + Resource/CMap/GBKp-EUC-H + Resource/CMap/GBKp-EUC-V + Resource/CMap/GBT-EUC-H + Resource/CMap/GBT-EUC-V + Resource/CMap/GBT-H + Resource/CMap/GBT-V + Resource/CMap/GBTpc-EUC-H + Resource/CMap/GBTpc-EUC-V + Resource/CMap/GBpc-EUC-H + Resource/CMap/GBpc-EUC-V + Resource/CMap/H + Resource/CMap/HKdla-B5-H + Resource/CMap/HKdla-B5-V + Resource/CMap/HKdlb-B5-H + Resource/CMap/HKdlb-B5-V + Resource/CMap/HKgccs-B5-H + Resource/CMap/HKgccs-B5-V + Resource/CMap/HKm314-B5-H + Resource/CMap/HKm314-B5-V + Resource/CMap/HKm471-B5-H + Resource/CMap/HKm471-B5-V + Resource/CMap/HKscs-B5-H + Resource/CMap/HKscs-B5-V + Resource/CMap/Hankaku + Resource/CMap/Hiragana + Resource/CMap/Identity-H + Resource/CMap/Identity-V + Resource/CMap/KSC-EUC-H + Resource/CMap/KSC-EUC-V + Resource/CMap/KSC-H + Resource/CMap/KSC-Johab-H + Resource/CMap/KSC-Johab-V + Resource/CMap/KSC-V + Resource/CMap/KSCms-UHC-H + Resource/CMap/KSCms-UHC-HW-H + Resource/CMap/KSCms-UHC-HW-V + Resource/CMap/KSCms-UHC-V + Resource/CMap/KSCpc-EUC-H + Resource/CMap/KSCpc-EUC-V + Resource/CMap/Katakana + Resource/CMap/NWP-H + Resource/CMap/NWP-V + Resource/CMap/RKSJ-H + Resource/CMap/RKSJ-V + Resource/CMap/Roman + Resource/CMap/UniCNS-UCS2-H + Resource/CMap/UniCNS-UCS2-V + Resource/CMap/UniCNS-UTF16-V + Resource/CMap/UniCNS-UTF32-V + Resource/CMap/UniCNS-UTF8-V + Resource/CMap/UniGB-UCS2-H + Resource/CMap/UniGB-UCS2-V + Resource/CMap/UniGB-UTF16-V + Resource/CMap/UniGB-UTF32-V + Resource/CMap/UniGB-UTF8-V + Resource/CMap/UniHojo-UCS2-H + Resource/CMap/UniJIS-UCS2-H + Resource/CMap/UniJIS-UCS2-HW-H + Resource/CMap/UniJIS-UCS2-HW-V + Resource/CMap/UniJIS-UCS2-V + Resource/CMap/UniJIS-UTF16-V + Resource/CMap/UniJIS-UTF32-V + Resource/CMap/UniJIS-UTF8-V + Resource/CMap/UniJIS2004-UTF16-V + Resource/CMap/UniJIS2004-UTF32-V + Resource/CMap/UniJIS2004-UTF8-V + Resource/CMap/UniJISPro-UCS2-HW-V + Resource/CMap/UniJISPro-UCS2-V + Resource/CMap/UniJISPro-UTF8-V + Resource/CMap/UniJISX0213-UTF32-V + Resource/CMap/UniJISX02132004-UTF32-V + Resource/CMap/UniKS-UCS2-H + Resource/CMap/UniKS-UCS2-V + Resource/CMap/UniKS-UTF16-V + Resource/CMap/UniKS-UTF32-V + Resource/CMap/UniKS-UTF8-V + Resource/CMap/V + Resource/CMap/WP-Symbol +Copyright: %%Copyright: Neither the name of Adobe Systems Incorporated nor the names / + %%Copyright: Redistribution and use in source and binary forms, with or + %%Copyright: Redistributions in binary form must reproduce the above + %%Copyright: Redistributions of source code must retain the above + %%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + Copyright 1990-2009 Adobe Systems Incorporated. + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + disclaimer. + following conditions are met: + of its contributors may be used to endorse or promote + products derived from this software without specific prior + provided with the distribution. + without modification, are permitted provided that the + written permission. +License: UNKNOWN + FIXME + +Files: contrib/pcl3/BUGS + contrib/pcl3/doc/gs-mods.txt + contrib/pcl3/doc/how-to-report.txt + contrib/pcl3/doc/notes.tex + contrib/pcl3/doc/reports.txt + contrib/pcl3/eprn/eprnfs.c + contrib/pcl3/eprn/eprnparm.c + contrib/pcl3/eprn/gdeveprn.c + contrib/pcl3/eprn/gdeveprn.h + contrib/pcl3/eprn/mediasize.c + contrib/pcl3/eprn/mediasize.h + contrib/pcl3/eprn/pagecount.c + contrib/pcl3/eprn/pagecount.h + contrib/pcl3/lib/cups-pcl3 + contrib/pcl3/lib/example.mcf + contrib/pcl3/lib/if-pcl3 + contrib/pcl3/ppd/README + contrib/pcl3/ppd/catppd + contrib/pcl3/ppd/fonts.ppd + contrib/pcl3/ppd/gs-5.50.ppd + contrib/pcl3/ppd/gs-6.01.ppd + contrib/pcl3/ppd/gs-6.50.ppd + contrib/pcl3/ppd/gs-6.51.ppd + contrib/pcl3/ppd/gs-7.00.ppd + contrib/pcl3/ppd/gs-common.ppd + contrib/pcl3/ppd/gs-pcl3-common.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj1120c.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj3xx.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj400.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj500.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj500c.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj510.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj540.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj550c.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj600.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj660c.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj680c.ppd + contrib/pcl3/ppd/gs-pcl3-hpdj8xxc.ppd + contrib/pcl3/ppd/gs-pcl3-hpdjportable.ppd + contrib/pcl3/ppd/gs-pcl3-unspec.ppd + contrib/pcl3/ppd/gs-pcl3-unspecold.ppd + contrib/pcl3/src/gdevpcl3.c + contrib/pcl3/src/pcl3opts-de.msg + contrib/pcl3/src/pcl3opts-en.msg + contrib/pcl3/src/pcl3opts.c + contrib/pcl3/src/pclcap.c + contrib/pcl3/src/pclcap.h + contrib/pcl3/src/pclcomp.c + contrib/pcl3/src/pclgen.c + contrib/pcl3/src/pclgen.h + contrib/pcl3/src/pclscan.c + contrib/pcl3/src/pclscan.h + contrib/pcl3/src/pclsize.c + contrib/pcl3/src/pclsize.h +Copyright: 1996-1998, 2000, Martin Lottermoser + 1997-1998, 2000, Martin Lottermoser + 1997-2001, Martin Lottermoser + 1998, 2000-2001, Martin Lottermoser + 1999-2000, Martin Lottermoser + 1999-2001, Martin Lottermoser + 2000, Martin Lottermoser + 2000-2001, Martin Lottermoser + 2000-2003, Martin Lottermoser + 2001, Martin Lottermoser +License: UNKNOWN + FIXME + +Files: iccprofiles/gray_to_k.icc + iccprofiles/ps_cmyk.icc + iccprofiles/ps_gray.icc + iccprofiles/ps_rgb.icc + toolbin/color/icc_creator/ICC Profiles/cmyk_k_ouput_only.icc + toolbin/color/icc_creator/ICC Profiles/ps_emulate_cmyk.icc + toolbin/color/icc_creator/ICC Profiles/ps_emulate_gray.icc + toolbin/color/icc_creator/ICC Profiles/ps_emulate_rgb.icc + toolbin/color/icc_creator/effects/black_output.icc + toolbin/color/icc_creator/effects/cyan_output.icc + toolbin/color/icc_creator/effects/magenta_output.icc + toolbin/color/icc_creator/effects/yellow_output.icc + toolbin/color/icc_creator/max_k.icc + toolbin/color/icc_creator/no_k.icc + toolbin/color/src_color/cmyk_des_renderintent.icc + toolbin/color/src_color/cmyk_src_cyan.icc + toolbin/color/src_color/cmyk_src_magenta.icc + toolbin/color/src_color/cmyk_src_renderintent.icc + toolbin/color/src_color/cmyk_src_yellow.icc + toolbin/color/src_color/rgb_source_blue.icc + toolbin/color/src_color/rgb_source_green.icc + toolbin/color/src_color/rgb_source_red.icc +Copyright: Copyright Artifex Software 2010 +License: UNKNOWN + FIXME + +Files: Resource/CMap/UniCNS-UTF16-H + Resource/CMap/UniCNS-UTF32-H + Resource/CMap/UniCNS-UTF8-H + Resource/CMap/UniGB-UTF16-H + Resource/CMap/UniGB-UTF32-H + Resource/CMap/UniGB-UTF8-H + Resource/CMap/UniJIS-UTF16-H + Resource/CMap/UniJIS-UTF32-H + Resource/CMap/UniJIS-UTF8-H + Resource/CMap/UniJIS2004-UTF16-H + Resource/CMap/UniJIS2004-UTF32-H + Resource/CMap/UniJIS2004-UTF8-H + Resource/CMap/UniJISX0213-UTF32-H + Resource/CMap/UniJISX02132004-UTF32-H + Resource/CMap/UniKS-UTF16-H + Resource/CMap/UniKS-UTF32-H + Resource/CMap/UniKS-UTF8-H +Copyright: %%Copyright: Neither the name of Adobe Systems Incorporated nor the names / + %%Copyright: Redistribution and use in source and binary forms, with or + %%Copyright: Redistributions in binary form must reproduce the above + %%Copyright: Redistributions of source code must retain the above + %%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + Copyright 1990-2010 Adobe Systems Incorporated. + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + disclaimer. + following conditions are met: + of its contributors may be used to endorse or promote + products derived from this software without specific prior + provided with the distribution. + without modification, are permitted provided that the + written permission. +License: UNKNOWN + FIXME + +Files: contrib/gdevlx7.c + contrib/gdevmd2k.c + contrib/japanese/dmp_init.ps + contrib/japanese/dviprlib.h + contrib/japanese/gdev10v.c + contrib/japanese/gdevalps.c + contrib/japanese/gdevdmpr.c + contrib/japanese/gdevfmlbp.c + contrib/japanese/gdevfmpr.c + contrib/japanese/gdevj100.c + contrib/japanese/gdevml6.c + contrib/japanese/gdevnpdl.c + contrib/japanese/gdevp201.c + examples/waterfal.ps +Copyright: 1989, 1992-1993, Aladdin Enterprises. + 1989-1994, 1998-1999, Aladdin Enterprises. + 1990, 1992, Aladdin Enterprises. + 1990, 1992-1993, Aladdin Enterprises. + 1990, 1995, 1997, Aladdin Enterprises. + 1991, 1995-1999, Aladdin Enterprises. + 1991, Aladdin Enterprises. + 1992-1993, 1996, Aladdin Enterprises. +License: UNKNOWN + FIXME + +Files: base/ttcalc.c + base/ttcalc.h + base/ttconfig.h + base/ttload.c + base/ttload.h + base/ttobjs.c + base/ttobjs.h + base/tttables.h + base/tttype.h + base/tttypes.h +Copyright: 1996-1998, David Turner, Robert Wilhelm, and Werner Lemberg. + 2001-2012, Artifex Software, Inc. +License: FTL + FIXME + +Files: examples/cjk/all_ac1.ps + examples/cjk/all_ag1.ps + examples/cjk/all_aj1.ps + examples/cjk/all_aj2.ps + examples/cjk/all_ak1.ps + examples/cjk/gscjk_ac.ps + examples/cjk/gscjk_ag.ps + examples/cjk/gscjk_ak.ps +Copyright: (C) 2001 Taiji Yamada and gs-cjk project +License: AGPL + FIXME + +Files: contrib/japanese/gdevespg.c + contrib/japanese/gdevrpdl.c + contrib/lips4/gdevl4r.c + contrib/lips4/gdevlips.c + contrib/lips4/gdevlips.h + contrib/lips4/gdevlprn.c + contrib/lips4/gdevlprn.h +Copyright: 1998-1999, Norihito Ohmori. + 1999, Norihito Ohmori. + 1999-2000, Norihito Ohmori. +License: UNKNOWN + FIXME + +Files: contrib/pcl3/ps/margins-A4.ps + contrib/pcl3/ps/margins-A4Rotated.ps + contrib/pcl3/ps/margins-Env10Rotated.ps + contrib/pcl3/ps/margins-EnvDLRotated.ps + contrib/pcl3/ps/margins-Letter.ps + contrib/pcl3/ps/margins-LetterRotated.ps +Copyright: Copyright (C) 1997, 1998, 1999, 2000 by Martin Lottermoser. +License: UNKNOWN + FIXME + +Files: contrib/pcl3/doc/gs-pcl3.html + contrib/pcl3/doc/gs-pcl3.ref + contrib/pcl3/doc/pcl3opts.1 + contrib/pcl3/doc/pcl3opts.html + contrib/pcl3/doc/pcl3opts.ref +Copyright: 2000-2001, Martin Lottermoser, +License: UNKNOWN + FIXME + +Files: iccprofiles/default_cmyk.icc + iccprofiles/default_gray.icc + iccprofiles/default_rgb.icc + iccprofiles/sgray.icc + iccprofiles/srgb.icc +Copyright: Copyright Artifex Software 2011 +License: UNKNOWN + FIXME + +Files: base/claptrap-init.c + base/claptrap-planar.c + base/claptrap.c + base/claptrap.h +Copyright: 2015, -16 Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: doc/GS9_Color_Management.tex + pcl/tools/pxlasm.py + pcl/tools/pxldis.py + toolbin/halftone/thresh_remap/thresh_remap.c +Copyright: 2001, Artifex Software Inc. + 2009, Artifex Software Inc. + 2017, Artifex Software Inc. +License: UNKNOWN + FIXME + +Files: contrib/gdevbjc_.c + contrib/gdevbjc_.h + contrib/gdevbjca.c +Copyright: 1989, 2000, Aladdin Enterprises. + 2000-2002, Gergely Szász (Gergely Sza'sz) +License: Aladdin and/or GPL-2 + FIXME + +Files: base/ttcommon.h + base/ttinterp.c + base/ttinterp.h +Copyright: 1996-1998, David Turner, Robert Wilhelm, and Werner Lemberg + 2001-2012, Artifex Software, Inc. +License: FTL + FIXME + +Files: contrib/pscolor/black.ps + contrib/pscolor/color.ps + contrib/pscolor/input.ps +Copyright: (Copyright (c) 1998 Hewlett-Packard Company) put + Copyright 1987-2001 Adobe Systems Incorporated. + Copyright 1987-2001,2003 Adobe Systems Incorporated. + Copyright 1987-2002 Adobe Systems Incorporated. + Copyright 1992-2003 Adobe Systems Incorporated. + Copyright 1993,2001 Adobe Systems Incorporated. + Copyright 1993-2001 Adobe Systems Incorporated. + Copyright 1998-2003 Adobe Systems Incorporated. +License: UNKNOWN + FIXME + +Files: base/gsmd5.c + base/gsmd5.h + base/md5main.c +Copyright: 1999-2012, Artifex Software, Inc. + 2002-2012, Artifex Software, Inc. + ed. +License: Zlib + FIXME + +Files: debian/NEWS + pcl/LICENSE +Copyright: NONE +License: AGPL + FIXME + +Files: lib/Fontmap.ATM + lib/Fontmap.OS2 +Copyright: 2001-2012, Artifex Software, Inc. + URW Software, Copyright 1994 by URW. +License: Aladdin + FIXME + +Files: lib/Fontmap.SGI + lib/Fontmap.Sol +Copyright: 1989, Adobe Systems Incorporated + 1989-1992, Bitstream Inc., Cambridge, MA. + 1992, URW GmbH, Hamburg, Germany + 1993, + 2001-2012, Artifex Software, Inc. + URW Software, Copyright 1994 by URW. + and are of unknown quality. + ed fonts were developed by Kevin Hartig. Permission is +License: Aladdin and/or GPL-2+ + FIXME + +Files: base/sha2.c + base/sha2.h +Copyright: 2000-2001, Aaron D. Gifford +License: BSD-3-clause + FIXME + +Files: base/aes.c + base/aes.h +Copyright: 2006-2007, Christophe Devine +License: BSD-3-clause + FIXME + +Files: contrib/opvp/opvp_0_2_0.h + contrib/opvp/opvp_common.h +Copyright: 2003-2004, AXE, Inc. +License: Expat + FIXME + +Files: lib/Fontmap.URW-136.T1 + lib/Fontmap.URW-136.TT +Copyright: 1989, Adobe Systems Incorporated + 1989-1992, Bitstream Inc., Cambridge, MA. + 1992, URW GmbH, Hamburg, Germany + 1993, Kevin Hartig (kevin.hartig@gmail.com), + 2001-2012, Artifex Software, Inc. + and are of unknown quality. +License: GPL-2+ and/or OFL-1.1 + FIXME + +Files: pcl/pxl/pxbfont.ps + pcl/pxl/pxsymbol.ps +Copyright: 2001-2012, Artifex Software, Inc. + 2012, Artifex Software Inc. +License: UNKNOWN + FIXME + +Files: Resource/Decoding/FCO_Unicode + Resource/Decoding/Unicode +Copyright: 16#2118 weierstrass Pscript + 2001-2012, Artifex Software, Inc. + LE120000 + sans + serif +License: UNKNOWN + FIXME + +Files: Resource/Decoding/FCO_Symbol + Resource/Init/gs_sym_e.ps +Copyright: 2001-2012, Artifex Software, Inc. + sans + serif +License: UNKNOWN + FIXME + +Files: contrib/gdevln03.c + contrib/gdevxes.c +Copyright: 1991-1993, Free Software Foundation, Inc. + 1991-1994, Free Software Foundation, Inc. +License: UNKNOWN + FIXME + +Files: doc/pclxps/ghostpdl.tex + doc/pclxps/ghostpdl.txt +Copyright: 1999, Hewlett-Packard Company. +License: UNKNOWN + FIXME + +Files: base/icc34.h + toolbin/color/icc_creator/ICC_Creator/icc34.h +Copyright: 1994-1996, SunSoft, Inc. + Tag = 0x63707274L, 'cprt' +License: UNKNOWN + FIXME + +Files: examples/cjk/iso2022.ps + examples/cjk/iso2022v.ps +Copyright: 2001, Taiji Yamada and gs-cjk project +License: UNKNOWN + FIXME + +Files: lib/cbjc600.ppd + lib/cbjc800.ppd +Copyright: 1995, Yves Arrouye for AFPL Ghostscript with Level 2 PS. +License: UNKNOWN + FIXME + +Files: contrib/pcl3/ps/calign.ps + contrib/pcl3/ps/levels-test.ps +Copyright: Copyright (C) 2000 by Martin Lottermoser. +License: UNKNOWN + FIXME + +Files: toolbin/color/icc_creator/example/artifex_blue_purple.icc + toolbin/color/icc_creator/example/artifex_tritone.icc +Copyright: Copyright Artifex Software 2009 +License: UNKNOWN + FIXME + +Files: examples/cjk/gscjk_aj.ps +Copyright: (C) 2001 Taiji Yamada and gs-cjk project + ‘Ì) show +License: AGPL + FIXME + +Files: doc/COPYING +Copyright: -like laws that apply to other kinds of + 2007, Free Software Foundation, Inc. + + able work licensed under this + are not + disclaimer" for the program, if necessary. + ed material outside their relationship with you. + if you do + permission, other than the making of an + permission. + treaty adopted on 20 December 1996, or +License: AGPL-3 + FIXME + +Files: LICENSE +Copyright: Adobe Systems Incorporated and covered by a separate, Affero GPL +License: AGPL-3+ + FIXME + +Files: pcl/COPYING.AFPL +Copyright: 1994-1995, 1997-2000, Aladdin Enterprises, + Act of 1976, + You must meet all of the following conditions with respect to any work + ed +License: Aladdin + FIXME + +Files: lib/Fontmap.VMS +Copyright: 1989, Adobe Systems Incorporated + 1989-1992, Bitstream Inc., Cambridge, MA. + 1992, URW GmbH, Hamburg, Germany + 1993, + 2001-2012, Artifex Software, Inc. + IBM Corporation 1990, 1991 + URW Software, Copyright 1994 by URW. + and are of unknown quality. + ed fonts were developed by Kevin Hartig. Permission is +License: Aladdin and/or GPL-2+ + FIXME + +Files: contrib/gdevdj9.c +Copyright: 1999, Aladdin Enterprises. + 2000, +License: Aladdin and/or GPL-2+ + FIXME + +Files: contrib/gdevcd8.c +Copyright: 1996-1998, . + 1999, Aladdin Enterprises. + 2000, Hewlett-Packard Company +License: Aladdin and/or GPL-2+ + FIXME + +Files: lib/afmdiff.awk +Copyright: 2000, Nelson H. F. Beebe ## +License: Aladdin and/or GPL-2+ + FIXME + +Files: Resource/Init/Fontmap.GS +Copyright: 1989, Adobe Systems Incorporated + 1989-1992, Bitstream Inc., Cambridge, MA. + 1992, URW GmbH, Hamburg, Germany + 1993, Kevin Hartig (kevin.hartig@gmail.com), + 2001-2012, Artifex Software, Inc. + URW Software, Copyright 1994 by URW. + and are of unknown quality. +License: Aladdin and/or GPL-2+ and/or OFL-1.1 + FIXME + +Files: base/gssprintf.c +Copyright: (C) Caldera International Inc. +License: Apache-2.0 + FIXME + +Files: DroidSansFallback.NOTICE +Copyright: 2005-2008, The Android Open Source Project + License. Subject to the terms and conditions of + You must retain, in the Source form of any Derivative Works + license to reproduce, prepare Derivative Works of, + patent, trademark, and +License: Apache-2.0 + FIXME + +Files: Resource/CIDFSubst/DroidSansFallback.ttf +Copyright: Digitized data copyright Google Corporation © 2006 +License: Apache-2.0 + FIXME + +Files: base/gsstrtok.c +Copyright: NONE +License: Apache-2.0 + FIXME + +Files: psi/dmmain.r +Copyright: 2001-2012, Artifex Software, Inc. +License: CC0 + FIXME + +Files: lib/ht_ccsto.ps +Copyright: NONE +License: CC0-4 + FIXME + +Files: configure +Copyright: 1992-1996, 1998-2012, Free Software Foundation, Inc. + 2012, Free Software Foundation, Inc. +License: FSFUL + FIXME + +Files: contrib/lxm3200-tweaked/RELEASE_NOTES +Copyright: 2000, Daniele Gordini (dgordin@tin.it) +License: GPL + FIXME + +Files: cups/gdevcups.c +Copyright: 1993-2006, Easy Software Products. +License: GPL + FIXME + +Files: contrib/japanese/doc/cdj880.txt +Copyright: 1999, +License: GPL-2+ + FIXME + +Files: contrib/japanese/doc/gdevcd8.txt +Copyright: 1996-1998, +License: GPL-2+ + FIXME + +Files: contrib/opvp/gdevopvp.c +Copyright: 2003-2004, AXE, Inc. +License: GPL-2+ + FIXME + +Files: cups/cups.mak +Copyright: 2001-2005, Easy Software Products. + 2007, Artifex Software, Inc. +License: GPL-2+ + FIXME + +Files: contrib/gdevlx32.c +Copyright: 2000, Daniel Gordini (dgordin@tin.it) +License: GPL-2+ + FIXME + +Files: contrib/chp2200/COPYING +Copyright: 1989, 1991, Free Software Foundation, Inc. + + disclaimer" for the program, if + ed by the Free + ed interfaces, the + interest in the program + the software, and + year name of author +License: GPL-2+ + FIXME + +Files: contrib/contrib.mak +Copyright: NONE +License: GPL-2+ + FIXME + +Files: debian/rules +Copyright: -check + -check = + 2004-2009, Masayuki Hatta (mhatta) + 2009-2017, Jonas Smedegaard +License: GPL-3+ + FIXME + +Files: debian/copyright-check +Copyright: 2016-2017, Jonas Smedegaard + check +License: GPL-3+ + FIXME + +Files: base/gsstrl.c +Copyright: 1998, Todd C. Miller +License: ISC + FIXME + +Files: contrib/pcl3/NEWS +Copyright: 1997-2001, Martin Lottermoser +License: LGPL + FIXME + +Files: contrib/pcl3/README +Copyright: 1997-2001, Martin Lottermoser +License: LGPL-2.1 + FIXME + +Files: contrib/pcl3/LGPL +Copyright: 1991, 1999, Free Software Foundation, Inc. + + disclaimer" for the library, if + ed by the Free Software Foundation, write to the Free + ed interfaces, the + interest in the + the +License: LGPL-2.1+ + FIXME + +Files: devices/gdev4693.c +Copyright: 1992, Washington State University. +License: NTP + FIXME + +Files: pcl/pcl/pcfont.h +Copyright: +License: UNKNOWN + FIXME + +Files: toolbin/color/icc_creator/ICC_Creator/ICC_Creator.rc +Copyright: 2009 + Artifex Software Incorporated. +License: UNKNOWN + FIXME + +Files: toolbin/gen_ldf_jb2.py +Copyright: %d Artifex Software, Inc. + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: lib/pdf2dsc.ps +Copyright: (CC) (CCC) (CD) (D) (DC) (DCC) (DCCC) (CM) + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: contrib/pcl3/doc/gs-pcl3.1 +Copyright: (co 2000, 2001 by Martin Lottermoser, +License: UNKNOWN + FIXME + +Files: devices/vector/gdevpdfk.c +Copyright: (useless, but required by icclib) + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: contrib/japanese/dviprlib.c +Copyright: *pinfo->pcodebuf++ = CFG_OP_OR; + 1990, 1992, Aladdin Enterprises. +License: UNKNOWN + FIXME + +Files: lib/ps2ai.ps +Copyright: 1993, -94 Jason Olszewskin) jp + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: contrib/opvp/opvp.h +Copyright: 2003-2006, AXE Inc. + 2006, Canon Inc. + 2006, Free Standards Group + 2006, Fuji Xerox Printing Systems Co., Ltd. +License: UNKNOWN + FIXME + +Files: lib/prfont.ps +Copyright: 1986, Eric Gisin + 1992, Aladdin Enterprises, Menlo Park, CA + 1993, Aladdin Enterprises, Menlo Park, CA + 1994, Aladdin Enterprises, Menlo Park, CA + 1995, Aladdin Enterprises, Menlo Park, CA + 1996, Aladdin Enterprises, Menlo Park, CA + 1999, Aladdin Enterprises, Menlo Park, CA + 2000, Aladdin Enterprises, Menlo Park, CA + 2001-2012, Artifex Software, Inc. + transferred 2000/09/15 to Artifex Software, Inc. Send any questions to +License: UNKNOWN + FIXME + +Files: base/bench.c +Copyright: 1995, Aladdin Enterprises, Menlo Park, CA. + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: contrib/japanese/gdevmjc.c +Copyright: 1991-1993, Aladdin Enterprises. + 24 -> 32 bit (1-stage) +License: UNKNOWN + FIXME + +Files: base/ttfsfnt.h +Copyright: 1991, Apple Computer, Inc. + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: base/gspmdrv.rc +Copyright: 1992-1993, 2001-2012, Artifex Software Inc.", -1, 34, 48, 210, 8 + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: toolbin/encs2c.ps +Copyright: 2001-2006, Artifex Software, Inc.) = + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: devices/gdevijs.c +Copyright: 2001-2012, Artifex Software, Inc. + 2003-2004, Copyright Hewlett-Packard Development Company, LP +License: UNKNOWN + FIXME + +Files: Resource/Init/pdf_sec.ps +Copyright: 1996-1998, Geoffrey Keating. + 2001-2008, Artifex Software, Inc. + 2001-2012, Artifex Software, Inc. +License: UNKNOWN + FIXME + +Files: devices/gdevicov.c +Copyright: 2001-2012, Artifex Software, Inc. + 2011, Sebastian Kapfer +License: UNKNOWN + FIXME + +Files: psi/zfont2.c +Copyright: 1, k_fontinfodict | k_sid); + 12 0 SID -, FontInfo + 2001-2012, Artifex Software, Inc. + isFixedPitch, +License: UNKNOWN + FIXME + +Files: base/gscedata.c +Copyright: 117, N(10,180): exclamdown + 161, N(10,180): exclamdown + 163, N(10,180): exclamdown + 193, N(10,180): exclamdown + 2001-2012, Artifex Software, Inc. + 96, N(10,180): exclamdown + N(11,473), ordfeminine + N(6,0), Aacute + N(8,64), currency + N(9,450), trademark + sans + serif +License: UNKNOWN + FIXME + +Files: Resource/Decoding/Latin1 +Copyright: 169 + 2001-2012, Artifex Software, Inc. + sans 169 + serif 169 +License: UNKNOWN + FIXME + +Files: devices/gdevcdj.c +Copyright: 2001-2012, Artifex Software, Inc. + 24 -> 32 bit (1-stage) +License: UNKNOWN + FIXME + +Files: Resource/Init/gs_res.ps +Copyright: 2001-2012, Artifex Software, Inc. + 3 1 roll % (scr) (c) (/) (n) +License: UNKNOWN + FIXME + +Files: base/gsicc_create.c +Copyright: 2001-2012, Artifex Software, Inc. + Artifex Software 2009"; + Tag + Tag; + tag white point RGB colorants and + tag white point and grayTRC +License: UNKNOWN + FIXME + +Files: toolbin/color/icc_creator/ICC_Creator/icc_create.cpp +Copyright: 2001-2012, Artifex Software, Inc. + Artifex Software 2016"; + Tag + Tag; +License: UNKNOWN + FIXME + +Files: devices/gdevpxut.c +Copyright: 2001-2012, Artifex Software, Inc. + Artifex Sofware, Inc. 2005000n"; +License: UNKNOWN + FIXME + +Files: toolbin/headers.tcl +Copyright: 2001-2012, Artifex Software, Inc. + BLOCK ****" + at line $i" + block in: $FInName" + block) by scanning for + or comment block +License: UNKNOWN + FIXME + +Files: base/gstype42.c +Copyright: 2001-2012, Artifex Software, Inc. + FONT_INFO_COPYRIGHT, 0); + informatoin if there is any, +License: UNKNOWN + FIXME + +Files: lib/font2pcl.ps +Copyright: 2001-2012, Artifex Software, Inc. + FontInfo /Notice .knownget not { () } if def + length add write==only + vendor.keys keysearch + writestring % Copyright +License: UNKNOWN + FIXME + +Files: pcl/pl/plvocab.c +Copyright: 2001-2012, Artifex Software, Inc. + Full, Sans + Full, Serif + Sign, Sup u +License: UNKNOWN + FIXME + +Files: devices/gdevbjc.h +Copyright: 2001-2012, Artifex Software, Inc. + Yves Arrouye , 1995, 1996. +License: UNKNOWN + FIXME + +Files: devices/vector/gdevpsu.c +Copyright: 2001-2012, Artifex Software, Inc. + applies to everything between here and the %%EndProlog:", + begin ProcSet +License: UNKNOWN + FIXME + +Files: psi/iminst.h +Copyright: 2001-2012, Artifex Software, Inc. + heap allocator +License: UNKNOWN + FIXME + +Files: devices/vector/gdevpsf1.c +Copyright: 2001-2012, Artifex Software, Inc. + info.members & FONT_INFO_COPYRIGHT); +License: UNKNOWN + FIXME + +Files: base/gsdll.h +Copyright: 2001-2012, Artifex Software, Inc. + long * gs_revision, long * gs_revisiondate); + long * revision, long * revisiondate); +License: UNKNOWN + FIXME + +Files: psi/gsdll.c +Copyright: 2001-2012, Artifex Software, Inc. + long * revision, long * revisiondate) +License: UNKNOWN + FIXME + +Files: base/gdevm40.c +Copyright: 2001-2012, Artifex Software, Inc. + mdev->color40.abcde = (color) + mdev->color40.bcde = bcde = (cdea << 8) | (b), +License: UNKNOWN + FIXME + +Files: base/gdevm48.c +Copyright: 2001-2012, Artifex Software, Inc. + mdev->color48.abcdef = (color) +License: UNKNOWN + FIXME + +Files: base/gdevm56.c +Copyright: 2001-2012, Artifex Software, Inc. + mdev->color56.abcdefg = (color) + mdev->color56.bcde = bcde = (cdef << 8) | (b), +License: UNKNOWN + FIXME + +Files: pcl/pxl/pxdiff.txt +Copyright: 2001-2012, Artifex Software, Inc. + or (D). We are willing to discuss +License: UNKNOWN + FIXME + +Files: pcl/pxl/pxsymbol.psc +Copyright: 2001-2012, Artifex Software, Inc. + pxg_congruent, + pxg_ordfeminine, pxg_guillemotleft, + pxg_trademark, pxg_acute, + sans, + serif, +License: UNKNOWN + FIXME + +Files: base/stdpre.h +Copyright: 2001-2012, Artifex Software, Inc. + requires + supports it but somehow only +License: UNKNOWN + FIXME + +Files: devices/vector/gdevagl.c +Copyright: 2001-2012, Artifex Software, Inc. + sans", 0xF8E9}, + serif", 0xF6D9}, +License: UNKNOWN + FIXME + +Files: psi/iref.h +Copyright: 2001-2012, Artifex Software, Inc. + type of the structure. +License: UNKNOWN + FIXME + +Files: Resource/CMap/Identity-UTF16-H +Copyright: 2003, Artifex Software. +License: UNKNOWN + FIXME + +Files: toolbin/halftone/ETS/README.txt +Copyright: 2000-2010, Artifex Sotware Inc. + 2000-2014, Artifex Sotware Inc. +License: UNKNOWN + FIXME + +Files: Resource/Init/gs_img.ps +Copyright: 2002, Artifex, Inc. +License: UNKNOWN + FIXME + +Files: contrib/japanese/doc/README.gs550j +Copyright: 1996-1999, Daisuke SUZUKI. + 1999, Norihito Ohmori. +License: UNKNOWN + FIXME + +Files: contrib/lxm3200-tweaked/LICENSE +Copyright: 1989, 1991, Free Software Foundation, Inc. + 19yy + 19yy name of author + disclaimer" for the program, if + ed by the Free + ed interfaces, the + interest in the program + the software, and +License: UNKNOWN + FIXME + +Files: lib/ghostpdf.ppd +Copyright: 2004-2006, Ghostgum Software Pty Ltd. +License: UNKNOWN + FIXME + +Files: contrib/gdevop4w.c +Copyright: 1998, Ivan Schreter +License: UNKNOWN + FIXME + +Files: debian/update-gsfontmap +Copyright: 2010, Kenshi Muto +License: UNKNOWN + FIXME + +Files: devices/gdevifno.c +Copyright: 1998, Lucent Technologies. +License: UNKNOWN + FIXME + +Files: contrib/pcl3/eprn/eprnrend.c +Copyright: 2000-2001, Martin Lottermoser + because it gives equal shares to all levels. + multiply by the number of levels and truncate, except for an +License: UNKNOWN + FIXME + +Files: contrib/pcl3/ps/dumppdd.ps +Copyright: 1999-2000, Martin Lottermoser. + Copyright (C) 2000 by Martin Lottermoser. +License: UNKNOWN + FIXME + +Files: contrib/lips4/gdevl4v.c +Copyright: 1998-1999, Norihito Ohmori. + ÌÀ ¥Ó¥Ã¥Èȿž¡¦zero ¿§¤ËÀ÷¤á¤ë +License: UNKNOWN + FIXME + +Files: base/ets.c +Copyright: 2001-2004, Raph Levien +License: UNKNOWN + FIXME + +Files: lib/viewjpeg.ps +Copyright: 1994, Thomas Merz +License: UNKNOWN + FIXME + +Files: debian/libgs9.symbols +Copyright: @Base 8.61.dfsg.1 +License: UNKNOWN + FIXME + +Files: debian/source/lintian-overrides +Copyright: Apache-2.0 + GPL + GPL-2 + GPL-2+ + GPL-3+ + LGPL-2.1+ + apache-2.0 + gpl + gpl-2 + gpl-2+ + gpl-3+ + lgpl-2.1+ +License: UNKNOWN + FIXME + +Files: pcl/examples/null.pxl +Copyright: Artifex Software Inc. 2012 +License: UNKNOWN + FIXME + +Files: xps/tools/xps2tiff/xps2tiff/AssemblyInfo.cpp +Copyright: Attribute("") +License: UNKNOWN + FIXME + +Files: iccprofiles/lab.icc +Copyright: Copyright 2009 Artifex Software Inc +License: UNKNOWN + FIXME + +Files: contrib/gdevhl12.c +Copyright: ED +License: UNKNOWN + FIXME + +Files: contrib/eplaser/gdevescv.h +Copyright: EPSON SOFTWARE DEVELOPMENT LABORATORY, INC. 1999,2000. + SEIKO EPSON CORPORATION 2000-2006,2009. +License: UNKNOWN + FIXME + +Files: contrib/eplaser/gdevescv.c +Copyright: EPSON SOFTWARE DEVELOPMENT LABORATORY, INC. 1999,2000. + SEIKO EPSON CORPORATION 2000-2006,2009. + ÌÀ ¥Ó¥Ã¥Èȿž¡¦zero ¿§¤ËÀ÷¤á¤ë +License: UNKNOWN + FIXME + +Files: lib/printafm.ps +Copyright: ed; you can do with it exactly as you please. +License: UNKNOWN + FIXME + +Files: Resource/Init/gs_agl.ps +Copyright: serif +License: UNKNOWN + FIXME + +Files: lib/pf2afm.ps +Copyright: skipw-p % PFM: Type +License: UNKNOWN + FIXME + +Files: contrib/japanese/doc/gdevmjc.txt +Copyright: ¥ë¥È 1024 +License: UNKNOWN + FIXME + +Files: contrib/japanese/doc/gdev10v.txt +Copyright: ¥ë¥È), 360x180, 180x180¤Î3¼ïÎà +License: UNKNOWN + FIXME + +Files: contrib/japanese/doc/gdevdmpr.txt +Copyright: ¥ë¥È¤Ç¤Ï false (off) ¤Ç¤¹ (²¿¤âɽ¼¨¤µ¤ì¤Þ¤»¤ó)¡£ +License: UNKNOWN + FIXME + +Files: contrib/japanese/doc/gdevfmlbp.txt +Copyright: ¥ë¥È¤Î²òÁüÅÙ¤Ï 400dpi ¤Ç¤¹¡£240dpi ¤Ç°õºþ¤¹¤ë¾ì¹ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ë + ¥ë¥È¤ÎÍÑ»æ¤Ï a4 ¤Ç¤¹¡£a3 ¤ò»ØÄꤹ¤ë»þ¤Ï¼¡¤Î¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£ +License: UNKNOWN + FIXME + +Files: contrib/japanese/doc/gdevml6.txt +Copyright: ¥ë¥È¤Î²òÁüÅÙ¤Ï 600 +License: UNKNOWN + FIXME + diff -Nru ghostscript-9.10~dfsg/debian/libgs-dev.install ghostscript-9.25~dfsg+1/debian/libgs-dev.install --- ghostscript-9.10~dfsg/debian/libgs-dev.install 2012-06-06 19:17:18.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/libgs-dev.install 2018-09-27 13:44:48.000000000 +0000 @@ -1,3 +1,2 @@ usr/include/ghostscript -usr/lib/libgs.a usr/lib/libgs.so diff -Nru ghostscript-9.10~dfsg/debian/patches/020130903-5ae4180-ps-interpreter-dont-interpolate-imagemask-data-for-high-level-devices.patch ghostscript-9.25~dfsg+1/debian/patches/020130903-5ae4180-ps-interpreter-dont-interpolate-imagemask-data-for-high-level-devices.patch --- ghostscript-9.10~dfsg/debian/patches/020130903-5ae4180-ps-interpreter-dont-interpolate-imagemask-data-for-high-level-devices.patch 2013-09-03 15:36:53.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020130903-5ae4180-ps-interpreter-dont-interpolate-imagemask-data-for-high-level-devices.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ ---- a/Resource/Init/gs_img.ps -+++ b/Resource/Init/gs_img.ps -@@ -696,7 +696,15 @@ - 2 index /ImageType get 1 eq and - 2 index /BitsPerComponent get 1 eq and - 2 index /Interpolate .knownget not { //false } if and -- //filterdict /ImscaleDecode known and { -+ //filterdict /ImscaleDecode known and -+ %% -+ %% Don't apply ImScaleDecode to interpolate imagemasks if -+ %% the current device is a high level device. -+ %% -+ currentdevice 1 dict dup /HighLevelDevice dup put .getdeviceparams -+ dup type /booleantype eq not {cleartomark //true}{3 1 roll cleartomark not}ifelse -+ and -+ { - % Apply interpolated imagemask scaling filter - exch .currentglobal exch dup .gcheck .setglobal - dup length dict .copydict diff -Nru ghostscript-9.10~dfsg/debian/patches/020131023-ad3e3ed-handle-type-0-font-in-annotation.patch ghostscript-9.25~dfsg+1/debian/patches/020131023-ad3e3ed-handle-type-0-font-in-annotation.patch --- ghostscript-9.10~dfsg/debian/patches/020131023-ad3e3ed-handle-type-0-font-in-annotation.patch 2013-11-01 14:51:34.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020131023-ad3e3ed-handle-type-0-font-in-annotation.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ ---- a/Resource/Init/pdf_ops.ps -+++ b/Resource/Init/pdf_ops.ps -@@ -1201,7 +1201,20 @@ - /Tform { % (V) Tform - - clippath pathbbox 4 2 roll pop pop % MaxLen (V) Ff Q dx dy - currentfont /ScaleMatrix .knownget { 3 get } { 1 } ifelse % MaxLen (V) Ff Q dx dy yy -- currentfont /FontBBox get dup 1 get neg exch 3 get % MaxLen (V) Ff Q dx dy yy desc asc -+ -+ currentfont /FontBBox .knownget -+ not -+ { -+ currentfont dup /FontType get -+ 0 eq -+ { -+ /FDepVector get 0 get /FontBBox get} -+ { -+ pop null % force an error -+ } ifelse -+ }if -+ dup 1 get neg exch 3 get % MaxLen (V) Ff Q dx dy yy desc asc -+ - dup 0 ne { div } { pop pop 0 } ifelse % MaxLen (V) Ff Q dx dy yy desc/asc - 1 index mul % MaxLen (V) Ff Q dx dy yy desc/asc*yy - diff -Nru ghostscript-9.10~dfsg/debian/patches/020131127-87a7fd8-cups-pwg-raster-output-ppd-less-support.patch ghostscript-9.25~dfsg+1/debian/patches/020131127-87a7fd8-cups-pwg-raster-output-ppd-less-support.patch --- ghostscript-9.10~dfsg/debian/patches/020131127-87a7fd8-cups-pwg-raster-output-ppd-less-support.patch 2013-12-04 10:33:15.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020131127-87a7fd8-cups-pwg-raster-output-ppd-less-support.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,200 +0,0 @@ ---- a/cups/gdevcups.c -+++ b/cups/gdevcups.c -@@ -3630,6 +3630,17 @@ - margins[0], margins[1], margins[2], margins[3]); - #endif /* CUPS_DEBUG */ - } -+ else -+ { -+ /* If we do not have a PPD file, make sure that margins given via the -+ input file or via something like -+ "-c '<>setpagedevice'" -+ on the command line are conserved */ -+ margins[0] = pdev->HWMargins[0] / 72.0; -+ margins[1] = pdev->HWMargins[1] / 72.0; -+ margins[2] = pdev->HWMargins[2] / 72.0; -+ margins[3] = pdev->HWMargins[3] / 72.0; -+ } - - /* - * Set the margins to update the bitmap size... -@@ -3733,85 +3744,125 @@ - cups->header.cupsPageSize[0] = pdev->MediaSize[1]; - cups->header.cupsPageSize[1] = pdev->MediaSize[0]; - -- cups->header.cupsImagingBBox[0] = pdev->HWMargins[1]; -- cups->header.cupsImagingBBox[1] = pdev->HWMargins[2]; -- cups->header.cupsImagingBBox[2] = pdev->MediaSize[1] - pdev->HWMargins[3]; -- cups->header.cupsImagingBBox[3] = pdev->MediaSize[0] - pdev->HWMargins[0]; -- - if ((sf = cups->header.cupsBorderlessScalingFactor) < 1.0) - sf = 1.0; - -- cups->header.Margins[0] = pdev->HWMargins[1] * sf; -- cups->header.Margins[1] = pdev->HWMargins[2] * sf; -+ cups->header.PageSize[0] = (pdev->MediaSize[1] * sf) + 0.5; -+ cups->header.PageSize[1] = (pdev->MediaSize[0] * sf) + 0.5; - -- cups->header.PageSize[0] = pdev->MediaSize[1] * sf; -- cups->header.PageSize[1] = pdev->MediaSize[0] * sf; -- -- cups->header.ImagingBoundingBox[0] = pdev->HWMargins[1] * sf; -- cups->header.ImagingBoundingBox[1] = pdev->HWMargins[2] * sf; -- cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[1] - -- pdev->HWMargins[3]) * sf; -- cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[0] - -- pdev->HWMargins[0]) * sf; -+ if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) -+ { -+ cups->header.Margins[0] = (pdev->HWMargins[1] * sf) + 0.5; -+ cups->header.Margins[1] = (pdev->HWMargins[2] * sf) + 0.5; -+ cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[1] * sf) + 0.5; -+ cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[2] * sf) + 0.5; -+ cups->header.ImagingBoundingBox[2] = ((pdev->MediaSize[1] - -+ pdev->HWMargins[3]) * sf) + 0.5; -+ cups->header.ImagingBoundingBox[3] = ((pdev->MediaSize[0] - -+ pdev->HWMargins[0]) * sf) + 0.5; -+ cups->header.cupsImagingBBox[0] = pdev->HWMargins[1]; -+ cups->header.cupsImagingBBox[1] = pdev->HWMargins[2]; -+ cups->header.cupsImagingBBox[2] = pdev->MediaSize[1] - pdev->HWMargins[3]; -+ cups->header.cupsImagingBBox[3] = pdev->MediaSize[0] - pdev->HWMargins[0]; -+ } -+ else -+ { -+ for (i = 0; i < 2; i ++) -+ cups->header.Margins[i] = 0; -+ for (i = 0; i < 4; i ++) -+ { -+ cups->header.ImagingBoundingBox[i] = 0; -+ cups->header.cupsImagingBBox[i] = 0.0; -+ } -+ } - } - else - { - cups->header.cupsPageSize[0] = pdev->MediaSize[0]; - cups->header.cupsPageSize[1] = pdev->MediaSize[1]; - -- cups->header.cupsImagingBBox[0] = pdev->HWMargins[0]; -- cups->header.cupsImagingBBox[1] = pdev->HWMargins[1]; -- cups->header.cupsImagingBBox[2] = pdev->MediaSize[0] - pdev->HWMargins[2]; -- cups->header.cupsImagingBBox[3] = pdev->MediaSize[1] - pdev->HWMargins[3]; -- - if ((sf = cups->header.cupsBorderlessScalingFactor) < 1.0) - sf = 1.0; - -- cups->header.Margins[0] = pdev->HWMargins[0] * sf; -- cups->header.Margins[1] = pdev->HWMargins[1] * sf; -- -- cups->header.PageSize[0] = pdev->MediaSize[0] * sf; -- cups->header.PageSize[1] = pdev->MediaSize[1] * sf; -+ cups->header.PageSize[0] = (pdev->MediaSize[0] * sf) + 0.5; -+ cups->header.PageSize[1] = (pdev->MediaSize[1] * sf) + 0.5; - -- cups->header.ImagingBoundingBox[0] = pdev->HWMargins[0] * sf; -- cups->header.ImagingBoundingBox[1] = pdev->HWMargins[1] * sf; -- cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[0] - -- pdev->HWMargins[2]) * sf; -- cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[1] - -- pdev->HWMargins[3]) * sf; -+ if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) -+ { -+ cups->header.Margins[0] = (pdev->HWMargins[0] * sf) + 0.5; -+ cups->header.Margins[1] = (pdev->HWMargins[1] * sf) + 0.5; -+ cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[0] * sf) + 0.5; -+ cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[1] * sf) + 0.5; -+ cups->header.ImagingBoundingBox[2] = ((pdev->MediaSize[0] - -+ pdev->HWMargins[2]) * sf) + 0.5; -+ cups->header.ImagingBoundingBox[3] = ((pdev->MediaSize[1] - -+ pdev->HWMargins[3]) * sf) + 0.5; -+ cups->header.cupsImagingBBox[0] = pdev->HWMargins[0]; -+ cups->header.cupsImagingBBox[1] = pdev->HWMargins[1]; -+ cups->header.cupsImagingBBox[2] = pdev->MediaSize[0] - pdev->HWMargins[2]; -+ cups->header.cupsImagingBBox[3] = pdev->MediaSize[1] - pdev->HWMargins[3]; -+ } -+ else -+ { -+ for (i = 0; i < 2; i ++) -+ cups->header.Margins[i] = 0; -+ for (i = 0; i < 4; i ++) -+ { -+ cups->header.ImagingBoundingBox[i] = 0; -+ cups->header.cupsImagingBBox[i] = 0.0; -+ } -+ } - } - - #else - - if (cups->landscape) - { -- cups->header.Margins[0] = pdev->HWMargins[1]; -- cups->header.Margins[1] = pdev->HWMargins[2]; -+ cups->header.PageSize[0] = pdev->MediaSize[1] + 0.5; -+ cups->header.PageSize[1] = pdev->MediaSize[0] + 0.5; - -- cups->header.PageSize[0] = pdev->MediaSize[1]; -- cups->header.PageSize[1] = pdev->MediaSize[0]; -- -- cups->header.ImagingBoundingBox[0] = pdev->HWMargins[1]; -- cups->header.ImagingBoundingBox[1] = pdev->HWMargins[0]; -- cups->header.ImagingBoundingBox[2] = pdev->MediaSize[1] - -- pdev->HWMargins[3]; -- cups->header.ImagingBoundingBox[3] = pdev->MediaSize[0] - -- pdev->HWMargins[2]; -+ if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) -+ { -+ cups->header.Margins[0] = (pdev->HWMargins[1]) + 0.5; -+ cups->header.Margins[1] = (pdev->HWMargins[2]) + 0.5; -+ cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[1]) + 0.5; -+ cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[0]) + 0.5; -+ cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[1] - -+ pdev->HWMargins[3]) + 0.5; -+ cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[0] - -+ pdev->HWMargins[2]) + 0.5; -+ } -+ else -+ { -+ for (i = 0; i < 2; i ++) -+ cups->header.Margins[i] = 0; -+ for (i = 0; i < 4; i ++) -+ cups->header.ImagingBoundingBox[i] = 0; -+ } - } - else - { -- cups->header.Margins[0] = pdev->HWMargins[0]; -- cups->header.Margins[1] = pdev->HWMargins[1]; -- -- cups->header.PageSize[0] = pdev->MediaSize[0]; -- cups->header.PageSize[1] = pdev->MediaSize[1]; -+ cups->header.PageSize[0] = pdev->MediaSize[0] + 0.5; -+ cups->header.PageSize[1] = pdev->MediaSize[1] + 0.5; - -- cups->header.ImagingBoundingBox[0] = pdev->HWMargins[0]; -- cups->header.ImagingBoundingBox[1] = pdev->HWMargins[3]; -- cups->header.ImagingBoundingBox[2] = pdev->MediaSize[0] - -- pdev->HWMargins[2]; -- cups->header.ImagingBoundingBox[3] = pdev->MediaSize[1] - -- pdev->HWMargins[1]; -+ if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0) -+ { -+ cups->header.Margins[0] = (pdev->HWMargins[0]) + 0.5; -+ cups->header.Margins[1] = (pdev->HWMargins[1]) + 0.5; -+ cups->header.ImagingBoundingBox[0] = (pdev->HWMargins[0]) + 0.5; -+ cups->header.ImagingBoundingBox[1] = (pdev->HWMargins[3]) + 0.5; -+ cups->header.ImagingBoundingBox[2] = (pdev->MediaSize[0] - -+ pdev->HWMargins[2]) + 0.5; -+ cups->header.ImagingBoundingBox[3] = (pdev->MediaSize[1] - -+ pdev->HWMargins[1]) + 0.5; -+ } -+ else -+ { -+ for (i = 0; i < 2; i ++) -+ cups->header.Margins[i] = 0; -+ for (i = 0; i < 4; i ++) -+ cups->header.ImagingBoundingBox[i] = 0; -+ } - } - - #endif /* CUPS_RASTER_SYNCv1 */ diff -Nru ghostscript-9.10~dfsg/debian/patches/020131218-5ddd13e-ps2write-dont-emit-a-page-size-change-if-the-last-request-failed.patch ghostscript-9.25~dfsg+1/debian/patches/020131218-5ddd13e-ps2write-dont-emit-a-page-size-change-if-the-last-request-failed.patch --- ghostscript-9.10~dfsg/debian/patches/020131218-5ddd13e-ps2write-dont-emit-a-page-size-change-if-the-last-request-failed.patch 2013-12-18 15:14:15.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020131218-5ddd13e-ps2write-dont-emit-a-page-size-change-if-the-last-request-failed.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ ---- a/devices/vector/opdfread.h -+++ b/devices/vector/opdfread.h -@@ -734,10 +734,27 @@ - "0 0}ifelse\n", - "round cvi 2 index round cvi eq\n", - "exch round cvi 3 index round cvi eq and{\n", -+"//PDFR_DEBUG{(PageSize matches request) == flush}if\n", - "pop pop}{\n", -+"/MediaRequested where {\n", -+"//PDFR_DEBUG{(MediaRequested is true, check against new request) == flush}if\n", -+"/MediaRequested get aload pop\n", -+"round cvi 2 index round cvi eq\n", -+"exch round cvi 3 index round cvi eq and\n", -+"{//PDFR_DEBUG{(MediaRequested same as current request, ignore) == flush}if pop pop false}\n", -+"{//PDFR_DEBUG{(MediaRequested different to current request) == flush}if true}ifelse\n", -+"}{\n", -+"//PDFR_DEBUG{(No MediaRequested yet) == flush}if\n", -+"true\n", -+"}ifelse\n", -+"{\n", -+"//PDFR_DEBUG{(Setting pagesize) == flush}if\n", - "2 array astore\n", -+"dup /MediaRequested exch def\n", - "<< exch /PageSize exch >> setpagedevice\n", --"} ifelse\n", -+"/pagesave save def\n", -+"}if\n", -+"}ifelse\n", - "userdict/PDFR_InitialGS gstate put\n", - "setglobal\n", - "}if\n", ---- a/lib/opdfread.ps -+++ b/lib/opdfread.ps -@@ -896,13 +896,27 @@ - 0 0 % dummy page size values if not known - }ifelse - % bw bh px0 py0 bw bh bool bw bh Width Height -- round cvi 2 index round cvi % bw bh px0 py0 bw bh bool bw bh Width bool -+ round cvi 2 index round cvi eq % bw bh px0 py0 bw bh bool bw bh Width bool - exch round cvi 3 index round cvi eq and % bw bh px0 py0 bw bh bool bw bh bool - { % Page Size unchanged, do not emit setpagedevice - pop pop % bw bh px0 py0 bw bh bool - } { -- 2 array astore % bw bh px0 py0 bw bh bool [] -- << exch /PageSize exch >> setpagedevice % bw bh px0 py0 bw bh bool -+ /MediaRequested where { -+ % bw bh px0 py0 bw bh -+ /MediaRequested get aload pop % bw bh px0 py0 bw bh Width Height -+ round cvi 2 index round cvi eq % bw bh px0 py0 bw bh bool bw bh Width bool -+ exch round cvi 3 index round cvi eq and % bw bh px0 py0 bw bh bool bw bh bool -+ {pop pop false} % We already requested this media size, so don't re-request -+ {true} ifelse % Media request different to last request -+ } { -+ true % No stored media request, so apply setpagedevice -+ } ifelse -+ { -+ 2 array astore % bw bh px0 py0 bw bh bool [] -+ dup /MediaRequested exch def -+ << exch /PageSize exch >> setpagedevice % bw bh px0 py0 bw bh bool -+ /pagesave save def -+ } if - } ifelse - userdict /PDFR_InitialGS gstate put - setglobal % bw bh px0 py0 bw bh diff -Nru ghostscript-9.10~dfsg/debian/patches/020131219-d997bc4-pwgraster-output-device.patch ghostscript-9.25~dfsg+1/debian/patches/020131219-d997bc4-pwgraster-output-device.patch --- ghostscript-9.10~dfsg/debian/patches/020131219-d997bc4-pwgraster-output-device.patch 2013-12-19 21:36:02.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020131219-d997bc4-pwgraster-output-device.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,253 +0,0 @@ ---- a/configure.ac -+++ b/configure.ac -@@ -1110,7 +1110,7 @@ - fi - - CUPSINCLUDE="include $srcdir/cups/cups.mak" -- CUPSDEV="cups" -+ CUPSDEV="cups pwgraster" - CUPSVERSION="`$CUPSCONFIG --version`" - LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" - LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" -@@ -1128,7 +1128,7 @@ - LCUPSBUILDTYPE=linux - LCUPSINCLUDE="include \$(GLSRCDIR)/lcups.mak" - LCUPSIINCLUDE="include \$(GLSRCDIR)/lcupsi.mak" -- CUPSDEV="cups" -+ CUPSDEV="cups pwgraster" - fi - fi - fi ---- a/cups/gdevcups.c -+++ b/cups/gdevcups.c -@@ -336,109 +336,118 @@ - ),\ - prn_device_body_copies_rest_(print_pages) - --gx_device_cups gs_cups_device = --{ -- prn_device_body_copies(gx_device_cups,/* type */ -- cups_procs, /* procedures */ -- "cups", /* device name */ -- 85, /* initial width */ -- 110, /* initial height */ -- 100, /* initial x resolution */ -- 100, /* initial y resolution */ -- 0, /* initial left offset */ -- 0, /* initial top offset */ -- 0, /* initial left margin */ -- 0, /* initial bottom margin */ -- 0, /* initial right margin */ -- 0, /* initial top margin */ -- 1, /* number of color components */ -- 1, /* number of color bits */ -- 1, /* maximum gray value */ -- 0, /* maximum color value */ -- 2, /* number of gray values */ -- 0, /* number of color values */ -- cups_print_pages), -- /* print procedure */ -- 0, /* page */ -- NULL, /* stream */ -- { /* header */ -- "", /* MediaClass */ -- "", /* MediaColor */ -- "", /* MediaType */ -- "", /* OutputType */ -- 0, /* AdvanceDistance */ -- CUPS_ADVANCE_NONE, /* AdvanceMedia */ -- CUPS_FALSE, /* Collate */ -- CUPS_CUT_NONE, /* CutMedia */ -- CUPS_FALSE, /* Duplex */ -- { 100, 100 }, /* HWResolution */ -- { 0, 0, 612, 792 }, /* ImagingBoundingBox */ -- CUPS_FALSE, /* InsertSheet */ -- CUPS_JOG_NONE, /* Jog */ -- CUPS_EDGE_TOP, /* LeadingEdge */ -- { 0, 0 }, /* Margins */ -- CUPS_FALSE, /* ManualFeed */ -- 0, /* MediaPosition */ -- 0, /* MediaWeight */ -- CUPS_FALSE, /* MirrorPrint */ -- CUPS_FALSE, /* NegativePrint */ -- 1, /* NumCopies */ -- CUPS_ORIENT_0, /* Orientation */ -- CUPS_FALSE, /* OutputFaceUp */ -- { 612, 792 }, /* PageSize */ -- CUPS_FALSE, /* Separations */ -- CUPS_FALSE, /* TraySwitch */ -- CUPS_FALSE, /* Tumble */ -- 850, /* cupsWidth */ -- 1100, /* cupsHeight */ -- 0, /* cupsMediaType */ -- 1, /* cupsBitsPerColor */ -- 1, /* cupsBitsPerPixel */ -- 107, /* cupsBytesPerLine */ -- CUPS_ORDER_CHUNKED, /* cupsColorOrder */ -- CUPS_CSPACE_K, /* cupsColorSpace */ -- 0, /* cupsCompression */ -- 0, /* cupsRowCount */ -- 0, /* cupsRowFeed */ -- 0 /* cupsRowStep */ -+ -+ - #ifdef CUPS_RASTER_SYNCv1 -- , -- 1, /* cupsNumColors */ -- 1.0, /* cupsBorderlessScalingFactor */ -- { 612.0, 792.0 }, /* cupsPageSize */ -- { 0.0, 0.0, 612.0, 792.0 }, /* cupsImagingBBox */ -- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* cupsInteger */ -- { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -- 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, /* cupsReal */ -- { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, -- /* cupsString */ -- "", /* cupsMarkerType */ -- "", /* cupsRenderingIntent */ -+#define RASTER_SYNCv1_ENTRIES \ -+ ,\ -+ 1, /* cupsNumColors */\ -+ 1.0, /* cupsBorderlessScalingFactor */\ -+ { 612.0, 792.0 }, /* cupsPageSize */\ -+ { 0.0, 0.0, 612.0, 792.0 }, /* cupsImagingBBox */\ -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* cupsInteger */\ -+ { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\ -+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, /* cupsReal */\ -+ { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },\ -+ /* cupsString */\ -+ "", /* cupsMarkerType */\ -+ "", /* cupsRenderingIntent */\ - "" /* cupsPageSizeName */ -+#else -+#define RASTER_SYNCv1_ENTRIES - #endif /* CUPS_RASTER_SYNCv1 */ -- }, -- 0, /* landscape */ -- 0, /* lastpage */ -- 0, /* HaveProfile */ -- NULL, /* Profile */ -- NULL, /* PPD */ -- { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, -- 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f },/* RevLower1 */ -- { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, -- 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 },/* RevUpper1 */ -- { 0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d, -- 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f },/* RevLower2 */ -- { 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0, -- 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0 },/* RevUpper2 */ -- {0x00}, /* DecodeLUT */ -- {0x00}, /* EncodeLUT */ -- {0x00}, /* Density */ -- {{{0x00},{0x00},{0x00}}, -- {{0x00},{0x00},{0x00}}, -- {{0x00},{0x00},{0x00}}}, /* Matrix */ -- 0, /* user_icc */ -+ -+#define gs_xxx_device(dname, mediaclass)\ -+ prn_device_body_copies(gx_device_cups,/* type */\ -+ cups_procs, /* procedures */\ -+ dname, /* device name */\ -+ 85, /* initial width */\ -+ 110, /* initial height */\ -+ 100, /* initial x resolution */\ -+ 100, /* initial y resolution */\ -+ 0, /* initial left offset */\ -+ 0, /* initial top offset */\ -+ 0, /* initial left margin */\ -+ 0, /* initial bottom margin */\ -+ 0, /* initial right margin */\ -+ 0, /* initial top margin */\ -+ 1, /* number of color components */\ -+ 1, /* number of color bits */\ -+ 1, /* maximum gray value */\ -+ 0, /* maximum color value */\ -+ 2, /* number of gray values */\ -+ 0, /* number of color values */\ -+ cups_print_pages),\ -+ /* print procedure */\ -+ 0, /* page */\ -+ NULL, /* stream */\ -+ { /* header */\ -+ mediaclass, /* MediaClass */\ -+ "", /* MediaColor */\ -+ "", /* MediaType */\ -+ "", /* OutputType */\ -+ 0, /* AdvanceDistance */\ -+ CUPS_ADVANCE_NONE, /* AdvanceMedia */\ -+ CUPS_FALSE, /* Collate */\ -+ CUPS_CUT_NONE, /* CutMedia */\ -+ CUPS_FALSE, /* Duplex */\ -+ { 100, 100 }, /* HWResolution */\ -+ { 0, 0, 612, 792 }, /* ImagingBoundingBox */\ -+ CUPS_FALSE, /* InsertSheet */\ -+ CUPS_JOG_NONE, /* Jog */\ -+ CUPS_EDGE_TOP, /* LeadingEdge */\ -+ { 0, 0 }, /* Margins */\ -+ CUPS_FALSE, /* ManualFeed */\ -+ 0, /* MediaPosition */\ -+ 0, /* MediaWeight */\ -+ CUPS_FALSE, /* MirrorPrint */\ -+ CUPS_FALSE, /* NegativePrint */\ -+ 1, /* NumCopies */\ -+ CUPS_ORIENT_0, /* Orientation */\ -+ CUPS_FALSE, /* OutputFaceUp */\ -+ { 612, 792 }, /* PageSize */\ -+ CUPS_FALSE, /* Separations */\ -+ CUPS_FALSE, /* TraySwitch */\ -+ CUPS_FALSE, /* Tumble */\ -+ 850, /* cupsWidth */\ -+ 1100, /* cupsHeight */\ -+ 0, /* cupsMediaType */\ -+ 1, /* cupsBitsPerColor */\ -+ 1, /* cupsBitsPerPixel */\ -+ 107, /* cupsBytesPerLine */\ -+ CUPS_ORDER_CHUNKED, /* cupsColorOrder */\ -+ CUPS_CSPACE_K, /* cupsColorSpace */\ -+ 0, /* cupsCompression */\ -+ 0, /* cupsRowCount */\ -+ 0, /* cupsRowFeed */\ -+ 0 /* cupsRowStep */\ -+ RASTER_SYNCv1_ENTRIES, /* See above */\ -+ },\ -+ 0, /* landscape */\ -+ 0, /* lastpage */\ -+ 0, /* HaveProfile */\ -+ NULL, /* Profile */\ -+ NULL, /* PPD */\ -+ { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,\ -+ 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f },/* RevLower1 */\ -+ { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,\ -+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 },/* RevUpper1 */\ -+ { 0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d,\ -+ 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f },/* RevLower2 */\ -+ { 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0,\ -+ 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0 },/* RevUpper2 */\ -+ {0x00}, /* DecodeLUT */\ -+ {0x00}, /* EncodeLUT */\ -+ {0x00}, /* Density */\ -+ {{{0x00},{0x00},{0x00}},\ -+ {{0x00},{0x00},{0x00}},\ -+ {{0x00},{0x00},{0x00}}}, /* Matrix */\ -+ 0, /* user_icc */\ - 3 /* cupsRasterVersion */ --}; -+ -+gx_device_cups gs_cups_device = { gs_xxx_device("cups", "") }; -+gx_device_cups gs_pwgraster_device = { gs_xxx_device("pwgraster", -+ "PwgRaster") }; - - /* - * Local functions... ---- a/devices/devs.mak -+++ b/devices/devs.mak -@@ -1905,6 +1905,10 @@ - $(SETPDEV2) $(DD)cups $(cups_) - $(ADDMOD) $(DD)cups -include $(lcups_dev) - $(ADDMOD) $(DD)cups -include $(lcupsi_dev) -+$(DD)pwgraster.dev : $(DEVS_MAK) $(lcups_dev) $(lcupsi_dev) $(cups_) $(GDEV) -+ $(SETPDEV2) $(DD)pwgraster $(cups_) -+ $(ADDMOD) $(DD)pwgraster -include $(lcups_dev) -+ $(ADDMOD) $(DD)pwgraster -include $(lcupsi_dev) - - $(DEVOBJ)gdevcups.$(OBJ) : $(LCUPSSRCDIR)$(D)gdevcups.c $(std_h) - $(CUPS_CC) $(DEVO_)gdevcups.$(OBJ) $(C_) $(CFLAGS) $(I_)$(GLSRC) \ diff -Nru ghostscript-9.10~dfsg/debian/patches/020140313-095ae57-ps2write-fix-missing-beginresource-comment-for-fontfile-objects.patch ghostscript-9.25~dfsg+1/debian/patches/020140313-095ae57-ps2write-fix-missing-beginresource-comment-for-fontfile-objects.patch --- ghostscript-9.10~dfsg/debian/patches/020140313-095ae57-ps2write-fix-missing-beginresource-comment-for-fontfile-objects.patch 2014-03-13 12:27:38.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140313-095ae57-ps2write-fix-missing-beginresource-comment-for-fontfile-objects.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ ---- a/devices/vector/gdevpdfu.c -+++ b/devices/vector/gdevpdfu.c -@@ -742,6 +742,10 @@ - /* This should not be possible, not valid in PostScript */ - pprintld1(s, "%%%%BeginResource: file (PDF Annotation obj_%ld)\n", id); - break; -+ case resourceFontFile: -+ /* This should not be possible, not valid in PostScript */ -+ pprintld1(s, "%%%%BeginResource: file (PDF FontFile obj_%ld)\n", id); -+ break; - default: - pprintld1(s, "%%%%BeginResource: file (PDF object obj_%ld)\n", id); - break; ---- a/devices/vector/gdevpdfx.h -+++ b/devices/vector/gdevpdfx.h -@@ -136,6 +136,7 @@ - resourceMetadata, - resourceICC, - resourceAnnotation, -+ resourceFontFile, - resourceNone /* Special, used when this isn't a resource at all - * eg when we execute a resource we've just written, such as - * a Pattern. ---- a/devices/vector/gdevpdtd.c -+++ b/devices/vector/gdevpdtd.c -@@ -747,9 +747,7 @@ - pfd->common.object->written = true; - { const cos_object_t *pco = (const cos_object_t *)pdf_get_FontFile_object(pfd->base_font); - if (pco != NULL) { -- if (pdev->is_ps2write) -- pprintld1(s, "%%%%BeginResource: file (PDF FontFile obj_%ld)\n", pco->id); -- code = COS_WRITE_OBJECT(pco, pdev, resourceNone); -+ code = COS_WRITE_OBJECT(pco, pdev, resourceFontFile); - if (code < 0) - return code; - } diff -Nru ghostscript-9.10~dfsg/debian/patches/020140313-5d6b18a-set-correct-portrait-landscape-orientation-on-pcl-5ce.patch ghostscript-9.25~dfsg+1/debian/patches/020140313-5d6b18a-set-correct-portrait-landscape-orientation-on-pcl-5ce.patch --- ghostscript-9.10~dfsg/debian/patches/020140313-5d6b18a-set-correct-portrait-landscape-orientation-on-pcl-5ce.patch 2014-03-13 12:06:42.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140313-5d6b18a-set-correct-portrait-landscape-orientation-on-pcl-5ce.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ ---- a/devices/gdevdjet.c -+++ b/devices/gdevdjet.c -@@ -443,6 +443,8 @@ - char init[80]; - - gs_sprintf(base_init, "\033&l-180u36Z\033*r0F\033&u%dD", dots_per_inch); -+ if (gdev_pcl_page_orientation((gx_device *) pdev) == PAGE_ORIENTATION_LANDSCAPE) -+ gs_sprintf(base_init, "\033&l0u140Z\033*r0F\033&u%dD", dots_per_inch); - hpjet_make_init(pdev, init, base_init); - - return dljet_mono_print_page_copies(pdev, prn_stream, num_copies, ---- a/devices/gdevdljm.c -+++ b/devices/gdevdljm.c -@@ -82,6 +82,7 @@ - int penalty_from2to3 = strlen(from2to3); - int penalty_from3to2 = strlen(from3to2); - int paper_size = gdev_pcl_paper_size((gx_device *) pdev); -+ int page_orientation = gdev_pcl_page_orientation((gx_device *) pdev); - int code = 0; - bool dup = pdev->Duplex; - bool dupset = pdev->Duplex_set >= 0; -@@ -109,6 +110,7 @@ - fputs("\033E", prn_stream); /* reset printer */ - /* If the printer supports it, set the paper size */ - /* based on the actual requested size. */ -+ fprintf(prn_stream, "\033&l%dO", page_orientation); - if (features & PCL_CAN_SET_PAPER_SIZE) { - fprintf(prn_stream, "\033&l%dA", paper_size); - } -@@ -140,18 +142,20 @@ - if ((features & PCL_HAS_DUPLEX) && dupset && dup) { - /* We are printing duplex, so change margins as needed */ - if (( (pdev->PageCount/num_copies)%2)==0) { -+ fprintf(prn_stream, "\033&l%dO", page_orientation); - if (features & PCL_CAN_SET_PAPER_SIZE) { - fprintf(prn_stream, "\033&l%dA", paper_size); - } -- fputs("\033&l0o0l0E", prn_stream); -+ fputs("\033&l0l0E", prn_stream); - fputs(odd_page_init, prn_stream); - } else - fputs(even_page_init, prn_stream); - } else { -+ fprintf(prn_stream, "\033&l%dO", page_orientation); - if (features & PCL_CAN_SET_PAPER_SIZE){ - fprintf(prn_stream, "\033&l%dA", paper_size); - } -- fputs("\033&l0o0l0E", prn_stream); -+ fputs("\033&l0l0E", prn_stream); - fputs(odd_page_init, prn_stream); - } - ---- a/devices/gdevpcl.c -+++ b/devices/gdevpcl.c -@@ -34,6 +34,12 @@ - float new_width_difference, new_height_difference; - int code = PAPER_SIZE_LETTER; - -+ if (dev->width > dev->height) { -+ /* Landscape orientation, switch width and height to find paper size */ -+ width_inches = dev->height / dev->y_pixels_per_inch; -+ height_inches = dev->width / dev->x_pixels_per_inch; -+ } -+ - /* Since we're telling the printer when to eject and start a new - page, the paper height doesn't matter a great deal, as long as - we ensure that it's at least as high as we want our pages to -@@ -88,6 +94,18 @@ - return code; - } - -+/* ------ Get page orientation ------ */ -+ -+/* Get the page orientation, based on width and height. */ -+int -+gdev_pcl_page_orientation(gx_device * dev) -+{ -+ if (dev->height >= dev->width) -+ return PAGE_ORIENTATION_PORTRAIT; -+ else -+ return PAGE_ORIENTATION_LANDSCAPE; -+} -+ - /* ------ Color mapping ------ */ - - /* The PaintJet and DeskJet 500C use additive colors in separate planes. */ ---- a/devices/gdevpcl.h -+++ b/devices/gdevpcl.h -@@ -50,6 +50,12 @@ - /* Get the paper size code, based on width and height. */ - int gdev_pcl_paper_size(gx_device *); - -+#define PAGE_ORIENTATION_PORTRAIT 0 -+#define PAGE_ORIENTATION_LANDSCAPE 1 -+ -+/* Get the page orientation, based on width and height. */ -+int gdev_pcl_page_orientation(gx_device * dev); -+ - /* Color mapping procedures for 3-bit-per-pixel RGB printers */ - dev_proc_map_rgb_color(gdev_pcl_3bit_map_rgb_color); - dev_proc_map_color_rgb(gdev_pcl_3bit_map_color_rgb); diff -Nru ghostscript-9.10~dfsg/debian/patches/020140313-6498483-ps2write-fix-a-dsc-comment.patch ghostscript-9.25~dfsg+1/debian/patches/020140313-6498483-ps2write-fix-a-dsc-comment.patch --- ghostscript-9.10~dfsg/debian/patches/020140313-6498483-ps2write-fix-a-dsc-comment.patch 2014-03-13 12:23:38.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140313-6498483-ps2write-fix-a-dsc-comment.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- a/devices/vector/gdevpdtd.c -+++ b/devices/vector/gdevpdtd.c -@@ -748,7 +748,7 @@ - { const cos_object_t *pco = (const cos_object_t *)pdf_get_FontFile_object(pfd->base_font); - if (pco != NULL) { - if (pdev->is_ps2write) -- pprintld1(s, "%%BeginResource: file (PDF FontFile obj_%ld)\n", pco->id); -+ pprintld1(s, "%%%%BeginResource: file (PDF FontFile obj_%ld)\n", pco->id); - code = COS_WRITE_OBJECT(pco, pdev, resourceNone); - if (code < 0) - return code; diff -Nru ghostscript-9.10~dfsg/debian/patches/020140324-b780ff0-protection-against-pxl-segfault-with-image-data-without-colorspace-info.patch ghostscript-9.25~dfsg+1/debian/patches/020140324-b780ff0-protection-against-pxl-segfault-with-image-data-without-colorspace-info.patch --- ghostscript-9.10~dfsg/debian/patches/020140324-b780ff0-protection-against-pxl-segfault-with-image-data-without-colorspace-info.patch 2014-03-24 22:34:27.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140324-b780ff0-protection-against-pxl-segfault-with-image-data-without-colorspace-info.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ ---- a/devices/vector/gdevpx.c -+++ b/devices/vector/gdevpx.c -@@ -326,7 +326,11 @@ - static bool - pclxl_can_handle_color_space(const gs_color_space * pcs) - { -- gs_color_space_index index = gs_color_space_get_index(pcs); -+ gs_color_space_index index; -+ /* an image with no colorspace info arrived; cannot handle */ -+ if (!pcs) -+ return false; -+ index = gs_color_space_get_index(pcs); - - if (index == gs_color_space_index_Indexed) { - if (pcs->params.indexed.use_proc) diff -Nru ghostscript-9.10~dfsg/debian/patches/020140331-41ab485-pxl-transform-deep-images-with-icc-transform-to-emit-high-level-images.patch ghostscript-9.25~dfsg+1/debian/patches/020140331-41ab485-pxl-transform-deep-images-with-icc-transform-to-emit-high-level-images.patch --- ghostscript-9.10~dfsg/debian/patches/020140331-41ab485-pxl-transform-deep-images-with-icc-transform-to-emit-high-level-images.patch 2014-03-31 16:12:55.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140331-41ab485-pxl-transform-deep-images-with-icc-transform-to-emit-high-level-images.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,162 +0,0 @@ ---- a/devices/vector/gdevpx.c -+++ b/devices/vector/gdevpx.c -@@ -38,6 +38,7 @@ - #include "gxlum.h" - #include "gdevpcl.h" /* for gdev_pcl_mode3compress() */ - #include "gsicc_manage.h" -+#include "gsicc_cache.h" - #include /* abs() */ - - /* ---------------- Device definition ---------------- */ -@@ -108,6 +109,7 @@ - floatp y_scale; - bool pen_null; - bool brush_null; -+ bool iccTransform; - } gx_device_pclxl; - - gs_public_st_suffix_add0_final(st_device_pclxl, gx_device_pclxl, -@@ -349,6 +351,22 @@ - index == gs_color_space_index_ICC); - } - -+/* Test whether we can icclink-transform an image. */ -+static bool -+pclxl_can_icctransform(const gs_image_t * pim) -+{ -+ const gs_color_space *pcs = pim->ColorSpace; -+ int bits_per_pixel = -+ (pim->ImageMask ? 1 : -+ pim->BitsPerComponent * gs_color_space_num_components(pcs)); -+ -+ if ((gs_color_space_get_index(pcs) == gs_color_space_index_ICC) -+ && (bits_per_pixel == 24)) -+ return true; -+ -+ return false; -+} -+ - /* Set brush, pen, and mode for painting a path. */ - static void - pclxl_set_paints(gx_device_pclxl * xdev, gx_path_type_t type) -@@ -1533,6 +1551,7 @@ - xdev->MediaPosition = eAutoSelect; - xdev->MediaType_old[0] = '\0'; - xdev->MediaType[0] = '\0'; -+ /* xdev->iccTransform = false; */ /* set true/false here to ignore command line */ - return 0; - } - -@@ -1893,6 +1912,7 @@ - uint raster; - } rows; - bool flipped; -+ gsicc_link_t *icclink; - } pclxl_image_enum_t; - gs_private_st_suffix_add1(st_pclxl_image_enum, pclxl_image_enum_t, - "pclxl_image_enum_t", pclxl_image_enum_enum_ptrs, -@@ -1939,9 +1959,10 @@ - !((mat.xx == 0) && (mat.yy == 0) && (mat.xy * mat.yx != 0))) || - (pim->ImageMask ? - (!gx_dc_is_pure(pdcolor) || pim->CombineWithColor) : -- (!pclxl_can_handle_color_space(pim->ColorSpace) || -- (bits_per_pixel != 1 && bits_per_pixel != 4 && -- bits_per_pixel != 8 && bits_per_pixel !=24))) || -+ ((!pclxl_can_handle_color_space(pcs) || -+ (bits_per_pixel != 1 && bits_per_pixel != 4 && -+ bits_per_pixel != 8 && bits_per_pixel !=24)) -+ && !(pclxl_can_icctransform(pim) && xdev->iccTransform) )) || - format != gs_image_format_chunky || pim->Interpolate || - prect - ) -@@ -2047,6 +2068,17 @@ - pie->rows.num_rows = num_rows; - pie->rows.first_y = 0; - pie->rows.raster = row_raster; -+ if (!pclxl_can_handle_color_space(pcs) -+ && pclxl_can_icctransform(pim) && pcs->cmm_icc_profile_data) { -+ gsicc_rendering_param_t rendering_params; -+ -+ rendering_params.black_point_comp = pis->blackptcomp; -+ rendering_params.graphics_type_tag = GS_IMAGE_TAG; -+ rendering_params.rendering_intent = pis->renderingintent; -+ pie->icclink = gsicc_get_link(pis, dev, pcs, NULL /*des */ , -+ &rendering_params, pis->memory); -+ } else -+ pie->icclink = NULL; - *pinfo = (gx_image_enum_common_t *) pie; - { - gs_logical_operation_t lop = pis->log_op; -@@ -2188,11 +2220,12 @@ - px_put_ub(s, eBit_values[8]); - PX_PUT_LIT(s, ci_); - if (xdev->color_info.depth==8) { -+ rows_raster/=3; -+ if (!pie->icclink) { - byte *in=pie->rows.data + offset_lastflippedstrip; - byte *out=pie->rows.data + offset_lastflippedstrip; - int i; - int j; -- rows_raster/=3; - for (j=0; jrows.first_y = pie->y; - } -+ if (!pie->icclink) - memcpy(pie->rows.data + - pie->rows.raster * (pie->flipped ? (pie->rows.num_rows - (pie->y - pie->rows.first_y) -1) :(pie->y - pie->rows.first_y)), - planes[0].data + planes[0].raster * i + (data_bit >> 3), - pie->rows.raster); -+ else { -+ gsicc_bufferdesc_t input_buff_desc; -+ gsicc_bufferdesc_t output_buff_desc; -+ int pixels_per_row = pie->rows.raster / 3 ; -+ int out_raster_stride = pixels_per_row * info->dev->color_info.num_components; -+ gsicc_init_buffer(&input_buff_desc, 3 /*num_chan*/, 1 /*bytes_per_chan*/, -+ false/*has_alpha*/, false/*alpha_first*/, false /*is_planar*/, -+ 0 /*plane_stride*/, pie->rows.raster /*row_stride*/, -+ 1/*num_rows*/, pixels_per_row /*pixels_per_row*/); -+ gsicc_init_buffer(&output_buff_desc, info->dev->color_info.num_components, 1, -+ false, false, false, -+ 0, out_raster_stride, -+ 1, pixels_per_row); -+ gscms_transform_color_buffer(info->dev, pie->icclink, -+ &input_buff_desc, -+ &output_buff_desc, -+ (void *)(planes[0].data + planes[0].raster * i + (data_bit >> 3)), /*src*/ -+ pie->rows.data + -+ out_raster_stride * (pie->flipped ? (pie->rows.num_rows - (pie->y - pie->rows.first_y) -1) : (pie->y - pie->rows.first_y)) /*des*/ -+ ); -+ } - } - *rows_used = height; - return pie->y >= pie->height; -@@ -2341,6 +2397,9 @@ - &(xdev->CompressMode))) < 0) - return (code); - -+ if ((code = param_write_bool(plist, "iccTransform", &(xdev->iccTransform))) < 0) -+ return (code); -+ - return (0); - } - -@@ -2446,6 +2505,7 @@ - } - booloption(Tumble, "Tumble") - intoption(CompressMode, "CompressMode", int) -+ booloption(iccTransform, "iccTransform") - - /* - * Then process standard page device parameters... diff -Nru ghostscript-9.10~dfsg/debian/patches/020140331-4b44b41-pxlcolor-support-jpeg-in-output.patch ghostscript-9.25~dfsg+1/debian/patches/020140331-4b44b41-pxlcolor-support-jpeg-in-output.patch --- ghostscript-9.10~dfsg/debian/patches/020140331-4b44b41-pxlcolor-support-jpeg-in-output.patch 2014-03-31 16:11:21.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140331-4b44b41-pxlcolor-support-jpeg-in-output.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,259 +0,0 @@ ---- a/devices/devs.mak -+++ b/devices/devs.mak -@@ -1184,7 +1184,7 @@ - $(gx_h) $(gsccolor_h) $(gsdcolor_h) $(gxiparam_h) $(gserrors_h)\ - $(gxcspace_h) $(gxdevice_h) $(gxpath_h)\ - $(gdevpxat_h) $(gdevpxen_h) $(gdevpxop_h) $(gdevpxut_h) $(gdevvec_h)\ -- $(srlx_h) $(strimpl_h) -+ $(srlx_h) $(strimpl_h) $(jpeglib__h) $(sdct_h) $(sjpeg_h) - $(DEVCC) $(DEVO_)gdevpx.$(OBJ) $(C_) $(DEVVECSRC)gdevpx.c - - # Scalable Vector Graphics (SVG) output device ---- a/devices/vector/gdevpx.c -+++ b/devices/vector/gdevpx.c -@@ -28,6 +28,9 @@ - #include "gdevvec.h" - #include "strimpl.h" - #include "srlx.h" -+#include "jpeglib_.h" -+#include "sdct.h" -+#include "sjpeg.h" - #include "gdevpxat.h" - #include "gdevpxen.h" - #include "gdevpxop.h" -@@ -99,7 +102,7 @@ - } chars; - bool font_set; - int state_rotated; /* 0, 1, 2, -1, mutiple of 90 deg */ -- int CompressMode; /* std PXL enum: None=0, RLE=1, DeltaRow=3; JPEG=2 not used */ -+ int CompressMode; /* std PXL enum: None=0, RLE=1, JPEG=2, DeltaRow=3 */ - bool scaled; - floatp x_scale; /* chosen so that max(x) is scaled to 0x7FFF, to give max distinction between x values */ - floatp y_scale; -@@ -719,6 +722,118 @@ - px_put_bytes(s, (const byte *)"\000\000\000\000", -(int)width_bytes & 3); - } - } -+ -+static void -+pclxl_write_image_data_JPEG(gx_device_pclxl * xdev, const byte * base, -+ int data_bit, uint raster, uint width_bits, int y, -+ int height) -+{ -+ stream *s = pclxl_stream(xdev); -+ uint width_bytes = (width_bits + 7) >> 3; -+ int i; -+ int count; -+ int code; -+ -+ /* cannot handle data_bit not multiple of 8, but we don't invoke this routine that way */ -+ int offset = data_bit >> 3; -+ const byte *data = base + offset; -+ jpeg_compress_data *jcdp = -+ gs_alloc_struct_immovable(xdev->v_memory, jpeg_compress_data, -+ &st_jpeg_compress_data, -+ "pclxl_write_image_data_JPEG(jpeg_compress_data)"); -+ stream_DCT_state state; -+ stream_cursor_read r; -+ stream_cursor_write w; -+ /* Approx. The worse case is ~ header + width_bytes * height. -+ Apparently minimal SOI/DHT/DQT/SOS/EOI is 341 bytes. TO CHECK. */ -+ int buffersize = 341 + width_bytes * height; -+ -+ byte *buf = gs_alloc_bytes(xdev->v_memory, buffersize, -+ "pclxl_write_image_data_JPEG(buf)"); -+ /* RLE can write uncompressed without extra-allocation */ -+ if ((buf == 0) || (jcdp == 0)) { -+ goto failed_so_use_rle_instead; -+ } -+ /* Create the DCT encoder state. */ -+ jcdp->templat = s_DCTE_template; -+ s_init_state((stream_state *) & state, &jcdp->templat, 0); -+ if (state.templat->set_defaults) { -+ state.memory = xdev->v_memory; -+ (*state.templat->set_defaults) ((stream_state *) & state); -+ state.memory = NULL; -+ } -+ state.ColorTransform = (xdev->color_info.num_components == 3 ? 1 : 0); -+ state.data.compress = jcdp; -+ state.icc_profile = NULL; -+ jcdp->memory = state.jpeg_memory = xdev->v_memory; -+ if ((code = gs_jpeg_create_compress(&state)) < 0) -+ goto cleanup_and_use_rle; -+ /* image-specific info */ -+ jcdp->cinfo.image_width = width_bytes / xdev->color_info.num_components; -+ jcdp->cinfo.image_height = height; -+ switch (xdev->color_info.num_components) { -+ case 3: -+ jcdp->cinfo.input_components = 3; -+ jcdp->cinfo.in_color_space = JCS_RGB; -+ break; -+ case 1: -+ jcdp->cinfo.input_components = 1; -+ jcdp->cinfo.in_color_space = JCS_GRAYSCALE; -+ break; -+ default: -+ goto cleanup_and_use_rle; -+ break; -+ } -+ /* Set compression parameters. */ -+ if ((code = gs_jpeg_set_defaults(&state)) < 0) -+ goto cleanup_and_use_rle; -+ -+ if (state.templat->init) -+ (*state.templat->init) ((stream_state *)&state); -+ state.scan_line_size = jcdp->cinfo.input_components * -+ jcdp->cinfo.image_width; -+ jcdp->templat.min_in_size = -+ max(s_DCTE_template.min_in_size, state.scan_line_size); -+ jcdp->templat.min_out_size = -+ max(s_DCTE_template.min_out_size, state.Markers.size); -+ -+ w.ptr = buf - 1; -+ w.limit = w.ptr + buffersize; -+ for (i = 0; i < height; ++i) { -+ r.ptr = data + i * raster - 1; -+ r.limit = r.ptr + width_bytes; -+ if (((code = (*state.templat->process) -+ ((stream_state *) & state, &r, &w, false)) != 0 && code != EOFC) || r.ptr != r.limit) -+ goto cleanup_and_use_rle; -+ } -+ count = w.ptr + 1 - buf; -+ px_put_usa(s, y, pxaStartLine); -+ px_put_usa(s, height, pxaBlockHeight); -+ px_put_ub(s, eJPEGCompression); -+ px_put_ac(s, pxaCompressMode, pxtReadImage); -+ px_put_data_length(s, count); -+ px_put_bytes(s, buf, count); -+ -+ gs_free_object(xdev->v_memory, buf, -+ "pclxl_write_image_data_JPEG(buf)"); -+ if (jcdp) -+ gs_jpeg_destroy(&state); /* frees *jcdp */ -+ return; -+ -+ cleanup_and_use_rle: -+ /* cleans up - something went wrong after allocation */ -+ gs_free_object(xdev->v_memory, buf, -+ "pclxl_write_image_data_JPEG(buf)"); -+ if (jcdp) -+ gs_jpeg_destroy(&state); /* frees *jcdp */ -+ /* fall through to redo in RLE */ -+ failed_so_use_rle_instead: -+ /* the RLE routine can write without new allocation - use as fallback. */ -+ pclxl_write_image_data_RLE(xdev, data, data_bit, raster, width_bits, y, -+ height); -+ return; -+} -+ - /* DeltaRow compression (also called "mode 3"): - drawn heavily from gdevcljc.c:cljc_print_page(), - This is simplier since PCL XL does not allow -@@ -773,24 +888,38 @@ - return; - } - -+/* calling from copy_mono/copy_color/fill_mask should never do lossy compression */ - static void --pclxl_write_image_data(gx_device_pclxl * xdev, const byte * data, int data_bit, -- uint raster, uint width_bits, int y, int height) -+pclxl_write_image_data(gx_device_pclxl * xdev, const byte * data, -+ int data_bit, uint raster, uint width_bits, int y, -+ int height, bool allow_lossy) - { -- /* If we only have 1 line, it does not make sense to do DeltaRow */ -+ /* If we only have 1 line, it does not make sense to do JPEG/DeltaRow */ - if (height < 2) { -- pclxl_write_image_data_RLE(xdev, data, data_bit, raster, width_bits, y, height); -- return; -- } -- -- switch(xdev->CompressMode){ -- case eDeltaRowCompression: -- pclxl_write_image_data_DeltaRow(xdev, data, data_bit, raster, width_bits, y, height); -- break; -- case eRLECompression: -- default: -- pclxl_write_image_data_RLE(xdev, data, data_bit, raster, width_bits, y, height); -- break; -+ pclxl_write_image_data_RLE(xdev, data, data_bit, raster, width_bits, -+ y, height); -+ return; -+ } -+ -+ switch (xdev->CompressMode) { -+ case eDeltaRowCompression: -+ pclxl_write_image_data_DeltaRow(xdev, data, data_bit, raster, -+ width_bits, y, height); -+ break; -+ case eJPEGCompression: -+ /* JPEG should not be used for mask or other data */ -+ if (allow_lossy) -+ pclxl_write_image_data_JPEG(xdev, data, data_bit, raster, -+ width_bits, y, height); -+ else -+ pclxl_write_image_data_RLE(xdev, data, data_bit, raster, -+ width_bits, y, height); -+ break; -+ case eRLECompression: -+ default: -+ pclxl_write_image_data_RLE(xdev, data, data_bit, raster, -+ width_bits, y, height); -+ break; - } - } - -@@ -1594,7 +1723,7 @@ - PX_PUT_LIT(s, mi_); - } - pclxl_write_begin_image(xdev, w, h, w, h); -- pclxl_write_image_data(xdev, data, data_x, raster, w, 0, h); -+ pclxl_write_image_data(xdev, data, data_x, raster, w, 0, h, false); - pclxl_write_end_image(xdev); - return 0; - } -@@ -1656,7 +1785,7 @@ - } - pclxl_write_begin_image(xdev, w, h, w, h); - pclxl_write_image_data(xdev, base, source_bit, raster, -- w * dev->color_info.depth, 0, h); -+ w * dev->color_info.depth, 0, h, false); - pclxl_write_end_image(xdev); - return 0; - } -@@ -1723,7 +1852,7 @@ - PX_PUT_LIT(s, mi_); - } - pclxl_write_begin_image(xdev, w, h, w, h); -- pclxl_write_image_data(xdev, data, data_x, raster, w, 0, h); -+ pclxl_write_image_data(xdev, data, data_x, raster, w, 0, h, false); - pclxl_write_end_image(xdev); - return 0; - } -@@ -2084,8 +2213,10 @@ - PX_PUT_LIT(s, ii_); - } - pclxl_write_begin_image(xdev, pie->width, h, dw, dh); -+ /* 8-bit gray image may compress with jpeg, but we -+ cannot tell if it is 8-bit gray or 8-bit indexed */ - pclxl_write_image_data(xdev, pie->rows.data + offset_lastflippedstrip, 0, rows_raster, -- rows_raster << 3, 0, h); -+ rows_raster << 3, 0, h, (pie->bits_per_pixel==24 ? true : false)); - pclxl_write_end_image(xdev); - return 0; - } ---- a/doc/Devices.htm -+++ b/doc/Devices.htm -@@ -783,8 +783,10 @@ -

Options

-
-
--
-dCompressMode=1 | 3 (default is 1) --
Set the compression algorithm used for bitmap graphics. RLE=1, DeltaRow=3. (JPEG=2 is unimplemented) -+
-dCompressMode=1 | 2 | 3 (default is 1) -+
Set the compression algorithm used for bitmap graphics. RLE=1, JPEG=2, DeltaRow=3. -+When JPEG=2 is on, it is applied only to full-color images; indexed-color graphics -+and masks continues to be compressed with RLE. -
- -

Text output

diff -Nru ghostscript-9.10~dfsg/debian/patches/020140331-8ae4ee2-fixes-pxl-segfault-with-trying-to-set-up-icc-transform-for-bitmasks.patch ghostscript-9.25~dfsg+1/debian/patches/020140331-8ae4ee2-fixes-pxl-segfault-with-trying-to-set-up-icc-transform-for-bitmasks.patch --- ghostscript-9.10~dfsg/debian/patches/020140331-8ae4ee2-fixes-pxl-segfault-with-trying-to-set-up-icc-transform-for-bitmasks.patch 2014-03-31 16:14:10.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140331-8ae4ee2-fixes-pxl-segfault-with-trying-to-set-up-icc-transform-for-bitmasks.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ ---- a/devices/vector/gdevpx.c -+++ b/devices/vector/gdevpx.c -@@ -2068,7 +2068,7 @@ - pie->rows.num_rows = num_rows; - pie->rows.first_y = 0; - pie->rows.raster = row_raster; -- if (!pclxl_can_handle_color_space(pcs) -+ if (!pim->ImageMask && !pclxl_can_handle_color_space(pcs) - && pclxl_can_icctransform(pim) && pcs->cmm_icc_profile_data) { - gsicc_rendering_param_t rendering_params; - diff -Nru ghostscript-9.10~dfsg/debian/patches/020140428-f4584b0-skip-unsupported-font-files.patch ghostscript-9.25~dfsg+1/debian/patches/020140428-f4584b0-skip-unsupported-font-files.patch --- ghostscript-9.10~dfsg/debian/patches/020140428-f4584b0-skip-unsupported-font-files.patch 2014-04-28 15:24:16.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140428-f4584b0-skip-unsupported-font-files.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ ---- a/Resource/Init/gs_fonts.ps -+++ b/Resource/Init/gs_fonts.ps -@@ -385,12 +385,20 @@ - pop pop pop - }{ - % we could open the font file -- .findfontname -- not { dup 0 get } if % stack: (newname) [ (name) (path) ] -- % DEBUG { ( found ) print dup print (\n) print flush } if -- % add entry to the fontmap -- 1 index exch 0 exch dup type /nametype ne {cvn} if put -- aload pop .definefontmap -+ mark 2 1 roll -+ {.findfontname} stopped -+ { -+ cleartomark -+ pop pop -+ } -+ { -+ 3 -1 roll pop -+ not { dup 0 get } if % stack: (newname) [ (name) (path) ] -+ % DEBUG { ( found ) print dup print (\n) print flush } if -+ % add entry to the fontmap -+ 1 index exch 0 exch dup type /nametype ne {cvn} if put -+ aload pop .definefontmap -+ } ifelse - } ifelse - } forall - } if diff -Nru ghostscript-9.10~dfsg/debian/patches/020140626-142b12b-null-check-for-icc-profile.patch ghostscript-9.25~dfsg+1/debian/patches/020140626-142b12b-null-check-for-icc-profile.patch --- ghostscript-9.10~dfsg/debian/patches/020140626-142b12b-null-check-for-icc-profile.patch 2014-06-26 18:08:24.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/020140626-142b12b-null-check-for-icc-profile.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ ---- a/base/gsicc.c -+++ b/base/gsicc.c -@@ -354,6 +354,8 @@ - cmm_dev_profile_t *dev_profile; - - code = dev_proc(dev, get_profile)(dev, &dev_profile); -+ if (dev_profile == NULL) -+ return gs_throw(gs_error_Fatal, "Attempting to do ICC remap with no profile"); - num_des_comps = gsicc_get_device_profile_comps(dev_profile); - rendering_params.black_point_comp = pis->blackptcomp; - rendering_params.graphics_type_tag = dev->graphics_type_tag; ---- a/base/gsstate.c -+++ b/base/gsstate.c -@@ -708,7 +708,7 @@ - } else { - dev_proc(dev, get_profile)(dev, &profile_struct); - } -- if (profile_struct->sim_overprint == false) return; -+ if (profile_struct != NULL && profile_struct->sim_overprint == false) return; - } - pgs->overprint = ovp; - if (prior_ovp != ovp) diff -Nru ghostscript-9.10~dfsg/debian/patches/1002_pxl-make-dicctransform-default.patch ghostscript-9.25~dfsg+1/debian/patches/1002_pxl-make-dicctransform-default.patch --- ghostscript-9.10~dfsg/debian/patches/1002_pxl-make-dicctransform-default.patch 2014-03-31 16:15:37.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/1002_pxl-make-dicctransform-default.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ ---- a/devices/vector/gdevpx.c -+++ b/devices/vector/gdevpx.c -@@ -109,7 +109,6 @@ - floatp y_scale; - bool pen_null; - bool brush_null; -- bool iccTransform; - } gx_device_pclxl; - - gs_public_st_suffix_add0_final(st_device_pclxl, gx_device_pclxl, -@@ -1551,7 +1550,6 @@ - xdev->MediaPosition = eAutoSelect; - xdev->MediaType_old[0] = '\0'; - xdev->MediaType[0] = '\0'; -- /* xdev->iccTransform = false; */ /* set true/false here to ignore command line */ - return 0; - } - -@@ -1962,7 +1960,7 @@ - ((!pclxl_can_handle_color_space(pcs) || - (bits_per_pixel != 1 && bits_per_pixel != 4 && - bits_per_pixel != 8 && bits_per_pixel !=24)) -- && !(pclxl_can_icctransform(pim) && xdev->iccTransform) )) || -+ && !pclxl_can_icctransform(pim) )) || - format != gs_image_format_chunky || pim->Interpolate || - prect - ) -@@ -2397,9 +2395,6 @@ - &(xdev->CompressMode))) < 0) - return (code); - -- if ((code = param_write_bool(plist, "iccTransform", &(xdev->iccTransform))) < 0) -- return (code); -- - return (0); - } - -@@ -2505,7 +2500,6 @@ - } - booloption(Tumble, "Tumble") - intoption(CompressMode, "CompressMode", int) -- booloption(iccTransform, "iccTransform") - - /* - * Then process standard page device parameters... diff -Nru ghostscript-9.10~dfsg/debian/patches/2001_docdir_fix_for_debian.patch ghostscript-9.25~dfsg+1/debian/patches/2001_docdir_fix_for_debian.patch --- ghostscript-9.10~dfsg/debian/patches/2001_docdir_fix_for_debian.patch 2013-08-09 18:24:43.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2001_docdir_fix_for_debian.patch 2018-08-08 11:29:37.000000000 +0000 @@ -1,14 +1,24 @@ Description: Set docdir appropriately for Debian Author: Masayuki Hatta +Last-Update: 2009-04-15 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/Makefile.in +++ b/Makefile.in -@@ -76,8 +76,8 @@ - gssharedir = @libdir@/ghostscript/$(GS_DOT_VERSION) +@@ -92,7 +92,7 @@ + man1ext = 1 + man1dir = $(mandir)/man$(man1ext) + datadir = @datadir@ +-docdir = @docdir@@VERSIONED_PATH@ ++docdir = $(prefix)/share/doc/ghostscript + + # The following must be substituted using @datadir@ and @libdir@ + # to avoid adding RPM generation paths (CUPS STR #1112) +@@ -101,7 +101,7 @@ + gssharedir = @libdir@/ghostscript@VERSIONED_PATH@ gsincludedir = @includedir@/ghostscript/ --docdir=$(gsdatadir)/doc -exdir=$(gsdatadir)/examples -+docdir=$(prefix)/share/doc/ghostscript +exdir=$(prefix)/share/doc/ghostscript/examples GS_DOCDIR=$(docdir) diff -Nru ghostscript-9.10~dfsg/debian/patches/2002_gs_man_fix_debian.patch ghostscript-9.25~dfsg+1/debian/patches/2002_gs_man_fix_debian.patch --- ghostscript-9.10~dfsg/debian/patches/2002_gs_man_fix_debian.patch 2012-08-01 17:55:06.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2002_gs_man_fix_debian.patch 2018-08-08 11:29:37.000000000 +0000 @@ -1,8 +1,11 @@ Description: Fixes for gs.1 (Debian specific path adjustments) Author: Masayuki Hatta +Last-Update: 2009-04-15 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/man/gs.1 +++ b/man/gs.1 -@@ -346,18 +346,18 @@ +@@ -340,18 +340,18 @@ are typically based in \fBC:\\GS\fR, but may be elsewhere, especially if you install Ghostscript with \fBGSview\fR. Run "\fBgs -h\fR" to find the location of Ghostscript documentation on your system, from which you can @@ -27,7 +30,7 @@ Diverse document files .SH "INITIALIZATION FILES" When looking for the initialization files "gs_*.ps", the files related to -@@ -381,7 +381,8 @@ +@@ -375,7 +375,8 @@ Ghostscript makefile when the executable was built. When \fBgs\fR is built on Unix, \fBGS_LIB_DEFAULT\fR is usually "/usr/local/share/ghostscript/#.##:/usr/local/share/ghostscript/fonts" diff -Nru ghostscript-9.10~dfsg/debian/patches/2003_support_multiarch.patch ghostscript-9.25~dfsg+1/debian/patches/2003_support_multiarch.patch --- ghostscript-9.10~dfsg/debian/patches/2003_support_multiarch.patch 2013-08-09 18:26:06.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2003_support_multiarch.patch 2018-09-13 18:27:06.000000000 +0000 @@ -1,10 +1,11 @@ Description: Check multiarch paths Author: Jonas Smedegaard Last-Update: 2011-09-19 - +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/base/unix-aux.mak +++ b/base/unix-aux.mak -@@ -118,39 +118,39 @@ +@@ -109,37 +109,37 @@ $(ECHOGS_XE) -a $(gconfig__h) $(ECHOGS_XE) -a $(gconfig__h) -x 23 ifndef HAVE_DIRENT_H @@ -48,6 +49,3 @@ else $(ECHOGS_XE) -a $(gconfig__h) -x 23 define HAVE_SYS_TIMES_H 0; fi $(ECHOGS_XE) -a $(gconfig__h) -x 23 endif $(ECHOGS_XE) -a $(gconfig__h) - -- if ( test -f $(JSRCDIR)/jmemsys.h); then true; else $(ECHOGS_XE) -a $(gconfig__h) -x 23 define DONT_HAVE_JMEMSYS_H; fi -+ if ( test -f $(JSRCDIR)/jmemsys.h || test -f $(INCLUDE)/$(DEB_HOST_MULTIARCH)/jmemsys.h ); then true; else $(ECHOGS_XE) -a $(gconfig__h) -x 23 define DONT_HAVE_JMEMSYS_H; fi diff -Nru ghostscript-9.10~dfsg/debian/patches/2004_remove_non-Debian_paths_from_docs.patch ghostscript-9.25~dfsg+1/debian/patches/2004_remove_non-Debian_paths_from_docs.patch --- ghostscript-9.10~dfsg/debian/patches/2004_remove_non-Debian_paths_from_docs.patch 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2004_remove_non-Debian_paths_from_docs.patch 2018-08-08 11:29:37.000000000 +0000 @@ -0,0 +1,70 @@ +Description: Remove non-Debian paths from documentation +Author: Bastien ROUCARIÈS +Last-Update: 2012-07-24 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/man/gs.1 ++++ b/man/gs.1 +@@ -2,20 +2,14 @@ + .SH NAME + gs \- Ghostscript (PostScript and PDF language interpreter and previewer) + .SH SYNOPSIS +-\fBgs\fR [ \fIoptions\fR ] [ \fIfiles\fR ] ... \fB(Unix, VMS)\fR +-.br +-\fBgswin32c\fR [ \fIoptions\fR ] [ \fIfiles\fR ] ... \fB(MS Windows)\fR +-.br +-\fBgswin32\fR [ \fIoptions\fR ] [ \fIfiles\fR ] ... \fB(MS Windows 3.1)\fR +-.br +-\fBgsos2\fR [ \fIoptions\fR ] [ \fIfiles\fR ] ... \fB(OS/2)\fR ++\fBgs\fR [ \fIoptions\fR ] [ \fIfiles\fR ] ... + .de TQ + .br + .ns + .TP \\$1 + .. + .SH DESCRIPTION +-The \fBgs\fR (\fBgswin32c\fR, \fBgswin32\fR, \fBgsos2\fR) ++The \fBgs\fR + command invokes \fBGhostscript\fR, an interpreter of Adobe Systems' + \fBPostScript\fR(tm) and \fBPortable Document Format\fR (PDF) languages. + \fBgs\fR reads "files" in sequence and executes them as Ghostscript +@@ -124,7 +118,7 @@ + in sequence. "%d" is a printf format specification; you can also use a + variant like "%02d". + .PP +-On Unix and MS Windows systems you can also send output to a pipe. For example, to ++You can also send output to a pipe. For example, to + pipe output to the "\fBlpr\fR" command (which, on many Unix systems, + directs it to a printer), use the option + .PP +@@ -132,9 +126,6 @@ + \-sOutputFile=%pipe%lpr + .fi + .PP +-Note that the '%' characters need to be doubled on MS Windows to avoid +-mangling by the command interpreter. +-.PP + You can also send output to standard output: + .PP + .nf +@@ -336,9 +327,8 @@ + .PP + The locations of many Ghostscript run-time files are compiled into the + executable when it is built. On Unix these are typically based in +-\fB/usr/local\fR, but this may be different on your system. Under DOS they +-are typically based in \fBC:\\GS\fR, but may be elsewhere, especially if +-you install Ghostscript with \fBGSview\fR. Run "\fBgs -h\fR" to find the ++\fB/usr/local\fR, but this may be different on your system. ++Run "\fBgs -h\fR" to find the + location of Ghostscript documentation on your system, from which you can + get more details. On a Debian system they are in \fB/usr\fR. + .TP +@@ -359,7 +349,7 @@ + the file with the name as given, using the current working directory if no + directory is specified. If this fails, and the file name doesn't specify + an explicit directory or drive (for instance, doesn't contain "/" on Unix +-systems or "\\" on MS Windows systems), Ghostscript tries directories in this ++systems), Ghostscript tries directories in this + order: + .TP 4 + 1. diff -Nru ghostscript-9.10~dfsg/debian/patches/2005_fix_Debian_paths_in_docs.patch ghostscript-9.25~dfsg+1/debian/patches/2005_fix_Debian_paths_in_docs.patch --- ghostscript-9.10~dfsg/debian/patches/2005_fix_Debian_paths_in_docs.patch 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2005_fix_Debian_paths_in_docs.patch 2018-08-08 11:29:37.000000000 +0000 @@ -0,0 +1,56 @@ +Description: Fix Debian paths in documentation +Author: Bastien ROUCARIÈS +Last-Update: 2012-07-24 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/man/gs.1 ++++ b/man/gs.1 +@@ -326,23 +326,23 @@ + .SH FILES + .PP + The locations of many Ghostscript run-time files are compiled into the +-executable when it is built. On Unix these are typically based in +-\fB/usr/local\fR, but this may be different on your system. ++executable when it is built. + Run "\fBgs -h\fR" to find the + location of Ghostscript documentation on your system, from which you can + get more details. On a Debian system they are in \fB/usr\fR. + .TP +-.B /usr/share/gs-gpl/#.##/*/* +-Startup files, utilities, and basic font definitions ++.B /usr/share/ghostscript/[0-9]*.[0.9]*/* ++Startup files, utilities, and basic font definitions (where [0-9]*.[0.9]* is ++the ghostscript version) + .TP + .B /usr/share/fonts/type1/gsfonts/* + More font definitions from the gsfonts package + .TP +-.B /usr/share/doc/gs-gpl/examples/* +-Ghostscript demonstration files ++.B /usr/share/doc/ghostscript/examples/* ++Ghostscript demonstration files (if ghostscript-doc package is installed) + .TP +-.B /usr/share/doc/gs-gpl/* +-Diverse document files ++.B /usr/share/doc/ghostscript/* ++Diverse document files (may need to install ghostscript-doc package) + .SH "INITIALIZATION FILES" + When looking for the initialization files "gs_*.ps", the files related to + fonts, or the file for the "run" operator, Ghostscript first tries to open +@@ -362,11 +362,11 @@ + .TP + 3. + the directories specified by the \fBGS_LIB_DEFAULT\fR macro in the +-Ghostscript makefile when the executable was built. When \fBgs\fR is built +-on Unix, \fBGS_LIB_DEFAULT\fR is usually +-"/usr/local/share/ghostscript/#.##:/usr/local/share/ghostscript/fonts" +-where "#.##" represents the Ghostscript version number. They are +-"/usr/share/gs-gpl/#.## on a Debian system". ++Ghostscript makefile when the executable was built. ++\fBGS_LIB_DEFAULT\fR is ++"/usr/share/ghostscript/[0-9]*.[0-9]*/lib" ++on a Debian system where ++"[0-9]*.[0-9]*" represents the Ghostscript version number + .PP + Each of these (\fBGS_LIB_DEFAULT\fR, \fBGS_LIB\fR, and \fB\-I\fR parameter) + may be either a single directory or a list of directories separated by diff -Nru ghostscript-9.10~dfsg/debian/patches/2006_suggest_install_ghostscript-doc_in_docs.patch ghostscript-9.25~dfsg+1/debian/patches/2006_suggest_install_ghostscript-doc_in_docs.patch --- ghostscript-9.10~dfsg/debian/patches/2006_suggest_install_ghostscript-doc_in_docs.patch 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2006_suggest_install_ghostscript-doc_in_docs.patch 2018-08-08 11:29:37.000000000 +0000 @@ -0,0 +1,18 @@ +Description: Suggest install of ghostscript-doc in documentation +Author: Bastien ROUCARIÈS +Last-Update: 2012-07-24 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/man/gs.1 ++++ b/man/gs.1 +@@ -428,7 +428,9 @@ + % xrdb \-merge ~/.Xresources + .fi + .SH SEE ALSO +-The various Ghostscript document files (above), especially \fBUse.htm\fR. ++The various Ghostscript document files (above), especially \fBUse.htm\fR. ++On Debian you may need to install ghostscript-doc before ++reading the documentation. + .SH BUGS + See http://bugs.ghostscript.com/ and the Usenet news group + comp.lang.postscript. diff -Nru ghostscript-9.10~dfsg/debian/patches/2007_suggest_install_ghostscript-doc_in_code.patch ghostscript-9.25~dfsg+1/debian/patches/2007_suggest_install_ghostscript-doc_in_code.patch --- ghostscript-9.10~dfsg/debian/patches/2007_suggest_install_ghostscript-doc_in_code.patch 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2007_suggest_install_ghostscript-doc_in_code.patch 2018-09-13 18:27:06.000000000 +0000 @@ -0,0 +1,15 @@ +Description: Suggest install of ghostscript-doc in code +Author: Bastien ROUCARIÈS +Last-Update: 2012-07-24 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/psi/imainarg.c ++++ b/psi/imainarg.c +@@ -1123,6 +1123,7 @@ + #endif + static const char help_trailer[] = "\ + For more information, see %s.\n\ ++On debian system you may need to install ghostscript-doc package.\n\ + Please report bugs to bugs.ghostscript.com.\n"; + static const char help_devices[] = "Available devices:"; + static const char help_default_device[] = "Default output device:"; diff -Nru ghostscript-9.10~dfsg/debian/patches/2008_mention_ghostscript-x_in_docs.patch ghostscript-9.25~dfsg+1/debian/patches/2008_mention_ghostscript-x_in_docs.patch --- ghostscript-9.10~dfsg/debian/patches/2008_mention_ghostscript-x_in_docs.patch 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2008_mention_ghostscript-x_in_docs.patch 2018-02-23 20:04:45.000000000 +0000 @@ -0,0 +1,18 @@ +Description: Mention ghostscipt-x affect on default device in docs +Author: Bastien ROUCARIÈS +Last-Update: 2012-07-24 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/man/gs.1 ++++ b/man/gs.1 +@@ -36,9 +36,8 @@ + specify a particular device, Ghostscript normally opens the first one of + those and directs output to it. + .PP +-If built with X11 support, often ++If you have installed the ghostscript-x Debian package and are under X, + the default device is an X11 window (previewer), else ghostscript will +-typically + use the bbox device and print on stdout the dimension of the postscript file. + .PP + So if the first one in the list is the one diff -Nru ghostscript-9.10~dfsg/debian/patches/2010_add_build_timestamp_setting.patch ghostscript-9.25~dfsg+1/debian/patches/2010_add_build_timestamp_setting.patch --- ghostscript-9.10~dfsg/debian/patches/2010_add_build_timestamp_setting.patch 1970-01-01 00:00:00.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/2010_add_build_timestamp_setting.patch 2018-09-06 18:21:03.000000000 +0000 @@ -0,0 +1,122 @@ +Description: Allow the build timestamp to be externally set + In order to make Ghostscript output reproducible, we need a way to + set the build timestamp to other values than the current time. + We now consistently use gp_get_realtime() instead of directly calling + time() or gp_get_usertime() and make gp_get_realtime() use the value + found in the SOURCE_DATE_EPOCH environment variable if set. Also, + environment timezone is fixed to UTC if SOURCE_DATE_EPOCH is used to + avoid variations. +Author: Eduard Sanou +Author: Peter De Wachter +Bug-Debian: http://bugs.debian.org/794004 +Last-Update: 2015-07-30 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/base/gp_unix.c ++++ b/base/gp_unix.c +@@ -16,6 +16,7 @@ + + /* Unix-specific routines for Ghostscript */ + ++#include "errno_.h" + #include "pipe_.h" + #include "string_.h" + #include "time_.h" +@@ -145,6 +146,7 @@ + gp_get_realtime(long *pdt) + { + struct timeval tp; ++ const char *env; + + #if gettimeofday_no_timezone /* older versions of SVR4 */ + { +@@ -164,6 +166,26 @@ + } + #endif + ++ env = getenv("SOURCE_DATE_EPOCH"); ++ if (env) { ++ char *end; ++ long timestamp; ++ ++ errno = 0; ++ timestamp = strtol(env, &end, 10); ++ if (env == end || *end || errno != 0) { ++ lprintf("Ghostscript: SOURCE_DATE_EPOCH is not a number!\n"); ++ timestamp = 0; ++ } ++ ++ tp.tv_sec = timestamp; ++ tp.tv_usec = 0; ++ ++ /* We need to fix the environment timezone to get reproducible */ ++ /* results when parsing the result of gp_get_realtime. */ ++ setenv("TZ", "UTC", 1); ++ } ++ + /* tp.tv_sec is #secs since Jan 1, 1970 */ + pdt[0] = tp.tv_sec; + +--- a/devices/vector/gdevpdf.c ++++ b/devices/vector/gdevpdf.c +@@ -391,6 +391,9 @@ + */ + { + struct tm tms; ++#ifndef CLUSTER ++ long secs_ns[2]; ++#endif + time_t t; + char buf[1+2+4+2+2+2+2+2+1+2+1+2+1+1+1]; /* (D:yyyymmddhhmmssZhh'mm')\0 */ + int timeoffset; +@@ -402,7 +405,8 @@ + timesign = 'Z'; + timeoffset = 0; + #else +- time(&t); ++ gp_get_realtime(secs_ns); ++ t = secs_ns[0]; + tms = *gmtime(&t); + tms.tm_isdst = -1; + timeoffset = (int)difftime(t, mktime(&tms)); /* tz+dst in seconds */ +@@ -446,7 +450,7 @@ + if (s == NULL) + return_error(gs_error_VMerror); + pdev->KeyLength = 0; /* Disable encryption. Not so important though. */ +- gp_get_usertime(secs_ns); ++ gp_get_realtime(secs_ns); + sputs(s, (byte *)secs_ns, sizeof(secs_ns), &ignore); + sputs(s, (const byte *)pdev->fname, strlen(pdev->fname), &ignore); + pdev->strm = s; +--- a/devices/vector/gdevpdfe.c ++++ b/devices/vector/gdevpdfe.c +@@ -199,10 +199,12 @@ + { + /* We don't write a day time because we don't have a time zone. */ + struct tm tms; ++ long secs_ns[2]; + time_t t; + char buf1[4+1+2+1+2+1]; /* yyyy-mm-dd\0 */ + +- time(&t); ++ gp_get_realtime(secs_ns); ++ t = secs_ns[0]; + tms = *localtime(&t); + gs_sprintf(buf1, + "%04d-%02d-%02d", +--- a/devices/vector/gdevpsu.c ++++ b/devices/vector/gdevpsu.c +@@ -183,10 +183,12 @@ + fprintf(f, "%%%%Creator: %s %ld (%s)\n", gs_product, (long)gs_revision, + dev->dname); + { ++ long secs_ns[2]; + time_t t; + struct tm tms; + +- time(&t); ++ gp_get_realtime(secs_ns); ++ t = secs_ns[0]; + tms = *localtime(&t); + fprintf(f, "%%%%CreationDate: %d/%02d/%02d %02d:%02d:%02d\n", + tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2013-5653.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2013-5653.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2013-5653.patch 2016-11-28 21:54:37.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2013-5653.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ -Description: CVE-2013-5653: Information disclosure through getenv, filenameforall -Origin: backport, http://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=ab109aaeb3ddba59518b036fb288402a65cf7ce8 -Bug: http://bugs.ghostscript.com/show_bug.cgi?id=694724 -Bug-Debian: https://bugs.debian.org/839118 -Forwarded: not-needed -Author: Salvatore Bonaccorso -Reviewed-by: Emily Ratliff -Last-Update: 2016-11-23 ---- - ---- ghostscript-9.10~dfsg.orig/Resource/Init/gs_init.ps -+++ ghostscript-9.10~dfsg/Resource/Init/gs_init.ps -@@ -2017,6 +2017,7 @@ readonly def - - /.locksafe { - .locksafe_userparams -+ systemdict /getenv {pop //false} put - % setpagedevice has the side effect of clearing the page, but - % we will just document that. Using setpagedevice keeps the device - % properties and pagedevice .LockSafetyParams in agreement even -@@ -2035,6 +2036,7 @@ readonly def - %% - /.locksafeglobal { - .locksafe_userparams -+ systemdict /getenv {pop //false} put - % setpagedevice has the side effect of clearing the page, but - % we will just document that. Using setpagedevice keeps the device - % properties and pagedevice .LockSafetyParams in agreement even ---- ghostscript-9.10~dfsg.orig/psi/zfile.c -+++ ghostscript-9.10~dfsg/psi/zfile.c -@@ -390,22 +390,25 @@ file_continue(i_ctx_t *i_ctx_p) - - if (len < devlen) - return_error(e_rangecheck); /* not even room for device len */ -- memcpy((char *)pscratch->value.bytes, iodev->dname, devlen); -- code = iodev->procs.enumerate_next(pfen, (char *)pscratch->value.bytes + devlen, -- len - devlen); -- if (code == ~(uint) 0) { /* all done */ -- esp -= 5; /* pop proc, pfen, devlen, iodev , mark */ -- return o_pop_estack; -- } else if (code > len) /* overran string */ -- return_error(e_rangecheck); -- else { -- push(1); -- ref_assign(op, pscratch); -- r_set_size(op, code + devlen); -- push_op_estack(file_continue); /* come again */ -- *++esp = pscratch[2]; /* proc */ -- return o_push_estack; -- } -+ do { -+ memcpy((char *)pscratch->value.bytes, iodev->dname, devlen); -+ code = iodev->procs.enumerate_next(pfen, (char *)pscratch->value.bytes + devlen, -+ len - devlen); -+ if (code == ~(uint) 0) { /* all done */ -+ esp -= 5; /* pop proc, pfen, devlen, iodev , mark */ -+ return o_pop_estack; -+ } else if (code > len) /* overran string */ -+ return_error(e_rangecheck); -+ else if (iodev != iodev_default(imemory) -+ || (check_file_permissions_reduced(i_ctx_p, (char *)pscratch->value.bytes, code + devlen, "PermitFileReading")) == 0) { -+ push(1); -+ ref_assign(op, pscratch); -+ r_set_size(op, code + devlen); -+ push_op_estack(file_continue); /* come again */ -+ *++esp = pscratch[2]; /* proc */ -+ return o_push_estack; -+ } -+ } while(1); - } - /* Cleanup procedure for enumerating files */ - static int diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2013-5653-regression.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2013-5653-regression.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2013-5653-regression.patch 2016-12-05 17:16:14.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2013-5653-regression.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -Description: Replace put with .forceput in .locksafe -Origin: upstream, http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=99e331527d541a8f01ad5455c4eb2aabd67281a6 -Bug-Debian: https://bugs.debian.org/840691 -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/ghostscript/+bug/1647276 -Forwarded: not-needed -Author: Ken Sharp -Reviewed-by: Salvatore Bonaccorso -Reviewed-by: Emily Ratliff -Last-Update: 2016-12-05 ---- - ---- ghostscript-9.10~dfsg.orig/Resource/Init/gs_init.ps -+++ ghostscript-9.10~dfsg/Resource/Init/gs_init.ps -@@ -2017,7 +2017,7 @@ readonly def - - /.locksafe { - .locksafe_userparams -- systemdict /getenv {pop //false} put -+ systemdict /getenv {pop //false} .forceput - % setpagedevice has the side effect of clearing the page, but - % we will just document that. Using setpagedevice keeps the device - % properties and pagedevice .LockSafetyParams in agreement even diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2015-3228.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2015-3228.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2015-3228.patch 2015-07-29 20:03:42.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2015-3228.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -From 0c0b0859ae1aba64861599f0e7f74f143f305932 Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Tue, 7 Jul 2015 16:57:41 +0100 -Subject: [PATCH] Bug 696041: sanity check for memory allocation. - -In gs_heap_alloc_bytes(), add a sanity check to ensure we don't overflow the -variable holding the actual number of bytes we allocate. - -No cluster differences ---- - gs/base/gsmalloc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/base/gsmalloc.c b/base/gsmalloc.c -index 624552d..cad79c2 100644 ---- a/base/gsmalloc.c -+++ b/base/gsmalloc.c -@@ -178,7 +178,7 @@ gs_heap_alloc_bytes(gs_memory_t * mem, uint size, client_name_t cname) - } else { - uint added = size + sizeof(gs_malloc_block_t); - -- if (mmem->limit - added < mmem->used) -+ if (added <= size || mmem->limit - added < mmem->used) - set_msg("exceeded limit"); - else if ((ptr = (byte *) Memento_label(malloc(added), cname)) == 0) - set_msg("failed"); --- -2.4.6 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-10217.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10217.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-10217.patch 2017-04-28 00:40:15.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10217.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From 90fd0c7ca3efc1ddff64a86f4104b13b3ac969eb Mon Sep 17 00:00:00 2001 -From: Michael Vrhel -Date: Thu, 29 Dec 2016 14:00:21 -0800 -Subject: [PATCH] Bug 697456. Dont create new ctx when pdf14 device reenabled - -This bug had yet another weird case where the user created a -file that pushed the pdf14 device twice. We were in that case, -creating a new ctx and blowing away the original one with out -proper clean up. To avoid, only create a new one when we need it. ---- - base/gdevp14.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/base/gdevp14.c b/base/gdevp14.c -index fd56ec9..f19318e 100644 ---- a/base/gdevp14.c -+++ b/base/gdevp14.c -@@ -1669,8 +1669,10 @@ pdf14_open(gx_device *dev) - rect.p.y = 0; - rect.q.x = dev->width; - rect.q.y = dev->height; -- pdev->ctx = pdf14_ctx_new(&rect, dev->color_info.num_components, -- pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, dev); -+ /* If we are reenabling the device dont create a new ctx. Bug 697456 */ -+ if (pdev->ctx == NULL) -+ pdev->ctx = pdf14_ctx_new(&rect, dev->color_info.num_components, -+ pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE, dev); - if (pdev->ctx == NULL) - return_error(gs_error_VMerror); - pdev->free_devicen = true; --- -2.7.4 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-10219.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10219.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-10219.patch 2017-04-28 00:40:20.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10219.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -From 4bef1a1d32e29b68855616020dbff574b9cda08f Mon Sep 17 00:00:00 2001 -From: Robin Watts -Date: Thu, 29 Dec 2016 15:57:43 +0000 -Subject: [PATCH] Bug 697453: Avoid divide by 0 in scan conversion code. - -Arithmetic overflow due to extreme values in the scan conversion -code can cause a division by 0. - -Avoid this with a simple extra check. - - dx_old=cf814d81 - endp->x_next=b0e859b9 - alp->x_next=8069a73a - -leads to dx_den = 0 ---- - base/gxfill.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/base/gxfill.c b/base/gxfill.c -index 99196c0..2f81bb0 100644 ---- a/base/gxfill.c -+++ b/base/gxfill.c -@@ -1741,7 +1741,7 @@ intersect(active_line *endp, active_line *alp, fixed y, fixed y1, fixed *p_y_new - fixed dx_old = alp->x_current - endp->x_current; - fixed dx_den = dx_old + endp->x_next - alp->x_next; - -- if (dx_den <= dx_old) -+ if (dx_den <= dx_old || dx_den == 0) - return false; /* Intersection isn't possible. */ - dy = y1 - y; - if_debug3('F', "[F]cross: dy=%g, dx_old=%g, dx_new=%g\n", -@@ -1750,7 +1750,7 @@ intersect(active_line *endp, active_line *alp, fixed y, fixed y1, fixed *p_y_new - /* Do the computation in single precision */ - /* if the values are small enough. */ - y_new = -- ((dy | dx_old) < 1L << (size_of(fixed) * 4 - 1) ? -+ (((ufixed)(dy | dx_old)) < (1L << (size_of(fixed) * 4 - 1)) ? - dy * dx_old / dx_den : - (INCR_EXPR(mq_cross), fixed_mult_quo(dy, dx_old, dx_den))) - + y; --- -2.7.4 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-10220.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10220.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-10220.patch 2017-04-28 00:40:26.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10220.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -From daf85701dab05f17e924a48a81edc9195b4a04e8 Mon Sep 17 00:00:00 2001 -From: Ken Sharp -Date: Wed, 21 Dec 2016 16:54:14 +0000 -Subject: [PATCH] fix crash with bad data supplied to makeimagedevice - -Bug #697450 "Null pointer dereference in gx_device_finalize()" - -The problem here is that the code to finalise a device unconditionally -frees the icc_struct member of the device structure. However this -particular (weird) device is not setup as a normal device, probably -because its very, very ancient. Its possible for the initialisation -of the device to abort with an error before calling gs_make_mem_device() -which is where the icc_struct member gets allocated (or set to NULL). - -If that happens, then the cleanup code tries to free the device, which -calls finalize() which tries to free a garbage pointer. - -Setting the device memory to 0x00 after we allocate it means that the -icc_struct member will be NULL< and our memory manager allows for that -happily enough, which avoids the problem. ---- - base/gsdevmem.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/base/gsdevmem.c b/base/gsdevmem.c -index 97b9cf4..fe75bcc 100644 ---- a/base/gsdevmem.c -+++ b/base/gsdevmem.c -@@ -225,6 +225,18 @@ gs_makewordimagedevice(gx_device ** pnew_dev, const gs_matrix * pmat, - - if (pnew == 0) - return_error(gs_error_VMerror); -+ -+ /* Bug #697450 "Null pointer dereference in gx_device_finalize()" -+ * If we have incorrect data passed to gs_initialise_wordimagedevice() then the -+ * initialisation will fail, crucially it will fail *before* it calls -+ * gs_make_mem_device() which initialises the device. This means that the -+ * icc_struct member will be uninitialsed, but the device finalise method -+ * will unconditionally free that memory. Since its a garbage pointer, bad things happen. -+ * Apparently we do still need makeimagedevice to be available from -+ * PostScript, so in here just zero the device memory, which means that -+ * the finalise routine won't have a problem. -+ */ -+ memset(pnew, 0x00, st_device_memory.ssize); - code = gs_initialize_wordimagedevice(pnew, pmat, width, height, - colors, num_colors, word_oriented, - page_device, mem); --- -2.7.4 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-10317.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10317.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-10317.patch 2018-04-23 17:20:52.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-10317.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -Backported of: - -From 362ec9daadb9992b0def3520cd1dc6fa52edd1c4 Mon Sep 17 00:00:00 2001 -From: Ray Johnston -Date: Tue, 21 Nov 2017 12:48:54 -0800 -Subject: [PATCH] Fix bug 697459 Buffer overflow in fill_threshold_buffer - -There was an overflow check for ht_buffer size, but none for the larger -threshold_buffer. Note that this file didn't fail on Windows because the -combination of the ht_buffer and the size of the (miscalculated due to -overflow) threshold_buffer would have exceeded the 2Gb limit. -diff --git a/base/gxht_thresh.c b/base/gxht_thresh.c -index 3587454..fba5b23 100644 ---- a/base/gxht_thresh.c -+++ b/base/gxht_thresh.c -@@ -705,6 +705,11 @@ gxht_thresh_image_init(gx_image_enum *penum) - space */ - max_height = (int) ceil(fixed2float(any_abs(penum->dst_height)) / - (float) penum->Height); -+ if (max_height <= 0) -+ return -1; /* shouldn't happen, but check so we don't div by zero */ -+ if (penum->ht_stride * spp_out > max_int / max_height) -+ return -1; -+ - penum->ht_buffer = - gs_alloc_bytes(penum->memory, - penum->ht_stride * max_height * spp_out, -@@ -725,6 +730,11 @@ gxht_thresh_image_init(gx_image_enum *penum) - Also allow a 15 sample over run during the execution. */ - temp = (int) ceil((float) ((dev_width + 15.0) + 15.0)/16.0); - penum->line_size = bitmap_raster(temp * 16 * 8); /* The stride */ -+ if (penum->line_size > max_int / max_height) { -+ gs_free_object(penum->memory, penum->ht_buffer, "gxht_thresh"); -+ penum->ht_buffer = NULL; -+ return -1; /* thresh_buffer size overflow */ -+ } - penum->line = gs_alloc_bytes(penum->memory, penum->line_size * spp_out, - "gxht_thresh"); - penum->thresh_buffer = gs_alloc_bytes(penum->memory, -@@ -747,7 +757,7 @@ gxht_thresh_image_init(gx_image_enum *penum) - } - - static void --fill_threshhold_buffer(byte *dest_strip, byte *src_strip, int src_width, -+fill_threshold_buffer(byte *dest_strip, byte *src_strip, int src_width, - int left_offset, int left_width, int num_tiles, - int right_width) - { -@@ -911,7 +921,7 @@ gxht_thresh_planes(gx_image_enum *penum, fixed xrun, - to update with stride */ - position = contone_stride * k; - /* Tile into the 128 bit aligned threshold strip */ -- fill_threshhold_buffer(&(thresh_align[position]), -+ fill_threshold_buffer(&(thresh_align[position]), - thresh_tile, thresh_width, dx, left_width, - num_full_tiles, right_tile_width); - } -diff --git a/base/gxipixel.c b/base/gxipixel.c -index 7b7d034..3b2f156 100644 ---- a/base/gxipixel.c -+++ b/base/gxipixel.c -@@ -692,7 +692,7 @@ gx_image_enum_begin(gx_device * dev, const gs_imager_state * pis, - penum->memory = mem; - penum->buffer = buffer; - penum->buffer_size = bsize; -- penum->line = 0; -+ penum->line = NULL; - penum->icc_link = NULL; - penum->color_cache = NULL; - penum->ht_buffer = NULL; diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-7976.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-7976.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-7976.patch 2016-11-28 21:54:46.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-7976.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ -Description: CVE-2016-7976: Various userparams allow %pipe% in paths, allowing remote shell command execution -Origin: backport, http://git.ghostscript.com/?p=ghostpdl.git;h=6d444c273da5499a4cd72f21cb6d4c9a5256807d -Bug: http://bugs.ghostscript.com/show_bug.cgi?id=697178 -Bug-Debian: https://bugs.debian.org/839260 -Forwarded: not-needed -Author: Salvatore Bonaccorso -Reviewed-by: Emily Ratliff -Last-Update: 2016-11-23 ---- - ---- ghostscript-9.10~dfsg.orig/base/gsicc_manage.c -+++ ghostscript-9.10~dfsg/base/gsicc_manage.c -@@ -1009,10 +1009,12 @@ gsicc_open_search(const char* pname, int - } - - /* First just try it like it is */ -- str = sfopen(pname, "rb", mem_gc); -- if (str != NULL) { -- *strp = str; -- return 0; -+ if (gs_check_file_permission(mem_gc, pname, namelen, "r") >= 0) { -+ str = sfopen(pname, "r", mem_gc); -+ if (str != NULL) { -+ *strp = str; -+ return 0; -+ } - } - - /* If that fails, try %rom% */ /* FIXME: Not sure this is needed or correct */ ---- ghostscript-9.10~dfsg.orig/base/gslibctx.c -+++ ghostscript-9.10~dfsg/base/gslibctx.c -@@ -122,6 +122,7 @@ int gs_lib_ctx_init( gs_memory_t *mem ) - return -1; - } - -+ pio->client_check_file_permission = NULL; - gp_get_realtime(pio->real_time_0); - - return 0; -@@ -233,3 +234,13 @@ void errflush(const gs_memory_t *mem) - fflush(mem->gs_lib_ctx->fstderr); - /* else nothing to flush */ - } -+ -+int -+gs_check_file_permission (gs_memory_t *mem, const char *fname, const int len, const char *permission) -+{ -+ int code = 0; -+ if (mem->gs_lib_ctx->client_check_file_permission != NULL) { -+ code = mem->gs_lib_ctx->client_check_file_permission(mem, fname, len, permission); -+ } -+ return code; -+} ---- ghostscript-9.10~dfsg.orig/base/gslibctx.h -+++ ghostscript-9.10~dfsg/base/gslibctx.h -@@ -32,6 +32,9 @@ typedef struct gs_fapi_server_s gs_fapi_ - # define gs_font_dir_DEFINED - typedef struct gs_font_dir_s gs_font_dir; - #endif -+ -+typedef int (*client_check_file_permission_t) (gs_memory_t *mem, const char *fname, const int len, const char *permission); -+ - typedef struct gs_lib_ctx_s - { - gs_memory_t *memory; /* mem->gs_lib_ctx->memory == mem */ -@@ -59,6 +62,7 @@ typedef struct gs_lib_ctx_s - bool dict_auto_expand; /* ps dictionary: false level 1 true level 2 or 3 */ - /* A table of local copies of the IODevices */ - struct gx_io_device_s **io_device_table; -+ client_check_file_permission_t client_check_file_permission; - /* Define the default value of AccurateScreens that affects setscreen - and setcolorscreen. */ - bool screen_accurate_screens; -@@ -108,4 +112,7 @@ gs_memory_t * gs_lib_ctx_get_non_gc_memo - void gs_lib_ctx_set_icc_directory(const gs_memory_t *mem_gc, const char* pname, - int dir_namelen); - -+int -+gs_check_file_permission (gs_memory_t *mem, const char *fname, const int len, const char *permission); -+ - #endif /* GSLIBCTX_H */ ---- ghostscript-9.10~dfsg.orig/psi/imain.c -+++ ghostscript-9.10~dfsg/psi/imain.c -@@ -51,6 +51,7 @@ - #include "ivmspace.h" - #include "idisp.h" /* for setting display device callback */ - #include "iplugin.h" -+#include "zfile.h" - - #ifdef PACIFY_VALGRIND - #include "valgrind.h" -@@ -209,6 +210,7 @@ gs_main_init1(gs_main_instance * minst) - "the_gs_name_table"); - if (code < 0) - return code; -+ mem->gs_lib_ctx->client_check_file_permission = z_check_file_permissions; - } - code = obj_init(&minst->i_ctx_p, &idmem); /* requires name_init */ - if (code < 0) ---- ghostscript-9.10~dfsg.orig/psi/int.mak -+++ ghostscript-9.10~dfsg/psi/int.mak -@@ -1871,7 +1871,8 @@ $(PSOBJ)imain.$(OBJ) : $(PSSRC)imain.c $ - $(ialloc_h) $(iconf_h) $(idebug_h) $(idict_h) $(idisp_h) $(iinit_h)\ - $(iname_h) $(interp_h) $(iplugin_h) $(isave_h) $(iscan_h) $(ivmspace_h)\ - $(iinit_h) $(main_h) $(oper_h) $(ostack_h)\ -- $(sfilter_h) $(store_h) $(stream_h) $(strimpl_h) -+ $(sfilter_h) $(store_h) $(stream_h) $(strimpl_h) $(zfile_h)\ -+ $(INT_MAK) $(MAKEDIRS) - $(PSCC) $(PSO_)imain.$(OBJ) $(C_) $(PSSRC)imain.c - - #****** $(CCINT) interp.c ---- ghostscript-9.10~dfsg.orig/psi/zfile.c -+++ ghostscript-9.10~dfsg/psi/zfile.c -@@ -197,6 +197,25 @@ check_file_permissions(i_ctx_t *i_ctx_p, - return check_file_permissions_reduced(i_ctx_p, fname_reduced, rlen, permitgroup); - } - -+/* z_check_file_permissions: see zfile.h for explanation -+ */ -+int -+z_check_file_permissions(gs_memory_t *mem, const char *fname, const int len, const char *permission) -+{ -+ i_ctx_t *i_ctx_p = get_minst_from_memory(mem)->i_ctx_p; -+ gs_parsed_file_name_t pname; -+ const char *permitgroup = permission[0] == 'r' ? "PermitFileReading" : "PermitFileWriting"; -+ int code = gs_parse_file_name(&pname, fname, len, imemory); -+ if (code < 0) -+ return code; -+ -+ if (pname.iodev && i_ctx_p->LockFilePermissions && strcmp(pname.iodev->dname, "%pipe%") == 0) -+ return gs_error_invalidfileaccess; -+ -+ code = check_file_permissions(i_ctx_p, fname, len, permitgroup); -+ return code; -+} -+ - /* file */ - int /* exported for zsysvm.c */ - zfile(i_ctx_t *i_ctx_p) ---- ghostscript-9.10~dfsg.orig/psi/zfile.h -+++ ghostscript-9.10~dfsg/psi/zfile.h -@@ -22,4 +22,11 @@ - int zopen_file(i_ctx_t *i_ctx_p, const gs_parsed_file_name_t *pfn, - const char *file_access, stream **ps, gs_memory_t *mem); - -+/* z_check_file_permissions: a callback (via mem->gs_lib_ctx->client_check_file_permission) -+ * to allow applying the above permissions checks when opening file(s) from -+ * the graphics library -+ */ -+int -+z_check_file_permissions(gs_memory_t *mem, const char *fname, -+ const int len, const char *permission); - #endif diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-7978.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-7978.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-7978.patch 2016-11-28 21:54:46.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-7978.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -Description: CVE-2016-7978: reference leak in .setdevice allows use-after-free and remote code execution -Origin: upstream, http://git.ghostscript.com/?p=ghostpdl.git;h=6f749c0c44e7b9e09737b9f29edf29925a34f0cf -Bug: http://bugs.ghostscript.com/show_bug.cgi?id=697179 -Bug-Debian: https://bugs.debian.org/839845 -Forwarded: not-needed -Author: Chris Liddell -Reviewed-by: Salvatore Bonaccorso -Reviewed-by: Emily Ratliff -Last-Update: 2016-11-23 ---- - ---- ghostscript-9.10~dfsg.orig/base/gsdevice.c -+++ ghostscript-9.10~dfsg/base/gsdevice.c -@@ -554,6 +554,7 @@ gx_device_init(gx_device * dev, const gx - dev->memory = mem; - dev->retained = !internal; - rc_init(dev, mem, (internal ? 0 : 1)); -+ rc_increment(dev->icc_struct); - } - - void diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-7979.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-7979.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-7979.patch 2016-11-28 21:54:46.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-7979.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -Description: CVE-2016-7979: type confusion in .initialize_dsc_parser allows remote code execution -Origin: upstream, http://git.ghostscript.com/?p=ghostpdl.git;h=875a0095f37626a721c7ff57d606a0f95af03913 -Bug: http://bugs.ghostscript.com/show_bug.cgi?id=697190 -Bug-Debian: https://bugs.debian.org/839846 -Forwarded: not-needed -Author: Ken Sharp -Reviewed-by: Salvatore Bonaccorso -Reviewed-by: Emily Ratliff -Last-Update: 2016-11-23 ---- - ---- ghostscript-9.10~dfsg.orig/psi/zdscpars.c -+++ ghostscript-9.10~dfsg/psi/zdscpars.c -@@ -132,11 +132,16 @@ zinitialize_dsc_parser(i_ctx_t *i_ctx_p) - ref local_ref; - int code; - os_ptr const op = osp; -- dict * const pdict = op->value.pdict; -- gs_memory_t * const mem = (gs_memory_t *)dict_memory(pdict); -- dsc_data_t * const data = -- gs_alloc_struct(mem, dsc_data_t, &st_dsc_data_t, "DSC parser init"); -+ dict *pdict; -+ gs_memory_t *mem; -+ dsc_data_t *data; - -+ check_read_type(*op, t_dictionary); -+ -+ pdict = op->value.pdict; -+ mem = (gs_memory_t *)dict_memory(pdict); -+ -+ data = gs_alloc_struct(mem, dsc_data_t, &st_dsc_data_t, "DSC parser init"); - if (!data) - return_error(e_VMerror); - data->document_level = 0; diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2016-8602.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-8602.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2016-8602.patch 2016-11-28 21:54:46.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2016-8602.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -Description: CVE-2016-8602: check for sufficient params in .sethalftone5 and param types -Origin: backport, http://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=f5c7555c30393e64ec1f5ab0dfae5b55b3b3fc78 -Bug: http://bugs.ghostscript.com/show_bug.cgi?id=697203 -Bug-Debian: https://bugs.debian.org/840451 -Forwarded: not-needed -Author: Salvatore Bonaccorso -Reviewed-by: Emily Ratliff -Last-Update: 2016-11-23 ---- - ---- ghostscript-9.10~dfsg.orig/psi/zht2.c -+++ ghostscript-9.10~dfsg/psi/zht2.c -@@ -82,14 +82,22 @@ zsethalftone5(i_ctx_t *i_ctx_p) - gs_memory_t *mem; - uint edepth = ref_stack_count(&e_stack); - int npop = 2; -- int dict_enum = dict_first(op); -+ int dict_enum; - ref rvalue[2]; - int cname, colorant_number; - byte * pname; - uint name_size; - int halftonetype, type = 0; - gs_state *pgs = igs; -- int space_index = r_space_index(op - 1); -+ int space_index; -+ -+ if (ref_stack_count(&o_stack) < 2) -+ return_error(e_stackunderflow); -+ check_type(*op, t_dictionary); -+ check_type(*(op - 1), t_dictionary); -+ -+ dict_enum = dict_first(op); -+ space_index = r_space_index(op - 1); - - mem = (gs_memory_t *) idmemory->spaces_indexed[space_index]; - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-11714.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-11714.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-11714.patch 2017-08-24 18:26:25.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-11714.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,53 +0,0 @@ -From 671fd59eb657743aa86fbc1895cb15872a317caa Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Thu, 6 Jul 2017 14:54:02 +0100 -Subject: [PATCH 1/1] Bug 698158: prevent trying to reloc a freed object - -In the token reader, we pass the scanner state structure around as a -t_struct ref on the Postscript operand stack. - -But we explicitly free the scanner state when we're done, which leaves a -dangling reference on the operand stack and, unless that reference gets -overwritten before the next garbager run, we can end up with the garbager -trying to deal with an already freed object - that can cause a crash, or -memory corruption. ---- - psi/ztoken.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/psi/ztoken.c b/psi/ztoken.c -index 4dba7c5..af1ceeb 100644 ---- a/psi/ztoken.c -+++ b/psi/ztoken.c -@@ -107,6 +107,12 @@ token_continue(i_ctx_t *i_ctx_p, scanner_state * pstate, bool save) - int code; - ref token; - -+ /* Since we might free pstate below, and we're dealing with -+ * gc memory referenced by the stack, we need to explicitly -+ * remove the reference to pstate from the stack, otherwise -+ * the garbager will fall over -+ */ -+ make_null(osp); - /* Note that gs_scan_token may change osp! */ - pop(1); /* remove the file or scanner state */ - again: -@@ -183,8 +189,14 @@ ztokenexec_continue(i_ctx_t *i_ctx_p) - static int - tokenexec_continue(i_ctx_t *i_ctx_p, scanner_state * pstate, bool save) - { -- os_ptr op; -+ os_ptr op = osp; - int code; -+ /* Since we might free pstate below, and we're dealing with -+ * gc memory referenced by the stack, we need to explicitly -+ * remove the reference to pstate from the stack, otherwise -+ * the garbager will fall over -+ */ -+ make_null(osp); - /* Note that gs_scan_token may change osp! */ - pop(1); - again: --- -2.9.1 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-5951.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-5951.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-5951.patch 2017-04-28 00:40:32.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-5951.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -From bfa6b2ecbe48edc69a7d9d22a12419aed25960b8 Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Thu, 6 Apr 2017 16:44:54 +0100 -Subject: [PATCH] Bug 697548: use the correct param list enumerator - -When we encountered dictionary in a ref_param_list, we were using the enumerator -for the "parent" param_list, rather than the enumerator for the param_list -we just created for the dictionary. That parent was usually the stack -list enumerator, and caused a segfault. - -Using the correct enumerator works better. ---- - psi/iparam.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/psi/iparam.c b/psi/iparam.c -index 4e63b6d..b2fa85f 100644 ---- a/psi/iparam.c -+++ b/psi/iparam.c -@@ -770,12 +770,13 @@ ref_param_read_typed(gs_param_list * plist, gs_param_name pkey, - gs_param_enumerator_t enumr; - gs_param_key_t key; - ref_type keytype; -+ dict_param_list *dlist = (dict_param_list *) pvalue->value.d.list; - - param_init_enumerator(&enumr); -- if (!(*((iparam_list *) plist)->enumerate) -- ((iparam_list *) pvalue->value.d.list, &enumr, &key, &keytype) -+ if (!(*(dlist->enumerate)) -+ ((iparam_list *) dlist, &enumr, &key, &keytype) - && keytype == t_integer) { -- ((dict_param_list *) pvalue->value.d.list)->int_keys = 1; -+ dlist->int_keys = 1; - pvalue->type = gs_param_type_dict_int_keys; - } - } --- -2.7.4 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-7207.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-7207.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-7207.patch 2017-04-28 00:40:37.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-7207.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -From 309eca4e0a31ea70dcc844812691439312dad091 Mon Sep 17 00:00:00 2001 -From: Ken Sharp -Date: Mon, 20 Mar 2017 09:34:11 +0000 -Subject: [PATCH] Ensure a device has raster memory, before trying to read it. - -Bug #697676 "Null pointer dereference in mem_get_bits_rectangle()" - -This is only possible by abusing/mis-using Ghostscript-specific -language extensions, so cannot happen in a general PostScript program. - -Nevertheless, Ghostscript should not crash. So this commit checks the -memory device to see if raster memory has been allocated, before trying -to read from it. ---- - base/gdevmem.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/base/gdevmem.c b/base/gdevmem.c -index afd05bd..d52d684 100644 ---- a/base/gdevmem.c -+++ b/base/gdevmem.c -@@ -606,6 +606,8 @@ mem_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, - GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE; - return_error(gs_error_rangecheck); - } -+ if (mdev->line_ptrs == 0x00) -+ return_error(gs_error_rangecheck); - if ((w <= 0) | (h <= 0)) { - if ((w | h) < 0) - return_error(gs_error_rangecheck); --- -2.7.4 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-8291-1.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-8291-1.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-8291-1.patch 2017-04-28 02:07:32.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-8291-1.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ -From 4f83478c88c2e05d6e8d79ca4557eb039354d2f3 Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Thu, 27 Apr 2017 13:03:33 +0100 -Subject: [PATCH] Bug 697799: have .eqproc check its parameters - -The Ghostscript custom operator .eqproc was not check the number or type of -the parameters it was given. ---- - psi/zmisc3.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/psi/zmisc3.c b/psi/zmisc3.c -index 54b3042..37293ff 100644 ---- a/psi/zmisc3.c -+++ b/psi/zmisc3.c -@@ -56,6 +56,12 @@ zeqproc(i_ctx_t *i_ctx_p) - ref2_t stack[MAX_DEPTH + 1]; - ref2_t *top = stack; - -+ if (ref_stack_count(&o_stack) < 2) -+ return_error(e_stackunderflow); -+ if (!r_is_array(op - 1) || !r_is_array(op)) { -+ return_error(e_typecheck); -+ } -+ - make_array(&stack[0].proc1, 0, 1, op - 1); - make_array(&stack[0].proc2, 0, 1, op); - for (;;) { --- -2.7.4 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-8291-2.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-8291-2.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-8291-2.patch 2017-04-28 02:04:24.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-8291-2.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -From 04b37bbce174eed24edec7ad5b920eb93db4d47d Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Thu, 27 Apr 2017 13:21:31 +0100 -Subject: [PATCH] Bug 697799: have .rsdparams check its parameters - -The Ghostscript internal operator .rsdparams wasn't checking the number or -type of the operands it was being passed. Do so. - -[adjusted for ghostscript 9.10 -- sbeattie] ---- - psi/zfrsd.c | 22 +++++++++++++++------- - 1 file changed, 15 insertions(+), 7 deletions(-) - -Index: ghostscript-9.10~dfsg/psi/zfrsd.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/psi/zfrsd.c -+++ ghostscript-9.10~dfsg/psi/zfrsd.c -@@ -49,13 +49,20 @@ zrsdparams(i_ctx_t *i_ctx_p) - ref *pFilter; - ref *pDecodeParms; - int Intent = 0; -- bool AsyncRead; -+ bool AsyncRead = false; - ref empty_array, filter1_array, parms1_array; - uint i; -- int code; -+ int code = 0; -+ -+ if (ref_stack_count(&o_stack) < 1) -+ return_error(e_stackunderflow); -+ if (!r_has_type(op, t_dictionary) && !r_has_type(op, t_null)) { -+ return_error(e_typecheck); -+ } - - make_empty_array(&empty_array, a_readonly); -- if (dict_find_string(op, "Filter", &pFilter) > 0) { -+ if (r_has_type(op, t_dictionary) -+ && dict_find_string(op, "Filter", &pFilter) > 0) { - if (!r_is_array(pFilter)) { - if (!r_has_type(pFilter, t_name)) - return_error(e_typecheck); -@@ -94,12 +101,13 @@ zrsdparams(i_ctx_t *i_ctx_p) - return_error(e_typecheck); - } - } -- code = dict_int_param(op, "Intent", 0, 3, 0, &Intent); -+ if (r_has_type(op, t_dictionary)) -+ code = dict_int_param(op, "Intent", 0, 3, 0, &Intent); - if (code < 0 && code != e_rangecheck) /* out-of-range int is ok, use 0 */ - return code; -- if ((code = dict_bool_param(op, "AsyncRead", false, &AsyncRead)) < 0 -- ) -- return code; -+ if (r_has_type(op, t_dictionary)) -+ if ((code = dict_bool_param(op, "AsyncRead", false, &AsyncRead)) < 0) -+ return code; - push(1); - op[-1] = *pFilter; - if (pDecodeParms) diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-8291-regression.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-8291-regression.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-8291-regression.patch 2017-05-16 05:32:22.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-8291-regression.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -From 57f20719e1cfaea77b67cb26e26de7fe4d7f9b2e Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Wed, 3 May 2017 12:05:45 +0100 -Subject: [PATCH] Bug 697846: revision to commit 4f83478c88 (.eqproc) - -When using the "DELAYBIND" feature, it turns out that .eqproc can be called with -parameters that are not both procedures. In this case, it turns out, the -expectation is for the operator to return 'false', rather than throw an error. - -From ccfd2c75ac9be4cbd369e4cbdd40ba11a0c7bdad Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Thu, 11 May 2017 14:07:48 +0100 -Subject: [PATCH] Bug 697892: fix check for op stack underflow. - -In the original fix, I used the wrong method to check for stack underflow, this -is using the correct method. - -[Ubuntu note: backported to ghostscript 9.10 (error names changed) --sbeatte] - -Index: ghostscript-9.10~dfsg/psi/zmisc3.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/psi/zmisc3.c -+++ ghostscript-9.10~dfsg/psi/zmisc3.c -@@ -38,6 +38,15 @@ zcliprestore(i_ctx_t *i_ctx_p) - return gs_cliprestore(igs); - } - -+static inline bool -+eqproc_check_type(ref *r) -+{ -+ return r_has_type(r, t_array) -+ || r_has_type(r, t_mixedarray) -+ || r_has_type(r, t_shortarray) -+ || r_has_type(r, t_oparray); -+} -+ - /* .eqproc */ - /* - * Test whether two procedures are equal to depth 10. -@@ -56,10 +65,11 @@ zeqproc(i_ctx_t *i_ctx_p) - ref2_t stack[MAX_DEPTH + 1]; - ref2_t *top = stack; - -- if (ref_stack_count(&o_stack) < 2) -- return_error(e_stackunderflow); -- if (!r_is_array(op - 1) || !r_is_array(op)) { -- return_error(e_typecheck); -+ check_op(2); -+ if (!eqproc_check_type(op -1) || !eqproc_check_type(op)) { -+ make_false(op - 1); -+ pop(1); -+ return 0; - } - - make_array(&stack[0].proc1, 0, 1, op - 1); -Index: ghostscript-9.10~dfsg/psi/zfrsd.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/psi/zfrsd.c -+++ ghostscript-9.10~dfsg/psi/zfrsd.c -@@ -54,8 +54,7 @@ zrsdparams(i_ctx_t *i_ctx_p) - uint i; - int code = 0; - -- if (ref_stack_count(&o_stack) < 1) -- return_error(e_stackunderflow); -+ check_op(1); - if (!r_has_type(op, t_dictionary) && !r_has_type(op, t_null)) { - return_error(e_typecheck); - } diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-9611.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9611.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-9611.patch 2017-08-24 18:28:13.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9611.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -From c7c55972758a93350882c32147801a3485b010fe Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Mon, 12 Jun 2017 13:08:40 +0100 -Subject: [PATCH] Bug 698024: bounds check zone pointer in Ins_MIRP() - ---- - base/ttinterp.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -Index: ghostscript-9.10~dfsg/base/ttinterp.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/base/ttinterp.c -+++ ghostscript-9.10~dfsg/base/ttinterp.c -@@ -3850,7 +3850,8 @@ static int nInstrCount=0; - /* XXX: UNDOCUMENTED! cvt[-1] = 0 always */ - - if ( BOUNDS( args[0], CUR.zp1.n_points ) || -- BOUNDS( args[1]+1, CUR.cvtSize+1 ) ) -+ BOUNDS( args[1]+1, CUR.cvtSize+1 ) || -+ BOUNDS(CUR.GS.rp0, CUR.zp0.n_points) ) - { - CUR.error = TT_Err_Invalid_Reference; - return; diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-9612.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9612.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-9612.patch 2017-08-24 18:30:49.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9612.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +0,0 @@ -From 98f6da60b9d463c617e631fc254cf6d66f2e8e3c Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Mon, 12 Jun 2017 13:15:17 +0100 -Subject: [PATCH] Bug 698026: bounds check zone pointers in Ins_IP() - ---- - base/ttinterp.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -Index: ghostscript-9.10~dfsg/base/ttinterp.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/base/ttinterp.c -+++ ghostscript-9.10~dfsg/base/ttinterp.c -@@ -4121,7 +4121,9 @@ static int nInstrCount=0; - Int point; - (void)args; - -- if ( CUR.top < CUR.GS.loop ) -+ if ( CUR.top < CUR.GS.loop || -+ BOUNDS(CUR.GS.rp1, CUR.zp0.n_points) || -+ BOUNDS(CUR.GS.rp2, CUR.zp1.n_points)) - { - CUR.error = TT_Err_Invalid_Reference; - return; diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-9726.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9726.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-9726.patch 2017-08-24 18:31:21.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9726.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +0,0 @@ -From 7755e67116e8973ee0e3b22d653df026a84fa01b Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Thu, 15 Jun 2017 08:58:31 +0100 -Subject: [PATCH] Bug 698055: bounds check zone pointer in Ins_MDRP - ---- - base/ttinterp.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -Index: ghostscript-9.10~dfsg/base/ttinterp.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/base/ttinterp.c -+++ ghostscript-9.10~dfsg/base/ttinterp.c -@@ -3762,7 +3762,8 @@ static int nInstrCount=0; - - point = (Int)args[0]; - -- if ( BOUNDS( args[0], CUR.zp1.n_points ) ) -+ if ( BOUNDS( args[0], CUR.zp1.n_points ) || -+ BOUNDS( CUR.GS.rp0, CUR.zp0.n_points) ) - { - /* Current version of FreeType silently ignores this out of bounds error - * and drops the instruction, see bug #691121 diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-9727.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9727.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-9727.patch 2017-08-24 18:31:42.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9727.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ -From 937ccd17ac65935633b2ebc06cb7089b91e17e6b Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Thu, 15 Jun 2017 09:05:20 +0100 -Subject: [PATCH] Bug 698056: make bounds check in gx_ttfReader__Read more - robust - ---- - base/gxttfb.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/base/gxttfb.c b/base/gxttfb.c -index 0e9a444..e1561af 100644 ---- a/base/gxttfb.c -+++ b/base/gxttfb.c -@@ -79,7 +79,8 @@ static void gx_ttfReader__Read(ttfReader *self, void *p, int n) - if (!r->error) { - if (r->extra_glyph_index != -1) { - q = r->glyph_data.bits.data + r->pos; -- r->error = (r->glyph_data.bits.size - r->pos < n ? -+ r->error = ((r->pos >= r->glyph_data.bits.size || -+ r->glyph_data.bits.size - r->pos < n) ? - gs_note_error(gs_error_invalidfont) : 0); - if (r->error == 0) - memcpy(p, q, n); --- -2.9.1 - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-9739.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9739.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-9739.patch 2017-08-24 18:32:04.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9739.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -From c501a58f8d5650c8ba21d447c0d6f07eafcb0f15 Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Fri, 16 Jun 2017 08:29:25 +0100 -Subject: [PATCH] Bug 698063: Bounds check Ins_JMPR - ---- - base/ttinterp.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -Index: ghostscript-9.10~dfsg/base/ttinterp.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/base/ttinterp.c -+++ ghostscript-9.10~dfsg/base/ttinterp.c -@@ -1793,6 +1793,12 @@ static int nInstrCount=0; - - static void Ins_JMPR( INS_ARG ) - { -+ if ( BOUNDS(CUR.IP + args[0], CUR.codeSize ) ) -+ { -+ CUR.error = TT_Err_Invalid_Reference; -+ return; -+ } -+ - CUR.IP += (Int)(args[0]); - CUR.step_ins = FALSE; - diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2017-9835.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9835.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2017-9835.patch 2017-08-24 18:32:22.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2017-9835.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -From cfde94be1d4286bc47633c6e6eaf4e659bd78066 Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Wed, 7 Jun 2017 14:55:12 +0100 -Subject: [PATCH] Bug 697985: bounds check the array allocations methods - -The clump allocator has four allocation functions that use 'number of elements' -and 'size of elements' parameters (rather than a simple 'number of bytes'). - -Those need specific bounds checking. -diff --git a/base/gsalloc.c b/base/gsalloc.c -index 87503a3..d6d25d1 100644 ---- a/base/gsalloc.c -+++ b/base/gsalloc.c -@@ -669,6 +669,18 @@ i_alloc_struct_immovable(gs_memory_t * mem, gs_memory_type_ptr_t pstype, - alloc_trace("|+<.", imem, cname, pstype, size, obj); - return obj; - } -+ -+static inline bool -+alloc_array_check_size(ulong num_elements, ulong elt_size, ulong *lsize) -+{ -+ int64_t s = (int64_t)num_elements * elt_size; -+ if (s > max_uint) { -+ return false; -+ } -+ *lsize = (ulong)s; -+ return true; -+} -+ - static byte * - i_alloc_byte_array(gs_memory_t * mem, uint num_elements, uint elt_size, - client_name_t cname) -@@ -676,12 +688,15 @@ i_alloc_byte_array(gs_memory_t * mem, uint num_elements, uint elt_size, - gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; - obj_header_t *obj; - -+ ulong lsize; - #ifdef MEMENTO - if (Memento_failThisEvent()) - return NULL; - #endif - -- obj = alloc_obj(imem, (ulong) num_elements * elt_size, -+ if (alloc_array_check_size(num_elements, elt_size, &lsize) == false) -+ return NULL; -+ obj = alloc_obj(imem, lsize, - &st_bytes, ALLOC_DIRECT, cname); - - if_debug6m('A', mem, "[a%d:+b.]%s -bytes-*(%lu=%u*%u) = 0x%lx\n", -@@ -697,12 +712,15 @@ i_alloc_byte_array_immovable(gs_memory_t * mem, uint num_elements, - gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; - obj_header_t *obj; - -+ ulong lsize; - #ifdef MEMENTO - if (Memento_failThisEvent()) - return NULL; - #endif - -- obj = alloc_obj(imem, (ulong) num_elements * elt_size, -+ if (alloc_array_check_size(num_elements, elt_size, &lsize) == false) -+ return NULL; -+ obj = alloc_obj(imem, lsize, - &st_bytes, ALLOC_IMMOVABLE | ALLOC_DIRECT, - cname); - -@@ -719,6 +737,7 @@ i_alloc_struct_array(gs_memory_t * mem, uint num_elements, - gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; - obj_header_t *obj; - -+ ulong lsize; - #ifdef MEMENTO - if (Memento_failThisEvent()) - return NULL; -@@ -732,9 +751,9 @@ i_alloc_struct_array(gs_memory_t * mem, uint num_elements, - return NULL; /* fail */ - } - #endif -- obj = alloc_obj(imem, -- (ulong) num_elements * pstype->ssize, -- pstype, ALLOC_DIRECT, cname); -+ if (alloc_array_check_size(num_elements, pstype->ssize, &lsize) == false) -+ return NULL; -+ obj = alloc_obj(imem, lsize, pstype, ALLOC_DIRECT, cname); - if_debug7m('A', mem, "[a%d:+<.]%s %s*(%lu=%u*%u) = 0x%lx\n", - alloc_trace_space(imem), client_name_string(cname), - struct_type_name_string(pstype), -@@ -749,15 +768,16 @@ i_alloc_struct_array_immovable(gs_memory_t * mem, uint num_elements, - gs_ref_memory_t * const imem = (gs_ref_memory_t *)mem; - obj_header_t *obj; - -+ ulong lsize; - #ifdef MEMENTO - if (Memento_failThisEvent()) - return NULL; - #endif - - ALLOC_CHECK_SIZE(mem,pstype); -- obj = alloc_obj(imem, -- (ulong) num_elements * pstype->ssize, -- pstype, ALLOC_IMMOVABLE | ALLOC_DIRECT, cname); -+ if (alloc_array_check_size(num_elements, pstype->ssize, &lsize) == false) -+ return NULL; -+ obj = alloc_obj(imem, lsize, pstype, ALLOC_IMMOVABLE | ALLOC_DIRECT, cname); - if_debug7m('A', mem, "[a%d|+<.]%s %s*(%lu=%u*%u) = 0x%lx\n", - alloc_trace_space(imem), client_name_string(cname), - struct_type_name_string(pstype), diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2018-10194.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-10194.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2018-10194.patch 2018-04-23 17:27:40.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-10194.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -Backported of: - -From 39b1e54b2968620723bf32e96764c88797714879 Mon Sep 17 00:00:00 2001 -From: Ken Sharp -Date: Wed, 18 Apr 2018 15:46:32 +0100 -Subject: [PATCH] pdfwrite - Guard against trying to output an infinite number - -Bug #699255 " Buffer overflow on pprintg1 due to mishandle postscript file data to pdf" - -The file uses an enormous parameter to xyxhow, causing an overflow in -the calculation of text positioning (value > 1e39). - -Since this is basically a nonsense value, and PostScript only supports -real values up to 1e38, this patch follows the same approach as for -a degenerate CTM, and treats it as 0. - -Adobe Acrobat Distiller throws a limitcheck error, so we could do that -instead if this approach proves to be a problem. -diff --git a/devices/vector/gdevpdts.c b/devices/vector/gdevpdts.c -index b7ddec7..ca433fd 100644 ---- a/devices/vector/gdevpdts.c -+++ b/devices/vector/gdevpdts.c -@@ -152,9 +152,14 @@ append_text_move(pdf_text_state_t *pts, floatp dw) - static int - set_text_distance(gs_point *pdist, floatp dx, floatp dy, const gs_matrix *pmat) - { -- int code = gs_distance_transform_inverse(dx, dy, pmat, pdist); -+ int code; - double rounded; - -+ if (dx > 1e38 || dy > 1e38) -+ code = gs_error_undefinedresult; -+ else -+ code = gs_distance_transform_inverse(dx, dy, pmat, pdist); -+ - if (code == gs_error_undefinedresult) { - /* The CTM is degenerate. - Can't know the distance in user space. diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2018-11645.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-11645.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2018-11645.patch 2018-09-11 15:27:39.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-11645.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -From b60d50b7567369ad856cebe1efb6cd7dd2284219 Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Sat, 8 Oct 2016 16:35:39 +0100 -Subject: [PATCH] Bug 697193: status operator honour SAFER option - ---- - psi/zfile.c | 16 +++++++++++----- - 1 file changed, 11 insertions(+), 5 deletions(-) - -Index: ghostscript-9.10~dfsg/psi/zfile.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/psi/zfile.c 2018-09-11 11:27:37.527151269 -0400 -+++ ghostscript-9.10~dfsg/psi/zfile.c 2018-09-11 11:27:37.527151269 -0400 -@@ -209,10 +209,13 @@ z_check_file_permissions(gs_memory_t *me - if (code < 0) - return code; - -- if (pname.iodev && i_ctx_p->LockFilePermissions && strcmp(pname.iodev->dname, "%pipe%") == 0) -- return gs_error_invalidfileaccess; -- -- code = check_file_permissions(i_ctx_p, fname, len, permitgroup); -+ if (pname.iodev && i_ctx_p->LockFilePermissions -+ && strcmp(pname.iodev->dname, "%pipe%") == 0) { -+ code = gs_note_error(gs_error_invalidfileaccess); -+ } -+ else { -+ code = check_file_permissions(i_ctx_p, fname, len, permitgroup); -+ } - return code; - } - -@@ -502,8 +505,11 @@ zstatus(i_ctx_t *i_ctx_p) - code = gs_terminate_file_name(&pname, imemory, "status"); - if (code < 0) - return code; -- code = (*pname.iodev->procs.file_status)(pname.iodev, -+ if ((code = check_file_permissions(i_ctx_p, pname.fname, pname.len, -+ "PermitFileReading")) >= 0) { -+ code = (*pname.iodev->procs.file_status)(pname.iodev, - pname.fname, &fstat); -+ } - switch (code) { - case 0: - check_ostack(4); diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2018-15908.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-15908.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2018-15908.patch 2018-09-11 15:27:48.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-15908.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -Backport of: - -From 0d3901189f245232f0161addf215d7268c4d05a3 Mon Sep 17 00:00:00 2001 -From: Chris Liddell -Date: Tue, 21 Aug 2018 20:17:05 +0100 -Subject: [PATCH] Bug 699657: properly apply file permissions to .tempfile - ---- - psi/zfile.c | 20 ++++++++++++++++++-- - 1 file changed, 18 insertions(+), 2 deletions(-) - -Index: ghostscript-9.10~dfsg/psi/zfile.c -=================================================================== ---- ghostscript-9.10~dfsg.orig/psi/zfile.c 2018-09-11 11:27:46.631176513 -0400 -+++ ghostscript-9.10~dfsg/psi/zfile.c 2018-09-11 11:27:46.631176513 -0400 -@@ -718,7 +718,23 @@ ztempfile(i_ctx_t *i_ctx_p) - } - - if (gp_file_name_is_absolute(pstr, strlen(pstr))) { -- if (check_file_permissions(i_ctx_p, pstr, strlen(pstr), -+ int plen = strlen(pstr); -+ const char *sep = gp_file_name_separator(); -+#ifdef DEBUG -+ int seplen = strlen(sep); -+ if (seplen != 1) -+ return_error(gs_error_Fatal); -+#endif -+ /* strip off the file name prefix, leave just the directory name -+ * so we can check if we are allowed to write to it -+ */ -+ for ( ; plen >=0; plen--) { -+ if (pstr[plen] == sep[0]) -+ break; -+ } -+ memcpy(fname, pstr, plen); -+ fname[plen] = '\0'; -+ if (check_file_permissions(i_ctx_p, fname, strlen(fname), - "PermitFileWriting") < 0) { - return_error(e_invalidfileaccess); - } diff -Nru ghostscript-9.10~dfsg/debian/patches/CVE-2018-15909-1.patch ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-15909-1.patch --- ghostscript-9.10~dfsg/debian/patches/CVE-2018-15909-1.patch 2018-09-11 15:28:50.000000000 +0000 +++ ghostscript-9.25~dfsg+1/debian/patches/CVE-2018-15909-1.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -Backport of: - -From 0b6cd1918e1ec4ffd087400a754a845180a4522b Mon Sep 17 00:00:00 2001 -From: Ken Sharp -Date: Thu, 23 Aug 2018 14:12:48 +0100 -Subject: [PATCH] Fix Bug 699660 "shading_param incomplete type checking" - -Its possible to pass a t_struct parameter to .shfill which is not a -shading function built by .buildshading. This could then lead to memory -corruption or a segmentation fault by treating the object passed in -as if it were a shading. - -Its non-trivial to check the t_struct, because this function can take -7 different kinds of structures as a parameter. Checking these is -possible, of course, but would add a performance penalty. - -However, we can note that we never call .shfill without first calling -.buildshading, and we never call .buildshading without immediately -calling .shfill. So we can treat these as an atomic operation. The -.buildshading function takes all its parameters as PostScript objects -and validates them, so that should be safe. - -This allows us to 'hide' the .shfill operator preventing the possibility -of passing an invalid parameter. ---- - Resource/Init/gs_init.ps | 4 ++-- - Resource/Init/gs_ll3.ps | 7 ++++++- - Resource/Init/pdf_draw.ps | 3 +-- - 3 files changed, 9 insertions(+), 5 deletions(-) - -Index: ghostscript-9.10~dfsg/Resource/Init/gs_init.ps -=================================================================== ---- ghostscript-9.10~dfsg.orig/Resource/Init/gs_init.ps 2018-09-11 11:28:17.211261352 -0400 -+++ ghostscript-9.10~dfsg/Resource/Init/gs_init.ps 2018-09-11 11:28:17.207261341 -0400 -@@ -2154,8 +2154,8 @@ SAFER { .setsafeglobal } if - /.getiodevice /.getdevparms /.putdevparams /.bbox_transform /.matchmedia /.matchpagesize /.defaultpapersize - /.oserrno /.setoserrno /.oserrorstring /.getCPSImode - /.getscanconverter /.setscanconverter /.type1encrypt /.type1decrypt/.languagelevel /.setlanguagelevel /.eqproc /.fillpage /.buildpattern1 /.saslprep --/.buildshading1 /.buildshadin2 /.buildshading3 /.buildshading4 /.buildshading5 /.buildshading6 /.buildshading7 /.buildshadingpattern --/.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring -+/.buildshading1 /.buildshading2 /.buildshading3 /.buildshading4 /.buildshading5 /.buildshading6 /.buildshading7 /.buildshadingpattern -+%/.shfill /.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring - /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile - /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams - /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath -Index: ghostscript-9.10~dfsg/Resource/Init/gs_ll3.ps -=================================================================== ---- ghostscript-9.10~dfsg.orig/Resource/Init/gs_ll3.ps 2018-09-11 11:28:17.211261352 -0400 -+++ ghostscript-9.10~dfsg/Resource/Init/gs_ll3.ps 2018-09-11 11:28:17.211261352 -0400 -@@ -406,6 +406,11 @@ systemdict /.reuseparamdict mark - /shfill .systemvar /undefined signalerror - } ifelse - } bind def -+ -+/.buildshading_and_shfill { -+ .buildshading .shfill -+} bind def -+ - systemdict /.reuseparamdict undef - - /.buildpattern2 { %